Remove linux-2.4 sparse tree.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-10-07 23:36:26 +01:00
1 parent 7951aaa23a
commit 1660169e32
86 files changed
+8 -31371

No files matched your search

+1 -9
View File
@@ -3,8 +3,7 @@
#
KERNELS ?= linux-2.6-xen0 linux-2.6-xenU
# linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU
# You may use wildcards in the above e.g. KERNELS=*2.4*
# You may use wildcards in the above e.g. KERNELS=*2.6*
XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) )
@@ -188,12 +187,5 @@ uninstall:
rm -rf $(D)/usr/share/man/man8/xen*
# Legacy targets for compatibility
linux24:
$(MAKE) 'KERNELS=linux-2.4*' kernels
linux26:
$(MAKE) 'KERNELS=linux-2.6*' kernels
netbsd20:
$(MAKE) netbsd-2.0-xenU-build
+3 -3
View File
@@ -22,7 +22,7 @@ Xen is freely-distributable Open Source software, released under the
GNU GPL.
The 2.0 release offers excellent performance, hardware support and
enterprise-grade features such as live migration. Linux 2.6, 2.4 and
enterprise-grade features such as live migration. Linux 2.6 and
NetBSD 2.0 are already available for Xen, with more operating system
ports on the way.
@@ -97,8 +97,8 @@ performed with root privileges.]
version for unstable.
2. cd to xen-unstable (or whatever you sensibly rename it to).
The Linux (2.4 and 2.6), netbsd and freebsd kernel source
trees are in the $os-$version-xen-sparse directories.
The Linux, netbsd and freebsd kernel source trees are in
the $os-$version-xen-sparse directories.
On Linux:
-51
View File
@@ -1,51 +0,0 @@
OS = linux
LINUX_SERIES = 2.4
LINUX_VER = 2.4.30
EXTRAVERSION = xenU
LINUX_DIR = $(OS)-$(LINUX_VER)-$(EXTRAVERSION)
include buildconfigs/Rules.mk
.PHONY: build clean delete
# The real action starts here!
build: $(LINUX_DIR)/include/linux/autoconf.h
if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules ; \
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \
fi
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) install
$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
rm -rf $(LINUX_DIR)
cp -al $(<D) $(LINUX_DIR)
# Apply arch-xen patches
( cd linux-$(LINUX_SERIES)-xen-sparse ; \
LINUX_ARCH=$(LINUX_ARCH) ./mkbuildtree ../$(LINUX_DIR) )
# Re-use config from install dir if one exits else use default config
CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p' $(LINUX_DIR)/Makefile); \
[ -r $(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
cp $(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) $(LINUX_DIR)/.config \
|| cp $(LINUX_DIR)/arch/xen/defconfig-$(EXTRAVERSION) \
$(LINUX_DIR)/.config
# Patch kernel Makefile to set EXTRAVERSION
( cd $(LINUX_DIR) ; \
sed -e 's/^EXTRAVERSION.*/&$$(XENGUEST)\nXENGUEST = -$(EXTRAVERSION)/' Makefile >Mk.tmp ; \
rm -f Makefile ; mv Mk.tmp Makefile )
make -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) oldconfig
make -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) dep
config: CONFIGMODE = menuconfig
config: $(LINUX_DIR)/include/linux/autoconf.h
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) $(CONFIGMODE)
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) dep
clean::
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
delete:
rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR)
+1 -1
View File
@@ -154,7 +154,7 @@ one vif with default MAC.
(memory 64)
(image
(linux
(kernel /boot/vmlinuz-2.4.26-xen)
(kernel /boot/vmlinuz-2.6.12-xen)
(ip ::::xendom1:eth0:dhcp)
(root /dev/xda1)
(args 'rw fastboot 4')
+2 -6
View File
@@ -1,7 +1,7 @@
\chapter{Installation}
The Xen distribution includes three main components: Xen itself, ports
of Linux 2.4 and 2.6 and NetBSD to run on Xen, and the userspace
of Linux and NetBSD to run on Xen, and the userspace
tools required to manage a Xen-based system. This chapter describes
how to install the Xen~2.0 distribution from source. Alternatively,
there may be pre-built packages available as part of your operating
@@ -169,7 +169,7 @@ KERNELS ?= mk.linux-2.6-xen0 mk.linux-2.6-xenU
You can edit this line to include any set of operating system kernels
which have configurations in the top-level \path{buildconfigs/}
directory, for example \path{mk.linux-2.4-xenU} to build a Linux 2.4
directory, for example \path{mk.linux-2.6-xenU} to build a Linux 2.6
kernel containing only virtual device drivers.
%% Inspect the Makefile if you want to see what goes on during a
@@ -190,10 +190,6 @@ kernel containing only virtual device drivers.
%% mkbuildtree} script to add the Xen patches to the kernel.
%% The procedure is similar to build the Linux 2.4 port: \\
%% \verb!# LINUX_SRC=/path/to/linux2.4/source make linux24!
%% \framebox{\parbox{5in}{
%% {\bf Distro specific:} \\
%% {\it Gentoo} --- if not using udev (most installations,
+1 -1
View File
@@ -28,7 +28,7 @@ system kernels must explicitly support Xen, a key feature is that user
space applications and libraries \emph{do not} require modification.
Xen support is available for increasingly many operating systems:
right now, Linux 2.4, Linux 2.6 and NetBSD are available for Xen 2.0.
right now, Linux and NetBSD are available for Xen 2.0.
A FreeBSD port is undergoing testing and will be incorporated into the
release soon. Other OS ports, including Plan 9, are in progress. We
hope that that arch-xen patches will be incorporated into the
-592
View File
@@ -1,592 +0,0 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 30
EXTRAVERSION =
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
# SUBARCH always tells us the underlying machine architecture.
# Unless overridden, by default ARCH is equivalent to SUBARCH.
# This will be overriden for Xen and UML builds.
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
ARCH ?= $(SUBARCH)
## XXX The following hack can be discarded after users have adjusted to the
## architectural name change 'xeno' -> 'xen'.
ifeq ($(ARCH),xeno)
ARCH := xen
endif
KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi)
TOPDIR := $(shell /bin/pwd)
HPATH = $(TOPDIR)/include
FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math-emu
HOSTCC = gcc
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
CROSS_COMPILE =
#
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
MAKEFILES = $(TOPDIR)/.config
GENKSYMS = /sbin/genksyms
DEPMOD = /sbin/depmod
MODFLAGS = -DMODULE
CFLAGS_KERNEL =
PERL = perl
AWK = awk
RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
else echo rpm; fi)
export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL AWK
all: do-it-all
#
# Make "config" the default target if there is no configuration file or
# "depend" the target if there is no top-level dependency information.
#
ifeq (.config,$(wildcard .config))
include .config
ifeq (.depend,$(wildcard .depend))
include .depend
do-it-all: Version vmlinux
else
CONFIGURATION = depend
do-it-all: depend
endif
else
CONFIGURATION = config
do-it-all: config
endif
#
# INSTALL_PATH specifies where to place the updated kernel and system map
# images. Uncomment if you want to place them anywhere other than root.
#
#export INSTALL_PATH=/boot
#
# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
# relocations required by build roots. This is not defined in the
# makefile but the arguement can be passed to make if needed.
#
MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
export MODLIB
#
# standard CFLAGS
#
CPPFLAGS := -D__KERNEL__ -I$(HPATH)
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
-fno-strict-aliasing -fno-common
ifndef CONFIG_FRAME_POINTER
CFLAGS += -fomit-frame-pointer
endif
AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
#
# ROOT_DEV specifies the default root-device when making the image.
# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
# the default of FLOPPY is used by 'build'.
# This is i386 specific.
#
export ROOT_DEV = CURRENT
#
# If you want to preset the SVGA mode, uncomment the next line and
# set SVGA_MODE to whatever number you want.
# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
# The number is the same as you would ordinarily press at bootup.
# This is i386 specific.
#
export SVGA_MODE = -DSVGA_MODE=NORMAL_VGA
#
# If you want the RAM disk device, define this to be the size in blocks.
# This is i386 specific.
#
#export RAMDISK = -DRAMDISK=512
CORE_FILES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
NETWORKS =net/network.o
LIBS =$(TOPDIR)/lib/lib.a
SUBDIRS =kernel drivers mm fs net ipc lib crypto
DRIVERS-n :=
DRIVERS-y :=
DRIVERS-m :=
DRIVERS- :=
DRIVERS-$(CONFIG_ACPI_BOOT) += drivers/acpi/acpi.o
DRIVERS-$(CONFIG_PARPORT) += drivers/parport/driver.o
DRIVERS-y += drivers/char/char.o \
drivers/block/block.o \
drivers/misc/misc.o \
drivers/net/net.o
DRIVERS-$(CONFIG_AGP) += drivers/char/agp/agp.o
DRIVERS-$(CONFIG_DRM_NEW) += drivers/char/drm/drm.o
DRIVERS-$(CONFIG_DRM_OLD) += drivers/char/drm-4.0/drm.o
DRIVERS-$(CONFIG_NUBUS) += drivers/nubus/nubus.a
DRIVERS-$(CONFIG_NET_FC) += drivers/net/fc/fc.o
DRIVERS-$(CONFIG_DEV_APPLETALK) += drivers/net/appletalk/appletalk.o
DRIVERS-$(CONFIG_TR) += drivers/net/tokenring/tr.o
DRIVERS-$(CONFIG_WAN) += drivers/net/wan/wan.o
DRIVERS-$(CONFIG_ARCNET) += drivers/net/arcnet/arcnetdrv.o
DRIVERS-$(CONFIG_ATM) += drivers/atm/atm.o
DRIVERS-$(CONFIG_IDE) += drivers/ide/idedriver.o
DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
DRIVERS-$(CONFIG_SCSI) += drivers/scsi/scsidrv.o
DRIVERS-$(CONFIG_FUSION_BOOT) += drivers/message/fusion/fusion.o
DRIVERS-$(CONFIG_IEEE1394) += drivers/ieee1394/ieee1394drv.o
ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
DRIVERS-y += drivers/cdrom/driver.o
endif
DRIVERS-$(CONFIG_SOUND) += drivers/sound/sounddrivers.o
DRIVERS-$(CONFIG_PCI) += drivers/pci/driver.o
DRIVERS-$(CONFIG_MTD) += drivers/mtd/mtdlink.o
DRIVERS-$(CONFIG_PCMCIA) += drivers/pcmcia/pcmcia.o
DRIVERS-$(CONFIG_NET_PCMCIA) += drivers/net/pcmcia/pcmcia_net.o
DRIVERS-$(CONFIG_NET_WIRELESS) += drivers/net/wireless/wireless_net.o
DRIVERS-$(CONFIG_PCMCIA_CHRDEV) += drivers/char/pcmcia/pcmcia_char.o
DRIVERS-$(CONFIG_DIO) += drivers/dio/dio.a
DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o
DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/driver.o
DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
DRIVERS-$(CONFIG_PPC32) += drivers/macintosh/macintosh.o
DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o
DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o
DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
DRIVERS-$(CONFIG_VT) += drivers/video/video.o
DRIVERS-$(CONFIG_PARIDE) += drivers/block/paride/paride.a
DRIVERS-$(CONFIG_HAMRADIO) += drivers/net/hamradio/hamradio.o
DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a
DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o
DRIVERS-$(CONFIG_USB_GADGET) += drivers/usb/gadget/built-in.o
DRIVERS-y +=drivers/media/media.o
DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o
DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o
DRIVERS-$(CONFIG_I2O) += drivers/message/i2o/i2o.o
DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o
DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o
DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
DRIVERS-$(CONFIG_GSC) += drivers/gsc/gscbus.o
DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o
DRIVERS := $(DRIVERS-y)
# files removed with 'make clean'
CLEAN_FILES = \
kernel/ksyms.lst include/linux/compile.h \
vmlinux System.map \
.tmp* \
drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
drivers/char/conmakehash \
drivers/char/drm/*-mod.c \
drivers/pci/devlist.h drivers/pci/classlist.h drivers/pci/gen-devlist \
drivers/zorro/devlist.h drivers/zorro/gen-devlist \
drivers/sound/bin2hex drivers/sound/hex2hex \
drivers/atm/fore200e_mkfirm drivers/atm/{pca,sba}*{.bin,.bin1,.bin2} \
drivers/scsi/aic7xxx/aicasm/aicasm \
drivers/scsi/aic7xxx/aicasm/aicasm_gram.c \
drivers/scsi/aic7xxx/aicasm/aicasm_gram.h \
drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.c \
drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.h \
drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.c \
drivers/scsi/aic7xxx/aicasm/aicasm_scan.c \
drivers/scsi/aic7xxx/aicasm/aicdb.h \
drivers/scsi/aic7xxx/aicasm/y.tab.h \
drivers/scsi/53c700_d.h \
drivers/tc/lk201-map.c \
net/khttpd/make_times_h \
net/khttpd/times.h \
submenu* \
drivers/ieee1394/oui.c
# directories removed with 'make clean'
CLEAN_DIRS = \
modules
# files removed with 'make mrproper'
MRPROPER_FILES = \
include/linux/autoconf.h include/linux/version.h \
lib/crc32table.h lib/gen_crc32table \
drivers/net/hamradio/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h \
drivers/net/hamradio/soundmodem/sm_tbl_{hapn4800,psk4800}.h \
drivers/net/hamradio/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h \
drivers/net/hamradio/soundmodem/gentbl \
drivers/sound/*_boot.h drivers/sound/.*.boot \
drivers/sound/msndinit.c \
drivers/sound/msndperm.c \
drivers/sound/pndsperm.c \
drivers/sound/pndspini.c \
drivers/atm/fore200e_*_fw.c drivers/atm/.fore200e_*.fw \
.version .config* config.in config.old \
scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp \
scripts/lxdialog/*.o scripts/lxdialog/lxdialog \
.menuconfig.log \
include/asm \
.hdepend scripts/mkdep scripts/split-include scripts/docproc \
$(TOPDIR)/include/linux/modversions.h \
kernel.spec
# directories removed with 'make mrproper'
MRPROPER_DIRS = \
include/config \
$(TOPDIR)/include/linux/modules
include arch/$(ARCH)/Makefile
# Extra cflags for kbuild 2.4. The default is to forbid includes by kernel code
# from user space headers. Some UML code requires user space headers, in the
# UML Makefiles add 'kbuild_2_4_nostdinc :=' before include Rules.make. No
# other kernel code should include user space headers, if you need
# 'kbuild_2_4_nostdinc :=' or -I/usr/include for kernel code and you are not UML
# then your code is broken! KAO.
kbuild_2_4_nostdinc := -nostdinc -iwithprefix include
export kbuild_2_4_nostdinc
export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
.S.s:
$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
.S.o:
$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -c -o $*.o $<
Version: dummy
@rm -f include/linux/compile.h
boot: vmlinux
@$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
--start-group \
$(CORE_FILES) \
$(DRIVERS) \
$(NETWORKS) \
$(LIBS) \
--end-group \
-o vmlinux
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
symlinks:
rm -f include/asm
( cd include ; ln -sf asm-$(ARCH) asm)
@if [ ! -d include/linux/modules ]; then \
mkdir include/linux/modules; \
fi
oldconfig: symlinks
$(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
xconfig: symlinks
$(MAKE) -C scripts kconfig.tk
wish -f scripts/kconfig.tk
menuconfig: include/linux/version.h symlinks
$(MAKE) -C scripts/lxdialog all
$(CONFIG_SHELL) scripts/Menuconfig arch/$(ARCH)/config.in
config: symlinks
$(CONFIG_SHELL) scripts/Configure arch/$(ARCH)/config.in
include/config/MARKER: scripts/split-include include/linux/autoconf.h
scripts/split-include include/linux/autoconf.h include/config
@ touch include/config/MARKER
linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))
$(patsubst %, _dir_%, $(SUBDIRS)) : dummy include/linux/version.h include/config/MARKER
$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C $(patsubst _dir_%, %, $@)
$(TOPDIR)/include/linux/version.h: include/linux/version.h
$(TOPDIR)/include/linux/compile.h: include/linux/compile.h
newversion:
. scripts/mkversion > .tmpversion
@mv -f .tmpversion .version
uts_len := 64
uts_truncate := sed -e 's/\(.\{1,$(uts_len)\}\).*/\1/'
include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
@echo -n \#`cat .version` > .ver1
@if [ -n "$(CONFIG_SMP)" ] ; then echo -n " SMP" >> .ver1; fi
@if [ -f .name ]; then echo -n \-`cat .name` >> .ver1; fi
@LANG=C echo ' '`date` >> .ver1
@echo \#define UTS_VERSION \"`cat .ver1 | $(uts_truncate)`\" > .ver
@LANG=C echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver
@echo \#define LINUX_COMPILE_HOST \"`hostname | $(uts_truncate)`\" >> .ver
@([ -x /bin/dnsdomainname ] && /bin/dnsdomainname > .ver1) || \
([ -x /bin/domainname ] && /bin/domainname > .ver1) || \
echo > .ver1
@echo \#define LINUX_COMPILE_DOMAIN \"`cat .ver1 | $(uts_truncate)`\" >> .ver
@echo \#define LINUX_COMPILER \"`$(CC) $(CFLAGS) -v 2>&1 | tail -n 1`\" >> .ver
@mv -f .ver $@
@rm -f .ver1
include/linux/version.h: ./Makefile
@expr length "$(KERNELRELEASE)" \<= $(uts_len) > /dev/null || \
(echo KERNELRELEASE \"$(KERNELRELEASE)\" exceeds $(uts_len) characters >&2; false)
@echo \#define UTS_RELEASE \"$(KERNELRELEASE)\" > .ver
@echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver
@echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver
@mv -f .ver $@
comma := ,
init/version.o: init/version.c include/linux/compile.h include/config/MARKER
$(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DUTS_MACHINE='"$(SUBARCH)"' -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o init/version.o init/version.c
init/main.o: init/main.c include/config/MARKER
$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $@ $<
init/do_mounts.o: init/do_mounts.c include/config/MARKER
$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $@ $<
fs lib mm ipc kernel drivers net: dummy
$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
TAGS: dummy
{ find include/asm-${ARCH} -name '*.h' -print ; \
find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print ; \
find $(SUBDIRS) init arch/${ARCH} -name '*.[chS]' ; } | grep -v SCCS | grep -v '\.svn' | etags -
# Exuberant ctags works better with -I
tags: dummy
CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \
ctags $$CTAGSF `find include/asm-$(ARCH) -name '*.h'` && \
find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs ctags $$CTAGSF -a && \
find $(SUBDIRS) init -name '*.[ch]' | xargs ctags $$CTAGSF -a
ifdef CONFIG_MODULES
ifdef CONFIG_MODVERSIONS
MODFLAGS += -DMODVERSIONS -include $(HPATH)/linux/modversions.h
endif
.PHONY: modules
modules: $(patsubst %, _mod_%, $(SUBDIRS))
.PHONY: $(patsubst %, _mod_%, $(SUBDIRS))
$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h include/config/MARKER
$(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules
.PHONY: modules_install
modules_install: _modinst_ $(patsubst %, _modinst_%, $(SUBDIRS)) _modinst_post
.PHONY: _modinst_
_modinst_:
@rm -rf $(MODLIB)/kernel
@rm -f $(MODLIB)/build
@mkdir -p $(MODLIB)/kernel
@ln -s $(TOPDIR) $(MODLIB)/build
# If System.map exists, run depmod. This deliberately does not have a
# dependency on System.map since that would run the dependency tree on
# vmlinux. This depmod is only for convenience to give the initial
# boot a modules.dep even before / is mounted read-write. However the
# boot script depmod is the master version.
ifeq "$(strip $(INSTALL_MOD_PATH))" ""
depmod_opts :=
else
depmod_opts := -b $(INSTALL_MOD_PATH) -r
endif
.PHONY: _modinst_post
_modinst_post: _modinst_post_pcmcia
if [ -r System.map ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
# Backwards compatibilty symlinks for people still using old versions
# of pcmcia-cs with hard coded pathnames on insmod. Remove
# _modinst_post_pcmcia for kernel 2.4.1.
.PHONY: _modinst_post_pcmcia
_modinst_post_pcmcia:
cd $(MODLIB); \
mkdir -p pcmcia; \
find kernel -path '*/pcmcia/*' -name '*.o' | xargs -i -r ln -sf ../{} pcmcia
.PHONY: $(patsubst %, _modinst_%, $(SUBDIRS))
$(patsubst %, _modinst_%, $(SUBDIRS)) :
$(MAKE) -C $(patsubst _modinst_%, %, $@) modules_install
# modules disabled....
else
modules modules_install: dummy
@echo
@echo "The present kernel configuration has modules disabled."
@echo "Type 'make config' and enable loadable module support."
@echo "Then build a kernel with module support enabled."
@echo
@exit 1
endif
clean: archclean
find . \( -name '*.[oas]' -o -name core -o -name '.*.flags' \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
rm -f $(CLEAN_FILES)
rm -rf $(CLEAN_DIRS)
$(MAKE) -C Documentation/DocBook clean
mrproper: clean archmrproper
find . \( -size 0 -o -name .depend \) -type f -print | xargs rm -f
rm -f $(MRPROPER_FILES)
rm -rf $(MRPROPER_DIRS)
$(MAKE) -C Documentation/DocBook mrproper
distclean: mrproper
rm -f core `find . \( -not -type d \) -and \
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
-o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -type f -print` TAGS tags
backup: mrproper
cd .. && tar cf - linux/ | gzip -9 > backup.gz
sync
sgmldocs:
chmod 755 $(TOPDIR)/scripts/docgen
chmod 755 $(TOPDIR)/scripts/gen-all-syms
chmod 755 $(TOPDIR)/scripts/kernel-doc
$(MAKE) -C $(TOPDIR)/Documentation/DocBook books
psdocs: sgmldocs
$(MAKE) -C Documentation/DocBook ps
pdfdocs: sgmldocs
$(MAKE) -C Documentation/DocBook pdf
htmldocs: sgmldocs
$(MAKE) -C Documentation/DocBook html
mandocs:
chmod 755 $(TOPDIR)/scripts/kernel-doc
chmod 755 $(TOPDIR)/scripts/split-man
$(MAKE) -C Documentation/DocBook man
sums:
find . -type f -print | sort | xargs sum > .SUMS
dep-files: scripts/mkdep archdep include/linux/version.h
rm -f .depend .hdepend
$(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
ifdef CONFIG_MODVERSIONS
$(MAKE) update-modverfile
endif
scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
scripts/mkdep -- init/*.c > .depend
ifdef CONFIG_MODVERSIONS
MODVERFILE := $(TOPDIR)/include/linux/modversions.h
else
MODVERFILE :=
endif
export MODVERFILE
depend dep: dep-files
checkconfig:
find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w scripts/checkconfig.pl
checkhelp:
find * -name [cC]onfig.in -print | sort | xargs $(PERL) -w scripts/checkhelp.pl
checkincludes:
find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w scripts/checkincludes.pl
ifdef CONFIGURATION
..$(CONFIGURATION):
@echo
@echo "You have a bad or nonexistent" .$(CONFIGURATION) ": running 'make" $(CONFIGURATION)"'"
@echo
$(MAKE) $(CONFIGURATION)
@echo
@echo "Successful. Try re-making (ignore the error that follows)"
@echo
exit 1
#dummy: ..$(CONFIGURATION)
dummy:
else
dummy:
endif
include Rules.make
#
# This generates dependencies for the .h files.
#
scripts/mkdep: scripts/mkdep.c
$(HOSTCC) $(HOSTCFLAGS) -o scripts/mkdep scripts/mkdep.c
scripts/split-include: scripts/split-include.c
$(HOSTCC) $(HOSTCFLAGS) -o scripts/split-include scripts/split-include.c
#
# RPM target
#
# If you do a make spec before packing the tarball you can rpm -ta it
#
spec:
. scripts/mkspec >kernel.spec
#
# Build a tar ball, generate an rpm from it and pack the result
# There arw two bits of magic here
# 1) The use of /. to avoid tar packing just the symlink
# 2) Removing the .dep files as they have source paths in them that
# will become invalid
#
rpm: clean spec
find . \( -size 0 -o -name .depend -o -name .hdepend \) -type f -print | xargs rm -f
set -e; \
cd $(TOPDIR)/.. ; \
ln -sf $(TOPDIR) $(KERNELPATH) ; \
tar -cvz --exclude CVS -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
rm $(KERNELPATH) ; \
cd $(TOPDIR) ; \
. scripts/mkversion > .version ; \
$(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
rm $(TOPDIR)/../$(KERNELPATH).tar.gz
-137
View File
@@ -1,137 +0,0 @@
#
# xen/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1994 by Linus Torvalds
#
# 19990713 Artur Skawina <skawina@geocities.com>
# Added '-march' and '-mpreferred-stack-boundary' support
#
# If no .config file exists then use the appropriate defconfig-* file
ifneq (.config,$(wildcard .config))
DUMMYX:=$(shell cp $(TOPDIR)/arch/xen/defconfig$(EXTRAVERSION) $(TOPDIR)/.config)
-include $(TOPDIR)/.config
endif
LD=$(CROSS_COMPILE)ld -m elf_i386
OBJCOPY=$(CROSS_COMPILE)objcopy -R .note -R .comment -S
LDFLAGS=-e stext
LINKFLAGS =-T $(TOPDIR)/arch/xen/vmlinux.lds $(LDFLAGS)
CFLAGS += -pipe
check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
# prevent gcc from keeping the stack 16 byte aligned
CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,)
ifdef CONFIG_M686
CFLAGS += -march=i686
endif
ifdef CONFIG_MPENTIUMIII
CFLAGS += -march=i686
endif
ifdef CONFIG_MPENTIUM4
CFLAGS += -march=i686
endif
ifdef CONFIG_MK7
CFLAGS += $(call check_gcc,-march=athlon,-march=i686 -malign-functions=4)
endif
# Disable unit-at-a-time mode, it makes gcc use a lot more stack
# due to the lack of sharing of stacklots.
CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
HEAD := arch/xen/kernel/head.o arch/xen/kernel/init_task.o
SUBDIRS += arch/xen/kernel arch/xen/mm arch/xen/lib
SUBDIRS += arch/xen/drivers/console
SUBDIRS += arch/xen/drivers/evtchn
SUBDIRS += arch/xen/drivers/blkif
SUBDIRS += arch/xen/drivers/netif
SUBDIRS += arch/xen/drivers/balloon
ifdef CONFIG_XEN_PRIVILEGED_GUEST
SUBDIRS += arch/xen/drivers/dom0
endif
CORE_FILES += arch/xen/kernel/kernel.o arch/xen/mm/mm.o
CORE_FILES += arch/xen/drivers/evtchn/drv.o
CORE_FILES += arch/xen/drivers/console/drv.o
DRIVERS += arch/xen/drivers/blkif/drv.o
DRIVERS += arch/xen/drivers/netif/drv.o
ifdef CONFIG_XEN_PRIVILEGED_GUEST
CORE_FILES += arch/xen/drivers/dom0/drv.o
endif
CORE_FILES += arch/xen/drivers/balloon/drv.o
LIBS := $(TOPDIR)/arch/xen/lib/lib.a $(LIBS) $(TOPDIR)/arch/xen/lib/lib.a
arch/xen/kernel: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/xen/kernel
arch/xen/mm: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/xen/mm
arch/xen/drivers/console: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/console
arch/xen/drivers/network: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/network
arch/xen/drivers/block: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/block
arch/xen/drivers/dom0: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/dom0
arch/xen/drivers/balloon: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/balloon
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: arch/xen/vmlinux.lds
FORCE: ;
.PHONY: bzImage compressed clean archclean archmrproper archdep
bzImage: vmlinux
@$(MAKEBOOT) bzImage
INSTALL_NAME ?= $(KERNELRELEASE)
install: bzImage
mkdir -p $(INSTALL_PATH)/boot
ln -f -s vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
rm -f $(INSTALL_PATH)/boot/vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX)
install -m0644 arch/$(ARCH)/boot/bzImage $(INSTALL_PATH)/boot/vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX)
install -m0644 vmlinux $(INSTALL_PATH)/boot/vmlinux-syms-$(INSTALL_NAME)$(INSTALL_SUFFIX)
install -m0664 .config $(INSTALL_PATH)/boot/config-$(INSTALL_NAME)$(INSTALL_SUFFIX)
install -m0664 System.map $(INSTALL_PATH)/boot/System.map-$(INSTALL_NAME)$(INSTALL_SUFFIX)
ln -f -s vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
%_config: arch/xen/defconfig-%
rm -f .config arch/xen/defconfig
cp -f arch/xen/defconfig-$(@:_config=) arch/xen/defconfig
cp -f arch/xen/defconfig-$(@:_config=) .config
archclean:
@$(MAKEBOOT) clean
archmrproper:
rm -f include/asm-xen/xen-public/arch
archdep:
@$(MAKEBOOT) dep
@@ -1,13 +0,0 @@
#
# arch/xen/boot/Makefile
#
bzImage: $(TOPDIR)/vmlinux
$(OBJCOPY) $< Image
gzip -f -9 < Image > $@
rm -f Image
dep:
clean:
rm -f bzImage Image
-327
View File
@@ -1,327 +0,0 @@
#
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/config-language.txt.
#
mainmenu_name "Linux Kernel Configuration"
define_bool CONFIG_XEN y
define_bool CONFIG_X86 y
define_bool CONFIG_ISA y
define_bool CONFIG_SBUS n
define_bool CONFIG_UID16 y
mainmenu_option next_comment
comment 'Xen'
bool 'Support for privileged operations (domain 0)' CONFIG_XEN_PRIVILEGED_GUEST
bool 'Device-driver domain (physical device access)' CONFIG_XEN_PHYSDEV_ACCESS
bool 'Scrub memory before freeing it to Xen' CONFIG_XEN_SCRUB_PAGES
bool 'Network-device frontend driver' CONFIG_XEN_NETDEV_FRONTEND
bool 'Block-device frontend driver' CONFIG_XEN_BLKDEV_FRONTEND
bool 'Block-device uses grant tables' CONFIG_XEN_BLKDEV_GRANT
endmenu
# The IBM S/390 patch needs this.
define_bool CONFIG_NO_IDLE_HZ y
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
define_bool CONFIG_FOREIGN_PAGES y
else
define_bool CONFIG_FOREIGN_PAGES n
define_bool CONFIG_NETDEVICES y
define_bool CONFIG_VT n
fi
mainmenu_option next_comment
comment 'Code maturity level options'
bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES
if [ "$CONFIG_MODULES" = "y" ]; then
bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
bool ' Kernel module loader' CONFIG_KMOD
fi
endmenu
mainmenu_option next_comment
comment 'Processor type and features'
choice 'Processor family' \
"Pentium-Pro/Celeron/Pentium-II CONFIG_M686 \
Pentium-III/Celeron(Coppermine) CONFIG_MPENTIUMIII \
Pentium-4 CONFIG_MPENTIUM4 \
Athlon/Duron/K7 CONFIG_MK7 \
Opteron/Athlon64/Hammer/K8 CONFIG_MK8 \
VIA-C3-2 CONFIG_MVIAC3_2" Pentium-Pro
define_bool CONFIG_X86_WP_WORKS_OK y
define_bool CONFIG_X86_INVLPG y
define_bool CONFIG_X86_CMPXCHG y
define_bool CONFIG_X86_XADD y
define_bool CONFIG_X86_BSWAP y
define_bool CONFIG_X86_POPAD_OK y
define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
define_bool CONFIG_X86_GOOD_APIC y
define_bool CONFIG_X86_PGE y
define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
define_bool CONFIG_X86_TSC y
if [ "$CONFIG_M686" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 5
fi
if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 5
fi
if [ "$CONFIG_MPENTIUM4" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 7
fi
if [ "$CONFIG_MK8" = "y" ]; then
define_bool CONFIG_MK7 y
fi
if [ "$CONFIG_MK7" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 6
define_bool CONFIG_X86_USE_3DNOW y
fi
if [ "$CONFIG_MVIAC3_2" = "y" ]; then
define_int CONFIG_X86_L1_CACHE_SHIFT 5
fi
#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
# tristate 'BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)' CONFIG_EDD
#fi
choice 'High Memory Support' \
"off CONFIG_NOHIGHMEM \
4GB CONFIG_HIGHMEM4G" off
# 64GB CONFIG_HIGHMEM64G" off
if [ "$CONFIG_HIGHMEM4G" = "y" ]; then
define_bool CONFIG_HIGHMEM y
fi
if [ "$CONFIG_HIGHMEM64G" = "y" ]; then
define_bool CONFIG_HIGHMEM y
define_bool CONFIG_X86_PAE y
fi
if [ "$CONFIG_HIGHMEM" = "y" ]; then
bool 'HIGHMEM I/O support' CONFIG_HIGHIO
fi
define_int CONFIG_FORCE_MAX_ZONEORDER 11
#bool 'Symmetric multi-processing support' CONFIG_SMP
#if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
# define_bool CONFIG_HAVE_DEC_LOCK y
#fi
endmenu
mainmenu_option next_comment
comment 'General setup'
bool 'Networking support' CONFIG_NET
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
bool 'PCI support' CONFIG_PCI
source drivers/pci/Config.in
bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
if [ "$CONFIG_HOTPLUG" = "y" ] ; then
source drivers/pcmcia/Config.in
source drivers/hotplug/Config.in
else
define_bool CONFIG_PCMCIA n
define_bool CONFIG_HOTPLUG_PCI n
fi
fi
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
if [ "$CONFIG_PROC_FS" = "y" ]; then
choice 'Kernel core (/proc/kcore) format' \
"ELF CONFIG_KCORE_ELF \
A.OUT CONFIG_KCORE_AOUT" ELF
fi
tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER
endmenu
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
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
fi
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
fi
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
mainmenu_option next_comment
comment 'ATA/IDE/MFM/RLL support'
tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
fi
mainmenu_option next_comment
comment 'SCSI support'
tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in
fi
endmenu
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
source drivers/message/fusion/Config.in
source drivers/ieee1394/Config.in
source drivers/message/i2o/Config.in
if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment
comment 'Network device support'
bool 'Network device support' CONFIG_NETDEVICES
if [ "$CONFIG_NETDEVICES" = "y" ]; then
source drivers/net/Config.in
if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
source drivers/atm/Config.in
fi
fi
endmenu
fi
source net/ax25/Config.in
source net/irda/Config.in
mainmenu_option next_comment
comment 'ISDN subsystem'
if [ "$CONFIG_NET" != "n" ]; then
tristate 'ISDN support' CONFIG_ISDN
if [ "$CONFIG_ISDN" != "n" ]; then
source drivers/isdn/Config.in
fi
fi
endmenu
if [ "$CONFIG_ISA" = "y" ]; then
mainmenu_option next_comment
comment 'Old CD-ROM drivers (not SCSI, not IDE)'
bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
source drivers/cdrom/Config.in
fi
endmenu
fi
#
# input before char - char/joystick depends on it. As does USB.
#
source drivers/input/Config.in
else
#
# Block device driver configuration
#
mainmenu_option next_comment
comment 'Block devices'
tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
fi
dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
bool 'Per partition statistics in /proc/partitions' CONFIG_BLK_STATS
define_bool CONFIG_BLK_DEV_HD n
endmenu
fi
source drivers/char/Config.in
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
source drivers/media/Config.in
fi
source fs/Config.in
mainmenu_option next_comment
comment 'Console drivers'
define_bool CONFIG_XEN_CONSOLE y
if [ "$CONFIG_VT" = "y" ]; then
bool 'VGA text console' CONFIG_VGA_CONSOLE
bool 'Dummy console' CONFIG_DUMMY_CONSOLE
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
bool 'Video mode selection support' CONFIG_VIDEO_SELECT
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
source drivers/video/Config.in
fi
fi
fi
endmenu
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
mainmenu_option next_comment
comment 'Sound'
tristate 'Sound card support' CONFIG_SOUND
if [ "$CONFIG_SOUND" != "n" ]; then
source drivers/sound/Config.in
fi
endmenu
fi
if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
source drivers/usb/Config.in
source net/bluetooth/Config.in
fi
mainmenu_option next_comment
comment 'Kernel hacking'
bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
bool ' Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW
bool ' Debug high memory support' CONFIG_DEBUG_HIGHMEM
bool ' Debug memory allocations' CONFIG_DEBUG_SLAB
bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
bool ' Load all symbols for debugging' CONFIG_KALLSYMS
bool ' Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
fi
int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
endmenu
source crypto/Config.in
source lib/Config.in
@@ -1,927 +0,0 @@
#
# Automatically generated by make menuconfig: don't edit
#
CONFIG_XEN=y
CONFIG_X86=y
CONFIG_ISA=y
# CONFIG_SBUS is not set
CONFIG_UID16=y
#
# Xen
#
CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_PHYSDEV_ACCESS=y
# CONFIG_XEN_USB_BACKEND is not set
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_NETDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_GRANT=y
# CONFIG_XEN_USB_FRONTEND is not set
CONFIG_NO_IDLE_HZ=y
CONFIG_FOREIGN_PAGES=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODVERSIONS=y
CONFIG_KMOD=y
#
# Processor type and features
#
CONFIG_M686=y
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MVIAC3_2 is not set
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_PGE=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_TSC=y
CONFIG_X86_L1_CACHE_SHIFT=5
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
CONFIG_FORCE_MAX_ZONEORDER=11
#
# General setup
#
CONFIG_NET=y
CONFIG_PCI=y
CONFIG_PCI_NAMES=y
CONFIG_HOTPLUG=y
#
# PCMCIA/CardBus support
#
# CONFIG_PCMCIA is not set
#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set
# CONFIG_HOTPLUG_PCI_COMPAQ is not set
# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
# CONFIG_HOTPLUG_PCI_SHPC is not set
# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
# CONFIG_HOTPLUG_PCI_PCIE is not set
# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_KCORE_ELF=y
# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_OOM_KILLER is not set
#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
#
# Plug and Play configuration
#
CONFIG_PNP=y
# CONFIG_ISAPNP is not set
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_CISS_SCSI_TAPE is not set
# CONFIG_CISS_MONITOR_THREAD is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_STATS is not set
#
# Multi-device support (RAID and LVM)
#
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
# CONFIG_MD_RAID0 is not set
CONFIG_MD_RAID1=y
# CONFIG_MD_RAID5 is not set
# CONFIG_MD_MULTIPATH is not set
CONFIG_BLK_DEV_LVM=y
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
# CONFIG_NETLINK_DEV is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_FILTER=y
CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_FTP=m
# CONFIG_IP_NF_AMANDA is not set
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_IRC=m
# CONFIG_IP_NF_QUEUE is not set
CONFIG_IP_NF_IPTABLES=y
# CONFIG_IP_NF_MATCH_LIMIT is not set
# CONFIG_IP_NF_MATCH_MAC is not set
# CONFIG_IP_NF_MATCH_PKTTYPE is not set
# CONFIG_IP_NF_MATCH_MARK is not set
# CONFIG_IP_NF_MATCH_MULTIPORT is not set
# CONFIG_IP_NF_MATCH_TOS is not set
# CONFIG_IP_NF_MATCH_RECENT is not set
# CONFIG_IP_NF_MATCH_ECN is not set
# CONFIG_IP_NF_MATCH_DSCP is not set
# CONFIG_IP_NF_MATCH_AH_ESP is not set
# CONFIG_IP_NF_MATCH_LENGTH is not set
# CONFIG_IP_NF_MATCH_TTL is not set
# CONFIG_IP_NF_MATCH_TCPMSS is not set
# CONFIG_IP_NF_MATCH_HELPER is not set
CONFIG_IP_NF_MATCH_STATE=m
CONFIG_IP_NF_MATCH_CONNTRACK=m
# CONFIG_IP_NF_MATCH_UNCLEAN is not set
# CONFIG_IP_NF_MATCH_OWNER is not set
CONFIG_IP_NF_MATCH_PHYSDEV=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
# CONFIG_IP_NF_TARGET_MIRROR is not set
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
# CONFIG_IP_NF_MANGLE is not set
CONFIG_IP_NF_TARGET_LOG=y
CONFIG_IP_NF_TARGET_ULOG=y
# CONFIG_IP_NF_TARGET_TCPMSS is not set
# CONFIG_IP_NF_ARPTABLES is not set
#
# IP: Virtual Server Configuration
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
CONFIG_VLAN_8021Q=y
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
CONFIG_BRIDGE=y
CONFIG_BRIDGE_NF_EBTABLES=m
CONFIG_BRIDGE_EBT_T_FILTER=m
CONFIG_BRIDGE_EBT_T_NAT=m
CONFIG_BRIDGE_EBT_BROUTE=m
CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_IPF=m
CONFIG_BRIDGE_EBT_ARPF=m
CONFIG_BRIDGE_EBT_AMONG=m
CONFIG_BRIDGE_EBT_LIMIT=m
CONFIG_BRIDGE_EBT_VLANF=m
CONFIG_BRIDGE_EBT_802_3=m
CONFIG_BRIDGE_EBT_PKTTYPE=m
CONFIG_BRIDGE_EBT_STP=m
CONFIG_BRIDGE_EBT_MARKF=m
CONFIG_BRIDGE_EBT_ARPREPLY=m
CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_DNAT=m
CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_MARK_T=m
# 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
#
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
#
# ATA/IDE/MFM/RLL support
#
CONFIG_IDE=y
#
# IDE, ATA and ATAPI Block devices
#
CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
CONFIG_IDEDISK_STROKE=y
# CONFIG_BLK_DEV_IDECS is not set
# CONFIG_BLK_DEV_DELKIN is not set
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDETAPE=y
CONFIG_BLK_DEV_IDEFLOPPY=y
CONFIG_BLK_DEV_IDESCSI=y
CONFIG_IDE_TASK_IOCTL=y
CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_CMD640_ENHANCED=y
# CONFIG_BLK_DEV_ISAPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_BLK_DEV_GENERIC=y
CONFIG_IDEPCI_SHARE_IRQ=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_BLK_DEV_OFFBOARD=y
# 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_BLK_DEV_ADMA100=y
CONFIG_BLK_DEV_AEC62XX=y
CONFIG_BLK_DEV_ALI15X3=y
CONFIG_WDC_ALI15X3=y
CONFIG_BLK_DEV_AMD74XX=y
CONFIG_AMD74XX_OVERRIDE=y
# CONFIG_BLK_DEV_ATIIXP is not set
CONFIG_BLK_DEV_CMD64X=y
CONFIG_BLK_DEV_TRIFLEX=y
CONFIG_BLK_DEV_CY82C693=y
CONFIG_BLK_DEV_CS5530=y
CONFIG_BLK_DEV_HPT34X=y
# CONFIG_HPT34X_AUTODMA is not set
CONFIG_BLK_DEV_HPT366=y
CONFIG_BLK_DEV_PIIX=y
CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_PDC202XX_OLD=y
CONFIG_PDC202XX_BURST=y
CONFIG_BLK_DEV_PDC202XX_NEW=y
CONFIG_PDC202XX_FORCE=y
CONFIG_BLK_DEV_RZ1000=y
CONFIG_BLK_DEV_SC1200=y
CONFIG_BLK_DEV_SVWKS=y
CONFIG_BLK_DEV_SIIMAGE=y
CONFIG_BLK_DEV_SIS5513=y
CONFIG_BLK_DEV_SLC90E66=y
CONFIG_BLK_DEV_TRM290=y
CONFIG_BLK_DEV_VIA82CXXX=y
CONFIG_IDE_CHIPSETS=y
# CONFIG_BLK_DEV_4DRIVES is not set
# CONFIG_BLK_DEV_ALI14XX is not set
# CONFIG_BLK_DEV_DTC2278 is not set
# CONFIG_BLK_DEV_HT6560B is not set
# CONFIG_BLK_DEV_PDC4030 is not set
# CONFIG_BLK_DEV_QD65XX is not set
# CONFIG_BLK_DEV_UMC8672 is not set
CONFIG_IDEDMA_AUTO=y
# CONFIG_IDEDMA_IVB is not set
# CONFIG_DMA_NONPCI is not set
CONFIG_BLK_DEV_PDC202XX=y
# CONFIG_BLK_DEV_ATARAID is not set
# CONFIG_BLK_DEV_ATARAID_PDC is not set
# CONFIG_BLK_DEV_ATARAID_HPT is not set
# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
# CONFIG_BLK_DEV_ATARAID_SII 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=y
# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# 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_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
CONFIG_SCSI_AACRAID=y
CONFIG_SCSI_AIC7XXX=y
CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
CONFIG_AIC7XXX_DEBUG_MASK=0
# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
CONFIG_SCSI_AIC79XX=y
CONFIG_AIC79XX_CMDS_PER_DEVICE=32
CONFIG_AIC79XX_RESET_DELAY_MS=15000
# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
# CONFIG_AIC79XX_DEBUG_ENABLE is not set
CONFIG_AIC79XX_DEBUG_MASK=0
# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
CONFIG_SCSI_MEGARAID=y
# CONFIG_SCSI_MEGARAID2 is not set
CONFIG_SCSI_SATA=y
# CONFIG_SCSI_SATA_AHCI is not set
# CONFIG_SCSI_SATA_SVW is not set
CONFIG_SCSI_ATA_PIIX=y
# CONFIG_SCSI_SATA_NV is not set
# CONFIG_SCSI_SATA_QSTOR is not set
CONFIG_SCSI_SATA_PROMISE=y
CONFIG_SCSI_SATA_SX4=y
CONFIG_SCSI_SATA_SIL=y
CONFIG_SCSI_SATA_SIS=y
# CONFIG_SCSI_SATA_ULI is not set
CONFIG_SCSI_SATA_VIA=y
CONFIG_SCSI_SATA_VITESSE=y
CONFIG_SCSI_BUSLOGIC=y
# CONFIG_SCSI_OMIT_FLASHPOINT 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=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED 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_SEAGATE is not set
# CONFIG_SCSI_SIM710 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_ULTRASTOR is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG 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)
#
# CONFIG_IEEE1394 is not set
#
# I2O device support
#
# CONFIG_I2O is not set
# CONFIG_I2O_PCI is not set
# CONFIG_I2O_BLOCK is not set
# CONFIG_I2O_LAN is not set
# CONFIG_I2O_SCSI is not set
# CONFIG_I2O_PROC is not set
#
# Network device support
#
CONFIG_NETDEVICES=y
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_SUNLANCE is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNBMAC is not set
# CONFIG_SUNQE is not set
# CONFIG_SUNGEM is not set
CONFIG_NET_VENDOR_3COM=y
# CONFIG_EL1 is not set
# CONFIG_EL2 is not set
# CONFIG_ELPLUS is not set
# CONFIG_EL16 is not set
# CONFIG_EL3 is not set
# CONFIG_3C515 is not set
# CONFIG_ELMC is not set
# CONFIG_ELMC_II is not set
CONFIG_VORTEX=y
# CONFIG_TYPHOON is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_PCI=y
CONFIG_PCNET32=y
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_B44 is not set
# CONFIG_CS89x0 is not set
# CONFIG_TULIP is not set
# CONFIG_DE4X5 is not set
# CONFIG_DGRS is not set
# CONFIG_DM9102 is not set
# CONFIG_EEPRO100 is not set
# CONFIG_EEPRO100_PIO is not set
CONFIG_E100=y
# CONFIG_LNE390 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
CONFIG_NE2K_PCI=y
# CONFIG_FORCEDETH is not set
# CONFIG_NE3210 is not set
# CONFIG_ES3210 is not set
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
# CONFIG_8139TOO_PIO is not set
# CONFIG_8139TOO_TUNE_TWISTER is not set
# CONFIG_8139TOO_8129 is not set
# CONFIG_8139_OLD_RX_RESET is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_SUNDANCE_MMIO is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_VIA_RHINE_MMIO is not set
# CONFIG_WINBOND_840 is not set
# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
CONFIG_E1000=y
# CONFIG_E1000_NAPI is not set
# CONFIG_MYRI_SBUS is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SK98LIN is not set
CONFIG_TIGON3=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
#
# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set
#
# IrDA (infrared) support
#
# CONFIG_IRDA is not set
#
# ISDN subsystem
#
# CONFIG_ISDN is not set
#
# Old CD-ROM drivers (not SCSI, not IDE)
#
# CONFIG_CD_NO_IDESCSI is not set
#
# Input core support
#
# CONFIG_INPUT is not set
# CONFIG_INPUT_KEYBDEV is not set
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_UINPUT is not set
#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
# CONFIG_SERIAL is not set
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
#
# I2C support
#
# CONFIG_I2C is not set
#
# 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_MK712_MOUSE is not set
#
# Joysticks
#
# CONFIG_INPUT_GAMEPORT is not set
# CONFIG_QIC02_TAPE is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_IPMI_PANIC_EVENT is not set
# CONFIG_IPMI_DEVICE_INTERFACE is not set
# CONFIG_IPMI_KCS is not set
# CONFIG_IPMI_WATCHDOG is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
# CONFIG_SCx200 is not set
# CONFIG_SCx200_GPIO is not set
# CONFIG_AMD_RNG is not set
# CONFIG_INTEL_RNG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_AMD_PM768 is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
#
# Direct Rendering Manager (XFree86 DRI support)
#
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
# CONFIG_OBMOUSE is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
#
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_QFMT_V2 is not set
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
# CONFIG_REISERFS_FS is not set
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BEFS_DEBUG is not set
# CONFIG_BFS_FS is not set
CONFIG_EXT3_FS=y
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_UMSDOS_FS=y
CONFIG_VFAT_FS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
CONFIG_TMPFS=y
CONFIG_RAMFS=y
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
# CONFIG_JFS_FS is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVFS_MOUNT is not set
# CONFIG_DEVFS_DEBUG is not set
CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UDF_FS is not set
# 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_QUOTA is not set
# CONFIG_XFS_RT is not set
# CONFIG_XFS_TRACE is not set
# CONFIG_XFS_DEBUG is not set
#
# Network File Systems
#
# CONFIG_CODA_FS is not set
# CONFIG_INTERMEZZO_FS is not set
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_DIRECTIO is not set
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_TCP is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
# CONFIG_NCPFS_STRONG is not set
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
CONFIG_ZISOFS_FS=y
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SMB_NLS is not set
CONFIG_NLS=y
#
# Native Language Support
#
CONFIG_NLS_DEFAULT="iso8559-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
#
# Console drivers
#
CONFIG_XEN_CONSOLE=y
CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
# CONFIG_VIDEO_SELECT is not set
# CONFIG_MDA_CONSOLE is not set
#
# Frame-buffer support
#
# CONFIG_FB is not set
#
# Sound
#
# CONFIG_SOUND is not set
#
# USB support
#
# CONFIG_USB is not set
#
# Support for USB gadgets
#
# CONFIG_USB_GADGET is not set
#
# Bluetooth support
#
# CONFIG_BLUEZ is not set
#
# Kernel hacking
#
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_HIGHMEM is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_IOVIRT is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_KALLSYMS=y
# CONFIG_FRAME_POINTER is not set
CONFIG_LOG_BUF_SHIFT=0
#
# Cryptographic options
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
# CONFIG_CRYPTO_WP512 is not set
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_TEST is not set
#
# Library routines
#
# CONFIG_CRC32 is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
# CONFIG_FW_LOADER is not set
@@ -1,562 +0,0 @@
#
# Automatically generated make config: don't edit
#
CONFIG_XEN=y
CONFIG_X86=y
CONFIG_ISA=y
# CONFIG_SBUS is not set
CONFIG_UID16=y
#
# Xen
#
# CONFIG_XEN_PRIVILEGED_GUEST is not set
# CONFIG_XEN_PHYSDEV_ACCESS is not set
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_NETDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_GRANT=y
# CONFIG_XEN_USB_FRONTEND is not set
CONFIG_NO_IDLE_HZ=y
# CONFIG_FOREIGN_PAGES is not set
CONFIG_NETDEVICES=y
# CONFIG_VT is not set
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODVERSIONS=y
CONFIG_KMOD=y
#
# Processor type and features
#
CONFIG_M686=y
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MVIAC3_2 is not set
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_PGE=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_TSC=y
CONFIG_X86_L1_CACHE_SHIFT=5
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
CONFIG_FORCE_MAX_ZONEORDER=11
#
# General setup
#
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_KCORE_ELF=y
# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
# CONFIG_OOM_KILLER is not set
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
# CONFIG_NETLINK_DEV is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_FILTER=y
CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=y
CONFIG_IP_NF_FTP=y
# CONFIG_IP_NF_AMANDA is not set
CONFIG_IP_NF_TFTP=y
CONFIG_IP_NF_IRC=y
# CONFIG_IP_NF_QUEUE is not set
CONFIG_IP_NF_IPTABLES=y
# CONFIG_IP_NF_MATCH_LIMIT is not set
# CONFIG_IP_NF_MATCH_MAC is not set
# CONFIG_IP_NF_MATCH_PKTTYPE is not set
# CONFIG_IP_NF_MATCH_MARK is not set
# CONFIG_IP_NF_MATCH_MULTIPORT is not set
# CONFIG_IP_NF_MATCH_TOS is not set
# CONFIG_IP_NF_MATCH_RECENT is not set
# CONFIG_IP_NF_MATCH_ECN is not set
# CONFIG_IP_NF_MATCH_DSCP is not set
# CONFIG_IP_NF_MATCH_AH_ESP is not set
# CONFIG_IP_NF_MATCH_LENGTH is not set
# CONFIG_IP_NF_MATCH_TTL is not set
# CONFIG_IP_NF_MATCH_TCPMSS is not set
# CONFIG_IP_NF_MATCH_HELPER is not set
CONFIG_IP_NF_MATCH_STATE=y
CONFIG_IP_NF_MATCH_CONNTRACK=y
# CONFIG_IP_NF_MATCH_UNCLEAN is not set
# CONFIG_IP_NF_MATCH_OWNER is not set
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
# CONFIG_IP_NF_TARGET_MIRROR is not set
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_REDIRECT=y
# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
CONFIG_IP_NF_NAT_IRC=y
CONFIG_IP_NF_NAT_FTP=y
CONFIG_IP_NF_NAT_TFTP=y
# CONFIG_IP_NF_MANGLE is not set
CONFIG_IP_NF_TARGET_LOG=y
CONFIG_IP_NF_TARGET_ULOG=y
# CONFIG_IP_NF_TARGET_TCPMSS is not set
# CONFIG_IP_NF_ARPTABLES is not set
#
# IP: Virtual Server Configuration
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
CONFIG_VLAN_8021Q=y
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK 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
#
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
#
# SCSI support
#
CONFIG_SCSI=y
#
# SCSI support type (disk, tape, CD-ROM)
#
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=y
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
#
# SCSI low-level drivers
#
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_MEGARAID2 is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_SATA_AHCI is not set
# CONFIG_SCSI_SATA_SVW is not set
# CONFIG_SCSI_ATA_PIIX is not set
# CONFIG_SCSI_SATA_NV is not set
# CONFIG_SCSI_SATA_QSTOR is not set
# CONFIG_SCSI_SATA_PROMISE is not set
# CONFIG_SCSI_SATA_SX4 is not set
# CONFIG_SCSI_SATA_SIL is not set
# CONFIG_SCSI_SATA_SIS is not set
# CONFIG_SCSI_SATA_ULI is not set
# CONFIG_SCSI_SATA_VIA is not set
# CONFIG_SCSI_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC 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_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_NCR53C7xx 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_SEAGATE is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_ULTRASTOR is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
#
# Block devices
#
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_STATS is not set
# CONFIG_BLK_DEV_HD is not set
#
# Character devices
#
# CONFIG_VT is not set
# CONFIG_SERIAL is not set
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_PRINTER is not set
# CONFIG_PPDEV is not set
# CONFIG_TIPAR is not set
#
# I2C support
#
# CONFIG_I2C is not set
#
# 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_MK712_MOUSE is not set
#
# Joysticks
#
# CONFIG_INPUT_GAMEPORT is not set
# CONFIG_INPUT_NS558 is not set
# CONFIG_INPUT_LIGHTNING is not set
# CONFIG_INPUT_PCIGAME is not set
# CONFIG_INPUT_CS461X is not set
# CONFIG_INPUT_EMU10K1 is not set
# CONFIG_INPUT_SERIO is not set
# CONFIG_INPUT_SERPORT is not set
#
# Joysticks
#
# CONFIG_INPUT_ANALOG is not set
# CONFIG_INPUT_A3D is not set
# CONFIG_INPUT_ADI is not set
# CONFIG_INPUT_COBRA is not set
# CONFIG_INPUT_GF2K is not set
# CONFIG_INPUT_GRIP is not set
# CONFIG_INPUT_INTERACT is not set
# CONFIG_INPUT_TMDC is not set
# CONFIG_INPUT_SIDEWINDER is not set
# CONFIG_INPUT_IFORCE_USB is not set
# CONFIG_INPUT_IFORCE_232 is not set
# CONFIG_INPUT_WARRIOR is not set
# CONFIG_INPUT_MAGELLAN is not set
# CONFIG_INPUT_SPACEORB is not set
# CONFIG_INPUT_SPACEBALL is not set
# CONFIG_INPUT_STINGER is not set
# CONFIG_INPUT_DB9 is not set
# CONFIG_INPUT_GAMECON is not set
# CONFIG_INPUT_TURBOGRAFX is not set
# CONFIG_QIC02_TAPE is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_IPMI_PANIC_EVENT is not set
# CONFIG_IPMI_DEVICE_INTERFACE is not set
# CONFIG_IPMI_KCS is not set
# CONFIG_IPMI_WATCHDOG is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
# CONFIG_SCx200 is not set
# CONFIG_SCx200_GPIO is not set
# CONFIG_AMD_RNG is not set
# CONFIG_INTEL_RNG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_AMD_PM768 is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
#
# Direct Rendering Manager (XFree86 DRI support)
#
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
# CONFIG_OBMOUSE is not set
#
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_QFMT_V2 is not set
CONFIG_AUTOFS_FS=y
CONFIG_AUTOFS4_FS=y
# CONFIG_REISERFS_FS is not set
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BEFS_DEBUG is not set
# CONFIG_BFS_FS is not set
CONFIG_EXT3_FS=y
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_UMSDOS_FS=y
CONFIG_VFAT_FS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
CONFIG_TMPFS=y
CONFIG_RAMFS=y
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
# CONFIG_JFS_FS is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVFS_MOUNT is not set
# CONFIG_DEVFS_DEBUG is not set
CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UDF_FS is not set
# 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_QUOTA is not set
# CONFIG_XFS_RT is not set
# CONFIG_XFS_TRACE is not set
# CONFIG_XFS_DEBUG is not set
#
# Network File Systems
#
# CONFIG_CODA_FS is not set
# CONFIG_INTERMEZZO_FS is not set
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_DIRECTIO is not set
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_TCP is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
# CONFIG_NCPFS_STRONG is not set
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
CONFIG_ZISOFS_FS=y
#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SMB_NLS is not set
CONFIG_NLS=y
#
# Native Language Support
#
CONFIG_NLS_DEFAULT="iso8559-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
#
# Console drivers
#
CONFIG_XEN_CONSOLE=y
#
# Kernel hacking
#
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_HIGHMEM is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_IOVIRT is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_KALLSYMS=y
# CONFIG_FRAME_POINTER is not set
CONFIG_LOG_BUF_SHIFT=0
#
# Cryptographic options
#
# CONFIG_CRYPTO is not set
#
# Library routines
#
# CONFIG_CRC32 is not set
CONFIG_ZLIB_INFLATE=y
# CONFIG_ZLIB_DEFLATE is not set
@@ -1,4 +0,0 @@
O_TARGET := drv.o
export-objs := balloon.o
obj-y := balloon.o
include $(TOPDIR)/Rules.make
@@ -1,10 +0,0 @@
O_TARGET := drv.o
subdir-$(CONFIG_XEN_BLKDEV_FRONTEND) += frontend
obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += frontend/drv.o
subdir-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend
obj-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend/drv.o
include $(TOPDIR)/Rules.make
@@ -1,3 +0,0 @@
O_TARGET := drv.o
obj-y := main.o control.o interface.o vbd.o
include $(TOPDIR)/Rules.make
@@ -1,3 +0,0 @@
O_TARGET := drv.o
obj-y := blkfront.o vbd.o
include $(TOPDIR)/Rules.make
@@ -1,93 +0,0 @@
/******************************************************************************
* arch/xen/drivers/blkif/frontend/common.h
*
* Shared definitions between all levels of XenoLinux Virtual block devices.
*/
#ifndef __XEN_DRIVERS_COMMON_H__
#define __XEN_DRIVERS_COMMON_H__
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/major.h>
#include <asm-xen/xen-public/xen.h>
#include <asm/io.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include <asm-xen/xen-public/io/blkif.h>
#if 1
#define IPRINTK(fmt, args...) \
printk(KERN_INFO "xen_blk: " fmt, ##args)
#else
#define IPRINTK(fmt, args...) ((void)0)
#endif
#if 1
#define WPRINTK(fmt, args...) \
printk(KERN_WARNING "xen_blk: " fmt, ##args)
#else
#define WPRINTK(fmt, args...) ((void)0)
#endif
#if 0
#define DPRINTK(_f, _a...) printk ( KERN_ALERT _f , ## _a )
#else
#define DPRINTK(_f, _a...) ((void)0)
#endif
#if 0
#define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
#else
#define DPRINTK_IOCTL(_f, _a...) ((void)0)
#endif
/* Private gendisk->flags[] values. */
#define GENHD_FL_XEN 2 /* Is unit a Xen block device? */
#define GENHD_FL_VIRT_PARTNS 4 /* Are unit partitions virtual? */
/*
* We have one of these per vbd, whether ide, scsi or 'other'.
* They hang in an array off the gendisk structure. We may end up putting
* all kinds of interesting stuff here :-)
*/
typedef struct xl_disk {
int usage;
} xl_disk_t;
extern int blkif_open(struct inode *inode, struct file *filep);
extern int blkif_release(struct inode *inode, struct file *filep);
extern int blkif_ioctl(struct inode *inode, struct file *filep,
unsigned command, unsigned long argument);
extern int blkif_check(kdev_t dev);
extern int blkif_revalidate(kdev_t dev);
extern void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
extern void do_blkif_request (request_queue_t *rq);
extern void xlvbd_update_vbds(void);
static inline xl_disk_t *xldev_to_xldisk(kdev_t xldev)
{
struct gendisk *gd = get_gendisk(xldev);
if ( gd == NULL )
return NULL;
return (xl_disk_t *)gd->real_devices +
(MINOR(xldev) >> gd->minor_shift);
}
/* Virtual block-device subsystem. */
extern int xlvbd_init(void);
extern void xlvbd_cleanup(void);
#endif /* __XEN_DRIVERS_COMMON_H__ */
@@ -1,540 +0,0 @@
/******************************************************************************
* arch/xen/drivers/blkif/frontend/vbd.c
*
* Xenolinux virtual block-device driver.
*
* Copyright (c) 2003-2004, Keir Fraser & Steve Hand
* Modifications by Mark A. Williamson are (c) Intel Research Cambridge
*/
#include "common.h"
#include <linux/blk.h>
/*
* For convenience we distinguish between ide, scsi and 'other' (i.e.
* potentially combinations of the two) in the naming scheme and in a few
* other places (like default readahead, etc).
*/
#define XLIDE_MAJOR_NAME "hd"
#define XLSCSI_MAJOR_NAME "sd"
#define XLVBD_MAJOR_NAME "xvd"
#define XLIDE_DEVS_PER_MAJOR 2
#define XLSCSI_DEVS_PER_MAJOR 16
#define XLVBD_DEVS_PER_MAJOR 16
#define XLIDE_PARTN_SHIFT 6 /* amount to shift minor to get 'real' minor */
#define XLIDE_MAX_PART (1 << XLIDE_PARTN_SHIFT) /* minors per ide vbd */
#define XLSCSI_PARTN_SHIFT 4 /* amount to shift minor to get 'real' minor */
#define XLSCSI_MAX_PART (1 << XLSCSI_PARTN_SHIFT) /* minors per scsi vbd */
#define XLVBD_PARTN_SHIFT 4 /* amount to shift minor to get 'real' minor */
#define XLVBD_MAX_PART (1 << XLVBD_PARTN_SHIFT) /* minors per 'other' vbd */
/* The below are for the generic drivers/block/ll_rw_block.c code. */
static int xlide_blksize_size[256];
static int xlide_hardsect_size[256];
static int xlide_max_sectors[256];
static int xlscsi_blksize_size[256];
static int xlscsi_hardsect_size[256];
static int xlscsi_max_sectors[256];
static int xlvbd_blksize_size[256];
static int xlvbd_hardsect_size[256];
static int xlvbd_max_sectors[256];
/* Information about our VBDs. */
#define MAX_VBDS 64
static int nr_vbds;
static vdisk_t *vbd_info;
static struct block_device_operations xlvbd_block_fops =
{
open: blkif_open,
release: blkif_release,
ioctl: blkif_ioctl,
check_media_change: blkif_check,
revalidate: blkif_revalidate,
};
static int xlvbd_get_vbd_info(vdisk_t *disk_info)
{
vdisk_t *buf = (vdisk_t *)__get_free_page(GFP_KERNEL);
blkif_request_t req;
blkif_response_t rsp;
int nr;
memset(&req, 0, sizeof(req));
req.operation = BLKIF_OP_PROBE;
req.nr_segments = 1;
#ifdef CONFIG_XEN_BLKDEV_GRANT
blkif_control_probe_send(&req, &rsp,
(unsigned long)(virt_to_machine(buf)));
#else
req.frame_and_sects[0] = virt_to_machine(buf) | 7;
blkif_control_send(&req, &rsp);
#endif
if ( rsp.status <= 0 )
{
printk(KERN_ALERT "Could not probe disks (%d)\n", rsp.status);
return -1;
}
if ( (nr = rsp.status) > MAX_VBDS )
nr = MAX_VBDS;
memcpy(disk_info, buf, nr * sizeof(vdisk_t));
return nr;
}
/*
* xlvbd_init_device - initialise a VBD device
* @disk: a vdisk_t describing the VBD
*
* Takes a vdisk_t * that describes a VBD the domain has access to.
* Performs appropriate initialisation and registration of the device.
*
* Care needs to be taken when making re-entrant calls to ensure that
* corruption does not occur. Also, devices that are in use should not have
* their details updated. This is the caller's responsibility.
*/
static int xlvbd_init_device(vdisk_t *xd)
{
int device = xd->device;
int major = MAJOR(device);
int minor = MINOR(device);
int is_ide = IDE_DISK_MAJOR(major); /* is this an ide device? */
int is_scsi= SCSI_BLK_MAJOR(major); /* is this a scsi device? */
char *major_name;
struct gendisk *gd;
struct block_device *bd;
xl_disk_t *disk;
int i, rc = 0, max_part, partno;
unsigned long capacity;
unsigned char buf[64];
if ( (bd = bdget(device)) == NULL )
return -1;
if ( ((disk = xldev_to_xldisk(device)) != NULL) && (disk->usage != 0) )
{
printk(KERN_ALERT "VBD update failed - in use [dev=%x]\n", device);
rc = -1;
goto out;
}
if ( is_ide ) {
major_name = XLIDE_MAJOR_NAME;
max_part = XLIDE_MAX_PART;
} else if ( is_scsi ) {
major_name = XLSCSI_MAJOR_NAME;
max_part = XLSCSI_MAX_PART;
} else {
/* SMH: hmm - probably a CCISS driver or sim; assume CCISS for now */
printk(KERN_ALERT "Assuming device %02x:%02x is CCISS/SCSI\n",
major, minor);
is_scsi = 1;
major_name = "cciss";
max_part = XLSCSI_MAX_PART;
}
partno = minor & (max_part - 1);
if ( (gd = get_gendisk(device)) == NULL )
{
rc = register_blkdev(major, major_name, &xlvbd_block_fops);
if ( rc < 0 )
{
printk(KERN_ALERT "XL VBD: can't get major %d\n", major);
goto out;
}
if ( is_ide )
{
blksize_size[major] = xlide_blksize_size;
hardsect_size[major] = xlide_hardsect_size;
max_sectors[major] = xlide_max_sectors;
read_ahead[major] = 8;
}
else if ( is_scsi )
{
blksize_size[major] = xlscsi_blksize_size;
hardsect_size[major] = xlscsi_hardsect_size;
max_sectors[major] = xlscsi_max_sectors;
read_ahead[major] = 8;
}
else
{
blksize_size[major] = xlvbd_blksize_size;
hardsect_size[major] = xlvbd_hardsect_size;
max_sectors[major] = xlvbd_max_sectors;
read_ahead[major] = 8;
}
blk_init_queue(BLK_DEFAULT_QUEUE(major), do_blkif_request);
/*
* Turn off barking 'headactive' mode. We dequeue buffer heads as
* soon as we pass them to the back-end driver.
*/
blk_queue_headactive(BLK_DEFAULT_QUEUE(major), 0);
/* Construct an appropriate gendisk structure. */
gd = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
gd->major = major;
gd->major_name = major_name;
gd->max_p = max_part;
if ( is_ide )
{
gd->minor_shift = XLIDE_PARTN_SHIFT;
gd->nr_real = XLIDE_DEVS_PER_MAJOR;
}
else if ( is_scsi )
{
gd->minor_shift = XLSCSI_PARTN_SHIFT;
gd->nr_real = XLSCSI_DEVS_PER_MAJOR;
}
else
{
gd->minor_shift = XLVBD_PARTN_SHIFT;
gd->nr_real = XLVBD_DEVS_PER_MAJOR;
}
/*
** The sizes[] and part[] arrays hold the sizes and other
** information about every partition with this 'major' (i.e.
** every disk sharing the 8 bit prefix * max partns per disk)
*/
gd->sizes = kmalloc(max_part*gd->nr_real*sizeof(int), GFP_KERNEL);
gd->part = kmalloc(max_part*gd->nr_real*sizeof(struct hd_struct),
GFP_KERNEL);
memset(gd->sizes, 0, max_part * gd->nr_real * sizeof(int));
memset(gd->part, 0, max_part * gd->nr_real
* sizeof(struct hd_struct));
gd->real_devices = kmalloc(gd->nr_real * sizeof(xl_disk_t),
GFP_KERNEL);
memset(gd->real_devices, 0, gd->nr_real * sizeof(xl_disk_t));
gd->next = NULL;
gd->fops = &xlvbd_block_fops;
gd->de_arr = kmalloc(gd->nr_real * sizeof(*gd->de_arr),
GFP_KERNEL);
gd->flags = kmalloc(gd->nr_real * sizeof(*gd->flags), GFP_KERNEL);
memset(gd->de_arr, 0, gd->nr_real * sizeof(*gd->de_arr));
memset(gd->flags, 0, gd->nr_real * sizeof(*gd->flags));
add_gendisk(gd);
blk_size[major] = gd->sizes;
}
if ( xd->info & VDISK_READONLY )
set_device_ro(device, 1);
gd->flags[minor >> gd->minor_shift] |= GENHD_FL_XEN;
/* NB. Linux 2.4 only handles 32-bit sector offsets and capacities. */
capacity = (unsigned long)xd->capacity;
if ( partno != 0 )
{
/*
* If this was previously set up as a real disc we will have set
* up partition-table information. Virtual partitions override
* 'real' partitions, and the two cannot coexist on a device.
*/
if ( !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) &&
(gd->sizes[minor & ~(max_part-1)] != 0) )
{
/*
* Any non-zero sub-partition entries must be cleaned out before
* installing 'virtual' partition entries. The two types cannot
* coexist, and virtual partitions are favoured.
*/
kdev_t dev = device & ~(max_part-1);
for ( i = max_part - 1; i > 0; i-- )
{
invalidate_device(dev+i, 1);
gd->part[MINOR(dev+i)].start_sect = 0;
gd->part[MINOR(dev+i)].nr_sects = 0;
gd->sizes[MINOR(dev+i)] = 0;
}
printk(KERN_ALERT
"Virtual partitions found for /dev/%s - ignoring any "
"real partition information we may have found.\n",
disk_name(gd, MINOR(device), buf));
}
/* Need to skankily setup 'partition' information */
gd->part[minor].start_sect = 0;
gd->part[minor].nr_sects = capacity;
gd->sizes[minor] = capacity >>(BLOCK_SIZE_BITS-9);
gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS;
}
else
{
gd->part[minor].nr_sects = capacity;
gd->sizes[minor] = capacity>>(BLOCK_SIZE_BITS-9);
/* Some final fix-ups depending on the device type */
if ( xd->info & VDISK_REMOVABLE )
{
gd->flags[minor >> gd->minor_shift] |= GENHD_FL_REMOVABLE;
printk(KERN_ALERT
"Skipping partition check on %s /dev/%s\n",
(xd->info & VDISK_CDROM) ? "cdrom" : "removable",
disk_name(gd, MINOR(device), buf));
}
else
{
/* Only check partitions on real discs (not virtual!). */
if ( gd->flags[minor>>gd->minor_shift] & GENHD_FL_VIRT_PARTNS )
{
printk(KERN_ALERT
"Skipping partition check on virtual /dev/%s\n",
disk_name(gd, MINOR(device), buf));
break;
}
register_disk(gd, device, gd->max_p, &xlvbd_block_fops, capacity);
}
}
out:
bdput(bd);
return rc;
}
/*
* xlvbd_remove_device - remove a device node if possible
* @device: numeric device ID
*
* Updates the gendisk structure and invalidates devices.
*
* This is OK for now but in future, should perhaps consider where this should
* deallocate gendisks / unregister devices.
*/
static int xlvbd_remove_device(int device)
{
int i, rc = 0, minor = MINOR(device);
struct gendisk *gd;
struct block_device *bd;
xl_disk_t *disk = NULL;
if ( (bd = bdget(device)) == NULL )
return -1;
if ( ((gd = get_gendisk(device)) == NULL) ||
((disk = xldev_to_xldisk(device)) == NULL) )
BUG();
if ( disk->usage != 0 )
{
printk(KERN_ALERT "VBD removal failed - in use [dev=%x]\n", device);
rc = -1;
goto out;
}
if ( (minor & (gd->max_p-1)) != 0 )
{
/* 1: The VBD is mapped to a partition rather than a whole unit. */
invalidate_device(device, 1);
gd->part[minor].start_sect = 0;
gd->part[minor].nr_sects = 0;
gd->sizes[minor] = 0;
/* Clear the consists-of-virtual-partitions flag if possible. */
gd->flags[minor >> gd->minor_shift] &= ~GENHD_FL_VIRT_PARTNS;
for ( i = 1; i < gd->max_p; i++ )
if ( gd->sizes[(minor & ~(gd->max_p-1)) + i] != 0 )
gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS;
/*
* If all virtual partitions are now gone, and a 'whole unit' VBD is
* present, then we can try to grok the unit's real partition table.
*/
if ( !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) &&
(gd->sizes[minor & ~(gd->max_p-1)] != 0) &&
!(gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE) )
{
register_disk(gd,
device&~(gd->max_p-1),
gd->max_p,
&xlvbd_block_fops,
gd->part[minor&~(gd->max_p-1)].nr_sects);
}
}
else
{
/*
* 2: The VBD is mapped to an entire 'unit'. Clear all partitions.
* NB. The partition entries are only cleared if there are no VBDs
* mapped to individual partitions on this unit.
*/
i = gd->max_p - 1; /* Default: clear subpartitions as well. */
if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS )
i = 0; /* 'Virtual' mode: only clear the 'whole unit' entry. */
while ( i >= 0 )
{
invalidate_device(device+i, 1);
gd->part[minor+i].start_sect = 0;
gd->part[minor+i].nr_sects = 0;
gd->sizes[minor+i] = 0;
i--;
}
}
out:
bdput(bd);
return rc;
}
/*
* xlvbd_update_vbds - reprobes the VBD status and performs updates driver
* state. The VBDs need to be updated in this way when the domain is
* initialised and also each time we receive an XLBLK_UPDATE event.
*/
void xlvbd_update_vbds(void)
{
int i, j, k, old_nr, new_nr;
vdisk_t *old_info, *new_info, *merged_info;
old_info = vbd_info;
old_nr = nr_vbds;
new_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL);
if (!new_info)
return;
if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 )
goto out;
/*
* Final list maximum size is old list + new list. This occurs only when
* old list and new list do not overlap at all, and we cannot yet destroy
* VBDs in the old list because the usage counts are busy.
*/
merged_info = kmalloc((old_nr + new_nr) * sizeof(vdisk_t), GFP_KERNEL);
if (!merged_info)
goto out;
/* @i tracks old list; @j tracks new list; @k tracks merged list. */
i = j = k = 0;
while ( (i < old_nr) && (j < new_nr) )
{
if ( old_info[i].device < new_info[j].device )
{
if ( xlvbd_remove_device(old_info[i].device) != 0 )
memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
i++;
}
else if ( old_info[i].device > new_info[j].device )
{
if ( xlvbd_init_device(&new_info[j]) == 0 )
memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
j++;
}
else
{
if ( ((old_info[i].capacity == new_info[j].capacity) &&
(old_info[i].info == new_info[j].info)) ||
(xlvbd_remove_device(old_info[i].device) != 0) )
memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
else if ( xlvbd_init_device(&new_info[j]) == 0 )
memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
i++; j++;
}
}
for ( ; i < old_nr; i++ )
{
if ( xlvbd_remove_device(old_info[i].device) != 0 )
memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
}
for ( ; j < new_nr; j++ )
{
if ( xlvbd_init_device(&new_info[j]) == 0 )
memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
}
vbd_info = merged_info;
nr_vbds = k;
kfree(old_info);
out:
kfree(new_info);
}
/*
* Set up all the linux device goop for the virtual block devices (vbd's) that
* we know about. Note that although from the backend driver's p.o.v. VBDs are
* addressed simply an opaque 16-bit device number, the domain creation tools
* conventionally allocate these numbers to correspond to those used by 'real'
* linux -- this is just for convenience as it means e.g. that the same
* /etc/fstab can be used when booting with or without Xen.
*/
int xlvbd_init(void)
{
int i;
/*
* If compiled as a module, we don't support unloading yet. We therefore
* permanently increment the reference count to disallow it.
*/
SET_MODULE_OWNER(&xlvbd_block_fops);
MOD_INC_USE_COUNT;
/* Initialize the global arrays. */
for ( i = 0; i < 256; i++ )
{
xlide_blksize_size[i] = 1024;
xlide_hardsect_size[i] = 512;
xlide_max_sectors[i] = 512;
xlscsi_blksize_size[i] = 1024;
xlscsi_hardsect_size[i] = 512;
xlscsi_max_sectors[i] = 512;
xlvbd_blksize_size[i] = 512;
xlvbd_hardsect_size[i] = 512;
xlvbd_max_sectors[i] = 512;
}
vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL);
if (!vbd_info)
return -ENOMEM;
nr_vbds = xlvbd_get_vbd_info(vbd_info);
if ( nr_vbds < 0 )
{
kfree(vbd_info);
vbd_info = NULL;
nr_vbds = 0;
}
else
{
for ( i = 0; i < nr_vbds; i++ )
xlvbd_init_device(&vbd_info[i]);
}
return 0;
}
@@ -1,3 +0,0 @@
O_TARGET := drv.o
obj-$(CONFIG_XEN_CONSOLE) := console.o
include $(TOPDIR)/Rules.make
@@ -1,3 +0,0 @@
O_TARGET := drv.o
obj-y := core.o
include $(TOPDIR)/Rules.make
@@ -1,3 +0,0 @@
O_TARGET := drv.o
obj-y := evtchn.o
include $(TOPDIR)/Rules.make
@@ -1,10 +0,0 @@
O_TARGET := drv.o
subdir-$(CONFIG_XEN_NETDEV_FRONTEND) += frontend
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += frontend/drv.o
subdir-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend
obj-$(CONFIG_XEN_PHYSDEV_ACCESS) += backend/drv.o
include $(TOPDIR)/Rules.make
@@ -1,4 +0,0 @@
O_TARGET := drv.o
export-objs := interface.o
obj-y := main.o control.o interface.o
include $(TOPDIR)/Rules.make
@@ -1,3 +0,0 @@
O_TARGET := drv.o
obj-y := main.o
include $(TOPDIR)/Rules.make
@@ -1,20 +0,0 @@
.S.o:
$(CC) $(AFLAGS) -traditional -c $< -o $*.o
all: kernel.o head.o init_task.o
O_TARGET := kernel.o
export-objs := i386_ksyms.o gnttab.o skbuff.o ctrl_if.o
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o \
i386_ksyms.o i387.o evtchn.o ctrl_if.o pci-dma.o \
reboot.o fixup.o gnttab.o skbuff.o
ifdef CONFIG_PCI
obj-y += pci-i386.o pci-pc.o
endif
include $(TOPDIR)/Rules.make
@@ -1,779 +0,0 @@
/*
* linux/arch/i386/entry.S
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
* entry.S contains the system-call and fault low-level handling routines.
* This also contains the timer-interrupt handler, as well as all interrupts
* and faults that can result in a task-switch.
*
* NOTE: This code handles signal-recognition, which happens every time
* after a timer-interrupt and after each system call.
*
* I changed all the .align's to 4 (16 byte alignment), as that's faster
* on a 486.
*
* Stack layout in 'ret_to_user':
* ptrace needs to have all regs on the stack.
* if the order here is changed, it needs to be
* updated in fork.c:copy_process, signal.c:do_signal,
* ptrace.c and ptrace.h
*
* 0(%esp) - %ebx
* 4(%esp) - %ecx
* 8(%esp) - %edx
* C(%esp) - %esi
* 10(%esp) - %edi
* 14(%esp) - %ebp
* 18(%esp) - %eax
* 1C(%esp) - %ds
* 20(%esp) - %es
* 24(%esp) - orig_eax
* 28(%esp) - %eip
* 2C(%esp) - %cs
* 30(%esp) - %eflags
* 34(%esp) - %oldesp
* 38(%esp) - %oldss
*
* "current" is in register %ebx during any slow entries.
*/
#include <linux/config.h>
#include <linux/sys.h>
#include <linux/linkage.h>
#include <asm/segment.h>
#include <asm/smp.h>
EBX = 0x00
ECX = 0x04
EDX = 0x08
ESI = 0x0C
EDI = 0x10
EBP = 0x14
EAX = 0x18
DS = 0x1C
ES = 0x20
ORIG_EAX = 0x24
EIP = 0x28
CS = 0x2C
EFLAGS = 0x30
OLDESP = 0x34
OLDSS = 0x38
CF_MASK = 0x00000001
TF_MASK = 0x00000100
IF_MASK = 0x00000200
DF_MASK = 0x00000400
NT_MASK = 0x00004000
/* Offsets into task_struct. */
state = 0
flags = 4
sigpending = 8
addr_limit = 12
exec_domain = 16
need_resched = 20
tsk_ptrace = 24
processor = 52
/* Offsets into shared_info_t. */
#define evtchn_upcall_pending /* 0 */
#define evtchn_upcall_mask 1
ENOSYS = 38
#define SAVE_ALL \
cld; \
pushl %es; \
pushl %ds; \
pushl %eax; \
pushl %ebp; \
pushl %edi; \
pushl %esi; \
pushl %edx; \
pushl %ecx; \
pushl %ebx; \
movl $(__KERNEL_DS),%edx; \
movl %edx,%ds; \
movl %edx,%es;
#define RESTORE_ALL \
popl %ebx; \
popl %ecx; \
popl %edx; \
popl %esi; \
popl %edi; \
popl %ebp; \
popl %eax; \
1: popl %ds; \
2: popl %es; \
addl $4,%esp; \
3: iret; \
.section .fixup,"ax"; \
4: movl $0,(%esp); \
jmp 1b; \
5: movl $0,(%esp); \
jmp 2b; \
6: pushl %ss; \
popl %ds; \
pushl %ss; \
popl %es; \
pushl $11; \
call do_exit; \
.previous; \
.section __ex_table,"a";\
.align 4; \
.long 1b,4b; \
.long 2b,5b; \
.long 3b,6b; \
.previous
#define GET_CURRENT(reg) \
movl $-8192, reg; \
andl %esp, reg
ENTRY(lcall7)
pushfl # We get a different stack layout with call
pushl %eax # gates, which has to be cleaned up later..
SAVE_ALL
movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
movl CS(%esp),%edx # this is eip..
movl EFLAGS(%esp),%ecx # and this is cs..
movl %eax,EFLAGS(%esp) #
andl $~(NT_MASK|TF_MASK|DF_MASK), %eax
pushl %eax
popfl
movl %edx,EIP(%esp) # Now we move them to their "normal" places
movl %ecx,CS(%esp) #
movl %esp,%ebx
pushl %ebx
andl $-8192,%ebx # GET_CURRENT
movl exec_domain(%ebx),%edx # Get the execution domain
movl 4(%edx),%edx # Get the lcall7 handler for the domain
pushl $0x7
call *%edx
addl $4, %esp
popl %eax
jmp ret_to_user
ENTRY(lcall27)
pushfl # We get a different stack layout with call
pushl %eax # gates, which has to be cleaned up later..
SAVE_ALL
movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
movl CS(%esp),%edx # this is eip..
movl EFLAGS(%esp),%ecx # and this is cs..
movl %eax,EFLAGS(%esp) #
andl $~(NT_MASK|TF_MASK|DF_MASK), %eax
pushl %eax
popfl
movl %edx,EIP(%esp) # Now we move them to their "normal" places
movl %ecx,CS(%esp) #
movl %esp,%ebx
pushl %ebx
andl $-8192,%ebx # GET_CURRENT
movl exec_domain(%ebx),%edx # Get the execution domain
movl 4(%edx),%edx # Get the lcall7 handler for the domain
pushl $0x27
call *%edx
addl $4, %esp
popl %eax
jmp ret_to_user
ENTRY(ret_from_fork)
pushl %ebx
call SYMBOL_NAME(schedule_tail)
addl $4, %esp
GET_CURRENT(%ebx)
testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS
jne tracesys_exit
jmp ret_to_user
/*
* Return to user mode is not as complex as all this looks,
* but we want the default path for a system call return to
* go as quickly as possible which is why some of this is
* less clear than it otherwise should be.
*/
ENTRY(system_call)
pushl %eax # save orig_eax
SAVE_ALL
GET_CURRENT(%ebx)
testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS
jne tracesys
cmpl $(NR_syscalls),%eax
jae badsys
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
ret_to_user:
movl SYMBOL_NAME(HYPERVISOR_shared_info),%esi
movb $1,evtchn_upcall_mask(%esi) # make tests atomic
ret_to_user_nocli:
cmpl $0,need_resched(%ebx)
jne reschedule
cmpl $0,sigpending(%ebx)
je safesti # ensure need_resched updates are seen
/*signal_return:*/
movb $0,evtchn_upcall_mask(%esi) # reenable event callbacks
movl %esp,%eax
xorl %edx,%edx
call SYMBOL_NAME(do_signal)
jmp safesti
ALIGN
restore_all:
RESTORE_ALL
ALIGN
tracesys:
movl $-ENOSYS,EAX(%esp)
call SYMBOL_NAME(syscall_trace)
movl ORIG_EAX(%esp),%eax
cmpl $(NR_syscalls),%eax
jae tracesys_exit
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
tracesys_exit:
call SYMBOL_NAME(syscall_trace)
jmp ret_to_user
badsys:
movl $-ENOSYS,EAX(%esp)
jmp ret_to_user
ALIGN
ENTRY(ret_from_intr)
GET_CURRENT(%ebx)
ret_from_exception:
movb CS(%esp),%al
testl $2,%eax
jne ret_to_user
jmp restore_all
ALIGN
reschedule:
movb $0,evtchn_upcall_mask(%esi) # reenable event callbacks
call SYMBOL_NAME(schedule) # test
jmp ret_to_user
ENTRY(divide_error)
pushl $0 # no error code
pushl $ SYMBOL_NAME(do_divide_error)
ALIGN
error_code:
pushl %ds
pushl %eax
xorl %eax,%eax
pushl %ebp
pushl %edi
pushl %esi
pushl %edx
decl %eax # eax = -1
pushl %ecx
pushl %ebx
GET_CURRENT(%ebx)
cld
movl %es,%ecx
movl ORIG_EAX(%esp), %esi # get the error code
movl ES(%esp), %edi # get the function address
movl %eax, ORIG_EAX(%esp)
movl %ecx, ES(%esp)
movl %esp,%edx
pushl %esi # push the error code
pushl %edx # push the pt_regs pointer
movl $(__KERNEL_DS),%edx
movl %edx,%ds
movl %edx,%es
call *%edi
addl $8,%esp
jmp ret_from_exception
# A note on the "critical region" in our callback handler.
# We want to avoid stacking callback handlers due to events occurring
# during handling of the last event. To do this, we keep events disabled
# until we've done all processing. HOWEVER, we must enable events before
# popping the stack frame (can't be done atomically) and so it would still
# be possible to get enough handler activations to overflow the stack.
# Although unlikely, bugs of that kind are hard to track down, so we'd
# like to avoid the possibility.
# So, on entry to the handler we detect whether we interrupted an
# existing activation in its critical region -- if so, we pop the current
# activation and restart the handler using the previous one.
ENTRY(hypervisor_callback)
pushl %eax
SAVE_ALL
GET_CURRENT(%ebx)
movl EIP(%esp),%eax
cmpl $scrit,%eax
jb 11f
cmpl $ecrit,%eax
jb critical_region_fixup
11: push %esp
call evtchn_do_upcall
add $4,%esp
movl SYMBOL_NAME(HYPERVISOR_shared_info),%esi
movb CS(%esp),%cl
test $2,%cl # slow return to ring 2 or 3
jne ret_to_user_nocli
safesti:movb $0,evtchn_upcall_mask(%esi) # reenable event callbacks
scrit: /**** START OF CRITICAL REGION ****/
testb $0xFF,evtchn_upcall_pending(%esi)
jnz 14f # process more events if necessary...
RESTORE_ALL
14: movb $1,evtchn_upcall_mask(%esi)
jmp 11b
ecrit: /**** END OF CRITICAL REGION ****/
# [How we do the fixup]. We want to merge the current stack frame with the
# just-interrupted frame. How we do this depends on where in the critical
# region the interrupted handler was executing, and so how many saved
# registers are in each frame. We do this quickly using the lookup table
# 'critical_fixup_table'. For each byte offset in the critical region, it
# provides the number of bytes which have already been popped from the
# interrupted stack frame.
critical_region_fixup:
addl $critical_fixup_table-scrit,%eax
movzbl (%eax),%eax # %eax contains num bytes popped
mov %esp,%esi
add %eax,%esi # %esi points at end of src region
mov %esp,%edi
add $0x34,%edi # %edi points at end of dst region
mov %eax,%ecx
shr $2,%ecx # convert words to bytes
je 16f # skip loop if nothing to copy
15: subl $4,%esi # pre-decrementing copy loop
subl $4,%edi
movl (%esi),%eax
movl %eax,(%edi)
loop 15b
16: movl %edi,%esp # final %edi is top of merged stack
jmp 11b
critical_fixup_table:
.byte 0x00,0x00,0x00 # testb $0xFF,(%esi)
.byte 0x00,0x00 # jnz 14f
.byte 0x00 # pop %ebx
.byte 0x04 # pop %ecx
.byte 0x08 # pop %edx
.byte 0x0c # pop %esi
.byte 0x10 # pop %edi
.byte 0x14 # pop %ebp
.byte 0x18 # pop %eax
.byte 0x1c # pop %ds
.byte 0x20 # pop %es
.byte 0x24,0x24,0x24 # add $4,%esp
.byte 0x28 # iret
.byte 0x00,0x00,0x00,0x00 # movb $1,4(%esi)
.byte 0x00,0x00 # jmp 11b
# Hypervisor uses this for application faults while it executes.
ENTRY(failsafe_callback)
1: popl %ds
2: popl %es
3: popl %fs
4: popl %gs
5: iret
.section .fixup,"ax"; \
6: movl $0,(%esp); \
jmp 1b; \
7: movl $0,(%esp); \
jmp 2b; \
8: movl $0,(%esp); \
jmp 3b; \
9: movl $0,(%esp); \
jmp 4b; \
10: pushl %ss; \
popl %ds; \
pushl %ss; \
popl %es; \
pushl $11; \
call do_exit; \
.previous; \
.section __ex_table,"a";\
.align 4; \
.long 1b,6b; \
.long 2b,7b; \
.long 3b,8b; \
.long 4b,9b; \
.long 5b,10b; \
.previous
ENTRY(coprocessor_error)
pushl $0
pushl $ SYMBOL_NAME(do_coprocessor_error)
jmp error_code
ENTRY(simd_coprocessor_error)
pushl $0
pushl $ SYMBOL_NAME(do_simd_coprocessor_error)
jmp error_code
ENTRY(device_not_available)
pushl $-1 # mark this as an int
SAVE_ALL
GET_CURRENT(%ebx)
call SYMBOL_NAME(math_state_restore)
jmp ret_from_exception
ENTRY(debug)
pushl $0
pushl $ SYMBOL_NAME(do_debug)
jmp error_code
ENTRY(int3)
pushl $0
pushl $ SYMBOL_NAME(do_int3)
jmp error_code
ENTRY(overflow)
pushl $0
pushl $ SYMBOL_NAME(do_overflow)
jmp error_code
ENTRY(bounds)
pushl $0
pushl $ SYMBOL_NAME(do_bounds)
jmp error_code
ENTRY(invalid_op)
pushl $0
pushl $ SYMBOL_NAME(do_invalid_op)
jmp error_code
ENTRY(coprocessor_segment_overrun)
pushl $0
pushl $ SYMBOL_NAME(do_coprocessor_segment_overrun)
jmp error_code
ENTRY(double_fault)
pushl $ SYMBOL_NAME(do_double_fault)
jmp error_code
ENTRY(invalid_TSS)
pushl $ SYMBOL_NAME(do_invalid_TSS)
jmp error_code
ENTRY(segment_not_present)
pushl $ SYMBOL_NAME(do_segment_not_present)
jmp error_code
ENTRY(stack_segment)
pushl $ SYMBOL_NAME(do_stack_segment)
jmp error_code
ENTRY(general_protection)
pushl $ SYMBOL_NAME(do_general_protection)
jmp error_code
ENTRY(alignment_check)
pushl $ SYMBOL_NAME(do_alignment_check)
jmp error_code
# This handler is special, because it gets an extra value on its stack,
# which is the linear faulting address.
#define PAGE_FAULT_STUB(_name1, _name2) \
ENTRY(_name1) \
pushl %ds ; \
pushl %eax ; \
xorl %eax,%eax ; \
pushl %ebp ; \
pushl %edi ; \
pushl %esi ; \
pushl %edx ; \
decl %eax /* eax = -1 */ ; \
pushl %ecx ; \
pushl %ebx ; \
GET_CURRENT(%ebx) ; \
cld ; \
movl %es,%ecx ; \
movl ORIG_EAX(%esp), %esi /* get the error code */ ; \
movl ES(%esp), %edi /* get the faulting address */ ; \
movl %eax, ORIG_EAX(%esp) ; \
movl %ecx, ES(%esp) ; \
movl %esp,%edx ; \
pushl %edi /* push the faulting address */ ; \
pushl %esi /* push the error code */ ; \
pushl %edx /* push the pt_regs pointer */ ; \
movl $(__KERNEL_DS),%edx ; \
movl %edx,%ds ; \
movl %edx,%es ; \
call SYMBOL_NAME(_name2) ; \
addl $12,%esp ; \
jmp ret_from_exception ;
PAGE_FAULT_STUB(page_fault, do_page_fault)
ENTRY(machine_check)
pushl $0
pushl $ SYMBOL_NAME(do_machine_check)
jmp error_code
ENTRY(fixup_4gb_segment)
pushl $ SYMBOL_NAME(do_fixup_4gb_segment)
jmp error_code
.data
ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/
.long SYMBOL_NAME(sys_exit)
.long SYMBOL_NAME(sys_fork)
.long SYMBOL_NAME(sys_read)
.long SYMBOL_NAME(sys_write)
.long SYMBOL_NAME(sys_open) /* 5 */
.long SYMBOL_NAME(sys_close)
.long SYMBOL_NAME(sys_waitpid)
.long SYMBOL_NAME(sys_creat)
.long SYMBOL_NAME(sys_link)
.long SYMBOL_NAME(sys_unlink) /* 10 */
.long SYMBOL_NAME(sys_execve)
.long SYMBOL_NAME(sys_chdir)
.long SYMBOL_NAME(sys_time)
.long SYMBOL_NAME(sys_mknod)
.long SYMBOL_NAME(sys_chmod) /* 15 */
.long SYMBOL_NAME(sys_lchown16)
.long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
.long SYMBOL_NAME(sys_stat)
.long SYMBOL_NAME(sys_lseek)
.long SYMBOL_NAME(sys_getpid) /* 20 */
.long SYMBOL_NAME(sys_mount)
.long SYMBOL_NAME(sys_oldumount)
.long SYMBOL_NAME(sys_setuid16)
.long SYMBOL_NAME(sys_getuid16)
.long SYMBOL_NAME(sys_stime) /* 25 */
.long SYMBOL_NAME(sys_ptrace)
.long SYMBOL_NAME(sys_alarm)
.long SYMBOL_NAME(sys_fstat)
.long SYMBOL_NAME(sys_pause)
.long SYMBOL_NAME(sys_utime) /* 30 */
.long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
.long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
.long SYMBOL_NAME(sys_access)
.long SYMBOL_NAME(sys_nice)
.long SYMBOL_NAME(sys_ni_syscall) /* 35 */ /* old ftime syscall holder */
.long SYMBOL_NAME(sys_sync)
.long SYMBOL_NAME(sys_kill)
.long SYMBOL_NAME(sys_rename)
.long SYMBOL_NAME(sys_mkdir)
.long SYMBOL_NAME(sys_rmdir) /* 40 */
.long SYMBOL_NAME(sys_dup)
.long SYMBOL_NAME(sys_pipe)
.long SYMBOL_NAME(sys_times)
.long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
.long SYMBOL_NAME(sys_brk) /* 45 */
.long SYMBOL_NAME(sys_setgid16)
.long SYMBOL_NAME(sys_getgid16)
.long SYMBOL_NAME(sys_signal)
.long SYMBOL_NAME(sys_geteuid16)
.long SYMBOL_NAME(sys_getegid16) /* 50 */
.long SYMBOL_NAME(sys_acct)
.long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
.long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
.long SYMBOL_NAME(sys_ioctl)
.long SYMBOL_NAME(sys_fcntl) /* 55 */
.long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
.long SYMBOL_NAME(sys_setpgid)
.long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
.long SYMBOL_NAME(sys_olduname)
.long SYMBOL_NAME(sys_umask) /* 60 */
.long SYMBOL_NAME(sys_chroot)
.long SYMBOL_NAME(sys_ustat)
.long SYMBOL_NAME(sys_dup2)
.long SYMBOL_NAME(sys_getppid)
.long SYMBOL_NAME(sys_getpgrp) /* 65 */
.long SYMBOL_NAME(sys_setsid)
.long SYMBOL_NAME(sys_sigaction)
.long SYMBOL_NAME(sys_sgetmask)
.long SYMBOL_NAME(sys_ssetmask)
.long SYMBOL_NAME(sys_setreuid16) /* 70 */
.long SYMBOL_NAME(sys_setregid16)
.long SYMBOL_NAME(sys_sigsuspend)
.long SYMBOL_NAME(sys_sigpending)
.long SYMBOL_NAME(sys_sethostname)
.long SYMBOL_NAME(sys_setrlimit) /* 75 */
.long SYMBOL_NAME(sys_old_getrlimit)
.long SYMBOL_NAME(sys_getrusage)
.long SYMBOL_NAME(sys_gettimeofday)
.long SYMBOL_NAME(sys_settimeofday)
.long SYMBOL_NAME(sys_getgroups16) /* 80 */
.long SYMBOL_NAME(sys_setgroups16)
.long SYMBOL_NAME(old_select)
.long SYMBOL_NAME(sys_symlink)
.long SYMBOL_NAME(sys_lstat)
.long SYMBOL_NAME(sys_readlink) /* 85 */
.long SYMBOL_NAME(sys_uselib)
.long SYMBOL_NAME(sys_swapon)
.long SYMBOL_NAME(sys_reboot)
.long SYMBOL_NAME(old_readdir)
.long SYMBOL_NAME(old_mmap) /* 90 */
.long SYMBOL_NAME(sys_munmap)
.long SYMBOL_NAME(sys_truncate)
.long SYMBOL_NAME(sys_ftruncate)
.long SYMBOL_NAME(sys_fchmod)
.long SYMBOL_NAME(sys_fchown16) /* 95 */
.long SYMBOL_NAME(sys_getpriority)
.long SYMBOL_NAME(sys_setpriority)
.long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
.long SYMBOL_NAME(sys_statfs)
.long SYMBOL_NAME(sys_fstatfs) /* 100 */
.long SYMBOL_NAME(sys_ioperm)
.long SYMBOL_NAME(sys_socketcall)
.long SYMBOL_NAME(sys_syslog)
.long SYMBOL_NAME(sys_setitimer)
.long SYMBOL_NAME(sys_getitimer) /* 105 */
.long SYMBOL_NAME(sys_newstat)
.long SYMBOL_NAME(sys_newlstat)
.long SYMBOL_NAME(sys_newfstat)
.long SYMBOL_NAME(sys_uname)
.long SYMBOL_NAME(sys_iopl) /* 110 */
.long SYMBOL_NAME(sys_vhangup)
.long SYMBOL_NAME(sys_ni_syscall) /* old "idle" system call */
.long SYMBOL_NAME(sys_ni_syscall) /* was VM86 */
.long SYMBOL_NAME(sys_wait4)
.long SYMBOL_NAME(sys_swapoff) /* 115 */
.long SYMBOL_NAME(sys_sysinfo)
.long SYMBOL_NAME(sys_ipc)
.long SYMBOL_NAME(sys_fsync)
.long SYMBOL_NAME(sys_sigreturn)
.long SYMBOL_NAME(sys_clone) /* 120 */
.long SYMBOL_NAME(sys_setdomainname)
.long SYMBOL_NAME(sys_newuname)
.long SYMBOL_NAME(sys_modify_ldt)
.long SYMBOL_NAME(sys_adjtimex)
.long SYMBOL_NAME(sys_mprotect) /* 125 */
.long SYMBOL_NAME(sys_sigprocmask)
.long SYMBOL_NAME(sys_create_module)
.long SYMBOL_NAME(sys_init_module)
.long SYMBOL_NAME(sys_delete_module)
.long SYMBOL_NAME(sys_get_kernel_syms) /* 130 */
.long SYMBOL_NAME(sys_quotactl)
.long SYMBOL_NAME(sys_getpgid)
.long SYMBOL_NAME(sys_fchdir)
.long SYMBOL_NAME(sys_bdflush)
.long SYMBOL_NAME(sys_sysfs) /* 135 */
.long SYMBOL_NAME(sys_personality)
.long SYMBOL_NAME(sys_ni_syscall) /* for afs_syscall */
.long SYMBOL_NAME(sys_setfsuid16)
.long SYMBOL_NAME(sys_setfsgid16)
.long SYMBOL_NAME(sys_llseek) /* 140 */
.long SYMBOL_NAME(sys_getdents)
.long SYMBOL_NAME(sys_select)
.long SYMBOL_NAME(sys_flock)
.long SYMBOL_NAME(sys_msync)
.long SYMBOL_NAME(sys_readv) /* 145 */
.long SYMBOL_NAME(sys_writev)
.long SYMBOL_NAME(sys_getsid)
.long SYMBOL_NAME(sys_fdatasync)
.long SYMBOL_NAME(sys_sysctl)
.long SYMBOL_NAME(sys_mlock) /* 150 */
.long SYMBOL_NAME(sys_munlock)
.long SYMBOL_NAME(sys_mlockall)
.long SYMBOL_NAME(sys_munlockall)
.long SYMBOL_NAME(sys_sched_setparam)
.long SYMBOL_NAME(sys_sched_getparam) /* 155 */
.long SYMBOL_NAME(sys_sched_setscheduler)
.long SYMBOL_NAME(sys_sched_getscheduler)
.long SYMBOL_NAME(sys_sched_yield)
.long SYMBOL_NAME(sys_sched_get_priority_max)
.long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */
.long SYMBOL_NAME(sys_sched_rr_get_interval)
.long SYMBOL_NAME(sys_nanosleep)
.long SYMBOL_NAME(sys_mremap)
.long SYMBOL_NAME(sys_setresuid16)
.long SYMBOL_NAME(sys_getresuid16) /* 165 */
.long SYMBOL_NAME(sys_ni_syscall) /* was VM86 */
.long SYMBOL_NAME(sys_query_module)
.long SYMBOL_NAME(sys_poll)
.long SYMBOL_NAME(sys_nfsservctl)
.long SYMBOL_NAME(sys_setresgid16) /* 170 */
.long SYMBOL_NAME(sys_getresgid16)
.long SYMBOL_NAME(sys_prctl)
.long SYMBOL_NAME(sys_rt_sigreturn)
.long SYMBOL_NAME(sys_rt_sigaction)
.long SYMBOL_NAME(sys_rt_sigprocmask) /* 175 */
.long SYMBOL_NAME(sys_rt_sigpending)
.long SYMBOL_NAME(sys_rt_sigtimedwait)
.long SYMBOL_NAME(sys_rt_sigqueueinfo)
.long SYMBOL_NAME(sys_rt_sigsuspend)
.long SYMBOL_NAME(sys_pread) /* 180 */
.long SYMBOL_NAME(sys_pwrite)
.long SYMBOL_NAME(sys_chown16)
.long SYMBOL_NAME(sys_getcwd)
.long SYMBOL_NAME(sys_capget)
.long SYMBOL_NAME(sys_capset) /* 185 */
.long SYMBOL_NAME(sys_sigaltstack)
.long SYMBOL_NAME(sys_sendfile)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
.long SYMBOL_NAME(sys_getrlimit)
.long SYMBOL_NAME(sys_mmap2)
.long SYMBOL_NAME(sys_truncate64)
.long SYMBOL_NAME(sys_ftruncate64)
.long SYMBOL_NAME(sys_stat64) /* 195 */
.long SYMBOL_NAME(sys_lstat64)
.long SYMBOL_NAME(sys_fstat64)
.long SYMBOL_NAME(sys_lchown)
.long SYMBOL_NAME(sys_getuid)
.long SYMBOL_NAME(sys_getgid) /* 200 */
.long SYMBOL_NAME(sys_geteuid)
.long SYMBOL_NAME(sys_getegid)
.long SYMBOL_NAME(sys_setreuid)
.long SYMBOL_NAME(sys_setregid)
.long SYMBOL_NAME(sys_getgroups) /* 205 */
.long SYMBOL_NAME(sys_setgroups)
.long SYMBOL_NAME(sys_fchown)
.long SYMBOL_NAME(sys_setresuid)
.long SYMBOL_NAME(sys_getresuid)
.long SYMBOL_NAME(sys_setresgid) /* 210 */
.long SYMBOL_NAME(sys_getresgid)
.long SYMBOL_NAME(sys_chown)
.long SYMBOL_NAME(sys_setuid)
.long SYMBOL_NAME(sys_setgid)
.long SYMBOL_NAME(sys_setfsuid) /* 215 */
.long SYMBOL_NAME(sys_setfsgid)
.long SYMBOL_NAME(sys_pivot_root)
.long SYMBOL_NAME(sys_mincore)
.long SYMBOL_NAME(sys_madvise)
.long SYMBOL_NAME(sys_getdents64) /* 220 */
.long SYMBOL_NAME(sys_fcntl64)
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */
.long SYMBOL_NAME(sys_ni_syscall) /* Reserved for Security */
.long SYMBOL_NAME(sys_gettid)
.long SYMBOL_NAME(sys_readahead) /* 225 */
.long SYMBOL_NAME(sys_setxattr)
.long SYMBOL_NAME(sys_lsetxattr)
.long SYMBOL_NAME(sys_fsetxattr)
.long SYMBOL_NAME(sys_getxattr)
.long SYMBOL_NAME(sys_lgetxattr) /* 230 */
.long SYMBOL_NAME(sys_fgetxattr)
.long SYMBOL_NAME(sys_listxattr)
.long SYMBOL_NAME(sys_llistxattr)
.long SYMBOL_NAME(sys_flistxattr)
.long SYMBOL_NAME(sys_removexattr) /* 235 */
.long SYMBOL_NAME(sys_lremovexattr)
.long SYMBOL_NAME(sys_fremovexattr)
.long SYMBOL_NAME(sys_tkill)
.long SYMBOL_NAME(sys_sendfile64)
.long SYMBOL_NAME(sys_ni_syscall) /* 240 reserved for futex */
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for sched_setaffinity */
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for sched_getaffinity */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_set_thread_area */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_get_thread_area */
.long SYMBOL_NAME(sys_ni_syscall) /* 245 sys_io_setup */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_io_destroy */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_io_getevents */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_io_submit */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_io_cancel */
.long SYMBOL_NAME(sys_ni_syscall) /* 250 sys_alloc_hugepages */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_free_hugepages */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_exit_group */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_lookup_dcookie */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_epoll_create */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_epoll_ctl 255 */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_epoll_wait */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_remap_file_pages */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_set_tid_address */
.rept NR_syscalls-(.-sys_call_table)/4
.long SYMBOL_NAME(sys_ni_syscall)
.endr
@@ -1,41 +0,0 @@
.section __xen_guest
.ascii "GUEST_OS=linux,GUEST_VER=2.4,XEN_VER=3.0,VIRT_BASE=0xC0000000"
.ascii ",LOADER=generic"
.byte 0
.text
#include <linux/config.h>
#include <linux/threads.h>
#include <linux/linkage.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/desc.h>
ENTRY(stext)
ENTRY(_stext)
cld
lss stack_start,%esp
/* Copy the necessary stuff from xen_start_info structure. */
mov $SYMBOL_NAME(xen_start_info_union),%edi
mov $128,%ecx
rep movsl
jmp SYMBOL_NAME(start_kernel)
ENTRY(stack_start)
.long SYMBOL_NAME(init_task_union)+8192, __KERNEL_DS
.org 0x1000
ENTRY(empty_zero_page)
.org 0x2000
ENTRY(default_ldt)
.org 0x3000
ENTRY(cpu0_pte_quicklist)
.org 0x3400
ENTRY(cpu0_pgd_quicklist)
.org 0x3800
@@ -1,180 +0,0 @@
#include <linux/config.h>
#include <linux/module.h>
#include <linux/smp.h>
#include <linux/user.h>
#include <linux/elfcore.h>
#include <linux/mca.h>
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
#include <linux/smp_lock.h>
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/apm_bios.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/tty.h>
#include <asm/semaphore.h>
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/uaccess.h>
#include <asm/checksum.h>
#include <asm/io.h>
#include <asm/hardirq.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/mmx.h>
#include <asm/desc.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
extern void dump_thread(struct pt_regs *, struct user *);
extern spinlock_t rtc_lock;
#if defined(CONFIG_APMXXX) || defined(CONFIG_APM_MODULEXXX)
extern void machine_real_restart(unsigned char *, int);
EXPORT_SYMBOL(machine_real_restart);
extern void default_idle(void);
EXPORT_SYMBOL(default_idle);
#endif
#ifdef CONFIG_SMP
extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
#endif
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
extern struct drive_info_struct drive_info;
EXPORT_SYMBOL(drive_info);
#endif
// XXX extern unsigned long get_cmos_time(void);
/* platform dependent support */
EXPORT_SYMBOL(boot_cpu_data);
EXPORT_SYMBOL(dump_thread);
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(dump_extended_fpu);
EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(disable_irq_nosync);
EXPORT_SYMBOL(probe_irq_mask);
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(pm_idle);
EXPORT_SYMBOL(pm_power_off);
EXPORT_SYMBOL(apm_info);
//EXPORT_SYMBOL(gdt);
EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(phys_to_machine_mapping);
#ifdef CONFIG_DEBUG_IOVIRT
EXPORT_SYMBOL(__io_virt_debug);
#endif
EXPORT_SYMBOL_NOVERS(__down_failed);
EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
EXPORT_SYMBOL_NOVERS(__up_wakeup);
/* Networking helper routines. */
EXPORT_SYMBOL(csum_partial_copy_generic);
/* Delay loops */
EXPORT_SYMBOL(__ndelay);
EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(__delay);
EXPORT_SYMBOL(__const_udelay);
EXPORT_SYMBOL_NOVERS(__get_user_1);
EXPORT_SYMBOL_NOVERS(__get_user_2);
EXPORT_SYMBOL_NOVERS(__get_user_4);
EXPORT_SYMBOL(strtok);
EXPORT_SYMBOL(strpbrk);
EXPORT_SYMBOL(strstr);
EXPORT_SYMBOL(strncpy_from_user);
EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(clear_user);
EXPORT_SYMBOL(__clear_user);
EXPORT_SYMBOL(__generic_copy_from_user);
EXPORT_SYMBOL(__generic_copy_to_user);
EXPORT_SYMBOL(strnlen_user);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
#ifdef CONFIG_PCI
EXPORT_SYMBOL(pcibios_penalize_isa_irq);
EXPORT_SYMBOL(pci_mem_start);
#endif
#ifdef CONFIG_X86_USE_3DNOW
EXPORT_SYMBOL(_mmx_memcpy);
EXPORT_SYMBOL(mmx_clear_page);
EXPORT_SYMBOL(mmx_copy_page);
#endif
#ifdef CONFIG_SMP
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(kernel_flag_cacheline);
EXPORT_SYMBOL(smp_num_cpus);
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL_NOVERS(__write_lock_failed);
EXPORT_SYMBOL_NOVERS(__read_lock_failed);
/* Global SMP irq stuff */
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL(global_irq_holder);
EXPORT_SYMBOL(__global_cli);
EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_save_flags);
EXPORT_SYMBOL(__global_restore_flags);
EXPORT_SYMBOL(smp_call_function);
/* TLB flushing */
EXPORT_SYMBOL(flush_tlb_page);
/* HT support */
EXPORT_SYMBOL(smp_num_siblings);
EXPORT_SYMBOL(cpu_sibling_map);
#endif
#ifdef CONFIG_X86_IO_APIC
EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
#endif
#ifdef CONFIG_VT
EXPORT_SYMBOL(screen_info);
#endif
EXPORT_SYMBOL(get_wchan);
EXPORT_SYMBOL(rtc_lock);
#undef memcpy
#undef memset
extern void * memset(void *,int,__kernel_size_t);
extern void * memcpy(void *,const void *,__kernel_size_t);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memset);
#ifdef CONFIG_HAVE_DEC_LOCK
EXPORT_SYMBOL(atomic_dec_and_lock);
#endif
#ifdef CONFIG_MULTIQUAD
EXPORT_SYMBOL(xquad_portio);
#endif
#include <asm/xen_proc.h>
EXPORT_SYMBOL(create_xen_proc_entry);
EXPORT_SYMBOL(remove_xen_proc_entry);
EXPORT_SYMBOL(evtchn_do_upcall);
EXPORT_SYMBOL(force_evtchn_callback);
EXPORT_SYMBOL(HYPERVISOR_shared_info);
File diff suppressed because it is too large. Load diff
-272
View File
@@ -1,272 +0,0 @@
/*
* linux/kernel/ldt.c
*
* Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
* Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <asm/mmu_context.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/ldt.h>
#include <asm/desc.h>
#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
static void flush_ldt(void *mm)
{
if (current->active_mm)
load_LDT(&current->active_mm->context);
}
#endif
static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
{
void *oldldt;
void *newldt;
int oldsize;
if (mincount <= pc->size)
return 0;
oldsize = pc->size;
mincount = (mincount+511)&(~511);
if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
else
newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
if (!newldt)
return -ENOMEM;
if (oldsize)
memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
oldldt = pc->ldt;
memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
wmb();
pc->ldt = newldt;
pc->size = mincount;
if (reload) {
make_pages_readonly(
pc->ldt,
(pc->size*LDT_ENTRY_SIZE)/PAGE_SIZE);
load_LDT(pc);
#ifdef CONFIG_SMP
if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
smp_call_function(flush_ldt, 0, 1, 1);
#endif
}
wmb();
if (oldsize) {
make_pages_writable(
oldldt, (oldsize*LDT_ENTRY_SIZE)/PAGE_SIZE);
if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
vfree(oldldt);
else
kfree(oldldt);
}
return 0;
}
static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
{
int err = alloc_ldt(new, old->size, 0);
if (err < 0) {
printk(KERN_WARNING "ldt allocation failed\n");
new->size = 0;
return err;
}
memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
make_pages_readonly(new->ldt, (new->size*LDT_ENTRY_SIZE)/PAGE_SIZE);
return 0;
}
/*
* we do not have to muck with descriptors here, that is
* done in switch_mm() as needed.
*/
int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
struct mm_struct * old_mm;
int retval = 0;
init_MUTEX(&mm->context.sem);
mm->context.size = 0;
old_mm = current->mm;
if (old_mm && old_mm->context.size > 0) {
down(&old_mm->context.sem);
retval = copy_ldt(&mm->context, &old_mm->context);
up(&old_mm->context.sem);
}
return retval;
}
/*
* No need to lock the MM as we are the last user
* Do not touch the ldt register, we are already
* in the next thread.
*/
void destroy_context(struct mm_struct *mm)
{
if (mm->context.size) {
make_pages_writable(
mm->context.ldt,
(mm->context.size*LDT_ENTRY_SIZE)/PAGE_SIZE);
if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
vfree(mm->context.ldt);
else
kfree(mm->context.ldt);
mm->context.size = 0;
}
}
static int read_ldt(void * ptr, unsigned long bytecount)
{
int err;
unsigned long size;
struct mm_struct * mm = current->mm;
if (!mm->context.size)
return 0;
if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
down(&mm->context.sem);
size = mm->context.size*LDT_ENTRY_SIZE;
if (size > bytecount)
size = bytecount;
err = 0;
if (copy_to_user(ptr, mm->context.ldt, size))
err = -EFAULT;
up(&mm->context.sem);
if (err < 0)
return err;
if (size != bytecount) {
/* zero-fill the rest */
clear_user(ptr+size, bytecount-size);
}
return bytecount;
}
static int read_default_ldt(void * ptr, unsigned long bytecount)
{
int err;
unsigned long size;
void *address;
err = 0;
address = &default_ldt[0];
size = 5*sizeof(struct desc_struct);
if (size > bytecount)
size = bytecount;
err = size;
if (copy_to_user(ptr, address, size))
err = -EFAULT;
return err;
}
static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
{
struct mm_struct * mm = current->mm;
__u32 entry_1, entry_2, *lp;
unsigned long mach_lp;
int error;
struct modify_ldt_ldt_s ldt_info;
error = -EINVAL;
if (bytecount != sizeof(ldt_info))
goto out;
error = -EFAULT;
if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
goto out;
error = -EINVAL;
if (ldt_info.entry_number >= LDT_ENTRIES)
goto out;
if (ldt_info.contents == 3) {
if (oldmode)
goto out;
if (ldt_info.seg_not_present == 0)
goto out;
}
down(&mm->context.sem);
if (ldt_info.entry_number >= mm->context.size) {
error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
if (error < 0)
goto out_unlock;
}
lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
mach_lp = arbitrary_virt_to_machine(lp);
/* Allow LDTs to be cleared by the user. */
if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
if (oldmode ||
(ldt_info.contents == 0 &&
ldt_info.read_exec_only == 1 &&
ldt_info.seg_32bit == 0 &&
ldt_info.limit_in_pages == 0 &&
ldt_info.seg_not_present == 1 &&
ldt_info.useable == 0 )) {
entry_1 = 0;
entry_2 = 0;
goto install;
}
}
entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
(ldt_info.limit & 0x0ffff);
entry_2 = (ldt_info.base_addr & 0xff000000) |
((ldt_info.base_addr & 0x00ff0000) >> 16) |
(ldt_info.limit & 0xf0000) |
((ldt_info.read_exec_only ^ 1) << 9) |
(ldt_info.contents << 10) |
((ldt_info.seg_not_present ^ 1) << 15) |
(ldt_info.seg_32bit << 22) |
(ldt_info.limit_in_pages << 23) |
0x7000;
if (!oldmode)
entry_2 |= (ldt_info.useable << 20);
/* Install the new entry ... */
install:
error = HYPERVISOR_update_descriptor(mach_lp, entry_1, entry_2);
out_unlock:
up(&mm->context.sem);
out:
return error;
}
asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
{
int ret = -ENOSYS;
switch (func) {
case 0:
ret = read_ldt(ptr, bytecount);
break;
case 1:
ret = write_ldt(ptr, bytecount, 1);
break;
case 2:
ret = read_default_ldt(ptr, bytecount);
break;
case 0x11:
ret = write_ldt(ptr, bytecount, 0);
break;
}
return ret;
}
@@ -1,260 +0,0 @@
/*
* Low-Level PCI Support for PC
*
* (c) 1999--2000 Martin Mares <mj@ucw.cz>
*
* Adjusted to use Xen's interface by Rolf Neugebauer, Intel Research Cambridge
* Further modifications by Keir Fraser, University of Cambridge
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/segment.h>
#include <asm/io.h>
#include <asm-xen/xen-public/xen.h>
#include <asm-xen/xen-public/physdev.h>
#include "pci-i386.h"
/*
* NB. The following interface functions are not included here:
* 1. void eisa_set_level_irq(unsigned int irq)
* 2. irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
* 3. int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
* All are used by the ACPI driver. This should be ported to Xen if it is
* ever required -- Xen is the ultimate source for IRQ-routing knowledge.
*/
struct pci_ops *pci_root_ops = NULL;
int (*pci_config_read)(int seg, int bus, int dev, int fn,
int reg, int len, u32 *value) = NULL;
int (*pci_config_write)(int seg, int bus, int dev, int fn,
int reg, int len, u32 value) = NULL;
unsigned int pci_probe = PCI_PROBE_BIOS;
struct pci_fixup pcibios_fixups[] = { { 0 } };
static int pci_confx_read(int seg, int bus, int dev, int fn, int reg,
int len, u32 *value)
{
int ret;
physdev_op_t op;
if (bus > 255 || dev > 31 || fn > 7 || reg > 255)
return -EINVAL;
op.cmd = PHYSDEVOP_PCI_CFGREG_READ;
op.u.pci_cfgreg_read.bus = bus;
op.u.pci_cfgreg_read.dev = dev;
op.u.pci_cfgreg_read.func = fn;
op.u.pci_cfgreg_read.reg = reg;
op.u.pci_cfgreg_read.len = len;
if ( (ret = HYPERVISOR_physdev_op(&op)) != 0 )
return ret;
*value = op.u.pci_cfgreg_read.value;
return 0;
}
static int pci_confx_write(int seg, int bus, int dev, int fn, int reg,
int len, u32 value)
{
int ret;
physdev_op_t op;
if ((bus > 255 || dev > 31 || fn > 7 || reg > 255))
return -EINVAL;
op.cmd = PHYSDEVOP_PCI_CFGREG_WRITE;
op.u.pci_cfgreg_write.bus = bus;
op.u.pci_cfgreg_write.dev = dev;
op.u.pci_cfgreg_write.func = fn;
op.u.pci_cfgreg_write.reg = reg;
op.u.pci_cfgreg_write.len = len;
op.u.pci_cfgreg_write.value = value;
if ( (ret = HYPERVISOR_physdev_op(&op)) != 0 )
return ret;
return 0;
}
static int pci_confx_read_config_byte(struct pci_dev *dev,
int where, u8 *value)
{
int result;
u32 data;
result = pci_confx_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, &data);
*value = (u8)data;
return result;
}
static int pci_confx_read_config_word(struct pci_dev *dev,
int where, u16 *value)
{
int result;
u32 data;
result = pci_confx_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, &data);
*value = (u16)data;
return result;
}
static int pci_confx_read_config_dword(struct pci_dev *dev,
int where, u32 *value)
{
return pci_confx_read(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
}
static int pci_confx_write_config_byte(struct pci_dev *dev,
int where, u8 value)
{
return pci_confx_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 1, value);
}
static int pci_confx_write_config_word(struct pci_dev *dev,
int where, u16 value)
{
return pci_confx_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 2, value);
}
static int pci_confx_write_config_dword(struct pci_dev *dev,
int where, u32 value)
{
return pci_confx_write(0, dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn), where, 4, value);
}
static struct pci_ops pci_conf_xen = {
pci_confx_read_config_byte,
pci_confx_read_config_word,
pci_confx_read_config_dword,
pci_confx_write_config_byte,
pci_confx_write_config_word,
pci_confx_write_config_dword
};
void pcibios_penalize_isa_irq(int irq)
{
/* nothing */
}
void __devinit pcibios_fixup_bus(struct pci_bus *b)
{
pci_read_bridge_bases(b);
}
struct pci_bus * __devinit pcibios_scan_root(int busnum)
{
struct list_head *list;
struct pci_bus *bus;
list_for_each ( list, &pci_root_buses )
{
bus = pci_bus_b(list);
if ( bus->number == busnum )
return bus;
}
printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
return pci_scan_bus(busnum, pci_root_ops, NULL);
}
void __init pcibios_init(void)
{
int bus;
physdev_op_t op;
if ( !pci_probe )
return;
pci_root_ops = &pci_conf_xen;
pci_config_read = pci_confx_read;
pci_config_write = pci_confx_write;
pcibios_set_cacheline_size();
op.cmd = PHYSDEVOP_PCI_PROBE_ROOT_BUSES;
if ( HYPERVISOR_physdev_op(&op) != 0 )
{
printk(KERN_WARNING "PCI: System does not support PCI\n");
return;
}
printk(KERN_INFO "PCI: Probing PCI hardware\n");
for ( bus = 0; bus < 256; bus++ )
if ( test_bit(bus, &op.u.pci_probe_root_buses.busmask[0]) )
(void)pcibios_scan_root(bus);
pcibios_resource_survey();
}
char * __devinit pcibios_setup(char *str)
{
if ( !strcmp(str, "off") )
pci_probe = 0;
return NULL;
}
unsigned int pcibios_assign_all_busses(void)
{
return 0;
}
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
int err;
u8 pin;
physdev_op_t op;
/* Inform Xen that we are going to use this device. */
op.cmd = PHYSDEVOP_PCI_INITIALISE_DEVICE;
op.u.pci_initialise_device.bus = dev->bus->number;
op.u.pci_initialise_device.dev = PCI_SLOT(dev->devfn);
op.u.pci_initialise_device.func = PCI_FUNC(dev->devfn);
if ( (err = HYPERVISOR_physdev_op(&op)) != 0 )
return err;
/* Now we can bind to the very final IRQ line. */
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &pin);
dev->irq = pin;
/* Turn on device I/O and memory access as necessary. */
if ( (err = pcibios_enable_resources(dev, mask)) < 0 )
return err;
/* Sanity-check that an interrupt-producing device is routed to an IRQ. */
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
if ( pin != 0 )
{
if ( dev->irq != 0 )
printk(KERN_INFO "PCI: Obtained IRQ %d for device %s\n",
dev->irq, dev->slot_name);
else
printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of "
"device %s.\n", 'A' + pin - 1, dev->slot_name);
}
return 0;
}
@@ -1,448 +0,0 @@
/*
* linux/arch/i386/kernel/process.c
*
* Copyright (C) 1995 Linus Torvalds
*
* Pentium III FXSR, SSE support
* Gareth Hughes <gareth@valinux.com>, May 2000
*/
/*
* This file handles the architecture-dependent parts of process handling..
*/
#define __KERNEL_SYSCALLS__
#include <stdarg.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/mc146818rtc.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/ldt.h>
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/desc.h>
#include <asm/mmu_context.h>
#include <asm-xen/xen-public/physdev.h>
#include <linux/irq.h>
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
int hlt_counter;
/*
* Powermanagement idle function, if any..
*/
void (*pm_idle)(void);
/*
* Power off function, if any
*/
void (*pm_power_off)(void);
void disable_hlt(void)
{
hlt_counter++;
}
void enable_hlt(void)
{
hlt_counter--;
}
/*
* The idle thread. There's no useful work to be
* done, so just try to conserve power and have a
* low exit latency (ie sit in a loop waiting for
* somebody to say that they'd like to reschedule)
*/
void cpu_idle (void)
{
extern int set_timeout_timer(void);
/* Endless idle loop with no priority at all. */
init_idle();
current->nice = 20;
current->counter = -100;
for ( ; ; )
{
while ( !current->need_resched )
{
__cli();
if ( current->need_resched )
{
/* The race-free check for events failed. */
__sti();
break;
}
else if ( set_timeout_timer() == 0 )
{
/* NB. Blocking reenable events in a race-free manner. */
HYPERVISOR_block();
}
else
{
/* No race here: yielding will get us the CPU again anyway. */
__sti();
HYPERVISOR_yield();
}
}
schedule();
check_pgt_cache();
}
}
extern void show_trace(unsigned long* esp);
void show_regs(struct pt_regs * regs)
{
printk("\n");
printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs,regs->eip, smp_processor_id());
if (regs->xcs & 2)
printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
printk(" EFLAGS: %08lx %s\n",regs->eflags, print_tainted());
printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
regs->eax,regs->ebx,regs->ecx,regs->edx);
printk("ESI: %08lx EDI: %08lx EBP: %08lx",
regs->esi, regs->edi, regs->ebp);
printk(" DS: %04x ES: %04x\n",
0xffff & regs->xds,0xffff & regs->xes);
show_trace(&regs->esp);
}
/*
* Create a kernel thread
*/
int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval, d0;
__asm__ __volatile__(
"movl %%esp,%%esi\n\t"
"int $0x80\n\t" /* Linux/i386 system call */
"cmpl %%esp,%%esi\n\t" /* child or parent? */
"je 1f\n\t" /* parent - jump */
/* Load the argument into eax, and push it. That way, it does
* not matter whether the called function is compiled with
* -mregparm or not. */
"movl %4,%%eax\n\t"
"pushl %%eax\n\t"
"call *%5\n\t" /* call fn */
"movl %3,%0\n\t" /* exit */
"int $0x80\n"
"1:\t"
:"=&a" (retval), "=&S" (d0)
:"0" (__NR_clone), "i" (__NR_exit),
"r" (arg), "r" (fn),
"b" (flags | CLONE_VM)
: "memory");
return retval;
}
/*
* Free current thread data structures etc..
*/
void exit_thread(void)
{
/* nothing to do ... */
}
void flush_thread(void)
{
struct task_struct *tsk = current;
memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
/*
* Forget coprocessor state..
*/
clear_fpu(tsk);
tsk->used_math = 0;
}
void release_thread(struct task_struct *dead_task)
{
if (dead_task->mm) {
// temporary debugging check
if (dead_task->mm->context.size) {
printk("WARNING: dead process %8s still has LDT? <%p/%08x>\n",
dead_task->comm,
dead_task->mm->context.ldt,
dead_task->mm->context.size);
BUG();
}
}
//release_x86_irqs(dead_task);
}
/*
* Save a segment.
*/
#define savesegment(seg,value) \
asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value)))
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
struct_cpy(childregs, regs);
childregs->eax = 0;
childregs->esp = esp;
p->thread.esp = (unsigned long) childregs;
p->thread.esp0 = (unsigned long) (childregs+1);
p->thread.eip = (unsigned long) ret_from_fork;
savesegment(fs,p->thread.fs);
savesegment(gs,p->thread.gs);
unlazy_fpu(current);
struct_cpy(&p->thread.i387, &current->thread.i387);
p->thread.io_pl = current->thread.io_pl;
return 0;
}
/*
* fill in the user structure for a core dump..
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
int i;
/* changed the size calculations - should hopefully work better. lbt */
dump->magic = CMAGIC;
dump->start_code = 0;
dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
dump->u_dsize -= dump->u_tsize;
dump->u_ssize = 0;
for (i = 0; i < 8; i++)
dump->u_debugreg[i] = current->thread.debugreg[i];
if (dump->start_stack < TASK_SIZE)
dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
dump->regs.ebx = regs->ebx;
dump->regs.ecx = regs->ecx;
dump->regs.edx = regs->edx;
dump->regs.esi = regs->esi;
dump->regs.edi = regs->edi;
dump->regs.ebp = regs->ebp;
dump->regs.eax = regs->eax;
dump->regs.ds = regs->xds;
dump->regs.es = regs->xes;
savesegment(fs,dump->regs.fs);
savesegment(gs,dump->regs.gs);
dump->regs.orig_eax = regs->orig_eax;
dump->regs.eip = regs->eip;
dump->regs.cs = regs->xcs;
dump->regs.eflags = regs->eflags;
dump->regs.esp = regs->esp;
dump->regs.ss = regs->xss;
dump->u_fpvalid = dump_fpu (regs, &dump->i387);
}
/*
* switch_to(x,yn) should switch tasks from x to y.
*
* We fsave/fwait so that an exception goes off at the right time
* (as a call from the fsave or fwait in effect) rather than to
* the wrong process. Lazy FP saving no longer makes any sense
* with modern CPU's, and this simplifies a lot of things (SMP
* and UP become the same).
*
* NOTE! We used to use the x86 hardware context switching. The
* reason for not using it any more becomes apparent when you
* try to recover gracefully from saved state that is no longer
* valid (stale segment register values in particular). With the
* hardware task-switch, there is no way to fix up bad state in
* a reasonable manner.
*
* The fact that Intel documents the hardware task-switching to
* be slow is a fairly red herring - this code is not noticeably
* faster. However, there _is_ some room for improvement here,
* so the performance issues may eventually be a valid point.
* More important, however, is the fact that this allows us much
* more flexibility.
*/
void fastcall __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
struct thread_struct *next = &next_p->thread;
physdev_op_t op;
multicall_entry_t _mcl[8], *mcl = _mcl;
/*
* This is basically 'unlazy_fpu', except that we queue a multicall to
* indicate FPU task switch, rather than synchronously trapping to Xen.
*/
if ( prev_p->flags & PF_USEDFPU )
{
if ( cpu_has_fxsr )
asm volatile( "fxsave %0 ; fnclex"
: "=m" (prev_p->thread.i387.fxsave) );
else
asm volatile( "fnsave %0 ; fwait"
: "=m" (prev_p->thread.i387.fsave) );
prev_p->flags &= ~PF_USEDFPU;
mcl->op = __HYPERVISOR_fpu_taskswitch;
mcl->args[0] = 1;
mcl++;
}
mcl->op = __HYPERVISOR_stack_switch;
mcl->args[0] = __KERNEL_DS;
mcl->args[1] = next->esp0;
mcl++;
if ( prev_p->thread.io_pl != next->io_pl )
{
op.cmd = PHYSDEVOP_SET_IOPL;
op.u.set_iopl.iopl = next->io_pl;
mcl->op = __HYPERVISOR_physdev_op;
mcl->args[0] = (unsigned long)&op;
mcl++;
}
(void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
/*
* Restore %fs and %gs.
*/
loadsegment(fs, next->fs);
loadsegment(gs, next->gs);
/*
* Now maybe reload the debug registers
*/
if ( next->debugreg[7] != 0 )
{
HYPERVISOR_set_debugreg(0, next->debugreg[0]);
HYPERVISOR_set_debugreg(1, next->debugreg[1]);
HYPERVISOR_set_debugreg(2, next->debugreg[2]);
HYPERVISOR_set_debugreg(3, next->debugreg[3]);
/* no 4 and 5 */
HYPERVISOR_set_debugreg(6, next->debugreg[6]);
HYPERVISOR_set_debugreg(7, next->debugreg[7]);
}
}
asmlinkage int sys_fork(struct pt_regs regs)
{
return do_fork(SIGCHLD, regs.esp, &regs, 0);
}
asmlinkage int sys_clone(struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
clone_flags = regs.ebx;
newsp = regs.ecx;
if (!newsp)
newsp = regs.esp;
return do_fork(clone_flags, newsp, &regs, 0);
}
/*
* This is trivial, and on the face of it looks like it
* could equally well be done in user mode.
*
* Not so, for quite unobvious reasons - register pressure.
* In user mode vfork() cannot have a stack frame, and if
* done by calling the "clone()" system call directly, you
* do not have enough call-clobbered registers to hold all
* the information you need.
*/
asmlinkage int sys_vfork(struct pt_regs regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0);
}
/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(struct pt_regs regs)
{
int error;
char * filename;
filename = getname((char *) regs.ebx);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);
if (error == 0)
current->ptrace &= ~PT_DTRACE;
putname(filename);
out:
return error;
}
/*
* These bracket the sleeping functions..
*/
extern void scheduling_functions_start_here(void);
extern void scheduling_functions_end_here(void);
#define first_sched ((unsigned long) scheduling_functions_start_here)
#define last_sched ((unsigned long) scheduling_functions_end_here)
unsigned long get_wchan(struct task_struct *p)
{
unsigned long ebp, esp, eip;
unsigned long stack_page;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
stack_page = (unsigned long)p;
esp = p->thread.esp;
if (!stack_page || esp < stack_page || esp > 8188+stack_page)
return 0;
/* include/asm-i386/system.h:switch_to() pushes ebp last. */
ebp = *(unsigned long *) esp;
do {
if (ebp < stack_page || ebp > 8184+stack_page)
return 0;
eip = *(unsigned long *) (ebp+4);
if (eip < first_sched || eip >= last_sched)
return eip;
ebp = *(unsigned long *) ebp;
} while (count++ < 16);
return 0;
}
#undef last_sched
#undef first_sched
File diff suppressed because it is too large. Load diff
@@ -1,717 +0,0 @@
/*
* linux/arch/i386/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
* 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
*/
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/personality.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/i387.h>
#define DEBUG_SIG 0
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
{
if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
return -EFAULT;
if (from->si_code < 0)
return __copy_to_user(to, from, sizeof(siginfo_t));
else {
int err;
/* If you change siginfo_t structure, please be sure
this code is fixed accordingly.
It should never copy any pad contained in the structure
to avoid security leaks, but must copy the generic
3 ints plus the relevant union member. */
err = __put_user(from->si_signo, &to->si_signo);
err |= __put_user(from->si_errno, &to->si_errno);
err |= __put_user((short)from->si_code, &to->si_code);
/* First 32bits of unions are always present. */
err |= __put_user(from->si_pid, &to->si_pid);
switch (from->si_code >> 16) {
case __SI_FAULT >> 16:
break;
case __SI_CHLD >> 16:
err |= __put_user(from->si_utime, &to->si_utime);
err |= __put_user(from->si_stime, &to->si_stime);
err |= __put_user(from->si_status, &to->si_status);
default:
err |= __put_user(from->si_uid, &to->si_uid);
break;
/* case __SI_RT: This is not generated by the kernel as of now. */
}
return err;
}
}
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
asmlinkage int
sys_sigsuspend(int history0, int history1, old_sigset_t mask)
{
struct pt_regs * regs = (struct pt_regs *) &history0;
sigset_t saveset;
mask &= _BLOCKABLE;
spin_lock_irq(&current->sigmask_lock);
saveset = current->blocked;
siginitset(&current->blocked, mask);
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
regs->eax = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
if (do_signal(regs, &saveset))
return -EINTR;
}
}
asmlinkage int
sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
{
struct pt_regs * regs = (struct pt_regs *) &unewset;
sigset_t saveset, newset;
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
if (copy_from_user(&newset, unewset, sizeof(newset)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(&current->sigmask_lock);
saveset = current->blocked;
current->blocked = newset;
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
regs->eax = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
if (do_signal(regs, &saveset))
return -EINTR;
}
}
asmlinkage int
sys_sigaction(int sig, const struct old_sigaction *act,
struct old_sigaction *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
if (act) {
old_sigset_t mask;
if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
return -EFAULT;
__get_user(new_ka.sa.sa_flags, &act->sa_flags);
__get_user(mask, &act->sa_mask);
siginitset(&new_ka.sa.sa_mask, mask);
}
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
return -EFAULT;
__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
}
asmlinkage int
sys_sigaltstack(const stack_t *uss, stack_t *uoss)
{
struct pt_regs *regs = (struct pt_regs *) &uss;
return do_sigaltstack(uss, uoss, regs->esp);
}
/*
* Do a signal return; undo the signal stack.
*/
struct sigframe
{
char *pretcode;
int sig;
struct sigcontext sc;
struct _fpstate fpstate;
unsigned long extramask[_NSIG_WORDS-1];
char retcode[8];
};
struct rt_sigframe
{
char *pretcode;
int sig;
struct siginfo *pinfo;
void *puc;
struct siginfo info;
struct ucontext uc;
struct _fpstate fpstate;
char retcode[8];
};
static int
restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *peax)
{
unsigned int err = 0;
#define COPY(x) err |= __get_user(regs->x, &sc->x)
#define COPY_SEG(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->x##seg = tmp; }
#define COPY_SEG_STRICT(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
regs->x##seg = tmp|3; }
#define GET_SEG(seg) \
{ unsigned short tmp; \
err |= __get_user(tmp, &sc->seg); \
loadsegment(seg,tmp); }
GET_SEG(gs);
GET_SEG(fs);
COPY_SEG(es);
COPY_SEG(ds);
COPY(edi);
COPY(esi);
COPY(ebp);
COPY(esp);
COPY(ebx);
COPY(edx);
COPY(ecx);
COPY(eip);
COPY_SEG_STRICT(cs);
COPY_SEG_STRICT(ss);
{
unsigned int tmpflags;
err |= __get_user(tmpflags, &sc->eflags);
regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
regs->orig_eax = -1; /* disable syscall checks */
}
{
struct _fpstate * buf;
err |= __get_user(buf, &sc->fpstate);
if (buf) {
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387(buf);
}
}
err |= __get_user(*peax, &sc->eax);
return err;
badframe:
return 1;
}
asmlinkage int sys_sigreturn(unsigned long __unused)
{
struct pt_regs *regs = (struct pt_regs *) &__unused;
struct sigframe *frame = (struct sigframe *)(regs->esp - 8);
sigset_t set;
int eax;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__get_user(set.sig[0], &frame->sc.oldmask)
|| (_NSIG_WORDS > 1
&& __copy_from_user(&set.sig[1], &frame->extramask,
sizeof(frame->extramask))))
goto badframe;
sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sigmask_lock);
current->blocked = set;
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
if (restore_sigcontext(regs, &frame->sc, &eax))
goto badframe;
return eax;
badframe:
force_sig(SIGSEGV, current);
return 0;
}
asmlinkage int sys_rt_sigreturn(unsigned long __unused)
{
struct pt_regs *regs = (struct pt_regs *) &__unused;
struct rt_sigframe *frame = (struct rt_sigframe *)(regs->esp - 4);
sigset_t set;
stack_t st;
int eax;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sigmask_lock);
current->blocked = set;
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
goto badframe;
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
do_sigaltstack(&st, NULL, regs->esp);
return eax;
badframe:
force_sig(SIGSEGV, current);
return 0;
}
/*
* Set up a signal frame.
*/
static int
setup_sigcontext(struct sigcontext *sc, struct _fpstate *fpstate,
struct pt_regs *regs, unsigned long mask)
{
int tmp, err = 0;
tmp = 0;
__asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
err |= __put_user(tmp, (unsigned int *)&sc->gs);
__asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
err |= __put_user(tmp, (unsigned int *)&sc->fs);
err |= __put_user(regs->xes, (unsigned int *)&sc->es);
err |= __put_user(regs->xds, (unsigned int *)&sc->ds);
err |= __put_user(regs->edi, &sc->edi);
err |= __put_user(regs->esi, &sc->esi);
err |= __put_user(regs->ebp, &sc->ebp);
err |= __put_user(regs->esp, &sc->esp);
err |= __put_user(regs->ebx, &sc->ebx);
err |= __put_user(regs->edx, &sc->edx);
err |= __put_user(regs->ecx, &sc->ecx);
err |= __put_user(regs->eax, &sc->eax);
err |= __put_user(current->thread.trap_no, &sc->trapno);
err |= __put_user(current->thread.error_code, &sc->err);
err |= __put_user(regs->eip, &sc->eip);
err |= __put_user(regs->xcs, (unsigned int *)&sc->cs);
err |= __put_user(regs->eflags, &sc->eflags);
err |= __put_user(regs->esp, &sc->esp_at_signal);
err |= __put_user(regs->xss, (unsigned int *)&sc->ss);
tmp = save_i387(fpstate);
if (tmp < 0)
err = 1;
else
err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
/* non-iBCS2 extensions.. */
err |= __put_user(mask, &sc->oldmask);
err |= __put_user(current->thread.cr2, &sc->cr2);
return err;
}
/*
* Determine which stack to use..
*/
static inline void *
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{
unsigned long esp;
/* Default to using normal stack */
esp = regs->esp;
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (sas_ss_flags(esp) == 0)
esp = current->sas_ss_sp + current->sas_ss_size;
}
/* This is the legacy signal stack switching. */
else if ((regs->xss & 0xffff) != __USER_DS &&
!(ka->sa.sa_flags & SA_RESTORER) &&
ka->sa.sa_restorer) {
esp = (unsigned long) ka->sa.sa_restorer;
}
return (void *)((esp - frame_size) & -8ul);
}
static void setup_frame(int sig, struct k_sigaction *ka,
sigset_t *set, struct pt_regs * regs)
{
struct sigframe *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
err |= __put_user((current->exec_domain
&& current->exec_domain->signal_invmap
&& sig < 32
? current->exec_domain->signal_invmap[sig]
: sig),
&frame->sig);
if (err)
goto give_sigsegv;
err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
if (err)
goto give_sigsegv;
if (_NSIG_WORDS > 1) {
err |= __copy_to_user(frame->extramask, &set->sig[1],
sizeof(frame->extramask));
}
if (err)
goto give_sigsegv;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) {
err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
} else {
err |= __put_user(frame->retcode, &frame->pretcode);
/* This is popl %eax ; movl $,%eax ; int $0x80 */
err |= __put_user(0xb858, (short *)(frame->retcode+0));
err |= __put_user(__NR_sigreturn, (int *)(frame->retcode+2));
err |= __put_user(0x80cd, (short *)(frame->retcode+6));
}
if (err)
goto give_sigsegv;
/* Set up registers for signal handler */
regs->esp = (unsigned long) frame;
regs->eip = (unsigned long) ka->sa.sa_handler;
set_fs(USER_DS);
regs->xds = __USER_DS;
regs->xes = __USER_DS;
regs->xss = __USER_DS;
regs->xcs = __USER_CS;
regs->eflags &= ~TF_MASK;
#if DEBUG_SIG
printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
current->comm, current->pid, frame, regs->eip, frame->pretcode);
#endif
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs * regs)
{
struct rt_sigframe *frame;
int err = 0;
frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
err |= __put_user((current->exec_domain
&& current->exec_domain->signal_invmap
&& sig < 32
? current->exec_domain->signal_invmap[sig]
: sig),
&frame->sig);
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
err |= copy_siginfo_to_user(&frame->info, info);
if (err)
goto give_sigsegv;
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(0, &frame->uc.uc_link);
err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->esp),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
goto give_sigsegv;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if (ka->sa.sa_flags & SA_RESTORER) {
err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
} else {
err |= __put_user(frame->retcode, &frame->pretcode);
/* This is movl $,%eax ; int $0x80 */
err |= __put_user(0xb8, (char *)(frame->retcode+0));
err |= __put_user(__NR_rt_sigreturn, (int *)(frame->retcode+1));
err |= __put_user(0x80cd, (short *)(frame->retcode+5));
}
if (err)
goto give_sigsegv;
/* Set up registers for signal handler */
regs->esp = (unsigned long) frame;
regs->eip = (unsigned long) ka->sa.sa_handler;
set_fs(USER_DS);
regs->xds = __USER_DS;
regs->xes = __USER_DS;
regs->xss = __USER_DS;
regs->xcs = __USER_CS;
regs->eflags &= ~TF_MASK;
#if DEBUG_SIG
printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
current->comm, current->pid, frame, regs->eip, frame->pretcode);
#endif
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
}
/*
* OK, we're invoking a handler
*/
static void
handle_signal(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{
/* Are we from a system call? */
if (regs->orig_eax >= 0) {
/* If so, check system call restarting.. */
switch (regs->eax) {
case -ERESTARTNOHAND:
regs->eax = -EINTR;
break;
case -ERESTARTSYS:
if (!(ka->sa.sa_flags & SA_RESTART)) {
regs->eax = -EINTR;
break;
}
/* fallthrough */
case -ERESTARTNOINTR:
regs->eax = regs->orig_eax;
regs->eip -= 2;
}
}
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame(sig, ka, info, oldset, regs);
else
setup_frame(sig, ka, oldset, regs);
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(&current->sigmask_lock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
sigaddset(&current->blocked,sig);
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
}
}
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
{
siginfo_t info;
struct k_sigaction *ka;
/*
* We want the common case to go fast, which
* is why we may in certain cases get here from
* kernel mode. Just return without doing anything
* if so.
*/
if ((regs->xcs & 2) != 2)
return 1;
if (!oldset)
oldset = &current->blocked;
for (;;) {
unsigned long signr;
spin_lock_irq(&current->sigmask_lock);
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
if (!signr)
break;
if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
/* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code))
continue;
current->exit_code = 0;
/* The debugger continued. Ignore SIGSTOP. */
if (signr == SIGSTOP)
continue;
/* Update the siginfo structure. Is this good? */
if (signr != info.si_signo) {
info.si_signo = signr;
info.si_errno = 0;
info.si_code = SI_USER;
info.si_pid = current->p_pptr->pid;
info.si_uid = current->p_pptr->uid;
}
/* If the (new) signal is now blocked, requeue it. */
if (sigismember(&current->blocked, signr)) {
send_sig_info(signr, &info, current);
continue;
}
}
ka = &current->sig->action[signr-1];
if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
/* Check for SIGCHLD: it's special. */
while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
/* nothing */;
continue;
}
if (ka->sa.sa_handler == SIG_DFL) {
int exit_code = signr;
/* Init gets no signals it doesn't want. */
if (current->pid == 1)
continue;
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
continue;
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(current->pgrp))
continue;
/* FALLTHRU */
case SIGSTOP: {
struct signal_struct *sig;
current->state = TASK_STOPPED;
current->exit_code = signr;
sig = current->p_pptr->sig;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
continue;
}
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
default:
sig_exit(signr, exit_code, &info);
/* NOTREACHED */
}
}
/* Reenable any watchpoints before delivering the
* signal to user space. The processor register will
* have been cleared if the watchpoint triggered
* inside the kernel.
*/
if ( current->thread.debugreg[7] != 0 )
HYPERVISOR_set_debugreg(7, current->thread.debugreg[7]);
/* Whee! Actually deliver the signal. */
handle_signal(signr, ka, &info, oldset, regs);
return 1;
}
/* Did we come from a system call? */
if (regs->orig_eax >= 0) {
/* Restart the system call - no handlers present */
if (regs->eax == -ERESTARTNOHAND ||
regs->eax == -ERESTARTSYS ||
regs->eax == -ERESTARTNOINTR) {
regs->eax = regs->orig_eax;
regs->eip -= 2;
}
}
return 0;
}
-741
View File
@@ -1,741 +0,0 @@
/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
****************************************************************************
* (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge
* (C) 2002-2003 - Keir Fraser - University of Cambridge
****************************************************************************
*
* File: arch/xen/kernel/time.c
* Author: Rolf Neugebauer and Keir Fraser
*
* Description: Interface with Xen to get correct notion of time
*/
/*
* linux/arch/i386/kernel/time.c
*
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
*
* This file contains the PC-specific time handling details:
* reading the RTC at bootup, etc..
* 1994-07-02 Alan Modra
* fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
* 1995-03-26 Markus Kuhn
* fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
* precision CMOS clock update
* 1996-05-03 Ingo Molnar
* fixed time warps in do_[slow|fast]_gettimeoffset()
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
* "A Kernel Model for Precision Timekeeping" by Dave Mills
* 1998-09-05 (Various)
* More robust do_fast_gettimeoffset() algorithm implemented
* (works with APM, Cyrix 6x86MX and Centaur C6),
* monotonic gettimeofday() with fast_get_timeoffset(),
* drift-proof precision TSC calibration on boot
* (C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
* Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
* ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
* 1998-12-16 Andrea Arcangeli
* Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
* because was not accounting lost_ticks.
* 1998-12-24 Copyright (C) 1998 Andrea Arcangeli
* Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
* serialize accesses to xtime/lost_ticks).
*/
#include <asm/smp.h>
#include <asm/irq.h>
#include <asm/msr.h>
#include <asm/delay.h>
#include <asm/mpspec.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/div64.h>
#include <asm/hypervisor.h>
#include <asm-xen/xen-public/dom0_ops.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/sysctl.h>
#include <linux/sysrq.h>
spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
extern rwlock_t xtime_lock;
extern unsigned long wall_jiffies;
unsigned long cpu_khz; /* get this from Xen, used elsewhere */
static unsigned int rdtsc_bitshift;
static u32 st_scale_f; /* convert ticks -> usecs */
static u32 st_scale_i; /* convert ticks -> usecs */
/* These are peridically updated in shared_info, and then copied here. */
static u32 shadow_tsc_stamp;
static u64 shadow_system_time;
static u32 shadow_time_version;
static struct timeval shadow_tv;
/*
* We use this to ensure that gettimeofday() is monotonically increasing. We
* only break this guarantee if the wall clock jumps backwards "a long way".
*/
static struct timeval last_seen_tv = {0,0};
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
/* Periodically propagate synchronised time base to the RTC and to Xen. */
static long last_update_to_rtc, last_update_to_xen;
#endif
/* Periodically take synchronised time base from Xen, if we need it. */
static long last_update_from_xen; /* UTC seconds when last read Xen clock. */
/* Keep track of last time we did processing/updating of jiffies and xtime. */
static u64 processed_system_time; /* System time (ns) at last processing. */
#define NS_PER_TICK (1000000000ULL/HZ)
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC (1000000000L)
#endif
#define HANDLE_USEC_UNDERFLOW(_tv) \
do { \
while ( (_tv).tv_usec < 0 ) \
{ \
(_tv).tv_usec += 1000000; \
(_tv).tv_sec--; \
} \
} while ( 0 )
#define HANDLE_USEC_OVERFLOW(_tv) \
do { \
while ( (_tv).tv_usec >= 1000000 ) \
{ \
(_tv).tv_usec -= 1000000; \
(_tv).tv_sec++; \
} \
} while ( 0 )
static inline void __normalize_time(time_t *sec, s64 *nsec)
{
while (*nsec >= NSEC_PER_SEC) {
(*nsec) -= NSEC_PER_SEC;
(*sec)++;
}
while (*nsec < 0) {
(*nsec) += NSEC_PER_SEC;
(*sec)--;
}
}
/* Dynamically-mapped IRQs. */
static int time_irq, debug_irq;
/* Does this guest OS track Xen time, or set its wall clock independently? */
static int independent_wallclock = 0;
static int __init __independent_wallclock(char *str)
{
independent_wallclock = 1;
return 1;
}
__setup("independent_wallclock", __independent_wallclock);
#define INDEPENDENT_WALLCLOCK() \
(independent_wallclock || (xen_start_info.flags & SIF_INITDOMAIN))
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
/*
* In order to set the CMOS clock precisely, set_rtc_mmss has to be
* called 500 ms after the second nowtime has started, because when
* nowtime is written into the registers of the CMOS clock, it will
* jump to the next second precisely 500 ms later. Check the Motorola
* MC146818A or Dallas DS12887 data sheet for details.
*
* BUG: This routine does not handle hour overflow properly; it just
* sets the minutes. Usually you'll only notice that after reboot!
*/
static int set_rtc_mmss(unsigned long nowtime)
{
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
/* gets recalled with irq locally disabled */
spin_lock(&rtc_lock);
save_control = CMOS_READ(RTC_CONTROL);
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
cmos_minutes = CMOS_READ(RTC_MINUTES);
if ( !(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD )
BCD_TO_BIN(cmos_minutes);
/*
* since we're only adjusting minutes and seconds, don't interfere with
* hour overflow. This avoids messing with unknown time zones but requires
* your RTC not to be off by more than 15 minutes
*/
real_seconds = nowtime % 60;
real_minutes = nowtime / 60;
if ( ((abs(real_minutes - cmos_minutes) + 15)/30) & 1 )
real_minutes += 30; /* correct for half hour time zone */
real_minutes %= 60;
if ( abs(real_minutes - cmos_minutes) < 30 )
{
if ( !(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD )
{
BIN_TO_BCD(real_seconds);
BIN_TO_BCD(real_minutes);
}
CMOS_WRITE(real_seconds,RTC_SECONDS);
CMOS_WRITE(real_minutes,RTC_MINUTES);
}
else
{
printk(KERN_WARNING
"set_rtc_mmss: can't update from %d to %d\n",
cmos_minutes, real_minutes);
retval = -1;
}
/* The following flags have to be released exactly in this order,
* otherwise the DS12887 (popular MC146818A clone with integrated
* battery and quartz) will not reset the oscillator and will not
* update precisely 500 ms later. You won't find this mentioned in
* the Dallas Semiconductor data sheets, but who believes data
* sheets anyway ... -- Markus Kuhn
*/
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
spin_unlock(&rtc_lock);
return retval;
}
#endif
/*
* Reads a consistent set of time-base values from Xen, into a shadow data
* area. Must be called with the xtime_lock held for writing.
*/
static void __get_time_values_from_xen(void)
{
shared_info_t *s = HYPERVISOR_shared_info;
struct vcpu_time_info *src;
struct shadow_time_info *dst;
src = &s->vcpu_time[smp_processor_id()];
dst = &per_cpu(shadow_time, smp_processor_id());
do {
dst->version = src->time_version2;
rmb();
dst->tsc_timestamp = src->tsc_timestamp;
dst->system_timestamp = src->system_time;
dst->tsc_to_nsec_mul = src->tsc_to_system_mul;
dst->tsc_shift = src->tsc_shift;
rmb();
}
while (dst->version != src->time_version1);
dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000;
if ((shadow_tv.tv_sec != s->wc_sec) ||
(shadow_tv.tv_usec != s->wc_usec))
update_wallclock();
}
/*
* Returns the system time elapsed, in ns, since the current shadow_timestamp
* was calculated. Must be called with the xtime_lock held for reading.
*/
static inline unsigned long __get_time_delta_usecs(void)
{
s32 delta_tsc;
u32 low;
u64 delta, tsc;
rdtscll(tsc);
low = (u32)(tsc >> rdtsc_bitshift);
delta_tsc = (s32)(low - shadow_tsc_stamp);
if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
delta = ((u64)delta_tsc * st_scale_f);
delta >>= 32;
delta += ((u64)delta_tsc * st_scale_i);
return (unsigned long)delta;
}
static inline int time_values_up_to_date()
{
struct vcpu_time_info *src;
struct shadow_time_info *dst;
src = &HYPERVISOR_shared_info->vcpu_time[smp_processor_id()];
dst = &per_cpu(shadow_time, smp_processor_id());
return (dst->version == src->time_version2);
}
/*
* Returns the current time-of-day in UTC timeval format.
*/
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags, lost;
struct timeval _tv;
s64 nsec;
again:
read_lock_irqsave(&xtime_lock, flags);
_tv.tv_usec = __get_time_delta_usecs();
if ( (lost = (jiffies - wall_jiffies)) != 0 )
_tv.tv_usec += lost * (1000000 / HZ);
_tv.tv_sec = xtime.tv_sec;
_tv.tv_usec += xtime.tv_usec;
nsec = shadow_system_time - processed_system_time;
__normalize_time(&_tv.tv_sec, &nsec);
_tv.tv_usec += (long)nsec / 1000L;
if ( unlikely(!time_values_up_to_date()) )
{
/*
* We may have blocked for a long time, rendering our calculations
* invalid (e.g. the time delta may have overflowed). Detect that
* and recalculate with fresh values.
*/
read_unlock_irqrestore(&xtime_lock, flags);
write_lock_irqsave(&xtime_lock, flags);
__get_time_values_from_xen();
write_unlock_irqrestore(&xtime_lock, flags);
goto again;
}
HANDLE_USEC_OVERFLOW(_tv);
/* Ensure that time-of-day is monotonically increasing. */
if ( (_tv.tv_sec < last_seen_tv.tv_sec) ||
((_tv.tv_sec == last_seen_tv.tv_sec) &&
(_tv.tv_usec < last_seen_tv.tv_usec)) )
_tv = last_seen_tv;
last_seen_tv = _tv;
read_unlock_irqrestore(&xtime_lock, flags);
*tv = _tv;
}
/*
* Sets the current time-of-day based on passed-in UTC timeval parameter.
*/
void do_settimeofday(struct timeval *tv)
{
struct timeval newtv;
s64 nsec;
suseconds_t usec;
if ( !INDEPENDENT_WALLCLOCK() )
return;
write_lock_irq(&xtime_lock);
/*
* Ensure we don't get blocked for a long time so that our time delta
* overflows. If that were to happen then our shadow time values would
* be stale, so we can retry with fresh ones.
*/
again:
usec = tv->tv_usec - __get_time_delta_usecs();
nsec = shadow_system_time - processed_system_time;
__normalize_time(&tv->tv_sec, &nsec);
usec -= (long)nsec / 1000L;
if ( unlikely(!TIME_VALUES_UP_TO_DATE) )
{
__get_time_values_from_xen();
goto again;
}
tv->tv_usec = usec;
HANDLE_USEC_UNDERFLOW(*tv);
newtv = *tv;
tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
HANDLE_USEC_UNDERFLOW(*tv);
xtime = *tv;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
/* Reset all our running time counts. They make no sense now. */
last_seen_tv.tv_sec = 0;
last_update_from_xen = 0;
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
if ( xen_start_info.flags & SIF_INITDOMAIN )
{
dom0_op_t op;
last_update_to_rtc = last_update_to_xen = 0;
op.cmd = DOM0_SETTIME;
op.u.settime.secs = newtv.tv_sec;
op.u.settime.usecs = newtv.tv_usec;
op.u.settime.system_time = shadow_system_time;
write_unlock_irq(&xtime_lock);
HYPERVISOR_dom0_op(&op);
}
else
#endif
{
write_unlock_irq(&xtime_lock);
}
}
asmlinkage long sys_stime(int *tptr)
{
int value;
struct timeval tv;
if ( !capable(CAP_SYS_TIME) )
return -EPERM;
if ( get_user(value, tptr) )
return -EFAULT;
tv.tv_sec = value;
tv.tv_usec = 0;
do_settimeofday(&tv);
return 0;
}
/* Convert jiffies to system time. Call with xtime_lock held for reading. */
static inline u64 __jiffies_to_st(unsigned long j)
{
return processed_system_time + ((j - jiffies) * NS_PER_TICK);
}
static inline void do_timer_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
s64 delta;
unsigned long ticks = 0;
long sec_diff;
do {
__get_time_values_from_xen();
delta = (s64)(shadow_system_time +
((s64)__get_time_delta_usecs() * 1000LL) -
processed_system_time);
}
while ( !TIME_VALUES_UP_TO_DATE );
if ( unlikely(delta < 0) )
{
printk("Timer ISR: Time went backwards: %lld\n", delta);
return;
}
/* Process elapsed jiffies since last call. */
while ( delta >= NS_PER_TICK )
{
ticks++;
delta -= NS_PER_TICK;
processed_system_time += NS_PER_TICK;
}
if ( ticks != 0 )
{
do_timer_ticks(ticks);
if ( user_mode(regs) )
update_process_times_us(ticks, 0);
else
update_process_times_us(0, ticks);
}
/*
* Take synchronised time from Xen once a minute if we're not
* synchronised ourselves, and we haven't chosen to keep an independent
* time base.
*/
if ( !INDEPENDENT_WALLCLOCK() &&
((time_status & STA_UNSYNC) != 0) &&
(xtime.tv_sec > (last_update_from_xen + 60)) )
{
/* Adjust shadow timeval for jiffies that haven't updated xtime yet. */
shadow_tv.tv_usec -= (jiffies - wall_jiffies) * (1000000/HZ);
HANDLE_USEC_UNDERFLOW(shadow_tv);
/*
* Reset our running time counts if they are invalidated by a warp
* backwards of more than 500ms.
*/
sec_diff = xtime.tv_sec - shadow_tv.tv_sec;
if ( unlikely(abs(sec_diff) > 1) ||
unlikely(((sec_diff * 1000000) +
xtime.tv_usec - shadow_tv.tv_usec) > 500000) )
{
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
last_update_to_rtc = last_update_to_xen = 0;
#endif
last_seen_tv.tv_sec = 0;
}
/* Update our unsynchronised xtime appropriately. */
xtime = shadow_tv;
last_update_from_xen = xtime.tv_sec;
}
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
if ( (xen_start_info.flags & SIF_INITDOMAIN) &&
((time_status & STA_UNSYNC) == 0) )
{
/* Send synchronised time to Xen approximately every minute. */
if ( xtime.tv_sec > (last_update_to_xen + 60) )
{
dom0_op_t op;
struct timeval tv = xtime;
tv.tv_usec += (jiffies - wall_jiffies) * (1000000/HZ);
HANDLE_USEC_OVERFLOW(tv);
op.cmd = DOM0_SETTIME;
op.u.settime.secs = tv.tv_sec;
op.u.settime.usecs = tv.tv_usec;
op.u.settime.system_time = shadow_system_time;
HYPERVISOR_dom0_op(&op);
last_update_to_xen = xtime.tv_sec;
}
/*
* If we have an externally synchronized Linux clock, then update CMOS
* clock accordingly every ~11 minutes. Set_rtc_mmss() has to be called
* as close as possible to 500 ms before the new second starts.
*/
if ( (xtime.tv_sec > (last_update_to_rtc + 660)) &&
(xtime.tv_usec >= (500000 - ((unsigned) tick) / 2)) &&
(xtime.tv_usec <= (500000 + ((unsigned) tick) / 2)) )
{
if ( set_rtc_mmss(xtime.tv_sec) == 0 )
last_update_to_rtc = xtime.tv_sec;
else
last_update_to_rtc = xtime.tv_sec - 600;
}
}
#endif
}
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
write_lock(&xtime_lock);
do_timer_interrupt(irq, NULL, regs);
write_unlock(&xtime_lock);
}
static struct irqaction irq_timer = {
timer_interrupt,
SA_INTERRUPT,
0,
"timer",
NULL,
NULL
};
/*
* This function works out when the the next timer function has to be
* executed (by looking at the timer list) and sets the Xen one-shot
* domain timer to the appropriate value. This is typically called in
* cpu_idle() before the domain blocks.
*
* The function returns a non-0 value on error conditions.
*
* It must be called with interrupts disabled.
*/
extern spinlock_t timerlist_lock;
int set_timeout_timer(void)
{
struct timer_list *timer;
u64 alarm = 0;
int ret = 0;
spin_lock(&timerlist_lock);
/*
* This is safe against long blocking (since calculations are not based on
* TSC deltas). It is also safe against warped system time since
* suspend-resume is cooperative and we would first get locked out. It is
* safe against normal updates of jiffies since interrupts are off.
*/
if ( (timer = next_timer_event()) != NULL )
alarm = __jiffies_to_st(timer->expires);
/* Tasks on the timer task queue expect to be executed on the next tick. */
if ( TQ_ACTIVE(tq_timer) )
alarm = __jiffies_to_st(jiffies + 1);
/* Failure is pretty bad, but we'd best soldier on. */
if ( HYPERVISOR_set_timer_op(alarm) != 0 )
ret = -1;
spin_unlock(&timerlist_lock);
return ret;
}
/* Time debugging. */
static void dbg_time_int(int irq, void *dev_id, struct pt_regs *ptregs)
{
unsigned long flags, j;
u64 s_now, j_st;
struct timeval s_tv, tv;
struct timer_list *timer;
u64 t_st;
read_lock_irqsave(&xtime_lock, flags);
s_tv.tv_sec = shadow_tv.tv_sec;
s_tv.tv_usec = shadow_tv.tv_usec;
s_now = shadow_system_time;
read_unlock_irqrestore(&xtime_lock, flags);
do_gettimeofday(&tv);
j = jiffies;
j_st = __jiffies_to_st(j);
timer = next_timer_event();
t_st = __jiffies_to_st(timer->expires);
printk(KERN_ALERT "time: shadow_st=0x%X:%08X\n",
(u32)(s_now>>32), (u32)s_now);
printk(KERN_ALERT "time: wct=%lds %ldus shadow_wct=%lds %ldus\n",
tv.tv_sec, tv.tv_usec, s_tv.tv_sec, s_tv.tv_usec);
printk(KERN_ALERT "time: jiffies=%lu(0x%X:%08X) timeout=%lu(0x%X:%08X)\n",
jiffies,(u32)(j_st>>32), (u32)j_st,
timer->expires,(u32)(t_st>>32), (u32)t_st);
printk(KERN_ALERT "time: processed_system_time=0x%X:%08X\n",
(u32)(processed_system_time>>32), (u32)processed_system_time);
#ifdef CONFIG_MAGIC_SYSRQ
handle_sysrq('t',NULL,NULL,NULL);
#endif
}
static struct irqaction dbg_time = {
dbg_time_int,
SA_SHIRQ,
0,
"timer_dbg",
&dbg_time_int,
NULL
};
void __init time_init(void)
{
unsigned long long alarm;
u64 __cpu_khz, __cpu_ghz, cpu_freq, scale, scale2;
unsigned int cpu_ghz;
__cpu_khz = __cpu_ghz = cpu_freq = HYPERVISOR_shared_info->cpu_freq;
do_div(__cpu_khz, 1000UL);
cpu_khz = (u32)__cpu_khz;
do_div(__cpu_ghz, 1000000000UL);
cpu_ghz = (unsigned int)__cpu_ghz;
printk("Xen reported: %lu.%03lu MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000);
xtime.tv_sec = HYPERVISOR_shared_info->wc_sec;
xtime.tv_usec = HYPERVISOR_shared_info->wc_usec;
processed_system_time = shadow_system_time;
for ( rdtsc_bitshift = 0; cpu_ghz != 0; rdtsc_bitshift++, cpu_ghz >>= 1 )
continue;
scale = 1000000LL << (32 + rdtsc_bitshift);
do_div(scale, (u32)cpu_freq);
if ( (cpu_freq >> 32) != 0 )
{
scale2 = 1000000LL << rdtsc_bitshift;
do_div(scale2, (u32)(cpu_freq>>32));
scale += scale2;
}
st_scale_f = scale & 0xffffffff;
st_scale_i = scale >> 32;
__get_time_values_from_xen();
processed_system_time = shadow_system_time;
time_irq = bind_virq_to_irq(VIRQ_TIMER);
debug_irq = bind_virq_to_irq(VIRQ_DEBUG);
(void)setup_irq(time_irq, &irq_timer);
(void)setup_irq(debug_irq, &dbg_time);
rdtscll(alarm);
}
void time_suspend(void)
{
}
void time_resume(void)
{
unsigned long flags;
write_lock_irqsave(&xtime_lock, flags);
/* Get timebases for new environment. */
__get_time_values_from_xen();
/* Reset our own concept of passage of system time. */
processed_system_time = shadow_system_time;
/* Accept a warp in UTC (wall-clock) time. */
last_seen_tv.tv_sec = 0;
/* Make sure we resync UTC time with Xen on next timer interrupt. */
last_update_from_xen = 0;
write_unlock_irqrestore(&xtime_lock, flags);
}
/*
* /proc/sys/xen: This really belongs in another file. It can stay here for
* now however.
*/
static ctl_table xen_subtable[] = {
{1, "independent_wallclock", &independent_wallclock,
sizeof(independent_wallclock), 0644, NULL, proc_dointvec},
{0}
};
static ctl_table xen_table[] = {
{123, "xen", NULL, 0, 0555, xen_subtable},
{0}
};
static int __init xen_sysctl_init(void)
{
(void)register_sysctl_table(xen_table, 0);
return 0;
}
__initcall(xen_sysctl_init);
@@ -1,619 +0,0 @@
/*
* linux/arch/i386/traps.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Pentium III FXSR, SSE support
* Gareth Hughes <gareth@valinux.com>, May 2000
*/
/*
* 'Traps.c' handles hardware traps and faults after we have saved some
* state in 'asm.s'.
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/atomic.h>
#include <asm/debugreg.h>
#include <asm/desc.h>
#include <asm/i387.h>
#include <asm/smp.h>
#include <asm/pgalloc.h>
#include <asm/hypervisor.h>
#include <linux/irq.h>
#include <linux/module.h>
asmlinkage int system_call(void);
asmlinkage void lcall7(void);
asmlinkage void lcall27(void);
asmlinkage void divide_error(void);
asmlinkage void debug(void);
asmlinkage void int3(void);
asmlinkage void overflow(void);
asmlinkage void bounds(void);
asmlinkage void invalid_op(void);
asmlinkage void device_not_available(void);
asmlinkage void double_fault(void);
asmlinkage void coprocessor_segment_overrun(void);
asmlinkage void invalid_TSS(void);
asmlinkage void segment_not_present(void);
asmlinkage void stack_segment(void);
asmlinkage void general_protection(void);
asmlinkage void page_fault(void);
asmlinkage void coprocessor_error(void);
asmlinkage void simd_coprocessor_error(void);
asmlinkage void alignment_check(void);
asmlinkage void fixup_4gb_segment(void);
asmlinkage void machine_check(void);
int kstack_depth_to_print = 24;
/*
* If the address is either in the .text section of the
* kernel, or in the vmalloc'ed module regions, it *may*
* be the address of a calling routine
*/
#ifdef CONFIG_MODULES
extern struct module *module_list;
extern struct module kernel_module;
static inline int kernel_text_address(unsigned long addr)
{
int retval = 0;
struct module *mod;
if (addr >= (unsigned long) &_stext &&
addr <= (unsigned long) &_etext)
return 1;
for (mod = module_list; mod != &kernel_module; mod = mod->next) {
/* mod_bound tests for addr being inside the vmalloc'ed
* module area. Of course it'd be better to test only
* for the .text subset... */
if (mod_bound(addr, 0, mod)) {
retval = 1;
break;
}
}
return retval;
}
#else
static inline int kernel_text_address(unsigned long addr)
{
return (addr >= (unsigned long) &_stext &&
addr <= (unsigned long) &_etext);
}
#endif
void show_trace(unsigned long * stack)
{
int i;
unsigned long addr;
if (!stack)
stack = (unsigned long*)&stack;
printk("Call Trace: ");
i = 1;
while (((long) stack & (THREAD_SIZE-1)) != 0) {
addr = *stack++;
if (kernel_text_address(addr)) {
if (i && ((i % 6) == 0))
printk("\n ");
printk("[<%08lx>] ", addr);
i++;
}
}
printk("\n");
}
void show_trace_task(struct task_struct *tsk)
{
unsigned long esp = tsk->thread.esp;
/* User space on another CPU? */
if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
return;
show_trace((unsigned long *)esp);
}
void show_stack(unsigned long * esp)
{
unsigned long *stack;
int i;
// debugging aid: "show_stack(NULL);" prints the
// back trace for this cpu.
if(esp==NULL)
esp=(unsigned long*)&esp;
stack = esp;
for(i=0; i < kstack_depth_to_print; i++) {
if (((long) stack & (THREAD_SIZE-1)) == 0)
break;
if (i && ((i % 8) == 0))
printk("\n ");
printk("%08lx ", *stack++);
}
printk("\n");
show_trace(esp);
}
void show_registers(struct pt_regs *regs)
{
int in_kernel = 1;
unsigned long esp;
unsigned short ss;
esp = (unsigned long) (&regs->esp);
ss = __KERNEL_DS;
if (regs->xcs & 2) {
in_kernel = 0;
esp = regs->esp;
ss = regs->xss & 0xffff;
}
printk(KERN_ALERT "CPU: %d\n", smp_processor_id() );
printk(KERN_ALERT "EIP: %04x:[<%08lx>] %s\n",
0xffff & regs->xcs, regs->eip, print_tainted());
printk(KERN_ALERT "EFLAGS: %08lx\n",regs->eflags);
printk(KERN_ALERT "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
regs->eax, regs->ebx, regs->ecx, regs->edx);
printk(KERN_ALERT "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
regs->esi, regs->edi, regs->ebp, esp);
printk(KERN_ALERT "ds: %04x es: %04x ss: %04x\n",
regs->xds & 0xffff, regs->xes & 0xffff, ss);
printk(KERN_ALERT "Process %s (pid: %d, stackpage=%08lx)",
current->comm, current->pid, 4096+(unsigned long)current);
/*
* When in-kernel, we also print out the stack and code at the
* time of the fault..
*/
if (in_kernel) {
printk(KERN_ALERT "\nStack: ");
show_stack((unsigned long*)esp);
#if 0
{
int i;
printk(KERN_ALERT "\nCode: ");
if(regs->eip < PAGE_OFFSET)
goto bad;
for(i=0;i<20;i++)
{
unsigned char c;
if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
bad:
printk(KERN_ALERT " Bad EIP value.");
break;
}
printk("%02x ", c);
}
}
#endif
}
printk(KERN_ALERT "\n");
}
spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
void die(const char * str, struct pt_regs * regs, long err)
{
console_verbose();
spin_lock_irq(&die_lock);
bust_spinlocks(1);
printk("%s: %04lx\n", str, err & 0xffff);
show_registers(regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
}
static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
{
if (!(2 & regs->xcs))
die(str, regs, err);
}
static void inline do_trap(int trapnr, int signr, char *str,
struct pt_regs * regs, long error_code,
siginfo_t *info)
{
if (!(regs->xcs & 2))
goto kernel_trap;
/*trap_signal:*/ {
struct task_struct *tsk = current;
tsk->thread.error_code = error_code;
tsk->thread.trap_no = trapnr;
if (info)
force_sig_info(signr, info, tsk);
else
force_sig(signr, tsk);
return;
}
kernel_trap: {
unsigned long fixup = search_exception_table(regs->eip);
if (fixup)
regs->eip = fixup;
else
die(str, regs, error_code);
return;
}
}
#define DO_ERROR(trapnr, signr, str, name) \
asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
{ \
do_trap(trapnr, signr, str, regs, error_code, NULL); \
}
#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
{ \
siginfo_t info; \
info.si_signo = signr; \
info.si_errno = 0; \
info.si_code = sicode; \
info.si_addr = (void *)siaddr; \
do_trap(trapnr, signr, str, regs, error_code, &info); \
}
DO_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip)
DO_ERROR( 3, SIGTRAP, "int3", int3)
DO_ERROR( 4, SIGSEGV, "overflow", overflow)
DO_ERROR( 5, SIGSEGV, "bounds", bounds)
DO_ERROR_INFO( 6, SIGILL, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
DO_ERROR( 8, SIGSEGV, "double fault", double_fault)
DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
DO_ERROR(18, SIGBUS, "machine check", machine_check)
asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
{
/*
* If we trapped on an LDT access then ensure that the default_ldt is
* loaded, if nothing else. We load default_ldt lazily because LDT
* switching costs time and many applications don't need it.
*/
if ( unlikely((error_code & 6) == 4) )
{
unsigned long ldt;
__asm__ __volatile__ ( "sldt %0" : "=r" (ldt) );
if ( ldt == 0 )
{
xen_set_ldt((unsigned long)&default_ldt[0], 5);
return;
}
}
if (!(regs->xcs & 2))
goto gp_in_kernel;
current->thread.error_code = error_code;
current->thread.trap_no = 13;
force_sig(SIGSEGV, current);
return;
gp_in_kernel:
{
unsigned long fixup;
fixup = search_exception_table(regs->eip);
if (fixup) {
regs->eip = fixup;
return;
}
die("general protection fault", regs, error_code);
}
}
asmlinkage void do_debug(struct pt_regs * regs, long error_code)
{
unsigned int condition;
struct task_struct *tsk = current;
siginfo_t info;
condition = HYPERVISOR_get_debugreg(6);
/* Mask out spurious debug traps due to lazy DR7 setting */
if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
if (!tsk->thread.debugreg[7])
goto clear_dr7;
}
/* Save debug status register where ptrace can see it */
tsk->thread.debugreg[6] = condition;
/* Mask out spurious TF errors due to lazy TF clearing */
if (condition & DR_STEP) {
/*
* The TF error should be masked out only if the current
* process is not traced and if the TRAP flag has been set
* previously by a tracing process (condition detected by
* the PT_DTRACE flag); remember that the i386 TRAP flag
* can be modified by the process itself in user mode,
* allowing programs to debug themselves without the ptrace()
* interface.
*/
if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
goto clear_TF;
}
/* Ok, finally something we can handle */
tsk->thread.trap_no = 1;
tsk->thread.error_code = error_code;
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
/* If this is a kernel mode trap, save the user PC on entry to
* the kernel, that's what the debugger can make sense of.
*/
info.si_addr = ((regs->xcs & 2) == 0) ? (void *)tsk->thread.eip :
(void *)regs->eip;
force_sig_info(SIGTRAP, &info, tsk);
/* Disable additional traps. They'll be re-enabled when
* the signal is delivered.
*/
clear_dr7:
HYPERVISOR_set_debugreg(7, 0);
return;
clear_TF:
regs->eflags &= ~TF_MASK;
return;
}
/*
* Note that we play around with the 'TS' bit in an attempt to get
* the correct behaviour even in the presence of the asynchronous
* IRQ13 behaviour
*/
void math_error(void *eip)
{
struct task_struct * task;
siginfo_t info;
unsigned short cwd, swd;
/*
* Save the info for the exception handler and clear the error.
*/
task = current;
save_init_fpu(task);
task->thread.trap_no = 16;
task->thread.error_code = 0;
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_code = __SI_FAULT;
info.si_addr = eip;
/*
* (~cwd & swd) will mask out exceptions that are not set to unmasked
* status. 0x3f is the exception bits in these regs, 0x200 is the
* C1 reg you need in case of a stack fault, 0x040 is the stack
* fault bit. We should only be taking one exception at a time,
* so if this combination doesn't produce any single exception,
* then we have a bad program that isn't syncronizing its FPU usage
* and it will suffer the consequences since we won't be able to
* fully reproduce the context of the exception
*/
cwd = get_fpu_cwd(task);
swd = get_fpu_swd(task);
switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
case 0x000:
default:
break;
case 0x001: /* Invalid Op */
case 0x041: /* Stack Fault */
case 0x241: /* Stack Fault | Direction */
info.si_code = FPE_FLTINV;
break;
case 0x002: /* Denormalize */
case 0x010: /* Underflow */
info.si_code = FPE_FLTUND;
break;
case 0x004: /* Zero Divide */
info.si_code = FPE_FLTDIV;
break;
case 0x008: /* Overflow */
info.si_code = FPE_FLTOVF;
break;
case 0x020: /* Precision */
info.si_code = FPE_FLTRES;
break;
}
force_sig_info(SIGFPE, &info, task);
}
asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
{
ignore_irq13 = 1;
math_error((void *)regs->eip);
}
void simd_math_error(void *eip)
{
struct task_struct * task;
siginfo_t info;
unsigned short mxcsr;
/*
* Save the info for the exception handler and clear the error.
*/
task = current;
save_init_fpu(task);
task->thread.trap_no = 19;
task->thread.error_code = 0;
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_code = __SI_FAULT;
info.si_addr = eip;
/*
* The SIMD FPU exceptions are handled a little differently, as there
* is only a single status/control register. Thus, to determine which
* unmasked exception was caught we must mask the exception mask bits
* at 0x1f80, and then use these to mask the exception bits at 0x3f.
*/
mxcsr = get_fpu_mxcsr(task);
switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
case 0x000:
default:
break;
case 0x001: /* Invalid Op */
info.si_code = FPE_FLTINV;
break;
case 0x002: /* Denormalize */
case 0x010: /* Underflow */
info.si_code = FPE_FLTUND;
break;
case 0x004: /* Zero Divide */
info.si_code = FPE_FLTDIV;
break;
case 0x008: /* Overflow */
info.si_code = FPE_FLTOVF;
break;
case 0x020: /* Precision */
info.si_code = FPE_FLTRES;
break;
}
force_sig_info(SIGFPE, &info, task);
}
asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs,
long error_code)
{
if (cpu_has_xmm) {
/* Handle SIMD FPU exceptions on PIII+ processors. */
ignore_irq13 = 1;
simd_math_error((void *)regs->eip);
} else {
die_if_kernel("cache flush denied", regs, error_code);
current->thread.trap_no = 19;
current->thread.error_code = error_code;
force_sig(SIGSEGV, current);
}
}
/*
* 'math_state_restore()' saves the current math information in the
* old math state array, and gets the new ones from the current task
*
* Careful.. There are problems with IBM-designed IRQ13 behaviour.
* Don't touch unless you *really* know how it works.
*/
asmlinkage void math_state_restore(struct pt_regs regs)
{
/*
* A trap in kernel mode can be ignored. It'll be the fast XOR or
* copying libraries, which will correctly save/restore state and
* reset the TS bit in CR0.
*/
if ( (regs.xcs & 2) == 0 )
return;
if (current->used_math) {
restore_fpu(current);
} else {
init_fpu();
}
current->flags |= PF_USEDFPU; /* So we fnsave on switch_to() */
}
#define _set_gate(gate_addr,type,dpl,addr) \
do { \
int __d0, __d1; \
__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
"movw %4,%%dx\n\t" \
"movl %%eax,%0\n\t" \
"movl %%edx,%1" \
:"=m" (*((long *) (gate_addr))), \
"=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
"3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
} while (0)
static void __init set_call_gate(void *a, void *addr)
{
_set_gate(a,12,3,addr);
}
/* NB. All these are "trap gates" (i.e. events_mask isn't cleared). */
static trap_info_t trap_table[] = {
{ 0, 0, __KERNEL_CS, (unsigned long)divide_error },
{ 1, 0, __KERNEL_CS, (unsigned long)debug },
{ 3, 3, __KERNEL_CS, (unsigned long)int3 },
{ 4, 3, __KERNEL_CS, (unsigned long)overflow },
{ 5, 3, __KERNEL_CS, (unsigned long)bounds },
{ 6, 0, __KERNEL_CS, (unsigned long)invalid_op },
{ 7, 0, __KERNEL_CS, (unsigned long)device_not_available },
{ 8, 0, __KERNEL_CS, (unsigned long)double_fault },
{ 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
{ 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
{ 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
{ 12, 0, __KERNEL_CS, (unsigned long)stack_segment },
{ 13, 0, __KERNEL_CS, (unsigned long)general_protection },
{ 14, 0, __KERNEL_CS, (unsigned long)page_fault },
{ 15, 0, __KERNEL_CS, (unsigned long)fixup_4gb_segment },
{ 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
{ 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
{ 18, 0, __KERNEL_CS, (unsigned long)machine_check },
{ 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
{ SYSCALL_VECTOR,
3, __KERNEL_CS, (unsigned long)system_call },
{ 0, 0, 0, 0 }
};
void __init trap_init(void)
{
HYPERVISOR_set_trap_table(trap_table);
/*
* The default LDT is a single-entry callgate to lcall7 for iBCS and a
* callgate to lcall27 for Solaris/x86 binaries.
*/
clear_page(&default_ldt[0]);
set_call_gate(&default_ldt[0],lcall7);
set_call_gate(&default_ldt[4],lcall27);
__make_page_readonly(&default_ldt[0]);
cpu_init();
}
@@ -1,15 +0,0 @@
.S.o:
$(CC) $(AFLAGS) -c $< -o $*.o
L_TARGET = lib.a
obj-y = checksum.o old-checksum.o delay.o \
usercopy.o getuser.o \
memcpy.o strstr.o xen_proc.o
obj-$(CONFIG_X86_USE_3DNOW) += mmx.o
obj-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
obj-$(CONFIG_DEBUG_IOVIRT) += iodebug.o
include $(TOPDIR)/Rules.make
-52
View File
@@ -1,52 +0,0 @@
/*
* Precise Delay Loops for i386
*
* Copyright (C) 1993 Linus Torvalds
* Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
*
* The __delay function must _NOT_ be inlined as its execution time
* depends wildly on alignment on many x86 processors. The additional
* jump magic is needed to get the timing stable on all the CPU's
* we have to worry about.
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <asm/processor.h>
#include <asm/delay.h>
#ifdef CONFIG_SMP
#include <asm/smp.h>
#endif
void __delay(unsigned long loops)
{
unsigned long bclock, now;
rdtscl(bclock);
do
{
rep_nop();
rdtscl(now);
} while ((now-bclock) < loops);
}
inline void __const_udelay(unsigned long xloops)
{
int d0;
__asm__("mull %0"
:"=d" (xloops), "=&a" (d0)
:"1" (xloops),"0" (current_cpu_data.loops_per_jiffy));
__delay(xloops * HZ);
}
void __udelay(unsigned long usecs)
{
__const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */
}
void __ndelay(unsigned long nsecs)
{
__const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
}
-16
View File
@@ -1,16 +0,0 @@
#
# 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 extable.o pageattr.o hypervisor.o ioremap.o
export-objs := pageattr.o
include $(TOPDIR)/Rules.make
-302
View File
@@ -1,302 +0,0 @@
/*
* linux/arch/i386/mm/fault.c
*
* Copyright (C) 1995 Linus Torvalds
*/
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/hardirq.h>
extern void die(const char *,struct pt_regs *,long);
pgd_t *cur_pgd;
extern spinlock_t timerlist_lock;
/*
* Unlock any spinlocks which will prevent us from getting the
* message out (timerlist_lock is acquired through the
* console unblank code)
*/
void bust_spinlocks(int yes)
{
spin_lock_init(&timerlist_lock);
if (yes) {
oops_in_progress = 1;
} else {
int loglevel_save = console_loglevel;
#ifdef CONFIG_VT
unblank_screen();
#endif
oops_in_progress = 0;
/*
* OK, the message is on the console. Now we call printk()
* without oops_in_progress set so that printk will give klogd
* a poke. Hold onto your hats...
*/
console_loglevel = 15; /* NMI oopser may have shut the console up */
printk(" ");
console_loglevel = loglevel_save;
}
}
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
* routines.
*
* error_code:
* bit 0 == 0 means no page found, 1 means protection fault
* bit 1 == 0 means read, 1 means write
* bit 2 == 0 means kernel, 1 means user-mode
*/
asmlinkage void do_page_fault(struct pt_regs *regs,
unsigned long error_code,
unsigned long address)
{
struct task_struct *tsk = current;
struct mm_struct *mm;
struct vm_area_struct * vma;
unsigned long page;
unsigned long fixup;
int write;
siginfo_t info;
/* Set the "privileged fault" bit to something sane. */
error_code &= 3;
error_code |= (regs->xcs & 2) << 1;
/*
* We fault-in kernel-space virtual memory on-demand. The
* 'reference' page table is init_mm.pgd.
*
* NOTE! We MUST NOT take any locks for this case. We may
* be in an interrupt or a critical region, and should
* only copy the information from the master page table,
* nothing more.
*
* This verifies that the fault happens in kernel space
* (error_code & 4) == 0, and that the fault was not a
* protection error (error_code & 1) == 0.
*/
if (address >= TASK_SIZE && !(error_code & 5))
goto vmalloc_fault;
mm = tsk->mm;
info.si_code = SEGV_MAPERR;
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
if (in_interrupt() || !mm)
goto no_context;
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
goto bad_area;
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
if (error_code & 4) {
/*
* accessing the stack below %esp is always a bug.
* The "+ 32" is there due to some instructions (like
* pusha) doing post-decrement on the stack and that
* doesn't show up until later..
*/
if (address + 32 < regs->esp)
goto bad_area;
}
if (expand_stack(vma, address))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
* we can handle it..
*/
good_area:
info.si_code = SEGV_ACCERR;
write = 0;
switch (error_code & 3) {
default: /* 3: write, present */
/* fall through */
case 2: /* write, not present */
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
write++;
break;
case 1: /* read, present */
goto bad_area;
case 0: /* read, not present */
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
survive:
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
switch (handle_mm_fault(mm, vma, address, write)) {
case 1:
tsk->min_flt++;
break;
case 2:
tsk->maj_flt++;
break;
case 0:
goto do_sigbus;
default:
goto out_of_memory;
}
up_read(&mm->mmap_sem);
return;
/*
* Something tried to access memory that isn't in our memory map..
* Fix it, but check if it's kernel or user first..
*/
bad_area:
up_read(&mm->mmap_sem);
/* User mode accesses just cause a SIGSEGV */
if (error_code & 4) {
tsk->thread.cr2 = address;
/* Kernel addresses are always protection faults */
tsk->thread.error_code = error_code | (address >= TASK_SIZE);
tsk->thread.trap_no = 14;
info.si_signo = SIGSEGV;
info.si_errno = 0;
/* info.si_code has been set above */
info.si_addr = (void *)address;
force_sig_info(SIGSEGV, &info, tsk);
return;
}
no_context:
/* Are we prepared to handle this kernel fault? */
if ((fixup = search_exception_table(regs->eip)) != 0) {
regs->eip = fixup;
return;
}
/*
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
*/
bust_spinlocks(1);
if (address < PAGE_SIZE)
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
else
printk(KERN_ALERT "Unable to handle kernel paging request");
printk(" at virtual address %08lx\n",address);
printk(" printing eip:\n");
printk("%08lx\n", regs->eip);
page = ((unsigned long *) cur_pgd)[address >> 22];
printk(KERN_ALERT "*pde=%08lx(%08lx)\n", page, machine_to_phys(page));
if (page & 1) {
page &= PAGE_MASK;
address &= 0x003ff000;
page = machine_to_phys(page);
page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
printk(KERN_ALERT "*pte=%08lx(%08lx)\n", page,
machine_to_phys(page));
}
die("Oops", regs, error_code);
bust_spinlocks(0);
do_exit(SIGKILL);
/*
* We ran out of memory, or some other thing happened to us that made
* us unable to handle the page fault gracefully.
*/
out_of_memory:
if (tsk->pid == 1) {
yield();
goto survive;
}
up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (error_code & 4)
do_exit(SIGKILL);
goto no_context;
do_sigbus:
up_read(&mm->mmap_sem);
/*
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
tsk->thread.cr2 = address;
tsk->thread.error_code = error_code;
tsk->thread.trap_no = 14;
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
info.si_addr = (void *)address;
force_sig_info(SIGBUS, &info, tsk);
/* Kernel mode? Handle exceptions or die */
if (!(error_code & 4))
goto no_context;
return;
vmalloc_fault:
{
/*
* Synchronize this task's top level page-table
* with the 'reference' page table.
*
* Do _not_ use "tsk" here. We might be inside
* an interrupt in the middle of a task switch..
*/
int offset = __pgd_offset(address);
pgd_t *pgd, *pgd_k;
pmd_t *pmd, *pmd_k;
pte_t *pte_k;
pgd = offset + cur_pgd;
pgd_k = init_mm.pgd + offset;
if (!pgd_present(*pgd_k))
goto no_context;
set_pgd(pgd, *pgd_k);
pmd = pmd_offset(pgd, address);
pmd_k = pmd_offset(pgd_k, address);
if (!pmd_present(*pmd_k))
goto no_context;
set_pmd(pmd, *pmd_k);
pte_k = pte_offset(pmd_k, address);
if (!pte_present(*pte_k))
goto no_context;
return;
}
}
-482
View File
@@ -1,482 +0,0 @@
/*
* linux/arch/i386/mm/init.c
*
* Copyright (C) 1995 Linus Torvalds
*
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
*/
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/smp.h>
#include <linux/init.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/bootmem.h>
#include <linux/slab.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/dma.h>
#include <asm/apic.h>
#include <asm/tlb.h>
/* XEN: We *cannot* use mmx_clear_page() this early. Force dumb memset(). */
#undef clear_page
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
mmu_gather_t mmu_gathers[NR_CPUS];
unsigned long highstart_pfn, highend_pfn;
static unsigned long totalram_pages;
static unsigned long totalhigh_pages;
int do_check_pgt_cache(int low, int high)
{
int freed = 0;
if(pgtable_cache_size > high) {
do {
if (!QUICKLIST_EMPTY(pgd_quicklist)) {
free_pgd_slow(get_pgd_fast());
freed++;
}
if (!QUICKLIST_EMPTY(pte_quicklist)) {
pte_free_slow(pte_alloc_one_fast(NULL, 0));
freed++;
}
} while(pgtable_cache_size > low);
}
return freed;
}
/*
* NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
* physical space so we can cache the place of the first one and move
* around without checking the pgd every time.
*/
#if CONFIG_HIGHMEM
pte_t *kmap_pte;
pgprot_t kmap_prot;
#define kmap_get_fixmap_pte(vaddr) \
pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
void __init kmap_init(void)
{
unsigned long kmap_vstart;
/* cache the first kmap pte */
kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
kmap_prot = PAGE_KERNEL;
}
#endif /* CONFIG_HIGHMEM */
void show_mem(void)
{
int i, total = 0, reserved = 0;
int shared = 0, cached = 0;
int highmem = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = max_mapnr;
while (i-- > 0) {
total++;
if (PageHighMem(mem_map+i))
highmem++;
if (PageReserved(mem_map+i))
reserved++;
else if (PageSwapCache(mem_map+i))
cached++;
else if (page_count(mem_map+i))
shared += page_count(mem_map+i) - 1;
}
printk("%d pages of RAM\n", total);
printk("%d pages of HIGHMEM\n",highmem);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached);
printk("%ld pages in page table cache\n",pgtable_cache_size);
show_buffers();
}
/* References to section boundaries */
extern char _text, _etext, _edata, __bss_start, _end;
extern char __init_begin, __init_end;
static inline void set_pte_phys (unsigned long vaddr,
unsigned long phys, pgprot_t prot)
{
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
pgd = init_mm.pgd + __pgd_offset(vaddr);
if (pgd_none(*pgd)) {
printk("PAE BUG #00!\n");
return;
}
pmd = pmd_offset(pgd, vaddr);
if (pmd_none(*pmd)) {
printk("PAE BUG #01!\n");
return;
}
pte = pte_offset(pmd, vaddr);
set_pte(pte, (pte_t) { phys | pgprot_val(prot) });
/*
* It's enough to flush this one mapping.
* (PGE mappings get flushed as well)
*/
__flush_tlb_one(vaddr);
}
void __set_fixmap(enum fixed_addresses idx, unsigned long phys,
pgprot_t flags)
{
unsigned long address = __fix_to_virt(idx);
if (idx >= __end_of_fixed_addresses) {
printk("Invalid __set_fixmap\n");
return;
}
set_pte_phys(address, phys, flags);
}
void clear_fixmap(enum fixed_addresses idx)
{
set_pte_phys(__fix_to_virt(idx), 0, __pgprot(0));
}
static void __init fixrange_init (unsigned long start,
unsigned long end, pgd_t *pgd_base)
{
pgd_t *pgd, *kpgd;
pmd_t *pmd, *kpmd;
pte_t *pte, *kpte;
int i, j;
unsigned long vaddr;
vaddr = start;
i = __pgd_offset(vaddr);
j = __pmd_offset(vaddr);
pgd = pgd_base + i;
for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
#if CONFIG_X86_PAE
if (pgd_none(*pgd)) {
pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
if (pmd != pmd_offset(pgd, 0))
printk("PAE BUG #02!\n");
}
pmd = pmd_offset(pgd, vaddr);
#else
pmd = (pmd_t *)pgd;
#endif
for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
clear_page(pte);
kpgd = pgd_offset_k((unsigned long)pte);
kpmd = pmd_offset(kpgd, (unsigned long)pte);
kpte = pte_offset(kpmd, (unsigned long)pte);
set_pte(kpte, pte_wrprotect(*kpte));
set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
}
vaddr += PMD_SIZE;
}
j = 0;
}
}
static void __init pagetable_init (void)
{
unsigned long vaddr, end, ram_end;
pgd_t *kpgd, *pgd, *pgd_base;
int i, j, k;
pmd_t *kpmd, *pmd;
pte_t *kpte, *pte, *pte_base;
ram_end = end = (unsigned long)__va(max_low_pfn * PAGE_SIZE);
if ( xen_start_info.nr_pages < max_low_pfn )
ram_end = (unsigned long)__va(xen_start_info.nr_pages * PAGE_SIZE);
pgd_base = init_mm.pgd;
i = __pgd_offset(PAGE_OFFSET);
pgd = pgd_base + i;
for (; i < PTRS_PER_PGD; pgd++, i++) {
vaddr = i*PGDIR_SIZE;
if (vaddr >= end)
break;
pmd = (pmd_t *)pgd;
for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
if (vaddr >= end)
break;
/* Filled in for us already? */
if ( pmd_val(*pmd) & _PAGE_PRESENT )
continue;
pte_base = pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
clear_page(pte_base);
for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
if (vaddr >= ram_end)
break;
*pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL);
}
kpgd = pgd_offset_k((unsigned long)pte_base);
kpmd = pmd_offset(kpgd, (unsigned long)pte_base);
kpte = pte_offset(kpmd, (unsigned long)pte_base);
set_pte(kpte, pte_wrprotect(*kpte));
set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
}
}
/*
* Fixed mappings, only the page table structure has to be
* created - mappings will be set by set_fixmap():
*/
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
fixrange_init(vaddr, HYPERVISOR_VIRT_START, init_mm.pgd);
#if CONFIG_HIGHMEM
/*
* Permanent kmaps:
*/
vaddr = PKMAP_BASE;
fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, init_mm.pgd);
pgd = init_mm.pgd + __pgd_offset(vaddr);
pmd = pmd_offset(pgd, vaddr);
pte = pte_offset(pmd, vaddr);
pkmap_page_table = pte;
#endif
}
static void __init zone_sizes_init(void)
{
unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
unsigned int max_dma, high, low;
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
high = highend_pfn;
if (low < max_dma)
zones_size[ZONE_DMA] = low;
else {
zones_size[ZONE_DMA] = max_dma;
zones_size[ZONE_NORMAL] = low - max_dma;
#ifdef CONFIG_HIGHMEM
zones_size[ZONE_HIGHMEM] = high - low;
#endif
}
free_area_init(zones_size);
}
void __init paging_init(void)
{
pagetable_init();
zone_sizes_init();
/* Switch to the real shared_info page, and clear the dummy page. */
set_fixmap(FIX_SHARED_INFO, xen_start_info.shared_info);
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
memset(empty_zero_page, 0, sizeof(empty_zero_page));
#ifdef CONFIG_HIGHMEM
kmap_init();
#endif
}
static inline int page_is_ram (unsigned long pagenr)
{
return 1;
}
#ifdef CONFIG_HIGHMEM
void __init one_highpage_init(struct page *page, int free_page)
{
ClearPageReserved(page);
set_bit(PG_highmem, &page->flags);
atomic_set(&page->count, 1);
if ( free_page )
__free_page(page);
totalhigh_pages++;
}
#endif /* CONFIG_HIGHMEM */
static void __init set_max_mapnr_init(void)
{
#ifdef CONFIG_HIGHMEM
highmem_start_page = mem_map + highstart_pfn;
max_mapnr = num_physpages = highend_pfn;
num_mappedpages = max_low_pfn;
#else
max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
#endif
}
static int __init free_pages_init(void)
{
#ifdef CONFIG_HIGHMEM
int bad_ppro = 0;
#endif
int reservedpages, pfn;
/* add only boot_pfn pages of low memory to free list.
* max_low_pfn may be sized for
* pages yet to be allocated from the hypervisor, or it may be set
* to override the xen_start_info amount of memory
*/
int boot_pfn = min(xen_start_info.nr_pages,max_low_pfn);
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem();
/* XEN: init and count low-mem pages outside initial allocation. */
for (pfn = boot_pfn; pfn < max_low_pfn; pfn++) {
ClearPageReserved(&mem_map[pfn]);
atomic_set(&mem_map[pfn].count, 1);
totalram_pages++;
}
reservedpages = 0;
for (pfn = 0; pfn < boot_pfn ; pfn++) {
/*
* Only count reserved RAM pages
*/
if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
reservedpages++;
}
#ifdef CONFIG_HIGHMEM
for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
one_highpage_init((struct page *) (mem_map + pfn),
(pfn < xen_start_info.nr_pages));
totalram_pages += totalhigh_pages;
#endif
return reservedpages;
}
void __init mem_init(void)
{
int codesize, reservedpages, datasize, initsize;
if (!mem_map)
BUG();
#ifdef CONFIG_HIGHMEM
/* check that fixmap and pkmap do not overlap */
if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n");
printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",
PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START);
BUG();
}
#endif
set_max_mapnr_init();
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
reservedpages = free_pages_init();
codesize = (unsigned long) &_etext - (unsigned long) &_text;
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
datasize >> 10,
initsize >> 10,
(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
);
boot_cpu_data.wp_works_ok = 1;
}
void free_initmem(void)
{
unsigned long addr;
addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1);
free_page(addr);
totalram_pages++;
}
printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
if (start < end)
printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1);
free_page(start);
totalram_pages++;
}
}
#endif
void si_meminfo(struct sysinfo *val)
{
val->totalram = max_pfn;
val->sharedram = 0;
val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
val->totalhigh = max_pfn-max_low_pfn;
val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
return;
}
#if defined(CONFIG_X86_PAE)
struct kmem_cache_s *pae_pgd_cachep;
void __init pgtable_cache_init(void)
{
/*
* PAE pgds must be 16-byte aligned:
*/
pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
if (!pae_pgd_cachep)
panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
}
#endif /* CONFIG_X86_PAE */
-266
View File
@@ -1,266 +0,0 @@
/*
* arch/xen/mm/ioremap.c
*
* Re-map IO memory to kernel address space so that we can access it.
*
* (C) Copyright 1995 1996 Linus Torvalds
*
* Modifications for Xenolinux (c) 2003-2004 Keir Fraser
*/
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
#include <asm/tlb.h>
#include <asm/mmu.h>
#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
/* These hacky macros avoid phys->machine translations. */
#define __direct_pte(x) ((pte_t) { (x) } )
#define __direct_mk_pte(page_nr,pgprot) \
__direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
#define direct_mk_pte_phys(physpage, pgprot) \
__direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
static inline void direct_remap_area_pte(pte_t *pte,
unsigned long address,
unsigned long size,
mmu_update_t **v)
{
unsigned long end;
address &= ~PMD_MASK;
end = address + size;
if (end > PMD_SIZE)
end = PMD_SIZE;
if (address >= end)
BUG();
do {
(*v)->ptr = virt_to_machine(pte);
(*v)++;
address += PAGE_SIZE;
pte++;
} while (address && (address < end));
}
static inline int direct_remap_area_pmd(struct mm_struct *mm,
pmd_t *pmd,
unsigned long address,
unsigned long size,
mmu_update_t **v)
{
unsigned long end;
address &= ~PGDIR_MASK;
end = address + size;
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
if (address >= end)
BUG();
do {
pte_t *pte = pte_alloc(mm, pmd, address);
if (!pte)
return -ENOMEM;
direct_remap_area_pte(pte, address, end - address, v);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address && (address < end));
return 0;
}
int __direct_remap_area_pages(struct mm_struct *mm,
unsigned long address,
unsigned long size,
mmu_update_t *v)
{
pgd_t * dir;
unsigned long end = address + size;
dir = pgd_offset(mm, address);
flush_cache_all();
if (address >= end)
BUG();
spin_lock(&mm->page_table_lock);
do {
pmd_t *pmd = pmd_alloc(mm, dir, address);
if (!pmd)
return -ENOMEM;
direct_remap_area_pmd(mm, pmd, address, end - address, &v);
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
spin_unlock(&mm->page_table_lock);
flush_tlb_all();
return 0;
}
int direct_remap_area_pages(struct mm_struct *mm,
unsigned long address,
unsigned long machine_addr,
unsigned long size,
pgprot_t prot,
domid_t domid)
{
int i;
unsigned long start_address;
#define MAX_DIRECTMAP_MMU_QUEUE 130
mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *v = u;
start_address = address;
for( i = 0; i < size; i += PAGE_SIZE )
{
if ( (v - u) == MAX_DIRECTMAP_MMU_QUEUE )
{
/* Fill in the PTE pointers. */
__direct_remap_area_pages( mm,
start_address,
address-start_address,
u);
if ( HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0 )
return -EFAULT;
v = u;
start_address = address;
}
/*
* Fill in the machine address: PTE ptr is done later by
* __direct_remap_area_pages().
*/
v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
machine_addr += PAGE_SIZE;
address += PAGE_SIZE;
v++;
}
if ( v != u )
{
/* get the ptep's filled in */
__direct_remap_area_pages(mm,
start_address,
address-start_address,
u);
if ( unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0) )
return -EFAULT;
}
return 0;
}
#endif /* CONFIG_XEN_PRIVILEGED_GUEST */
/*
* Remap an arbitrary machine address space into the kernel virtual
* address space. Needed when a privileged instance of Xenolinux wants
* to access space outside its world directly.
*
* NOTE! We need to allow non-page-aligned mappings too: we will obviously
* have to convert them into an offset in a page-aligned mapping, but the
* caller shouldn't need to know that small detail.
*/
void * __ioremap(unsigned long machine_addr,
unsigned long size,
unsigned long flags)
{
#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
void * addr;
struct vm_struct * area;
unsigned long offset, last_addr;
pgprot_t prot;
/* Don't allow wraparound or zero size */
last_addr = machine_addr + size - 1;
if (!size || last_addr < machine_addr)
return NULL;
/* Mappings have to be page-aligned */
offset = machine_addr & ~PAGE_MASK;
machine_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr+1) - machine_addr;
/* Ok, go for it */
area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;
addr = area->addr;
prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY |
_PAGE_ACCESSED | flags);
if (direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(addr),
machine_addr, size, prot, 0)) {
vfree(addr);
return NULL;
}
return (void *) (offset + (char *)addr);
#else
return NULL;
#endif
}
void iounmap(void *addr)
{
vfree((void *)((unsigned long)addr & PAGE_MASK));
}
/* implementation of boot time ioremap for purpose of provising access
to the vga console for privileged domains. Unlike boot time ioremap on
other architectures, ours is permanent and not reclaimed when then vmalloc
infrastructure is started */
void __init *bt_ioremap(unsigned long machine_addr, unsigned long size)
{
unsigned long offset, last_addr;
unsigned int nrpages;
enum fixed_addresses idx;
/* Don't allow wraparound or zero size */
last_addr = machine_addr + size - 1;
if (!size || last_addr < machine_addr)
return NULL;
/*
* Mappings have to be page-aligned
*/
offset = machine_addr & ~PAGE_MASK;
machine_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr) - machine_addr;
/*
* Mappings have to fit in the FIX_BTMAP area.
*/
nrpages = size >> PAGE_SHIFT;
if (nrpages > NR_FIX_BTMAPS)
return NULL;
/*
* Ok, go for it..
*/
idx = FIX_BTMAP_BEGIN;
while (nrpages > 0) {
__set_fixmap(idx, machine_addr, PAGE_KERNEL);
machine_addr += PAGE_SIZE;
--idx;
--nrpages;
}
flush_tlb_all();
return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
}
#if 0 /* We don't support these functions. They shouldn't be required. */
void __init bt_iounmap(void *addr, unsigned long size) {}
#endif
-75
View File
@@ -1,75 +0,0 @@
/* ld script to make i386 Linux kernel
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0xC0000000 + 0x100000;
_text = .; /* Text and read-only data */
.text : {
*(.text)
*(.fixup)
*(.gnu.warning)
} = 0x9090
_etext = .; /* End of text section */
.rodata : { *(.rodata) *(.rodata.*) }
.kstrtab : { *(.kstrtab) }
. = ALIGN(16); /* Exception table */
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
__start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
.data : { /* Data */
*(.data)
CONSTRUCTORS
}
_edata = .; /* End of data section */
. = ALIGN(8192); /* init_task */
.data.init_task : { *(.data.init_task) }
. = ALIGN(4096); /* Init code and data */
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(16);
__setup_start = .;
.setup.init : { *(.setup.init) }
__setup_end = .;
__initcall_start = .;
.initcall.init : { *(.initcall.init) }
__initcall_end = .;
. = ALIGN(4096);
__init_end = .;
. = ALIGN(4096);
.data.page_aligned : { *(.data.idt) }
. = ALIGN(32);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
__bss_start = .; /* BSS */
.bss : {
*(.bss)
}
_end = . ;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
}
File diff suppressed because it is too large. Load diff
-361
View File
@@ -1,361 +0,0 @@
#
# Makefile for the kernel character device drivers.
#
# 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 definitions are now inherited from the
# parent makes..
#
#
# This file contains the font map for the default (hardware) font
#
FONTMAPFILE = cp437.uni
O_TARGET := char.o
obj-y += mem.o tty_io.o n_tty.o tty_ioctl.o raw.o pty.o misc.o random.o
# All of the (potential) objects that export symbols.
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
export-objs := busmouse.o console.o keyboard.o sysrq.o \
misc.o pty.o random.o selection.o serial.o \
sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \
scx200.o fetchop.o
mod-subdirs := joystick ftape drm drm-4.0 pcmcia
list-multi :=
KEYMAP =defkeymap.o
KEYBD =pc_keyb.o
CONSOLE =console.o
SERIAL =serial.o
ifeq ($(ARCH),xen)
ifneq ($(CONFIG_XEN_PHYSDEV_ACCESS),y)
KEYBD =
endif
endif
ifeq ($(ARCH),s390)
KEYMAP =
KEYBD =
CONSOLE =
SERIAL =
endif
ifeq ($(ARCH),mips)
ifneq ($(CONFIG_PC_KEYB),y)
KEYBD =
endif
ifeq ($(CONFIG_VR41XX_KIU),y)
KEYMAP =
KEYBD = vr41xx_keyb.o
endif
endif
ifeq ($(ARCH),s390x)
KEYMAP =
KEYBD =
CONSOLE =
SERIAL =
endif
ifeq ($(ARCH),m68k)
ifdef CONFIG_AMIGA
KEYBD = amikeyb.o
else
ifndef CONFIG_MAC
KEYBD =
endif
endif
SERIAL =
endif
ifeq ($(ARCH),parisc)
ifdef CONFIG_GSC_PS2
KEYBD = hp_psaux.o hp_keyb.o
else
KEYBD =
endif
ifdef CONFIG_SERIAL_MUX
CONSOLE += mux.o
endif
ifdef CONFIG_PDC_CONSOLE
CONSOLE += pdc_console.o
endif
endif
ifdef CONFIG_Q40
KEYBD += q40_keyb.o
SERIAL = serial.o
endif
ifdef CONFIG_APOLLO
KEYBD += dn_keyb.o
endif
ifeq ($(ARCH),parisc)
ifdef CONFIG_GSC_PS2
KEYBD = hp_psaux.o hp_keyb.o
else
KEYBD =
endif
ifdef CONFIG_PDC_CONSOLE
CONSOLE += pdc_console.o
endif
endif
ifeq ($(ARCH),arm)
ifneq ($(CONFIG_PC_KEYMAP),y)
KEYMAP =
endif
ifneq ($(CONFIG_PC_KEYB),y)
KEYBD =
endif
endif
ifeq ($(ARCH),sh)
KEYMAP =
KEYBD =
CONSOLE =
ifeq ($(CONFIG_SH_HP600),y)
KEYMAP = defkeymap.o
KEYBD = scan_keyb.o hp600_keyb.o
CONSOLE = console.o
endif
ifeq ($(CONFIG_SH_DMIDA),y)
# DMIDA does not connect the HD64465 PS/2 keyboard port
# but we allow for USB keyboards to be plugged in.
KEYMAP = defkeymap.o
KEYBD = # hd64465_keyb.o pc_keyb.o
CONSOLE = console.o
endif
ifeq ($(CONFIG_SH_EC3104),y)
KEYMAP = defkeymap.o
KEYBD = ec3104_keyb.o
CONSOLE = console.o
endif
ifeq ($(CONFIG_SH_DREAMCAST),y)
KEYMAP = defkeymap.o
KEYBD =
CONSOLE = console.o
endif
endif
ifeq ($(CONFIG_DECSTATION),y)
KEYMAP =
KEYBD =
endif
ifeq ($(CONFIG_BAGET_MIPS),y)
KEYBD =
SERIAL = vac-serial.o
endif
ifeq ($(CONFIG_NINO),y)
SERIAL =
endif
ifneq ($(CONFIG_SUN_SERIAL),)
SERIAL =
endif
ifeq ($(CONFIG_QTRONIX_KEYBOARD),y)
KEYBD = qtronix.o
KEYMAP = qtronixmap.o
endif
ifeq ($(CONFIG_DUMMY_KEYB),y)
KEYBD = dummy_keyb.o
endif
obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
obj-$(CONFIG_SERIAL) += $(SERIAL)
obj-$(CONFIG_PARPORT_SERIAL) += parport_serial.o
obj-$(CONFIG_SERIAL_HCDP) += hcdp_serial.o
obj-$(CONFIG_SERIAL_21285) += serial_21285.o
obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o
obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o
obj-$(CONFIG_TS_AU1X00_ADS7846) += au1000_ts.o
obj-$(CONFIG_SERIAL_DEC) += decserial.o
ifndef CONFIG_SUN_KEYBOARD
obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
else
obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP)
endif
obj-$(CONFIG_HIL) += hp_keyb.o
obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
obj-$(CONFIG_ROCKETPORT) += rocket.o
obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
obj-$(CONFIG_DIGI) += pcxx.o
obj-$(CONFIG_DIGIEPCA) += epca.o
obj-$(CONFIG_CYCLADES) += cyclades.o
obj-$(CONFIG_STALLION) += stallion.o
obj-$(CONFIG_ISTALLION) += istallion.o
obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o
obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o
obj-$(CONFIG_RISCOM8) += riscom8.o
obj-$(CONFIG_ISI) += isicom.o
obj-$(CONFIG_ESPSERIAL) += esp.o
obj-$(CONFIG_SYNCLINK) += synclink.o
obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o
obj-$(CONFIG_N_HDLC) += n_hdlc.o
obj-$(CONFIG_SPECIALIX) += specialix.o
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o
obj-$(CONFIG_SX) += sx.o generic_serial.o
obj-$(CONFIG_RIO) += rio/rio.o generic_serial.o
obj-$(CONFIG_SH_SCI) += sh-sci.o generic_serial.o
obj-$(CONFIG_SERIAL167) += serial167.o
obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o
obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o
obj-$(CONFIG_TXX927_SERIAL) += serial_txx927.o
obj-$(CONFIG_SERIAL_TXX9) += generic_serial.o serial_txx9.o
obj-$(CONFIG_IP22_SERIAL) += sgiserial.o
obj-$(CONFIG_AU1X00_UART) += au1x00-serial.o
obj-$(CONFIG_SGI_L1_SERIAL) += sn_serial.o
subdir-$(CONFIG_RIO) += rio
subdir-$(CONFIG_INPUT) += joystick
obj-$(CONFIG_ATIXL_BUSMOUSE) += atixlmouse.o
obj-$(CONFIG_LOGIBUSMOUSE) += logibusmouse.o
obj-$(CONFIG_PRINTER) += lp.o
obj-$(CONFIG_TIPAR) += tipar.o
obj-$(CONFIG_OBMOUSE) += obmouse.o
ifeq ($(CONFIG_INPUT),y)
obj-y += joystick/js.o
endif
obj-$(CONFIG_FETCHOP) += fetchop.o
obj-$(CONFIG_BUSMOUSE) += busmouse.o
obj-$(CONFIG_DTLK) += dtlk.o
obj-$(CONFIG_R3964) += n_r3964.o
obj-$(CONFIG_APPLICOM) += applicom.o
obj-$(CONFIG_SONYPI) += sonypi.o
obj-$(CONFIG_MS_BUSMOUSE) += msbusmouse.o
obj-$(CONFIG_82C710_MOUSE) += qpmouse.o
obj-$(CONFIG_AMIGAMOUSE) += amigamouse.o
obj-$(CONFIG_ATARIMOUSE) += atarimouse.o
obj-$(CONFIG_ADBMOUSE) += adbmouse.o
obj-$(CONFIG_PC110_PAD) += pc110pad.o
obj-$(CONFIG_MK712_MOUSE) += mk712.o
obj-$(CONFIG_RTC) += rtc.o
obj-$(CONFIG_GEN_RTC) += genrtc.o
obj-$(CONFIG_EFI_RTC) += efirtc.o
obj-$(CONFIG_SGI_DS1286) += ds1286.o
obj-$(CONFIG_MIPS_RTC) += mips_rtc.o
obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
ifeq ($(CONFIG_PPC),)
obj-$(CONFIG_NVRAM) += nvram.o
endif
obj-$(CONFIG_TOSHIBA) += toshiba.o
obj-$(CONFIG_I8K) += i8k.o
obj-$(CONFIG_DS1620) += ds1620.o
obj-$(CONFIG_DS1742) += ds1742.o
obj-$(CONFIG_INTEL_RNG) += i810_rng.o
obj-$(CONFIG_AMD_RNG) += amd768_rng.o
obj-$(CONFIG_HW_RANDOM) += hw_random.o
obj-$(CONFIG_AMD_PM768) += amd76x_pm.o
obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
obj-$(CONFIG_AU1X00_GPIO) += au1000_gpio.o
obj-$(CONFIG_AU1X00_USB_TTY) += au1000_usbtty.o
obj-$(CONFIG_AU1X00_USB_RAW) += au1000_usbraw.o
obj-$(CONFIG_COBALT_LCD) += lcd.o
obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
subdir-$(CONFIG_FTAPE) += ftape
subdir-$(CONFIG_DRM_OLD) += drm-4.0
subdir-$(CONFIG_DRM_NEW) += drm
subdir-$(CONFIG_PCMCIA) += pcmcia
subdir-$(CONFIG_AGP) += agp
ifeq ($(CONFIG_FTAPE),y)
obj-y += ftape/ftape.o
endif
obj-$(CONFIG_H8) += h8.o
obj-$(CONFIG_PPDEV) += ppdev.o
obj-$(CONFIG_DZ) += dz.o
obj-$(CONFIG_NWBUTTON) += nwbutton.o
obj-$(CONFIG_NWFLASH) += nwflash.o
obj-$(CONFIG_SCx200) += scx200.o
obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
# Only one watchdog can succeed. We probe the hardware watchdog
# drivers first, then the softdog driver. This means if your hardware
# watchdog dies or is 'borrowed' for some reason the software watchdog
# still gives you some cover.
obj-$(CONFIG_PCWATCHDOG) += pcwd.o
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
obj-$(CONFIG_IB700_WDT) += ib700wdt.o
obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
obj-$(CONFIG_WDT) += wdt.o
obj-$(CONFIG_WDTPCI) += wdt_pci.o
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
obj-$(CONFIG_I810_TCO) += i810-tco.o
obj-$(CONFIG_MACHZ_WDT) += machzwd.o
obj-$(CONFIG_SH_WDT) += shwdt.o
obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
obj-$(CONFIG_ALIM1535_WDT) += alim1535d_wdt.o
obj-$(CONFIG_INDYDOG) += indydog.o
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
obj-$(CONFIG_INDYDOG) += indydog.o
obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
subdir-$(CONFIG_MWAVE) += mwave
ifeq ($(CONFIG_MWAVE),y)
obj-y += mwave/mwave.o
endif
subdir-$(CONFIG_IPMI_HANDLER) += ipmi
ifeq ($(CONFIG_IPMI_HANDLER),y)
obj-y += ipmi/ipmi.o
endif
include $(TOPDIR)/Rules.make
fastdep:
conmakehash: conmakehash.c
$(HOSTCC) $(HOSTCFLAGS) -o conmakehash conmakehash.c
consolemap_deftbl.c: $(FONTMAPFILE) conmakehash
./conmakehash $(FONTMAPFILE) > consolemap_deftbl.c
consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h
.DELETE_ON_ERROR:
defkeymap.c: defkeymap.map
set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
qtronixmap.c: qtronixmap.map
set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
-812
View File
@@ -1,812 +0,0 @@
/*
* linux/drivers/char/mem.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Added devfs support.
* Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
* Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
*
* MODIFIED FOR XEN by Keir Fraser, 10th July 2003.
* Linux running on Xen has strange semantics for /dev/mem and /dev/kmem!!
* 1. mmap will not work on /dev/kmem
* 2. mmap on /dev/mem interprets the 'file offset' as a machine address
* rather than a physical address.
* I don't believe anyone sane mmaps /dev/kmem, but /dev/mem is mmapped
* to get at memory-mapped I/O spaces (eg. the VESA X server does this).
* For this to work at all we need to expect machine addresses.
* Reading/writing of /dev/kmem expects kernel virtual addresses, as usual.
* Reading/writing of /dev/mem expects 'physical addresses' as usual -- this
* is because /dev/mem can only read/write existing kernel mappings, which
* will be normal RAM, and we should present pseudo-physical layout for all
* except I/O (which is the sticky case that mmap is hacked to deal with).
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/tpqic02.h>
#include <linux/ftape.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/raw.h>
#include <linux/tty.h>
#include <linux/capability.h>
#include <linux/ptrace.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#ifdef CONFIG_I2C
extern int i2c_init_all(void);
#endif
#ifdef CONFIG_FB
extern void fbmem_init(void);
#endif
#ifdef CONFIG_PROM_CONSOLE
extern void prom_con_init(void);
#endif
#ifdef CONFIG_MDA_CONSOLE
extern void mda_console_init(void);
#endif
#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
extern void tapechar_init(void);
#endif
static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
const char * buf, size_t count, loff_t *ppos)
{
ssize_t written;
written = 0;
#if defined(__sparc__) || defined(__mc68000__)
/* we don't have page 0 mapped on sparc and m68k.. */
if (realp < PAGE_SIZE) {
unsigned long sz = PAGE_SIZE-realp;
if (sz > count) sz = count;
/* Hmm. Do something? */
buf+=sz;
p+=sz;
count-=sz;
written+=sz;
}
#endif
if (copy_from_user(p, buf, count))
return -EFAULT;
written += count;
*ppos = realp + written;
return written;
}
/*
* This funcion reads the *physical* memory. The f_pos points directly to the
* memory location.
*/
static ssize_t read_mem(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned long end_mem;
ssize_t read;
end_mem = __pa(high_memory);
if (p >= end_mem)
return 0;
if (count > end_mem - p)
count = end_mem - p;
read = 0;
#if defined(__sparc__) || defined(__mc68000__)
/* we don't have page 0 mapped on sparc and m68k.. */
if (p < PAGE_SIZE) {
unsigned long sz = PAGE_SIZE-p;
if (sz > count)
sz = count;
if (sz > 0) {
if (clear_user(buf, sz))
return -EFAULT;
buf += sz;
p += sz;
count -= sz;
read += sz;
}
}
#endif
if (copy_to_user(buf, __va(p), count))
return -EFAULT;
read += count;
*ppos = p + read;
return read;
}
static ssize_t write_mem(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned long end_mem;
end_mem = __pa(high_memory);
if (p >= end_mem)
return 0;
if (count > end_mem - p)
count = end_mem - p;
return do_write_mem(file, __va(p), p, buf, count, ppos);
}
#ifndef pgprot_noncached
/*
* This should probably be per-architecture in <asm/pgtable.h>
*/
static inline pgprot_t pgprot_noncached(pgprot_t _prot)
{
unsigned long prot = pgprot_val(_prot);
#if defined(__i386__) || defined(__x86_64__)
/* On PPro and successors, PCD alone doesn't always mean
uncached because of interactions with the MTRRs. PCD | PWT
means definitely uncached. */
if (boot_cpu_data.x86 > 3)
prot |= _PAGE_PCD | _PAGE_PWT;
#elif defined(__powerpc__)
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
#elif defined(__mc68000__)
#ifdef SUN3_PAGE_NOCACHE
if (MMU_IS_SUN3)
prot |= SUN3_PAGE_NOCACHE;
else
#endif
if (MMU_IS_851 || MMU_IS_030)
prot |= _PAGE_NOCACHE030;
/* Use no-cache mode, serialized */
else if (MMU_IS_040 || MMU_IS_060)
prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
#endif
return __pgprot(prot);
}
#endif /* !pgprot_noncached */
/*
* Architectures vary in how they handle caching for addresses
* outside of main memory.
*/
static inline int noncached_address(unsigned long addr)
{
#if defined(__i386__)
/*
* On the PPro and successors, the MTRRs are used to set
* memory types for physical addresses outside main memory,
* so blindly setting PCD or PWT on those pages is wrong.
* For Pentiums and earlier, the surround logic should disable
* caching for the high addresses through the KEN pin, but
* we maintain the tradition of paranoia in this code.
*/
return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ||
test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ||
test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) )
&& addr >= __pa(high_memory);
#else
return addr >= __pa(high_memory);
#endif
}
#if !defined(CONFIG_XEN)
static int mmap_mem(struct file * file, struct vm_area_struct * vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
/*
* Accessing memory above the top the kernel knows about or
* through a file pointer that was marked O_SYNC will be
* done non-cached.
*/
if (noncached_address(offset) || (file->f_flags & O_SYNC))
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
/* Don't try to swap out physical pages.. */
vma->vm_flags |= VM_RESERVED;
/*
* Don't dump addresses that are not real memory to a core file.
*/
if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
vma->vm_flags |= VM_IO;
if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
return 0;
}
#elif !defined(CONFIG_XEN_PRIVILEGED_GUEST)
static int mmap_mem(struct file * file, struct vm_area_struct * vma)
{
return -ENXIO;
}
#else
static int mmap_mem(struct file * file, struct vm_area_struct * vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
if (!(xen_start_info.flags & SIF_PRIVILEGED))
return -ENXIO;
/* DONTCOPY is essential for Xen as copy_page_range is broken. */
vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
if (direct_remap_area_pages(vma->vm_mm, vma->vm_start, offset,
vma->vm_end-vma->vm_start, vma->vm_page_prot,
DOMID_IO))
return -EAGAIN;
return 0;
}
#endif /* CONFIG_XEN */
/*
* This function reads the *virtual* memory as seen by the kernel.
*/
static ssize_t read_kmem(struct file *file, char *buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
ssize_t read = 0;
ssize_t virtr = 0;
char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
if (p < (unsigned long) high_memory) {
read = count;
if (count > (unsigned long) high_memory - p)
read = (unsigned long) high_memory - p;
#if defined(__sparc__) || defined(__mc68000__)
/* we don't have page 0 mapped on sparc and m68k.. */
if (p < PAGE_SIZE && read > 0) {
size_t tmp = PAGE_SIZE - p;
if (tmp > read) tmp = read;
if (clear_user(buf, tmp))
return -EFAULT;
buf += tmp;
p += tmp;
read -= tmp;
count -= tmp;
}
#endif
if (copy_to_user(buf, (char *)p, read))
return -EFAULT;
p += read;
buf += read;
count -= read;
}
if (count > 0) {
kbuf = (char *)__get_free_page(GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
while (count > 0) {
int len = count;
if (len > PAGE_SIZE)
len = PAGE_SIZE;
len = vread(kbuf, (char *)p, len);
if (!len)
break;
if (copy_to_user(buf, kbuf, len)) {
free_page((unsigned long)kbuf);
return -EFAULT;
}
count -= len;
buf += len;
virtr += len;
p += len;
}
free_page((unsigned long)kbuf);
}
*ppos = p;
return virtr + read;
}
extern long vwrite(char *buf, char *addr, unsigned long count);
/*
* This function writes to the *virtual* memory as seen by the kernel.
*/
static ssize_t write_kmem(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
unsigned long p = *ppos;
ssize_t wrote = 0;
ssize_t virtr = 0;
char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
if (p < (unsigned long) high_memory) {
wrote = count;
if (count > (unsigned long) high_memory - p)
wrote = (unsigned long) high_memory - p;
wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
p += wrote;
buf += wrote;
count -= wrote;
}
if (count > 0) {
kbuf = (char *)__get_free_page(GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
while (count > 0) {
int len = count;
if (len > PAGE_SIZE)
len = PAGE_SIZE;
if (len && copy_from_user(kbuf, buf, len)) {
free_page((unsigned long)kbuf);
return -EFAULT;
}
len = vwrite(kbuf, (char *)p, len);
count -= len;
buf += len;
virtr += len;
p += len;
}
free_page((unsigned long)kbuf);
}
*ppos = p;
return virtr + wrote;
}
#if defined(CONFIG_ISA) || !defined(__mc68000__)
static ssize_t read_port(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
unsigned long i = *ppos;
char *tmp = buf;
if (verify_area(VERIFY_WRITE,buf,count))
return -EFAULT;
while (count-- > 0 && i < 65536) {
if (__put_user(inb(i),tmp) < 0)
return -EFAULT;
i++;
tmp++;
}
*ppos = i;
return tmp-buf;
}
static ssize_t write_port(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
unsigned long i = *ppos;
const char * tmp = buf;
if (verify_area(VERIFY_READ,buf,count))
return -EFAULT;
while (count-- > 0 && i < 65536) {
char c;
if (__get_user(c, tmp))
return -EFAULT;
outb(c,i);
i++;
tmp++;
}
*ppos = i;
return tmp-buf;
}
#endif
static ssize_t read_null(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t write_null(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
return count;
}
/*
* For fun, we are using the MMU for this.
*/
static inline size_t read_zero_pagealigned(char * buf, size_t size)
{
struct mm_struct *mm;
struct vm_area_struct * vma;
unsigned long addr=(unsigned long)buf;
mm = current->mm;
/* Oops, this was forgotten before. -ben */
down_read(&mm->mmap_sem);
/* For private mappings, just map in zero pages. */
for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
unsigned long count;
if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
goto out_up;
if (vma->vm_flags & VM_SHARED)
break;
count = vma->vm_end - addr;
if (count > size)
count = size;
zap_page_range(mm, addr, count);
zeromap_page_range(addr, count, PAGE_COPY);
size -= count;
buf += count;
addr += count;
if (size == 0)
goto out_up;
}
up_read(&mm->mmap_sem);
/* The shared case is hard. Let's do the conventional zeroing. */
do {
unsigned long unwritten = clear_user(buf, PAGE_SIZE);
if (unwritten)
return size + unwritten - PAGE_SIZE;
if (current->need_resched)
schedule();
buf += PAGE_SIZE;
size -= PAGE_SIZE;
} while (size);
return size;
out_up:
up_read(&mm->mmap_sem);
return size;
}
static ssize_t read_zero(struct file * file, char * buf,
size_t count, loff_t *ppos)
{
unsigned long left, unwritten, written = 0;
if (!count)
return 0;
if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
left = count;
/* do we want to be clever? Arbitrary cut-off */
if (count >= PAGE_SIZE*4) {
unsigned long partial;
/* How much left of the page? */
partial = (PAGE_SIZE-1) & -(unsigned long) buf;
unwritten = clear_user(buf, partial);
written = partial - unwritten;
if (unwritten)
goto out;
left -= partial;
buf += partial;
unwritten = read_zero_pagealigned(buf, left & PAGE_MASK);
written += (left & PAGE_MASK) - unwritten;
if (unwritten)
goto out;
buf += left & PAGE_MASK;
left &= ~PAGE_MASK;
}
unwritten = clear_user(buf, left);
written += left - unwritten;
out:
return written ? written : -EFAULT;
}
static int mmap_zero(struct file * file, struct vm_area_struct * vma)
{
if (vma->vm_flags & VM_SHARED)
return shmem_zero_setup(vma);
if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
}
static ssize_t write_full(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
return -ENOSPC;
}
/*
* Special lseek() function for /dev/null and /dev/zero. Most notably, you
* can fopen() both devices with "a" now. This was previously impossible.
* -- SRB.
*/
static loff_t null_lseek(struct file * file, loff_t offset, int orig)
{
return file->f_pos = 0;
}
/*
* The memory devices use the full 32/64 bits of the offset, and so we cannot
* check against negative addresses: they are ok. The return value is weird,
* though, in that case (0).
*
* also note that seeking relative to the "end of file" isn't supported:
* it has no meaning, so it returns -EINVAL.
*/
static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
{
loff_t ret;
switch (orig) {
case 0:
file->f_pos = offset;
ret = file->f_pos;
force_successful_syscall_return();
break;
case 1:
file->f_pos += offset;
ret = file->f_pos;
force_successful_syscall_return();
break;
default:
ret = -EINVAL;
}
return ret;
}
static int open_port(struct inode * inode, struct file * filp)
{
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}
struct page *kmem_vm_nopage(struct vm_area_struct *vma, unsigned long address, int write)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long kaddr;
pgd_t *pgd;
pmd_t *pmd;
pte_t *ptep, pte;
struct page *page = NULL;
/* address is user VA; convert to kernel VA of desired page */
kaddr = (address - vma->vm_start) + offset;
kaddr = VMALLOC_VMADDR(kaddr);
spin_lock(&init_mm.page_table_lock);
/* Lookup page structure for kernel VA */
pgd = pgd_offset(&init_mm, kaddr);
if (pgd_none(*pgd) || pgd_bad(*pgd))
goto out;
pmd = pmd_offset(pgd, kaddr);
if (pmd_none(*pmd) || pmd_bad(*pmd))
goto out;
ptep = pte_offset(pmd, kaddr);
if (!ptep)
goto out;
pte = *ptep;
if (!pte_present(pte))
goto out;
if (write && !pte_write(pte))
goto out;
page = pte_page(pte);
if (!VALID_PAGE(page)) {
page = NULL;
goto out;
}
/* Increment reference count on page */
get_page(page);
out:
spin_unlock(&init_mm.page_table_lock);
return page;
}
struct vm_operations_struct kmem_vm_ops = {
nopage: kmem_vm_nopage,
};
static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long size = vma->vm_end - vma->vm_start;
/*
* If the user is not attempting to mmap a high memory address then
* the standard mmap_mem mechanism will work. High memory addresses
* need special handling, as remap_page_range expects a physically-
* contiguous range of kernel addresses (such as obtained in kmalloc).
*/
if ((offset + size) < (unsigned long) high_memory)
return mmap_mem(file, vma);
/*
* Accessing memory above the top the kernel knows about or
* through a file pointer that was marked O_SYNC will be
* done non-cached.
*/
if (noncached_address(offset) || (file->f_flags & O_SYNC))
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
/* Don't do anything here; "nopage" will fill the holes */
vma->vm_ops = &kmem_vm_ops;
/* Don't try to swap out physical pages.. */
vma->vm_flags |= VM_RESERVED;
/*
* Don't dump addresses that are not real memory to a core file.
*/
vma->vm_flags |= VM_IO;
return 0;
}
#define zero_lseek null_lseek
#define full_lseek null_lseek
#define write_zero write_null
#define read_full read_zero
#define open_mem open_port
#define open_kmem open_mem
static struct file_operations mem_fops = {
llseek: memory_lseek,
read: read_mem,
write: write_mem,
mmap: mmap_mem,
open: open_mem,
};
static struct file_operations kmem_fops = {
llseek: memory_lseek,
read: read_kmem,
write: write_kmem,
#if !defined(CONFIG_XEN)
mmap: mmap_kmem,
#endif
open: open_kmem,
};
static struct file_operations null_fops = {
llseek: null_lseek,
read: read_null,
write: write_null,
};
#if defined(CONFIG_ISA) || !defined(__mc68000__)
static struct file_operations port_fops = {
llseek: memory_lseek,
read: read_port,
write: write_port,
open: open_port,
};
#endif
static struct file_operations zero_fops = {
llseek: zero_lseek,
read: read_zero,
write: write_zero,
mmap: mmap_zero,
};
static struct file_operations full_fops = {
llseek: full_lseek,
read: read_full,
write: write_full,
};
static int memory_open(struct inode * inode, struct file * filp)
{
switch (MINOR(inode->i_rdev)) {
case 1:
filp->f_op = &mem_fops;
break;
case 2:
filp->f_op = &kmem_fops;
break;
case 3:
filp->f_op = &null_fops;
break;
#if defined(CONFIG_ISA) || !defined(__mc68000__)
case 4:
filp->f_op = &port_fops;
break;
#endif
case 5:
filp->f_op = &zero_fops;
break;
case 7:
filp->f_op = &full_fops;
break;
case 8:
filp->f_op = &random_fops;
break;
case 9:
filp->f_op = &urandom_fops;
break;
default:
return -ENXIO;
}
if (filp->f_op && filp->f_op->open)
return filp->f_op->open(inode,filp);
return 0;
}
void __init memory_devfs_register (void)
{
/* These are never unregistered */
static const struct {
unsigned short minor;
char *name;
umode_t mode;
struct file_operations *fops;
} list[] = { /* list of minor devices */
{1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
{2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
{3, "null", S_IRUGO | S_IWUGO, &null_fops},
#if defined(CONFIG_ISA) || !defined(__mc68000__)
{4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
#endif
{5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
{7, "full", S_IRUGO | S_IWUGO, &full_fops},
{8, "random", S_IRUGO | S_IWUSR, &random_fops},
{9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}
};
int i;
for (i=0; i<(sizeof(list)/sizeof(*list)); i++)
devfs_register (NULL, list[i].name, DEVFS_FL_NONE,
MEM_MAJOR, list[i].minor,
list[i].mode | S_IFCHR,
list[i].fops, NULL);
}
static struct file_operations memory_fops = {
open: memory_open, /* just a selector for the real open */
};
int __init chr_dev_init(void)
{
if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
memory_devfs_register();
rand_initialize();
#ifdef CONFIG_I2C
i2c_init_all();
#endif
#if defined (CONFIG_FB)
fbmem_init();
#endif
#if defined (CONFIG_PROM_CONSOLE)
prom_con_init();
#endif
#if defined (CONFIG_MDA_CONSOLE)
mda_console_init();
#endif
tty_init();
#ifdef CONFIG_M68K_PRINTER
lp_m68k_init();
#endif
misc_init();
#if CONFIG_QIC02_TAPE
qic02_tape_init();
#endif
#ifdef CONFIG_FTAPE
ftape_init();
#endif
#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
tapechar_init();
#endif
return 0;
}
__initcall(chr_dev_init);
File diff suppressed because it is too large. Load diff
@@ -1,97 +0,0 @@
#
# drivers/scsi/aic7xxx/Makefile
#
# Makefile for the Linux aic7xxx SCSI driver.
#
O_TARGET := aic7xxx_drv.o
list-multi := aic7xxx.o aic79xx.o
obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o
ifeq ($(CONFIG_PCI),y)
obj-$(CONFIG_SCSI_AIC79XX) += aic79xx.o
endif
EXTRA_CFLAGS += -I$(TOPDIR)/drivers/scsi -Werror
#EXTRA_CFLAGS += -g
# Platform Specific Files
obj-aic7xxx = aic7xxx_osm.o aic7xxx_proc.o
# Core Files
obj-aic7xxx += aic7xxx_core.o aic7xxx_93cx6.o
ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y)
obj-aic7xxx += aic7xxx_reg_print.o
endif
#EISA Specific Files
AIC7XXX_EISA_ARCH = $(filter i386 alpha xen,$(ARCH))
ifneq ($(AIC7XXX_EISA_ARCH),)
obj-aic7xxx += aic7770.o
# Platform Specific EISA Files
obj-aic7xxx += aic7770_osm.o
endif
#PCI Specific Files
ifeq ($(CONFIG_PCI),y)
obj-aic7xxx += aic7xxx_pci.o
# Platform Specific PCI Files
obj-aic7xxx += aic7xxx_osm_pci.o
endif
# Platform Specific U320 Files
obj-aic79xx = aic79xx_osm.o aic79xx_proc.o aic79xx_osm_pci.o
# Core Files
obj-aic79xx += aic79xx_core.o aic79xx_pci.o
ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y)
obj-aic79xx += aic79xx_reg_print.o
endif
# Override our module desitnation
MOD_DESTDIR = $(shell cd .. && $(CONFIG_SHELL) $(TOPDIR)/scripts/pathdown.sh)
include $(TOPDIR)/Rules.make
aic7xxx_core.o: aic7xxx_seq.h
$(obj-aic7xxx): aic7xxx_reg.h
aic7xxx.o: aic7xxx_seq.h aic7xxx_reg.h $(obj-aic7xxx)
$(LD) $(LD_RFLAG) -r -o $@ $(obj-aic7xxx)
aic79xx_core.o: aic79xx_seq.h
$(obj-aic79xx): aic79xx_reg.h
aic79xx.o: aic79xx_seq.h aic79xx_reg.h $(obj-aic79xx)
$(LD) $(LD_RFLAG) -r -o $@ $(obj-aic79xx)
ifeq ($(CONFIG_AIC7XXX_BUILD_FIRMWARE),y)
aic7xxx_gen = aic7xxx_seq.h aic7xxx_reg.h
ifeq ($(CONFIG_AIC7XXX_REG_PRETTY_PRINT),y)
aic7xxx_gen += aic7xxx_reg_print.c
aic7xxx_asm_cmd = aicasm/aicasm -I. -r aic7xxx_reg.h \
-p aic7xxx_reg_print.c -i aic7xxx_osm.h \
-o aic7xxx_seq.h aic7xxx.seq
else
aic7xxx_asm_cmd = aicasm/aicasm -I. -r aic7xxx_reg.h \
-o aic7xxx_seq.h aic7xxx.seq
endif
$(aic7xxx_gen): aic7xxx.seq aic7xxx.reg aicasm/aicasm
$(aic7xxx_asm_cmd)
endif
ifeq ($(CONFIG_AIC79XX_BUILD_FIRMWARE),y)
aic79xx_gen = aic79xx_seq.h aic79xx_reg.h
ifeq ($(CONFIG_AIC79XX_REG_PRETTY_PRINT),y)
aic79xx_gen += aic79xx_reg_print.c
aic79xx_asm_cmd = aicasm/aicasm -I. -r aic79xx_reg.h \
-p aic79xx_reg_print.c -i aic79xx_osm.h \
-o aic79xx_seq.h aic79xx.seq
else
aic79xx_asm_cmd = aicasm/aicasm -I. -r aic79xx_reg.h \
-o aic79xx_seq.h aic79xx.seq
endif
$(aic79xx_gen): aic79xx.seq aic79xx.reg aicasm/aicasm
$(aic79xx_asm_cmd)
endif
aicasm/aicasm: aicasm/*.[chyl]
$(MAKE) -C aicasm
@@ -1,53 +0,0 @@
/*
* include/asm-i386/bugs.h
*
* Copyright (C) 1994 Linus Torvalds
*
* Cyrix stuff, June 1998 by:
* - Rafael R. Reilova (moved everything from head.S),
* <rreilova@ececs.uc.edu>
* - Channing Corn (tests & fixes),
* - Andrew D. Balsa (code cleanup).
*
* Pentium III FXSR, SSE support
* Gareth Hughes <gareth@valinux.com>, May 2000
*/
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*/
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/msr.h>
static void __init check_fpu(void)
{
boot_cpu_data.fdiv_bug = 0;
}
static void __init check_hlt(void)
{
boot_cpu_data.hlt_works_ok = 1;
}
static void __init check_bugs(void)
{
extern void __init boot_init_fpu(void);
identify_cpu(&boot_cpu_data);
boot_init_fpu();
#ifndef CONFIG_SMP
printk("CPU: ");
print_cpu_info(&boot_cpu_data);
#endif
check_fpu();
check_hlt();
system_utsname.machine[1] = '0' +
(boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86);
}
@@ -1,37 +0,0 @@
#ifndef __ARCH_DESC_H
#define __ARCH_DESC_H
#include <asm/ldt.h>
#ifndef __ASSEMBLY__
struct desc_struct {
unsigned long a,b;
};
struct Xgt_desc_struct {
unsigned short size;
unsigned long address __attribute__((packed));
};
extern struct desc_struct default_ldt[];
static inline void clear_LDT(void)
{
xen_set_ldt(0, 0);
}
static inline void load_LDT(mm_context_t *pc)
{
void *segments = pc->ldt;
int count = pc->size;
if ( count == 0 )
segments = NULL;
xen_set_ldt((unsigned long)segments, count);
}
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_DESC_H__ */
@@ -1,107 +0,0 @@
/*
* fixmap.h: compile-time virtual memory allocation
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1998 Ingo Molnar
*
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
*/
#ifndef _ASM_FIXMAP_H
#define _ASM_FIXMAP_H
#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/apicdef.h>
#include <asm/page.h>
#include <asm-xen/gnttab.h>
#ifdef CONFIG_HIGHMEM
#include <linux/threads.h>
#include <asm/kmap_types.h>
#endif
/*
* Here we define all the compile-time 'special' virtual
* addresses. The point is to have a constant address at
* compile time, but to set the physical address only
* in the boot process. We allocate these special addresses
* from the end of virtual memory (0xfffff000) backwards.
* Also this lets us do fail-safe vmalloc(), we
* can guarantee that these special addresses and
* vmalloc()-ed addresses never overlap.
*
* these 'compile-time allocated' memory buffers are
* fixed-size 4k pages. (or larger if used with an increment
* highger than 1) use fixmap_set(idx,phys) to associate
* physical memory with fixmap indices.
*
* TLB entries of such buffers will not be flushed across
* task switches.
*/
enum fixed_addresses {
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
FIX_BLKRING_BASE,
FIX_NETRING0_BASE,
FIX_NETRING1_BASE,
FIX_NETRING2_BASE,
FIX_NETRING3_BASE,
FIX_SHARED_INFO,
FIX_GNTTAB_BEGIN,
FIX_GNTTAB_END = FIX_GNTTAB_BEGIN + NR_GRANT_FRAMES - 1,
#ifdef CONFIG_VGA_CONSOLE
#define NR_FIX_BTMAPS 32 /* 128KB For the Dom0 VGA Console A0000-C0000 */
#else
#define NR_FIX_BTMAPS 1 /* in case anyone wants it in future... */
#endif
FIX_BTMAP_END,
FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
/* our bt_ioremap is permanent, unlike other architectures */
__end_of_permanent_fixed_addresses,
__end_of_fixed_addresses = __end_of_permanent_fixed_addresses
};
extern void __set_fixmap (enum fixed_addresses idx,
unsigned long phys, pgprot_t flags);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
/*
* Some hardware wants to get fixmapped without caching.
*/
#define set_fixmap_nocache(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
extern void clear_fixmap(enum fixed_addresses idx);
/*
* used by vmalloc.c.
*
* Leave one empty page between vmalloc'ed areas and
* the start of the fixmap, and leave one page empty
* at the top of mem..
*/
#define FIXADDR_TOP (HYPERVISOR_VIRT_START - 2*PAGE_SIZE)
#define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
/*
* 'index to address' translation. If anyone tries to use the idx
* directly without tranlation, we catch the bug with a NULL-deference
* kernel oops. Illegal ranges of incoming indices are caught too.
*/
static inline unsigned long fix_to_virt(unsigned int idx)
{
return __fix_to_virt(idx);
}
#endif
@@ -1,132 +0,0 @@
/*
* highmem.h: virtual kernel memory mappings for high memory
*
* Used in CONFIG_HIGHMEM systems for memory pages which
* are not addressable by direct kernel virtual addresses.
*
* Copyright (C) 1999 Gerhard Wichert, Siemens AG
* Gerhard.Wichert@pdb.siemens.de
*
*
* Redesigned the x86 32-bit VM architecture to deal with
* up to 16 Terabyte physical memory. With current x86 CPUs
* we now support up to 64 Gigabytes physical RAM.
*
* Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
*/
#ifndef _ASM_HIGHMEM_H
#define _ASM_HIGHMEM_H
#ifdef __KERNEL__
#include <linux/config.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/kmap_types.h>
#include <asm/pgtable.h>
#ifdef CONFIG_DEBUG_HIGHMEM
#define HIGHMEM_DEBUG 1
#else
#define HIGHMEM_DEBUG 0
#endif
/* declarations for highmem.c */
extern unsigned long highstart_pfn, highend_pfn;
extern pte_t *kmap_pte;
extern pgprot_t kmap_prot;
extern pte_t *pkmap_page_table;
extern void kmap_init(void) __init;
/*
* Right now we initialize only a single pte table. It can be extended
* easily, subsequent pte tables have to be allocated in one physical
* chunk of RAM.
*/
#define PKMAP_BASE (HYPERVISOR_VIRT_START - (1<<23))
#ifdef CONFIG_X86_PAE
#define LAST_PKMAP 512
#else
#define LAST_PKMAP 1024
#endif
#define LAST_PKMAP_MASK (LAST_PKMAP-1)
#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
extern void * FASTCALL(kmap_high(struct page *page, int nonblocking));
extern void FASTCALL(kunmap_high(struct page *page));
#define kmap(page) __kmap(page, 0)
#define kmap_nonblock(page) __kmap(page, 1)
static inline void *__kmap(struct page *page, int nonblocking)
{
if (in_interrupt())
out_of_line_bug();
if (page < highmem_start_page)
return page_address(page);
return kmap_high(page, nonblocking);
}
static inline void kunmap(struct page *page)
{
if (in_interrupt())
out_of_line_bug();
if (page < highmem_start_page)
return;
kunmap_high(page);
}
/*
* The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
* gives a more generic (and caching) interface. But kmap_atomic can
* be used in IRQ contexts, so in some (very limited) cases we need
* it.
*/
static inline void *kmap_atomic(struct page *page, enum km_type type)
{
enum fixed_addresses idx;
unsigned long vaddr;
if (page < highmem_start_page)
return page_address(page);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#if HIGHMEM_DEBUG
if (!pte_none(*(kmap_pte-idx)))
out_of_line_bug();
#endif
set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
__flush_tlb_one(vaddr);
return (void*) vaddr;
}
static inline void kunmap_atomic(void *kvaddr, enum km_type type)
{
#if HIGHMEM_DEBUG
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
if (vaddr < FIXADDR_START) // FIXME
return;
if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
out_of_line_bug();
/*
* force other mappings to Oops if they'll try to access
* this pte without first remap it
*/
pte_clear(kmap_pte-idx);
__flush_tlb_one(vaddr);
#endif
}
#endif /* __KERNEL__ */
#endif /* _ASM_HIGHMEM_H */
@@ -1,61 +0,0 @@
#ifndef _ASM_HW_IRQ_H
#define _ASM_HW_IRQ_H
/*
* linux/include/asm/hw_irq.h
*
* (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
*/
#include <linux/config.h>
#include <linux/smp.h>
#include <asm/atomic.h>
#include <asm/irq.h>
#define SYSCALL_VECTOR 0x80
extern int irq_vector[NR_IRQS];
extern atomic_t irq_err_count;
extern atomic_t irq_mis_count;
extern char _stext, _etext;
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 eip)
{
if (!prof_buffer)
return;
/*
* Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
* (default is all CPUs.)
*/
if (!((1<<smp_processor_id()) & prof_cpu_mask))
return;
eip -= (unsigned long) &_stext;
eip >>= prof_shift;
/*
* Don't ignore out-of-bounds EIP values silently,
* put them into the last histogram slot, so if
* present, they will show up as a sharp peak.
*/
if (eip > prof_len-1)
eip = prof_len-1;
atomic_inc((atomic_t *)&prof_buffer[eip]);
}
static inline void hw_resend_irq(struct hw_interrupt_type *h,
unsigned int i)
{}
#endif /* _ASM_HW_IRQ_H */
-457
View File
@@ -1,457 +0,0 @@
#ifndef _ASM_IO_H
#define _ASM_IO_H
#include <linux/config.h>
/*
* This file contains the definitions for the x86 IO instructions
* inb/inw/inl/outb/outw/outl and the "string versions" of the same
* (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
* versions of the single-IO instructions (inb_p/inw_p/..).
*
* This file is not meant to be obfuscating: it's just complicated
* to (a) handle it all in a way that makes gcc able to optimize it
* as well as possible and (b) trying to avoid writing the same thing
* over and over again with slight variations and possibly making a
* mistake somewhere.
*/
/*
* Thanks to James van Artsdalen for a better timing-fix than
* the two short jumps: using outb's to a nonexistent port seems
* to guarantee better timings even on fast machines.
*
* On the other hand, I'd like to be sure of a non-existent port:
* I feel a bit unsafe about using 0x80 (should be safe, though)
*
* Linus
*/
/*
* Bit simplified and optimized by Jan Hubicka
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
*
* isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added,
* isa_read[wl] and isa_write[wl] fixed
* - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*/
#define IO_SPACE_LIMIT 0xffff
#define XQUAD_PORTIO_BASE 0xfe400000
#define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */
#define XQUAD_PORTIO_LEN 0x80000 /* Only remapping first 2 quads */
#ifdef __KERNEL__
#include <linux/vmalloc.h>
/*
* Temporary debugging check to catch old code using
* unmapped ISA addresses. Will be removed in 2.4.
*/
#if CONFIG_DEBUG_IOVIRT
extern void *__io_virt_debug(unsigned long x, const char *file, int line);
extern unsigned long __io_phys_debug(unsigned long x, const char *file, int line);
#define __io_virt(x) __io_virt_debug((unsigned long)(x), __FILE__, __LINE__)
//#define __io_phys(x) __io_phys_debug((unsigned long)(x), __FILE__, __LINE__)
#else
#define __io_virt(x) ((void *)(x))
//#define __io_phys(x) __pa(x)
#endif
/**
* virt_to_phys - map virtual addresses to physical
* @address: address to remap
*
* The returned physical address is the physical (CPU) mapping for
* the memory address given. It is only valid to use this function on
* addresses directly mapped or allocated via kmalloc.
*
* This function does not give bus mappings for DMA transfers. In
* almost all conceivable cases a device driver should not be using
* this function
*/
static inline unsigned long virt_to_phys(volatile void * address)
{
return __pa(address);
}
/**
* phys_to_virt - map physical address to virtual
* @address: address to remap
*
* The returned virtual address is a current CPU mapping for
* the memory address given. It is only valid to use this function on
* addresses that have a kernel mapping
*
* This function does not handle bus mappings for DMA transfers. In
* almost all conceivable cases a device driver should not be using
* this function
*/
static inline void * phys_to_virt(unsigned long address)
{
return __va(address);
}
/*
* We define page_to_phys 'incorrectly' because it is used when merging blkdev
* requests, and the correct thing to do there is to use machine addresses.
*/
#define page_to_phys(_x) phys_to_machine(((_x) - mem_map) << PAGE_SHIFT)
extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
/**
* ioremap - map bus memory into CPU space
* @offset: bus address of the memory
* @size: size of the resource to map
*
* ioremap 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.
*/
static inline void * ioremap (unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, 0);
}
/**
* 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 paticular 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:
*/
static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, _PAGE_PCD);
}
extern void iounmap(void *addr);
/*
* bt_ioremap() and bt_iounmap() are for temporary early boot-time
* mappings, before the real ioremap() is functional.
* A boot-time mapping is currently limited to at most 16 pages.
*/
extern void *bt_ioremap(unsigned long offset, unsigned long size);
extern void bt_iounmap(void *addr, unsigned long size);
#define virt_to_bus(_x) phys_to_machine(virt_to_phys(_x))
#define bus_to_virt(_x) phys_to_virt(machine_to_phys(_x))
#define page_to_bus(_x) phys_to_machine(((_x) - mem_map) << PAGE_SHIFT)
#define bus_to_phys(_x) machine_to_phys(_x)
#define bus_to_page(_x) (mem_map + (bus_to_phys(_x) >> PAGE_SHIFT))
/*
* readX/writeX() are used to access memory mapped devices. On some
* architectures the memory mapped IO stuff needs to be accessed
* differently. On the x86 architecture, we just read/write the
* memory location directly.
*/
#define readb(addr) (*(volatile unsigned char *) __io_virt(addr))
#define readw(addr) (*(volatile unsigned short *) __io_virt(addr))
#define readl(addr) (*(volatile unsigned int *) __io_virt(addr))
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))
#define __raw_writeb writeb
#define __raw_writew writew
#define __raw_writel writel
#define memset_io(a,b,c) __memset(__io_virt(a),(b),(c))
#define memcpy_fromio(a,b,c) __memcpy((a),__io_virt(b),(c))
#define memcpy_toio(a,b,c) __memcpy(__io_virt(a),(b),(c))
/*
* ISA space is 'always mapped' on a typical x86 system, no need to
* explicitly ioremap() it. The fact that the ISA IO space is mapped
* to PAGE_OFFSET is pure coincidence - it does not mean ISA values
* are physical addresses. The following constant pointer can be
* used as the IO-area pointer (it can be iounmapped as well, so the
* analogy with PCI is quite large):
*/
#define __ISA_IO_base ((char *)(PAGE_OFFSET))
#define isa_readb(a) readb(__ISA_IO_base + (a))
#define isa_readw(a) readw(__ISA_IO_base + (a))
#define isa_readl(a) readl(__ISA_IO_base + (a))
#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c))
#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c))
#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c))
/*
* Again, i386 does not require mem IO specific function.
*/
#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d))
#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(__ISA_IO_base + (b)),(c),(d))
/**
* check_signature - find BIOS signatures
* @io_addr: mmio address to check
* @signature: signature block
* @length: length of signature
*
* Perform a signature comparison with the mmio address io_addr. This
* address should have been obtained by ioremap.
* Returns 1 on a match.
*/
static inline int check_signature(unsigned long io_addr,
const unsigned char *signature, int length)
{
int retval = 0;
do {
if (readb(io_addr) != *signature)
goto out;
io_addr++;
signature++;
length--;
} while (length);
retval = 1;
out:
return retval;
}
/**
* isa_check_signature - find BIOS signatures
* @io_addr: mmio address to check
* @signature: signature block
* @length: length of signature
*
* Perform a signature comparison with the ISA mmio address io_addr.
* Returns 1 on a match.
*
* This function is deprecated. New drivers should use ioremap and
* check_signature.
*/
static inline int isa_check_signature(unsigned long io_addr,
const unsigned char *signature, int length)
{
int retval = 0;
do {
if (isa_readb(io_addr) != *signature)
goto out;
io_addr++;
signature++;
length--;
} while (length);
retval = 1;
out:
return retval;
}
/*
* Cache management
*
* This needed for two cases
* 1. Out of order aware processors
* 2. Accidentally out of order processors (PPro errata #51)
*/
#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
static inline void flush_write_buffers(void)
{
__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
}
#define dma_cache_inv(_start,_size) flush_write_buffers()
#define dma_cache_wback(_start,_size) flush_write_buffers()
#define dma_cache_wback_inv(_start,_size) flush_write_buffers()
#else
/* Nothing to do */
#define dma_cache_inv(_start,_size) do { } while (0)
#define dma_cache_wback(_start,_size) do { } while (0)
#define dma_cache_wback_inv(_start,_size) do { } while (0)
#define flush_write_buffers()
#endif
#endif /* __KERNEL__ */
#ifdef SLOW_IO_BY_JUMPING
#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
#elif defined(__UNSAFE_IO__)
#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
#else
#define __SLOW_DOWN_IO "\n1: outb %%al,$0x80\n" \
"2:\n" \
".section __ex_table,\"a\"\n\t" \
".align 4\n\t" \
".long 1b,2b\n" \
".previous"
#endif
#ifdef REALLY_SLOW_IO
#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
#else
#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
#endif
#ifdef CONFIG_MULTIQUAD
extern void *xquad_portio; /* Where the IO area was mapped */
#endif /* CONFIG_MULTIQUAD */
/*
* Talk about misusing macros..
*/
#define __OUT1(s,x) \
static inline void out##s(unsigned x value, unsigned short port) {
#ifdef __UNSAFE_IO__
#define __OUT2(s,s1,s2) \
__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
#else
#define __OUT2(s,s1,s2) \
__asm__ __volatile__ ("1: out" #s " %" s1 "0,%" s2 "1\n" \
"2:\n" \
".section __ex_table,\"a\"\n\t" \
".align 4\n\t" \
".long 1b,2b\n" \
".previous"
#endif
#if defined (CONFIG_MULTIQUAD) && !defined(STANDALONE)
#define __OUTQ(s,ss,x) /* Do the equivalent of the portio op on quads */ \
static inline void out##ss(unsigned x value, unsigned short port) { \
if (xquad_portio) \
write##s(value, (unsigned long) xquad_portio + port); \
else /* We're still in early boot, running on quad 0 */ \
out##ss##_local(value, port); \
} \
static inline void out##ss##_quad(unsigned x value, unsigned short port, int quad) { \
if (xquad_portio) \
write##s(value, (unsigned long) xquad_portio + (XQUAD_PORTIO_QUAD*quad)\
+ port); \
}
#define __INQ(s,ss) /* Do the equivalent of the portio op on quads */ \
static inline RETURN_TYPE in##ss(unsigned short port) { \
if (xquad_portio) \
return read##s((unsigned long) xquad_portio + port); \
else /* We're still in early boot, running on quad 0 */ \
return in##ss##_local(port); \
} \
static inline RETURN_TYPE in##ss##_quad(unsigned short port, int quad) { \
if (xquad_portio) \
return read##s((unsigned long) xquad_portio + (XQUAD_PORTIO_QUAD*quad)\
+ port); \
else\
return 0;\
}
#endif /* CONFIG_MULTIQUAD && !STANDALONE */
#if !defined(CONFIG_MULTIQUAD) || defined(STANDALONE)
#define __OUT(s,s1,x) \
__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));}
#else
/* Make the default portio routines operate on quad 0 */
#define __OUT(s,s1,x) \
__OUT1(s##_local,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
__OUT1(s##_p_local,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
__OUTQ(s,s,x) \
__OUTQ(s,s##_p,x)
#endif /* !CONFIG_MULTIQUAD || STANDALONE */
#define __IN1(s) \
static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
#ifdef __UNSAFE_IO__
#define __IN2(s,s1,s2) \
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
#else
#define __IN2(s,s1,s2) \
__asm__ __volatile__ ("1: in" #s " %" s2 "1,%" s1 "0\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: mov" #s " $~0,%" s1 "0\n\t" \
"jmp 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n\t" \
".align 4\n\t" \
".long 1b,3b\n" \
".previous"
#endif
#if !defined(CONFIG_MULTIQUAD) || defined(STANDALONE)
#define __IN(s,s1,i...) \
__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; }
#else
/* Make the default portio routines operate on quad 0 */
#define __IN(s,s1,i...) \
__IN1(s##_local) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
__IN1(s##_p_local) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
__INQ(s,s) \
__INQ(s,s##_p)
#endif /* !CONFIG_MULTIQUAD || STANDALONE */
#define __INS(s) \
static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
{ __asm__ __volatile__ ("rep ; ins" #s \
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define __OUTS(s) \
static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
{ __asm__ __volatile__ ("rep ; outs" #s \
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define RETURN_TYPE unsigned char
__IN(b,"")
#undef RETURN_TYPE
#define RETURN_TYPE unsigned short
__IN(w,"")
#undef RETURN_TYPE
#define RETURN_TYPE unsigned int
__IN(l,"")
#undef RETURN_TYPE
__OUT(b,"b",char)
__OUT(w,"w",short)
__OUT(l,,int)
__INS(b)
__INS(w)
__INS(l)
__OUTS(b)
__OUTS(w)
__OUTS(l)
#endif
@@ -1,65 +0,0 @@
#ifndef _ASM_IRQ_H
#define _ASM_IRQ_H
/*
* linux/include/asm/irq.h
*
* (C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar
*
* IRQ/IPI changes taken from work by Thomas Radke
* <tomsoft@informatik.tu-chemnitz.de>
*/
#include <linux/config.h>
#include <asm/hypervisor.h>
#include <asm/ptrace.h>
/*
* The flat IRQ space is divided into two regions:
* 1. A one-to-one mapping of real physical IRQs. This space is only used
* if we have physical device-access privilege. This region is at the
* start of the IRQ space so that existing device drivers do not need
* to be modified to translate physical IRQ numbers into our IRQ space.
* 3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
* are bound using the provided bind/unbind functions.
*/
#define PIRQ_BASE 0
#define NR_PIRQS 128
#define DYNIRQ_BASE (PIRQ_BASE + NR_PIRQS)
#define NR_DYNIRQS 128
#define NR_IRQS (NR_PIRQS + NR_DYNIRQS)
#define pirq_to_irq(_x) ((_x) + PIRQ_BASE)
#define irq_to_pirq(_x) ((_x) - PIRQ_BASE)
#define dynirq_to_irq(_x) ((_x) + DYNIRQ_BASE)
#define irq_to_dynirq(_x) ((_x) - DYNIRQ_BASE)
/* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
extern int bind_virq_to_irq(int virq);
extern void unbind_virq_from_irq(int virq);
extern int bind_evtchn_to_irq(int evtchn);
extern void unbind_evtchn_from_irq(int evtchn);
static __inline__ int irq_cannonicalize(int irq)
{
return (irq == 2) ? 9 : irq;
}
extern void disable_irq(unsigned int);
extern void disable_irq_nosync(unsigned int);
extern void enable_irq(unsigned int);
extern void irq_suspend(void);
extern void irq_resume(void);
#define CPU_MASK_NONE 0
/* XXX SMH: no-op for compat w/ 2.6 shared files */
#define irq_ctx_init(cpu) do { ; } while (0)
#endif /* _ASM_IRQ_H */
@@ -1,74 +0,0 @@
/*
* linux/include/asm-i386/keyboard.h
*
* Created 3 Nov 1996 by Geert Uytterhoeven
*/
/*
* This file contains the i386 architecture specific keyboard definitions
*/
#ifndef _I386_KEYBOARD_H
#define _I386_KEYBOARD_H
#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/kd.h>
#include <linux/pm.h>
#include <asm/io.h>
#define KEYBOARD_IRQ 1
#define DISABLE_KBD_DURING_INTERRUPTS 0
extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int pckbd_getkeycode(unsigned int scancode);
extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode);
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
extern void pckbd_init_hw(void);
extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *);
extern pm_callback pm_kbd_request_override;
extern unsigned char pckbd_sysrq_xlate[128];
#define kbd_setkeycode pckbd_setkeycode
#define kbd_getkeycode pckbd_getkeycode
#define kbd_translate pckbd_translate
#define kbd_unexpected_up pckbd_unexpected_up
#define kbd_leds pckbd_leds
#define kbd_init_hw pckbd_init_hw
#define kbd_sysrq_xlate pckbd_sysrq_xlate
#define SYSRQ_KEY 0x54
#define kbd_controller_present() (xen_start_info.flags & SIF_INITDOMAIN)
/* resource allocation */
#define kbd_request_region()
#define kbd_request_irq(handler) request_irq(KEYBOARD_IRQ, handler, 0, \
"keyboard", NULL)
/* How to access the keyboard macros on this platform. */
#define kbd_read_input() inb(KBD_DATA_REG)
#define kbd_read_status() inb(KBD_STATUS_REG)
#define kbd_write_output(val) outb(val, KBD_DATA_REG)
#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
/* Some stoneage hardware needs delays after some operations. */
#define kbd_pause() do { } while(0)
/*
* Machine specific bits for the PS/2 driver
*/
#define AUX_IRQ 12
#define aux_request_irq(hand, dev_id) \
request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id)
#define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id)
#endif /* __KERNEL__ */
#endif /* _I386_KEYBOARD_H */
@@ -1,59 +0,0 @@
#ifndef __I386_MMU_CONTEXT_H
#define __I386_MMU_CONTEXT_H
#include <linux/config.h>
#include <asm/desc.h>
#include <asm/atomic.h>
#include <asm/pgalloc.h>
/*
* hooks to add arch specific data into the mm struct.
* Note that destroy_context is called even if init_new_context
* fails.
*/
int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
void destroy_context(struct mm_struct *mm);
#ifdef CONFIG_SMP
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
{
if(cpu_tlbstate[cpu].state == TLBSTATE_OK)
cpu_tlbstate[cpu].state = TLBSTATE_LAZY;
}
#else
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
{
}
#endif
extern pgd_t *cur_pgd;
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
{
struct mmuext_op _op[2], *op = _op;
if (prev != next) {
/* stop flush ipis for the previous mm */
clear_bit(cpu, &prev->cpu_vm_mask);
/* Re-load page tables */
cur_pgd = next->pgd;
op->cmd = MMUEXT_NEW_BASEPTR;
op->mfn = pfn_to_mfn(__pa(next->pgd) >> PAGE_SHIFT);
op++;
/* load_LDT, if either the previous or next thread
* has a non-default LDT.
*/
if (next->context.size+prev->context.size) {
op->cmd = MMUEXT_SET_LDT;
op->linear_addr = (unsigned long)next->context.ldt;
op->nr_ents = next->context.size;
op++;
}
BUG_ON(HYPERVISOR_mmuext_op(_op, op-_op, NULL, DOMID_SELF));
}
}
#define activate_mm(prev, next) \
switch_mm((prev),(next),NULL,smp_processor_id())
#endif
@@ -1,14 +0,0 @@
#ifndef _ASM_I386_MODULE_H
#define _ASM_I386_MODULE_H
/*
* This file contains the i386 architecture specific module code.
*/
extern int xen_module_init(struct module *mod);
#define module_map(x) vmalloc(x)
#define module_unmap(x) vfree(x)
#define module_arch_init(x) xen_module_init(x)
#define arch_init_modules(x) do { } while (0)
#endif /* _ASM_I386_MODULE_H */
-178
View File
@@ -1,178 +0,0 @@
#ifndef _I386_PAGE_H
#define _I386_PAGE_H
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <linux/config.h>
#include <linux/string.h>
#include <asm/types.h>
#include <asm-xen/xen-public/xen.h>
#ifdef CONFIG_XEN_SCRUB_PAGES
#define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
#else
#define scrub_pages(_p,_n) ((void)0)
#endif
#ifdef CONFIG_X86_USE_3DNOW
#include <asm/mmx.h>
#define clear_page(page) mmx_clear_page((void *)(page))
#define copy_page(to,from) mmx_copy_page(to,from)
#else
/*
* On older X86 processors its not a win to use MMX here it seems.
* Maybe the K6-III ?
*/
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
#endif
#define clear_user_page(page, vaddr) clear_page(page)
#define copy_user_page(to, from, vaddr) copy_page(to, from)
/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
extern unsigned int *phys_to_machine_mapping;
#define pfn_to_mfn(_pfn) ((unsigned long)(phys_to_machine_mapping[(_pfn)]))
#define mfn_to_pfn(_mfn) ((unsigned long)(machine_to_phys_mapping[(_mfn)]))
static inline unsigned long phys_to_machine(unsigned long phys)
{
unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT);
machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
return machine;
}
static inline unsigned long machine_to_phys(unsigned long machine)
{
unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT);
phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
return phys;
}
/*
* These are used to make use of C type-checking..
*/
#if CONFIG_X86_PAE
typedef struct { unsigned long pte_low, pte_high; } pte_t;
typedef struct { unsigned long long pmd; } pmd_t;
typedef struct { unsigned long long pgd; } pgd_t;
#define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
#else
typedef struct { unsigned long pte_low; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
static inline unsigned long pte_val(pte_t x)
{
unsigned long ret = x.pte_low;
if ( (ret & 1) ) ret = machine_to_phys(ret);
return ret;
}
#define pte_val_ma(x) ((x).pte_low)
#endif
#define PTE_MASK PAGE_MASK
typedef struct { unsigned long pgprot; } pgprot_t;
static inline unsigned long pmd_val(pmd_t x)
{
unsigned long ret = x.pmd;
if ( ret ) ret = machine_to_phys(ret) | 1;
return ret;
}
#define pmd_val_ma(x) ((x).pmd)
#define pgd_val(x) ({ BUG(); (unsigned long)0; })
#define pgprot_val(x) ((x).pgprot)
#define __pte(x) ({ unsigned long _x = (x); \
(((_x)&1) ? ((pte_t) {phys_to_machine(_x)}) : ((pte_t) {(_x)})); })
#define __pte_ma(x) ((pte_t) { (x) } )
#define __pmd(x) ({ unsigned long _x = (x); \
(((_x)&1) ? ((pmd_t) {phys_to_machine(_x)}) : ((pmd_t) {(_x)})); })
#define __pgd(x) ({ BUG(); (pgprot_t) { 0 }; })
#define __pgprot(x) ((pgprot_t) { (x) } )
#endif /* !__ASSEMBLY__ */
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
/*
* This handles the memory map.. We could make this a config
* option, but too many people screw it up, and too few need
* it.
*
* A __PAGE_OFFSET of 0xC0000000 means that the kernel has
* a virtual address space of one gigabyte, which limits the
* amount of physical memory you can use to about 950MB.
*
* If you want more physical memory than this then see the CONFIG_HIGHMEM4G
* and CONFIG_HIGHMEM64G options in the kernel configuration.
*/
#define __PAGE_OFFSET (0xC0000000)
#ifndef __ASSEMBLY__
/*
* Tell the user there is some problem. Beep too, so we can
* see^H^H^Hhear bugs in early bootup as well!
* The offending file and line are encoded after the "officially
* undefined" opcode for parsing in the trap handler.
*/
#if 1 /* Set to zero for a slightly smaller kernel */
#define BUG() \
__asm__ __volatile__( "ud2\n" \
"\t.word %c0\n" \
"\t.long %c1\n" \
: : "i" (__LINE__), "i" (__FILE__))
#else
#define BUG() __asm__ __volatile__("ud2\n")
#endif
#define PAGE_BUG(page) do { \
BUG(); \
} while (0)
/* Pure 2^n version of get_order */
static __inline__ int get_order(unsigned long size)
{
int order;
size = (size-1) >> (PAGE_SHIFT-1);
order = -1;
do {
size >>= 1;
order++;
} while (size);
return order;
}
#endif /* __ASSEMBLY__ */
#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT))
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
/* VIRT <-> MACHINE conversion */
#define virt_to_machine(_a) (phys_to_machine(__pa(_a)))
#define machine_to_virt(_m) (__va(machine_to_phys(_m)))
#endif /* __KERNEL__ */
#endif /* _I386_PAGE_H */
-283
View File
@@ -1,283 +0,0 @@
#ifndef __i386_PCI_H
#define __i386_PCI_H
#include <linux/config.h>
#ifdef __KERNEL__
/* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
#ifdef CONFIG_PCI
extern unsigned int pcibios_assign_all_busses(void);
#else
#define pcibios_assign_all_busses() 0
#endif
#define pcibios_scan_all_fns() 0
extern unsigned long pci_mem_start;
#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM (pci_mem_start)
void pcibios_config_init(void);
struct pci_bus * pcibios_scan_root(int bus);
extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
void pcibios_set_master(struct pci_dev *dev);
void pcibios_penalize_isa_irq(int irq);
struct irq_routing_table *pcibios_get_irq_routing_table(void);
int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
/* Dynamic DMA mapping stuff.
* i386 has everything mapped statically.
*/
#include <linux/types.h>
#include <linux/slab.h>
#include <asm/scatterlist.h>
#include <linux/string.h>
#include <asm/io.h>
struct pci_dev;
/* The networking and block device layers use this boolean for bounce
* buffer decisions.
*/
#define PCI_DMA_BUS_IS_PHYS (0)
/* Allocate and map kernel buffer using consistent mode DMA for a device.
* hwdev should be valid struct pci_dev pointer for PCI devices,
* NULL for PCI-like buses (ISA, EISA).
* Returns non-NULL cpu-view pointer to the buffer if successful and
* sets *dma_addrp to the pci side dma address as well, else *dma_addrp
* is undefined.
*/
extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle);
/* Free and unmap a consistent DMA buffer.
* cpu_addr is what was returned from pci_alloc_consistent,
* size must be the same as what as passed into pci_alloc_consistent,
* and likewise dma_addr must be the same as what *dma_addrp was set to.
*
* References to the memory and mappings associated with cpu_addr/dma_addr
* past this call are illegal.
*/
extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
/* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
*
* Once the device is given the dma address, the device owns this memory
* until either pci_unmap_single or pci_dma_sync_single is performed.
*/
static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
out_of_line_bug();
flush_write_buffers();
return virt_to_bus(ptr);
}
/* Unmap a single streaming mode DMA translation. The dma_addr and size
* must match what was provided for in a previous pci_map_single call. All
* other usages are undefined.
*
* After this call, reads by the cpu to the buffer are guarenteed to see
* whatever the device wrote there.
*/
static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
out_of_line_bug();
/* Nothing to do */
}
/*
* pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical
* to pci_map_single, but takes a struct page instead of a virtual address
*/
static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
unsigned long offset, size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
out_of_line_bug();
return page_to_bus(page) + offset;
}
static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
out_of_line_bug();
/* Nothing to do */
}
/* pci_unmap_{page,single} is a nop so... */
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
#define pci_unmap_addr(PTR, ADDR_NAME) (0)
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
#define pci_unmap_len(PTR, LEN_NAME) (0)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
/* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
* above pci_map_single interface. Here the scatter gather list
* elements are each tagged with the appropriate dma address
* and length. They are obtained via sg_dma_{address,length}(SG).
*
* NOTE: An implementation may be able to use a smaller number of
* DMA address/length pairs than there are SG table elements.
* (for example via virtual mapping capabilities)
* The routine returns the number of addr/length pairs actually
* used, at most nents.
*
* Device ownership issues as mentioned above for pci_map_single are
* the same here.
*/
static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
{
int i;
if (direction == PCI_DMA_NONE)
out_of_line_bug();
/*
* temporary 2.4 hack
*/
for (i = 0; i < nents; i++ ) {
if (sg[i].address && sg[i].page)
out_of_line_bug();
else if (!sg[i].address && !sg[i].page)
out_of_line_bug();
if (sg[i].address)
sg[i].dma_address = virt_to_bus(sg[i].address);
else
sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
}
flush_write_buffers();
return nents;
}
/* Unmap a set of streaming mode DMA translations.
* Again, cpu read rules concerning calls here are the same as for
* pci_unmap_single() above.
*/
static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
{
if (direction == PCI_DMA_NONE)
out_of_line_bug();
/* Nothing to do */
}
/* Make physical memory consistent for a single
* streaming mode DMA translation after a transfer.
*
* If you perform a pci_map_single() but wish to interrogate the
* buffer using the cpu, yet do not wish to teardown the PCI dma
* mapping, you must call this function before doing so. At the
* next point you give the PCI dma address back to the card, the
* device again owns the buffer.
*/
static inline void pci_dma_sync_single(struct pci_dev *hwdev,
dma_addr_t dma_handle,
size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
out_of_line_bug();
flush_write_buffers();
}
/* Make physical memory consistent for a set of streaming
* mode DMA translations after a transfer.
*
* The same as pci_dma_sync_single but for a scatter-gather list,
* same rules and usage.
*/
static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
struct scatterlist *sg,
int nelems, int direction)
{
if (direction == PCI_DMA_NONE)
out_of_line_bug();
flush_write_buffers();
}
/* Return whether the given PCI device DMA address mask can
* be supported properly. For example, if your device can
* only drive the low 24-bits during PCI bus mastering, then
* you would pass 0x00ffffff as the mask to this function.
*/
static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
{
/*
* we fall back to GFP_DMA when the mask isn't all 1s,
* so we can't guarantee allocations that must be
* within a tighter range than GFP_DMA..
*/
if(mask < 0x00ffffff)
return 0;
return 1;
}
/* This is always fine. */
#define pci_dac_dma_supported(pci_dev, mask) (1)
static __inline__ dma64_addr_t
pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
{
return ((dma64_addr_t) page_to_bus(page) +
(dma64_addr_t) offset);
}
static __inline__ struct page *
pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
{
return bus_to_page(dma_addr);
}
static __inline__ unsigned long
pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
{
return (dma_addr & ~PAGE_MASK);
}
static __inline__ void
pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
{
flush_write_buffers();
}
/* These macros should be used after a pci_map_sg call has been done
* to get bus addresses of each of the SG entries and their lengths.
* You should only work with the number of sg entries pci_map_sg
* returns.
*/
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->length)
/* Return the index of the PCI controller for device. */
static inline int pci_controller_num(struct pci_dev *dev)
{
return 0;
}
#define HAVE_PCI_MMAP
extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
#endif /* __KERNEL__ */
#endif /* __i386_PCI_H */
@@ -1,280 +0,0 @@
#ifndef _I386_PGALLOC_H
#define _I386_PGALLOC_H
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/fixmap.h>
#include <asm/hypervisor.h>
#include <linux/threads.h>
/*
* Quick lists are aligned so that least significant bits of array pointer
* are all zero when list is empty, and all one when list is full.
*/
#define QUICKLIST_ENTRIES 256
#define QUICKLIST_EMPTY(_l) !((unsigned long)(_l) & ((QUICKLIST_ENTRIES*4)-1))
#define QUICKLIST_FULL(_l) QUICKLIST_EMPTY((_l)+1)
#define pgd_quicklist (current_cpu_data.pgd_quick)
#define pmd_quicklist (current_cpu_data.pmd_quick)
#define pte_quicklist (current_cpu_data.pte_quick)
#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
#define pmd_populate(mm, pmd, pte) \
do { \
set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \
} while ( 0 )
/*
* Allocate and free page tables.
*/
#if defined (CONFIG_X86_PAE)
#error "no PAE support as yet"
/*
* We can't include <linux/slab.h> here, thus these uglinesses.
*/
struct kmem_cache_s;
extern struct kmem_cache_s *pae_pgd_cachep;
extern void *kmem_cache_alloc(struct kmem_cache_s *, int);
extern void kmem_cache_free(struct kmem_cache_s *, void *);
static inline pgd_t *get_pgd_slow(void)
{
int i;
pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL);
if (pgd) {
for (i = 0; i < USER_PTRS_PER_PGD; i++) {
unsigned long pmd = __get_free_page(GFP_KERNEL);
if (!pmd)
goto out_oom;
clear_page(pmd);
set_pgd(pgd + i, __pgd(1 + __pa(pmd)));
}
memcpy(pgd + USER_PTRS_PER_PGD,
init_mm.pgd + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
}
return pgd;
out_oom:
for (i--; i >= 0; i--)
free_page((unsigned long)__va(pgd_val(pgd[i])-1));
kmem_cache_free(pae_pgd_cachep, pgd);
return NULL;
}
#else
static inline pgd_t *get_pgd_slow(void)
{
pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
if (pgd) {
memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
memcpy(pgd + USER_PTRS_PER_PGD,
init_mm.pgd + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
__make_page_readonly(pgd);
xen_pgd_pin(__pa(pgd));
}
return pgd;
}
#endif /* CONFIG_X86_PAE */
static inline pgd_t *get_pgd_fast(void)
{
unsigned long ret;
if ( !QUICKLIST_EMPTY(pgd_quicklist) ) {
ret = *(--pgd_quicklist);
pgtable_cache_size--;
} else
ret = (unsigned long)get_pgd_slow();
return (pgd_t *)ret;
}
static inline void free_pgd_slow(pgd_t *pgd)
{
#if defined(CONFIG_X86_PAE)
#error
int i;
for (i = 0; i < USER_PTRS_PER_PGD; i++)
free_page((unsigned long)__va(pgd_val(pgd[i])-1));
kmem_cache_free(pae_pgd_cachep, pgd);
#else
xen_pgd_unpin(__pa(pgd));
__make_page_writable(pgd);
free_page((unsigned long)pgd);
#endif
}
static inline void free_pgd_fast(pgd_t *pgd)
{
if ( !QUICKLIST_FULL(pgd_quicklist) ) {
*(pgd_quicklist++) = (unsigned long)pgd;
pgtable_cache_size++;
} else
free_pgd_slow(pgd);
}
static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
pte_t *pte;
pte = (pte_t *) __get_free_page(GFP_KERNEL);
if (pte)
{
clear_page(pte);
__make_page_readonly(pte);
xen_pte_pin(__pa(pte));
}
return pte;
}
static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm,
unsigned long address)
{
unsigned long ret = 0;
if ( !QUICKLIST_EMPTY(pte_quicklist) ) {
ret = *(--pte_quicklist);
pgtable_cache_size--;
}
return (pte_t *)ret;
}
static __inline__ void pte_free_slow(pte_t *pte)
{
xen_pte_unpin(__pa(pte));
__make_page_writable(pte);
free_page((unsigned long)pte);
}
static inline void pte_free_fast(pte_t *pte)
{
if ( !QUICKLIST_FULL(pte_quicklist) ) {
*(pte_quicklist++) = (unsigned long)pte;
pgtable_cache_size++;
} else
pte_free_slow(pte);
}
#define pte_free(pte) pte_free_fast(pte)
#define pgd_free(pgd) free_pgd_fast(pgd)
#define pgd_alloc(mm) get_pgd_fast()
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
* inside the pgd, so has no extra memory associated with it.
* (In the PAE case we free the pmds as part of the pgd.)
*/
#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); })
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
#define pmd_free_slow(x) do { } while (0)
#define pmd_free_fast(x) do { } while (0)
#define pmd_free(x) do { } while (0)
#define pgd_populate(mm, pmd, pte) BUG()
extern int do_check_pgt_cache(int, int);
/*
* TLB flushing:
*
* - flush_tlb() flushes the current mm struct TLBs
* - flush_tlb_all() flushes all processes TLBs
* - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(mm, start, end) flushes a range of pages
* - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*
* ..but the i386 has somewhat limited tlb flushing capabilities,
* and page-granular flushes are available only on i486 and up.
*/
#ifndef CONFIG_SMP
#define flush_tlb() __flush_tlb()
#define flush_tlb_all() __flush_tlb_all()
#define local_flush_tlb() __flush_tlb()
static inline void flush_tlb_mm(struct mm_struct *mm)
{
if (mm == current->active_mm) xen_tlb_flush();
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr)
{
if (vma->vm_mm == current->active_mm) xen_invlpg(addr);
}
static inline void flush_tlb_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
if (mm == current->active_mm) xen_tlb_flush();
}
#else
#error no kernel SMP support yet...
#include <asm/smp.h>
#define local_flush_tlb() \
__flush_tlb()
extern void flush_tlb_all(void);
extern void flush_tlb_current_task(void);
extern void flush_tlb_mm(struct mm_struct *);
extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
#define flush_tlb() flush_tlb_current_task()
static inline void flush_tlb_range(struct mm_struct * mm, unsigned long start, unsigned long end)
{
flush_tlb_mm(mm);
}
#define TLBSTATE_OK 1
#define TLBSTATE_LAZY 2
struct tlb_state
{
struct mm_struct *active_mm;
int state;
} ____cacheline_aligned;
extern struct tlb_state cpu_tlbstate[NR_CPUS];
#endif /* CONFIG_SMP */
static inline void flush_tlb_pgtables(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
/* i386 does not keep any page table caches in TLB */
}
/*
* NB. The 'domid' field should be zero if mapping I/O space (non RAM).
* Otherwise it identifies the owner of the memory that is being mapped.
*/
extern int direct_remap_area_pages(struct mm_struct *mm,
unsigned long address,
unsigned long machine_addr,
unsigned long size,
pgprot_t prot,
domid_t domid);
extern int __direct_remap_area_pages(struct mm_struct *mm,
unsigned long address,
unsigned long size,
mmu_update_t *v);
#endif /* _I386_PGALLOC_H */
@@ -1,97 +0,0 @@
#ifndef _I386_PGTABLE_2LEVEL_H
#define _I386_PGTABLE_2LEVEL_H
/*
* traditional i386 two-level paging structure:
*/
#define PGDIR_SHIFT 22
#define PTRS_PER_PGD 1024
/*
* the i386 is two-level, so we don't really have any
* PMD directory physically.
*/
#define PMD_SHIFT 22
#define PTRS_PER_PMD 1
#define PTRS_PER_PTE 1024
#define pte_ERROR(e) \
printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
#define pmd_ERROR(e) \
printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
/*
* The "pgd_xxx()" functions here are trivial for a folded two-level
* setup: the pgd is never bad, and a pmd always exists (as it's folded
* into the pgd entry)
*/
static inline int pgd_none(pgd_t pgd) { return 0; }
static inline int pgd_bad(pgd_t pgd) { return 0; }
static inline int pgd_present(pgd_t pgd) { return 1; }
#define pgd_clear(xp) do { } while (0)
/*
* Certain architectures need to do special things when PTEs
* within a page table are directly modified. Thus, the following
* hook is made available.
*/
#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
#define set_pte_atomic(pteptr, pteval) (*(pteptr) = pteval)
/*
* (pmds are folded into pgds so this doesnt get actually called,
* but the define is needed for a generic inline function.)
*/
#define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval))
#define set_pgd(pgdptr, pgdval) ((void)0)
#define pgd_page(pgd) \
((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
{
return (pmd_t *) dir;
}
#define ptep_get_and_clear(xp) __pte_ma(xchg(&(xp)->pte_low, 0))
#define pte_same(a, b) ((a).pte_low == (b).pte_low)
/*
* We detect special mappings in one of two ways:
* 1. If the MFN is an I/O page then Xen will set the m2p entry
* to be outside our maximum possible pseudophys range.
* 2. If the MFN belongs to a different domain then we will certainly
* not have MFN in our p2m table. Conversely, if the page is ours,
* then we'll have p2m(m2p(MFN))==MFN.
* If we detect a special mapping then it doesn't have a 'struct page'.
* We force !VALID_PAGE() by returning an out-of-range pointer.
*
* NB. These checks require that, for any MFN that is not in our reservation,
* there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
* we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
* Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
*
* NB2. When deliberately mapping foreign pages into the p2m table, you *must*
* use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
* require. In all the cases we care about, the high bit gets shifted out
* (e.g., phys_to_machine()) so behaviour there is correct.
*/
#define INVALID_P2M_ENTRY (~0U)
#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
#define pte_page(_pte) \
({ \
unsigned long mfn = (_pte).pte_low >> PAGE_SHIFT; \
unsigned long pfn = mfn_to_pfn(mfn); \
if ( (pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn) ) \
pfn = max_mapnr; /* specia: force !VALID_PAGE() */ \
&mem_map[pfn]; \
})
#define pte_none(x) (!(x).pte_low)
#define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
#endif /* _I386_PGTABLE_2LEVEL_H */
@@ -1,371 +0,0 @@
#ifndef _I386_PGTABLE_H
#define _I386_PGTABLE_H
#include <linux/config.h>
/*
* The Linux memory management assumes a three-level page table setup. On
* the i386, we use that, but "fold" the mid level into the top-level page
* table, so that we physically have the same two-level page table as the
* i386 mmu expects.
*
* This file contains the functions and defines necessary to modify and use
* the i386 page table tree.
*/
#ifndef __ASSEMBLY__
#include <asm/processor.h>
#include <asm/hypervisor.h>
#include <linux/threads.h>
#include <asm/fixmap.h>
#ifndef _I386_BITOPS_H
#include <asm/bitops.h>
#endif
#define swapper_pg_dir 0
extern void paging_init(void);
/* Caches aren't brain-dead on the intel. */
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_range(mm, start, end) do { } while (0)
#define flush_cache_page(vma, vmaddr) do { } while (0)
#define flush_page_to_ram(page) do { } while (0)
#define flush_dcache_page(page) do { } while (0)
#define flush_icache_range(start, end) do { } while (0)
#define flush_icache_page(vma,pg) do { } while (0)
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
extern unsigned long pgkern_mask;
#define __flush_tlb() xen_tlb_flush()
#define __flush_tlb_global() __flush_tlb()
#define __flush_tlb_all() __flush_tlb_global()
#define __flush_tlb_one(addr) xen_invlpg(addr)
#define __flush_tlb_single(addr) xen_invlpg(addr)
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
*/
extern unsigned long empty_zero_page[1024];
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
#endif /* !__ASSEMBLY__ */
/*
* The Linux x86 paging architecture is 'compile-time dual-mode', it
* implements both the traditional 2-level x86 page tables and the
* newer 3-level PAE-mode page tables.
*/
#ifndef __ASSEMBLY__
#if CONFIG_X86_PAE
# include <asm/pgtable-3level.h>
/*
* Need to initialise the X86 PAE caches
*/
extern void pgtable_cache_init(void);
#else
# include <asm/pgtable-2level.h>
/*
* No page table caches to initialise
*/
#define pgtable_cache_init() do { } while (0)
#endif
#endif
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
#define FIRST_USER_PGD_NR 0
#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
#define TWOLEVEL_PGDIR_SHIFT 22
#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
#define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
#ifndef __ASSEMBLY__
/* 4MB is just a nice "safety zone". Also, we align to a fresh pde. */
#define VMALLOC_OFFSET (4*1024*1024)
extern void * high_memory;
#define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \
~(VMALLOC_OFFSET-1))
#define VMALLOC_VMADDR(x) ((unsigned long)(x))
#if CONFIG_HIGHMEM
# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
#else
# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
#endif
#define _PAGE_BIT_PRESENT 0
#define _PAGE_BIT_RW 1
#define _PAGE_BIT_USER 2
#define _PAGE_BIT_PWT 3
#define _PAGE_BIT_PCD 4
#define _PAGE_BIT_ACCESSED 5
#define _PAGE_BIT_DIRTY 6
#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page, Pentium+, if present.. */
#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
#define _PAGE_PRESENT 0x001
#define _PAGE_RW 0x002
#define _PAGE_USER 0x004
#define _PAGE_PWT 0x008
#define _PAGE_PCD 0x010
#define _PAGE_ACCESSED 0x020
#define _PAGE_DIRTY 0x040
#define _PAGE_PSE 0x080 /* 4 MB (or 2MB) page, Pentium+, if present.. */
#define _PAGE_GLOBAL 0x100 /* Global TLB entry PPro+ */
#define _PAGE_PROTNONE 0x080 /* If not present */
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
#define __PAGE_KERNEL \
(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
#define __PAGE_KERNEL_NOCACHE \
(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED)
#define __PAGE_KERNEL_RO \
(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
#if 0
#define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL)
#else
#define MAKE_GLOBAL(x) __pgprot(x)
#endif
#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
/*
* The i386 can't do page protection for execute, and considers that
* the same are read. Also, write permissions imply read permissions.
* This is the closest we can get..
*/
#define __P000 PAGE_NONE
#define __P001 PAGE_READONLY
#define __P010 PAGE_COPY
#define __P011 PAGE_COPY
#define __P100 PAGE_READONLY
#define __P101 PAGE_READONLY
#define __P110 PAGE_COPY
#define __P111 PAGE_COPY
#define __S000 PAGE_NONE
#define __S001 PAGE_READONLY
#define __S010 PAGE_SHARED
#define __S011 PAGE_SHARED
#define __S100 PAGE_READONLY
#define __S101 PAGE_READONLY
#define __S110 PAGE_SHARED
#define __S111 PAGE_SHARED
#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
#define pte_clear(xp) do { set_pte(xp, __pte(0)); } while (0)
#define pmd_none(x) (!pmd_val(x))
/* pmd_present doesn't just test the _PAGE_PRESENT bit since wr.p.t.
can temporarily clear it. */
#define pmd_present(x) (pmd_val(x))
#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
*/
static inline int pte_read(pte_t pte) { return (pte).pte_low & _PAGE_USER; }
static inline int pte_exec(pte_t pte) { return (pte).pte_low & _PAGE_USER; }
static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; }
static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; }
static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; }
static inline pte_t pte_rdprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; }
static inline pte_t pte_exprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; }
static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; }
static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
static inline pte_t pte_mkexec(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; }
static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
static inline int ptep_test_and_clear_dirty(pte_t *ptep)
{
if (!pte_dirty(*ptep))
return 0;
return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
}
static inline int ptep_test_and_clear_young(pte_t *ptep)
{
if (!pte_young(*ptep))
return 0;
return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
}
static inline void ptep_set_wrprotect(pte_t *ptep)
{
if (pte_write(*ptep))
clear_bit(_PAGE_BIT_RW, &ptep->pte_low);
}
static inline void ptep_mkdirty(pte_t *ptep)
{
if (!pte_dirty(*ptep))
set_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
}
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
#define mk_pte(page, pgprot) __mk_pte((page) - mem_map, (pgprot))
/* This takes a physical page address that is used by the remapping functions */
#define mk_pte_phys(physpage, pgprot) __mk_pte((physpage) >> PAGE_SHIFT, pgprot)
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
pte.pte_low &= _PAGE_CHG_MASK;
pte.pte_low |= pgprot_val(newprot);
return pte;
}
#define page_pte(page) page_pte_prot(page, __pgprot(0))
#define pmd_page(pmd) \
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
/* to find an entry in a page-table-directory. */
#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
#define __pgd_offset(address) pgd_index(address)
#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
#define __pmd_offset(address) \
(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
/* Find an entry in the third-level page table.. */
#define __pte_offset(address) \
((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pte_offset(dir, address) ((pte_t *) pmd_page(*(dir)) + \
__pte_offset(address))
/*
* The i386 doesn't have any external MMU info: the kernel page
* tables contain all the necessary information.
*/
#define update_mmu_cache(vma,address,pte) do { } while (0)
/* Encode and de-code a swap entry */
#define SWP_TYPE(x) (((x).val >> 1) & 0x3f)
#define SWP_OFFSET(x) ((x).val >> 8)
#define SWP_ENTRY(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
#define pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low })
#define swp_entry_to_pte(x) ((pte_t) { (x).val })
struct page;
int change_page_attr(struct page *, int, pgprot_t prot);
static inline void __make_page_readonly(void *va)
{
pgd_t *pgd = pgd_offset_k((unsigned long)va);
pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
pte_t *pte = pte_offset(pmd, (unsigned long)va);
set_pte(pte, pte_wrprotect(*pte));
}
static inline void __make_page_writable(void *va)
{
pgd_t *pgd = pgd_offset_k((unsigned long)va);
pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
pte_t *pte = pte_offset(pmd, (unsigned long)va);
set_pte(pte, pte_mkwrite(*pte));
}
static inline void make_page_readonly(void *va)
{
pgd_t *pgd = pgd_offset_k((unsigned long)va);
pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
pte_t *pte = pte_offset(pmd, (unsigned long)va);
set_pte(pte, pte_wrprotect(*pte));
if ( (unsigned long)va >= VMALLOC_START )
__make_page_readonly(machine_to_virt(
*(unsigned long *)pte&PAGE_MASK));
}
static inline void make_page_writable(void *va)
{
pgd_t *pgd = pgd_offset_k((unsigned long)va);
pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
pte_t *pte = pte_offset(pmd, (unsigned long)va);
set_pte(pte, pte_mkwrite(*pte));
if ( (unsigned long)va >= VMALLOC_START )
__make_page_writable(machine_to_virt(
*(unsigned long *)pte&PAGE_MASK));
}
static inline void make_pages_readonly(void *va, unsigned int nr)
{
while ( nr-- != 0 )
{
make_page_readonly(va);
va = (void *)((unsigned long)va + PAGE_SIZE);
}
}
static inline void make_pages_writable(void *va, unsigned int nr)
{
while ( nr-- != 0 )
{
make_page_writable(va);
va = (void *)((unsigned long)va + PAGE_SIZE);
}
}
static inline unsigned long arbitrary_virt_to_machine(void *va)
{
pgd_t *pgd = pgd_offset_k((unsigned long)va);
pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
pte_t *pte = pte_offset(pmd, (unsigned long)va);
unsigned long pa = (*(unsigned long *)pte) & PAGE_MASK;
return pa | ((unsigned long)va & (PAGE_SIZE-1));
}
#endif /* !__ASSEMBLY__ */
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
#define PageSkip(page) (0)
#define kern_addr_valid(addr) (1)
#define io_remap_page_range remap_page_range
#endif /* _I386_PGTABLE_H */
@@ -1,483 +0,0 @@
/*
* include/asm-i386/processor.h
*
* Copyright (C) 1994 Linus Torvalds
*/
#ifndef __ASM_I386_PROCESSOR_H
#define __ASM_I386_PROCESSOR_H
#include <asm/vm86.h>
#include <asm/math_emu.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/types.h>
#include <asm/sigcontext.h>
#include <asm/cpufeature.h>
#include <linux/cache.h>
#include <linux/config.h>
#include <linux/threads.h>
/*
* Default implementation of macro that returns current
* instruction pointer ("program counter").
*/
#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
/*
* CPU type and hardware bug flags. Kept separately for each CPU.
* Members of this structure are referenced in head.S, so think twice
* before touching them. [mj]
*/
struct cpuinfo_x86 {
__u8 x86; /* CPU family */
__u8 x86_vendor; /* CPU vendor */
__u8 x86_model;
__u8 x86_mask;
char wp_works_ok; /* It doesn't on 386's */
char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */
char hard_math;
char rfu;
int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */
__u32 x86_capability[NCAPINTS];
char x86_vendor_id[16];
char x86_model_id[64];
int x86_cache_size; /* in KB - valid for CPUS which support this
call */
int fdiv_bug;
int f00f_bug;
int coma_bug;
unsigned long loops_per_jiffy;
unsigned long *pgd_quick;
unsigned long *pmd_quick;
unsigned long *pte_quick;
unsigned long pgtable_cache_sz;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
#define X86_VENDOR_INTEL 0
#define X86_VENDOR_CYRIX 1
#define X86_VENDOR_AMD 2
#define X86_VENDOR_UMC 3
#define X86_VENDOR_NEXGEN 4
#define X86_VENDOR_CENTAUR 5
#define X86_VENDOR_RISE 6
#define X86_VENDOR_TRANSMETA 7
#define X86_VENDOR_NSC 8
#define X86_VENDOR_SIS 9
#define X86_VENDOR_UNKNOWN 0xff
/*
* capabilities of CPUs
*/
extern struct cpuinfo_x86 boot_cpu_data;
extern struct tss_struct init_tss[NR_CPUS];
#ifdef CONFIG_SMP
extern struct cpuinfo_x86 cpu_data[];
#define current_cpu_data cpu_data[smp_processor_id()]
#else
#define cpu_data (&boot_cpu_data)
#define current_cpu_data boot_cpu_data
#endif
extern char ignore_irq13;
extern void identify_cpu(struct cpuinfo_x86 *);
extern void print_cpu_info(struct cpuinfo_x86 *);
/*
* EFLAGS bits
*/
#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
#define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
#define X86_EFLAGS_NT 0x00004000 /* Nested Task */
#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
#define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */
#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
/*
* Generic CPUID function
*/
static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
{
__asm__("cpuid"
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (op));
}
/*
* CPUID functions returning a single datum
*/
static inline unsigned int cpuid_eax(unsigned int op)
{
unsigned int eax;
__asm__("cpuid"
: "=a" (eax)
: "0" (op)
: "bx", "cx", "dx");
return eax;
}
static inline unsigned int cpuid_ebx(unsigned int op)
{
unsigned int eax, ebx;
__asm__("cpuid"
: "=a" (eax), "=b" (ebx)
: "0" (op)
: "cx", "dx" );
return ebx;
}
static inline unsigned int cpuid_ecx(unsigned int op)
{
unsigned int eax, ecx;
__asm__("cpuid"
: "=a" (eax), "=c" (ecx)
: "0" (op)
: "bx", "dx" );
return ecx;
}
static inline unsigned int cpuid_edx(unsigned int op)
{
unsigned int eax, edx;
__asm__("cpuid"
: "=a" (eax), "=d" (edx)
: "0" (op)
: "bx", "cx");
return edx;
}
/*
* Intel CPU features in CR4
*/
#define X86_CR4_VME 0x0001 /* enable vm86 extensions */
#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */
#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
#define X86_CR4_DE 0x0008 /* enable debugging extensions */
#define X86_CR4_PSE 0x0010 /* enable page size extensions */
#define X86_CR4_PAE 0x0020 /* enable physical address extensions */
#define X86_CR4_MCE 0x0040 /* Machine check enable */
#define X86_CR4_PGE 0x0080 /* enable global pages */
#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
#define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */
#define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
#define load_cr3(pgdir) \
asm volatile("movl %0,%%cr3": :"r" (__pa(pgdir)));
extern unsigned long mmu_cr4_features;
#include <asm/hypervisor.h>
static inline void set_in_cr4 (unsigned long mask)
{
BUG();
}
static inline void clear_in_cr4 (unsigned long mask)
{
BUG();
}
/*
* Cyrix CPU configuration register indexes
*/
#define CX86_CCR0 0xc0
#define CX86_CCR1 0xc1
#define CX86_CCR2 0xc2
#define CX86_CCR3 0xc3
#define CX86_CCR4 0xe8
#define CX86_CCR5 0xe9
#define CX86_CCR6 0xea
#define CX86_CCR7 0xeb
#define CX86_DIR0 0xfe
#define CX86_DIR1 0xff
#define CX86_ARR_BASE 0xc4
#define CX86_RCR_BASE 0xdc
/*
* Cyrix CPU indexed register access macros
*/
#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
#define setCx86(reg, data) do { \
outb((reg), 0x22); \
outb((data), 0x23); \
} while (0)
/*
* Bus types (default is ISA, but people can check others with these..)
*/
#ifdef CONFIG_EISA
extern int EISA_bus;
#else
#define EISA_bus (0)
#endif
extern int MCA_bus;
/* from system description table in BIOS. Mostly for MCA use, but
others may find it useful. */
extern unsigned int machine_id;
extern unsigned int machine_submodel_id;
extern unsigned int BIOS_revision;
extern unsigned int mca_pentium_flag;
/*
* User space process size: 3GB (default).
*/
#define TASK_SIZE (PAGE_OFFSET)
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
/*
* Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
*/
#define IO_BITMAP_SIZE 32
#define IO_BITMAP_BYTES (IO_BITMAP_SIZE * 4)
#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
#define INVALID_IO_BITMAP_OFFSET 0x8000
struct i387_fsave_struct {
long cwd;
long swd;
long twd;
long fip;
long fcs;
long foo;
long fos;
long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
long status; /* software status information */
};
struct i387_fxsave_struct {
unsigned short cwd;
unsigned short swd;
unsigned short twd;
unsigned short fop;
long fip;
long fcs;
long foo;
long fos;
long mxcsr;
long reserved;
long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
long padding[56];
} __attribute__ ((aligned (16)));
struct i387_soft_struct {
long cwd;
long swd;
long twd;
long fip;
long fcs;
long foo;
long fos;
long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
unsigned char ftop, changed, lookahead, no_update, rm, alimit;
struct info *info;
unsigned long entry_eip;
};
union i387_union {
struct i387_fsave_struct fsave;
struct i387_fxsave_struct fxsave;
struct i387_soft_struct soft;
};
typedef struct {
unsigned long seg;
} mm_segment_t;
struct tss_struct {
unsigned short back_link,__blh;
unsigned long esp0;
unsigned short ss0,__ss0h;
unsigned long esp1;
unsigned short ss1,__ss1h;
unsigned long esp2;
unsigned short ss2,__ss2h;
unsigned long __cr3;
unsigned long eip;
unsigned long eflags;
unsigned long eax,ecx,edx,ebx;
unsigned long esp;
unsigned long ebp;
unsigned long esi;
unsigned long edi;
unsigned short es, __esh;
unsigned short cs, __csh;
unsigned short ss, __ssh;
unsigned short ds, __dsh;
unsigned short fs, __fsh;
unsigned short gs, __gsh;
unsigned short ldt, __ldth;
unsigned short trace, bitmap;
unsigned long io_bitmap[IO_BITMAP_SIZE+1];
/*
* pads the TSS to be cacheline-aligned (size is 0x100)
*/
unsigned long __cacheline_filler[5];
};
struct thread_struct {
unsigned long esp0;
unsigned long eip;
unsigned long esp;
unsigned long fs;
unsigned long gs;
unsigned int io_pl;
/* Hardware debugging registers */
unsigned long debugreg[8]; /* %%db0-7 debug registers */
/* fault info */
unsigned long cr2, trap_no, error_code;
/* floating point info */
union i387_union i387;
/* virtual 86 mode info */
struct vm86_struct * vm86_info;
unsigned long screen_bitmap;
unsigned long v86flags, v86mask, saved_esp0;
};
#define INIT_THREAD { sizeof(init_stack) + (long) &init_stack, \
0, 0, 0, 0, 0, 0, {0}, 0, 0, 0, {{0}}, 0, 0, 0, 0, 0 }
#define INIT_TSS { \
0,0, /* back_link, __blh */ \
sizeof(init_stack) + (long) &init_stack, /* esp0 */ \
__KERNEL_DS, 0, /* ss0 */ \
0,0,0,0,0,0, /* stack1, stack2 */ \
0, /* cr3 */ \
0,0, /* eip,eflags */ \
0,0,0,0, /* eax,ecx,edx,ebx */ \
0,0,0,0, /* esp,ebp,esi,edi */ \
0,0,0,0,0,0, /* es,cs,ss */ \
0,0,0,0,0,0, /* ds,fs,gs */ \
0,0, /* ldt */ \
0, INVALID_IO_BITMAP_OFFSET, /* tace, bitmap */ \
{~0, } /* ioperm */ \
}
#define start_thread(regs, new_eip, new_esp) do { \
__asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \
set_fs(USER_DS); \
regs->xds = __USER_DS; \
regs->xes = __USER_DS; \
regs->xss = __USER_DS; \
regs->xcs = __USER_CS; \
regs->eip = new_eip; \
regs->esp = new_esp; \
} while (0)
/* Forward declaration, a strange C thing */
struct task_struct;
struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/*
* create a kernel thread without removing it from tasklists
*/
extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/* Copy and release all segment info associated with a VM
* Unusable due to lack of error handling, use {init_new,destroy}_context
* instead.
*/
static inline void copy_segments(struct task_struct *p, struct mm_struct * mm) { }
static inline void release_segments(struct mm_struct * mm) { }
/*
* Return saved PC of a blocked thread.
*/
static inline unsigned long thread_saved_pc(struct thread_struct *t)
{
return ((unsigned long *)t->esp)[3];
}
unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
#define THREAD_SIZE (2*PAGE_SIZE)
#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
#define free_task_struct(p) free_pages((unsigned long) (p), 1)
#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count)
#define init_task (init_task_union.task)
#define init_stack (init_task_union.stack)
struct microcode {
unsigned int hdrver;
unsigned int rev;
unsigned int date;
unsigned int sig;
unsigned int cksum;
unsigned int ldrver;
unsigned int pf;
unsigned int reserved[5];
unsigned int bits[500];
};
/* '6' because it used to be for P6 only (but now covers Pentium 4 as well) */
#define MICROCODE_IOCFREE _IO('6',0)
/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
static inline void rep_nop(void)
{
__asm__ __volatile__("rep;nop" ::: "memory");
}
#define cpu_relax() rep_nop()
/* Prefetch instructions for Pentium III and AMD Athlon */
#if defined(CONFIG_MPENTIUMIII) || defined (CONFIG_MPENTIUM4)
#define ARCH_HAS_PREFETCH
extern inline void prefetch(const void *x)
{
__asm__ __volatile__ ("prefetchnta (%0)" : : "r"(x));
}
#elif CONFIG_X86_USE_3DNOW
#define ARCH_HAS_PREFETCH
#define ARCH_HAS_PREFETCHW
#define ARCH_HAS_SPINLOCK_PREFETCH
extern inline void prefetch(const void *x)
{
__asm__ __volatile__ ("prefetch (%0)" : : "r"(x));
}
extern inline void prefetchw(const void *x)
{
__asm__ __volatile__ ("prefetchw (%0)" : : "r"(x));
}
#define spin_lock_prefetch(x) prefetchw(x)
#endif
#endif /* __ASM_I386_PROCESSOR_H */
@@ -1,20 +0,0 @@
/* Work-queue emulation over task queues. Pretty simple. */
#ifndef __QUEUES_H__
#define __QUEUES_H__
#include <linux/version.h>
#include <linux/list.h>
#include <linux/tqueue.h>
#define DECLARE_TQUEUE(_name, _fn, _arg) \
struct tq_struct _name = { LIST_HEAD_INIT((_name).list), 0, _fn, _arg }
#define DECLARE_WORK(_name, _fn, _arg) DECLARE_TQUEUE(_name, _fn, _arg)
#define work_struct tq_struct
#define INIT_WORK(_work, _fn, _arg) INIT_TQUEUE(_work, _fn, _arg)
#define schedule_work(_w) schedule_task(_w)
#endif /* __QUEUES_H__ */
@@ -1,15 +0,0 @@
#ifndef _ASM_SEGMENT_H
#define _ASM_SEGMENT_H
#ifndef __ASSEMBLY__
#include <linux/types.h>
#endif
#include <asm-xen/xen-public/xen.h>
#define __KERNEL_CS FLAT_RING1_CS
#define __KERNEL_DS FLAT_RING1_DS
#define __USER_CS FLAT_RING3_CS
#define __USER_DS FLAT_RING3_DS
#endif
-102
View File
@@ -1,102 +0,0 @@
#ifndef __ASM_SMP_H
#define __ASM_SMP_H
/*
* We need the APIC definitions automatically as part of 'smp.h'
*/
#ifndef __ASSEMBLY__
#include <linux/config.h>
#include <linux/threads.h>
#include <linux/ptrace.h>
#endif
#ifdef CONFIG_X86_LOCAL_APIC
#ifndef __ASSEMBLY__
#include <asm/bitops.h>
#include <asm/mpspec.h>
#ifdef CONFIG_X86_IO_APIC
#include <asm/io_apic.h>
#endif
#include <asm/apic.h>
#endif
#endif
#ifdef CONFIG_SMP
#ifndef __ASSEMBLY__
/*
* Private routines/data
*/
extern void smp_alloc_memory(void);
extern unsigned long phys_cpu_present_map;
extern unsigned long cpu_online_map;
extern volatile unsigned long smp_invalidate_needed;
extern int pic_mode;
extern int smp_num_siblings;
extern int cpu_sibling_map[];
extern void smp_flush_tlb(void);
extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
extern void fastcall smp_send_reschedule(int cpu);
extern void smp_invalidate_rcv(void); /* Process an NMI */
extern void (*mtrr_hook) (void);
extern void zap_low_mappings (void);
/*
* On x86 all CPUs are mapped 1:1 to the APIC space.
* This simplifies scheduling and IPI sending and
* compresses data structures.
*/
static inline int cpu_logical_map(int cpu)
{
return cpu;
}
static inline int cpu_number_map(int cpu)
{
return cpu;
}
/*
* Some lowlevel functions might want to know about
* the real APIC ID <-> CPU # mapping.
*/
#define MAX_APICID 256
extern volatile int cpu_to_physical_apicid[NR_CPUS];
extern volatile int physical_apicid_to_cpu[MAX_APICID];
extern volatile int cpu_to_logical_apicid[NR_CPUS];
extern volatile int logical_apicid_to_cpu[MAX_APICID];
/*
* General functions that each host system must provide.
*/
extern void smp_boot_cpus(void);
extern void smp_store_cpu_info(int id); /* Store per CPU info (like the initial udelay numbers */
/*
* This function is needed by all SMP systems. It must _always_ be valid
* from the initial startup. We map APIC_BASE very early in page_setup(),
* so this is correct in the x86 case.
*/
#define smp_processor_id() (current->processor)
#endif /* !__ASSEMBLY__ */
#define NO_PROC_ID 0xFF /* No processor magic marker */
/*
* This magic constant controls our willingness to transfer
* a process across CPUs. Such a transfer incurs misses on the L1
* cache, and on a P6 or P5 with multiple L2 caches L2 hits. My
* gut feeling is this will vary by board in value. For a board
* with separate L2 cache it probably depends also on the RSS, and
* for a board with shared L2 cache it ought to decay fast as other
* processes are run.
*/
#define PROC_CHANGE_PENALTY 15 /* Schedule penalty */
#endif
#endif
@@ -1,424 +0,0 @@
#ifndef __ASM_SYSTEM_H
#define __ASM_SYSTEM_H
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <asm/synch_bitops.h>
#include <asm/segment.h>
#include <asm/hypervisor.h>
#include <asm/evtchn.h>
#ifdef __KERNEL__
struct task_struct;
extern void FASTCALL(__switch_to(struct task_struct *prev,
struct task_struct *next));
#define prepare_to_switch() \
do { \
struct thread_struct *__t = &current->thread; \
__asm__ __volatile__ ( "movl %%fs,%0" : "=m" (*(int *)&__t->fs) ); \
__asm__ __volatile__ ( "movl %%gs,%0" : "=m" (*(int *)&__t->gs) ); \
} while (0)
#define switch_to(prev,next,last) do { \
asm volatile("pushl %%esi\n\t" \
"pushl %%edi\n\t" \
"pushl %%ebp\n\t" \
"movl %%esp,%0\n\t" /* save ESP */ \
"movl %3,%%esp\n\t" /* restore ESP */ \
"movl $1f,%1\n\t" /* save EIP */ \
"pushl %4\n\t" /* restore EIP */ \
"jmp __switch_to\n" \
"1:\t" \
"popl %%ebp\n\t" \
"popl %%edi\n\t" \
"popl %%esi\n\t" \
:"=m" (prev->thread.esp),"=m" (prev->thread.eip), \
"=b" (last) \
:"m" (next->thread.esp),"m" (next->thread.eip), \
"a" (prev), "d" (next), \
"b" (prev)); \
} while (0)
#define _set_base(addr,base) do { unsigned long __pr; \
__asm__ __volatile__ ("movw %%dx,%1\n\t" \
"rorl $16,%%edx\n\t" \
"movb %%dl,%2\n\t" \
"movb %%dh,%3" \
:"=&d" (__pr) \
:"m" (*((addr)+2)), \
"m" (*((addr)+4)), \
"m" (*((addr)+7)), \
"0" (base) \
); } while(0)
#define _set_limit(addr,limit) do { unsigned long __lr; \
__asm__ __volatile__ ("movw %%dx,%1\n\t" \
"rorl $16,%%edx\n\t" \
"movb %2,%%dh\n\t" \
"andb $0xf0,%%dh\n\t" \
"orb %%dh,%%dl\n\t" \
"movb %%dl,%2" \
:"=&d" (__lr) \
:"m" (*(addr)), \
"m" (*((addr)+6)), \
"0" (limit) \
); } while(0)
#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 )
static inline unsigned long _get_base(char * addr)
{
unsigned long __base;
__asm__("movb %3,%%dh\n\t"
"movb %2,%%dl\n\t"
"shll $16,%%edx\n\t"
"movw %1,%%dx"
:"=&d" (__base)
:"m" (*((addr)+2)),
"m" (*((addr)+4)),
"m" (*((addr)+7)));
return __base;
}
#define get_base(ldt) _get_base( ((char *)&(ldt)) )
/*
* Load a segment. Fall back on loading the zero
* segment if something goes wrong..
*/
#define loadsegment(seg,value) \
asm volatile("\n" \
"1:\t" \
"movl %0,%%" #seg "\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3:\t" \
"pushl $0\n\t" \
"popl %%" #seg "\n\t" \
"jmp 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n\t" \
".align 4\n\t" \
".long 1b,3b\n" \
".previous" \
: :"m" (*(unsigned int *)&(value)))
/* NB. 'clts' is done for us by Xen during virtual trap. */
#define clts() ((void)0)
#define stts() (HYPERVISOR_fpu_taskswitch(1))
#endif /* __KERNEL__ */
/**
* __ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*
* Taken from 2.6 for Xen.
*/
static inline unsigned long __ffs(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
:"rm" (word));
return word;
}
static inline unsigned long get_limit(unsigned long segment)
{
unsigned long __limit;
__asm__("lsll %1,%0"
:"=r" (__limit):"r" (segment));
return __limit+1;
}
#define nop() __asm__ __volatile__ ("nop")
#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))
/*
* The semantics of XCHGCMP8B are a bit strange, this is why
* there is a loop and the loading of %%eax and %%edx has to
* be inside. This inlines well in most cases, the cached
* cost is around ~38 cycles. (in the future we might want
* to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
* might have an implicit FPU-save as a cost, so it's not
* clear which path to go.)
*
* chmxchg8b must be used with the lock prefix here to allow
* the instruction to be executed atomically, see page 3-102
* of the instruction set reference 24319102.pdf. We need
* the reader side to see the coherent 64bit value.
*/
static inline void __set_64bit (unsigned long long * ptr,
unsigned int low, unsigned int high)
{
__asm__ __volatile__ (
"\n1:\t"
"movl (%0), %%eax\n\t"
"movl 4(%0), %%edx\n\t"
"lock cmpxchg8b (%0)\n\t"
"jnz 1b"
: /* no outputs */
: "D"(ptr),
"b"(low),
"c"(high)
: "ax","dx","memory");
}
static inline void __set_64bit_constant (unsigned long long *ptr,
unsigned long long value)
{
__set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
}
#define ll_low(x) *(((unsigned int*)&(x))+0)
#define ll_high(x) *(((unsigned int*)&(x))+1)
static inline void __set_64bit_var (unsigned long long *ptr,
unsigned long long value)
{
__set_64bit(ptr,ll_low(value), ll_high(value));
}
#define set_64bit(ptr,value) \
(__builtin_constant_p(value) ? \
__set_64bit_constant(ptr, value) : \
__set_64bit_var(ptr, value) )
#define _set_64bit(ptr,value) \
(__builtin_constant_p(value) ? \
__set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
__set_64bit(ptr, ll_low(value), ll_high(value)) )
/*
* Note: no "lock" prefix even on SMP: xchg always implies lock anyway
* Note 2: xchg has side effect, so that attribute volatile is necessary,
* but generally the primitive is invalid, *ptr is output argument. --ANK
*/
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
case 1:
__asm__ __volatile__("xchgb %b0,%1"
:"=q" (x)
:"m" (*__xg(ptr)), "0" (x)
:"memory");
break;
case 2:
__asm__ __volatile__("xchgw %w0,%1"
:"=r" (x)
:"m" (*__xg(ptr)), "0" (x)
:"memory");
break;
case 4:
__asm__ __volatile__("xchgl %0,%1"
:"=r" (x)
:"m" (*__xg(ptr)), "0" (x)
:"memory");
break;
}
return x;
}
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
* store NEW in MEM. Return the initial value in MEM. Success is
* indicated by comparing RETURN with OLD.
*/
#ifdef CONFIG_X86_CMPXCHG
#define __HAVE_ARCH_CMPXCHG 1
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
unsigned long prev;
switch (size) {
case 1:
__asm__ __volatile__("lock cmpxchgb %b1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 2:
__asm__ __volatile__("lock cmpxchgw %w1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 4:
__asm__ __volatile__("lock cmpxchgl %1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
}
return old;
}
#define cmpxchg(ptr,o,n)\
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
(unsigned long)(n),sizeof(*(ptr))))
#else
/* Compiling for a 386 proper. Is it worth implementing via cli/sti? */
#endif
/*
* Force strict CPU ordering.
* And yes, this is required on UP too when we're talking
* to devices.
*
* For now, "wmb()" doesn't actually do anything, as all
* Intel CPU's follow what Intel calls a *Processor Order*,
* in which all writes are seen in the program order even
* outside the CPU.
*
* I expect future Intel CPU's to have a weaker ordering,
* but I'd also expect them to finally get their act together
* and add some real memory barriers if so.
*
* Some non intel clones support out of order store. wmb() ceases to be a
* nop for these.
*/
#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
#define rmb() mb()
#ifdef CONFIG_X86_OOSTORE
#define wmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
#else
#define wmb() __asm__ __volatile__ ("": : :"memory")
#endif
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
#define smp_wmb() wmb()
#define set_mb(var, value) do { xchg(&var, value); } while (0)
#else
#define smp_mb() barrier()
#define smp_rmb() barrier()
#define smp_wmb() barrier()
#define set_mb(var, value) do { var = value; barrier(); } while (0)
#endif
#define set_wmb(var, value) do { var = value; wmb(); } while (0)
#define safe_halt() ((void)0)
/*
* The use of 'barrier' in the following reflects their use as local-lock
* operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
* critical operations are executed. All critical operatiosn must complete
* /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
* includes these barriers, for example.
*/
#define __cli() \
do { \
HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask = 1; \
barrier(); \
} while (0)
#define __sti() \
do { \
shared_info_t *_shared = HYPERVISOR_shared_info; \
barrier(); \
_shared->vcpu_data[0].evtchn_upcall_mask = 0; \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) ) \
force_evtchn_callback(); \
} while (0)
#define __save_flags(x) \
do { \
(x) = HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask; \
} while (0)
#define __restore_flags(x) \
do { \
shared_info_t *_shared = HYPERVISOR_shared_info; \
barrier(); \
if ( (_shared->vcpu_data[0].evtchn_upcall_mask = x) == 0 ) { \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) ) \
force_evtchn_callback(); \
} \
} while (0)
#define __save_and_cli(x) \
do { \
(x) = HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask; \
HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask = 1; \
barrier(); \
} while (0)
#define __save_and_sti(x) \
do { \
shared_info_t *_shared = HYPERVISOR_shared_info; \
barrier(); \
(x) = _shared->vcpu_data[0].evtchn_upcall_mask; \
_shared->vcpu_data[0].evtchn_upcall_mask = 0; \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) ) \
force_evtchn_callback(); \
} while (0)
#define local_irq_save(x) __save_and_cli(x)
#define local_irq_set(x) __save_and_sti(x)
#define local_irq_restore(x) __restore_flags(x)
#define local_irq_disable() __cli()
#define local_irq_enable() __sti()
#ifdef CONFIG_SMP
#error no SMP
extern void __global_cli(void);
extern void __global_sti(void);
extern unsigned long __global_save_flags(void);
extern void __global_restore_flags(unsigned long);
#define cli() __global_cli()
#define sti() __global_sti()
#define save_flags(x) ((x)=__global_save_flags())
#define restore_flags(x) __global_restore_flags(x)
#define save_and_cli(x) do { save_flags(x); cli(); } while(0);
#define save_and_sti(x) do { save_flags(x); sti(); } while(0);
#else
#define cli() __cli()
#define sti() __sti()
#define save_flags(x) __save_flags(x)
#define restore_flags(x) __restore_flags(x)
#define save_and_cli(x) __save_and_cli(x)
#define save_and_sti(x) __save_and_sti(x)
#endif
/*
* disable hlt during certain critical i/o operations
*/
#define HAVE_DISABLE_HLT
void disable_hlt(void);
void enable_hlt(void);
extern unsigned long dmi_broken;
extern int is_sony_vaio_laptop;
#define BROKEN_ACPI_Sx 0x0001
#define BROKEN_INIT_AFTER_S1 0x0002
#define BROKEN_PNP_BIOS 0x0004
#endif
@@ -1,42 +0,0 @@
/*
* Access to VGA videoram
*
* (c) 1998 Martin Mares <mj@ucw.cz>
*/
#ifndef _LINUX_ASM_VGA_H_
#define _LINUX_ASM_VGA_H_
#include <asm/io.h>
extern unsigned char *vgacon_mmap;
static unsigned long VGA_MAP_MEM(unsigned long x)
{
if( vgacon_mmap == NULL )
{
/* This is our first time in this function. This whole thing
is a rather grim hack. We know we're going to get asked
to map a 32KB region between 0xb0000 and 0xb8000 because
that's what VGAs are. We used the boot time permanent
fixed map region, and map it to machine pages.
*/
if( x != 0xb8000 )
panic("Argghh! VGA Console is weird. 1:%08lx\n",x);
vgacon_mmap = (unsigned char*) bt_ioremap( 0xa0000, 128*1024 );
return (unsigned long) (vgacon_mmap+x-0xa0000);
}
else
{
if( x != 0xc0000 && x != 0xa0000 ) /* vidmem_end or charmap fonts */
panic("Argghh! VGA Console is weird. 2:%08lx\n",x);
return (unsigned long) (vgacon_mmap+x-0xa0000);
}
return 0;
}
static inline unsigned char vga_readb(unsigned char * x) { return (*(x)); }
static inline void vga_writeb(unsigned char x, unsigned char *y) { *(y) = (x); }
#endif
-879
View File
@@ -1,879 +0,0 @@
/*
* include/asm-i386/xor.h
*
* Optimized RAID-5 checksumming functions for MMX and SSE.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example /usr/src/linux/COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* High-speed RAID5 checksumming functions utilizing MMX instructions.
* Copyright (C) 1998 Ingo Molnar.
*/
#define FPU_SAVE \
do { \
if (!(current->flags & PF_USEDFPU)) \
clts(); \
__asm__ __volatile__ ("fsave %0; fwait": "=m"(fpu_save[0])); \
} while (0)
#define FPU_RESTORE \
do { \
__asm__ __volatile__ ("frstor %0": : "m"(fpu_save[0])); \
if (!(current->flags & PF_USEDFPU)) \
stts(); \
} while (0)
#define LD(x,y) " movq 8*("#x")(%1), %%mm"#y" ;\n"
#define ST(x,y) " movq %%mm"#y", 8*("#x")(%1) ;\n"
#define XO1(x,y) " pxor 8*("#x")(%2), %%mm"#y" ;\n"
#define XO2(x,y) " pxor 8*("#x")(%3), %%mm"#y" ;\n"
#define XO3(x,y) " pxor 8*("#x")(%4), %%mm"#y" ;\n"
#define XO4(x,y) " pxor 8*("#x")(%5), %%mm"#y" ;\n"
static void
xor_pII_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
{
unsigned long lines = bytes >> 7;
char fpu_save[108];
FPU_SAVE;
__asm__ __volatile__ (
#undef BLOCK
#define BLOCK(i) \
LD(i,0) \
LD(i+1,1) \
LD(i+2,2) \
LD(i+3,3) \
XO1(i,0) \
ST(i,0) \
XO1(i+1,1) \
ST(i+1,1) \
XO1(i+2,2) \
ST(i+2,2) \
XO1(i+3,3) \
ST(i+3,3)
" .align 32 ;\n"
" 1: ;\n"
BLOCK(0)
BLOCK(4)
BLOCK(8)
BLOCK(12)
" addl $128, %1 ;\n"
" addl $128, %2 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r" (p2)
:
: "memory");
FPU_RESTORE;
}
static void
xor_pII_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3)
{
unsigned long lines = bytes >> 7;
char fpu_save[108];
FPU_SAVE;
__asm__ __volatile__ (
#undef BLOCK
#define BLOCK(i) \
LD(i,0) \
LD(i+1,1) \
LD(i+2,2) \
LD(i+3,3) \
XO1(i,0) \
XO1(i+1,1) \
XO1(i+2,2) \
XO1(i+3,3) \
XO2(i,0) \
ST(i,0) \
XO2(i+1,1) \
ST(i+1,1) \
XO2(i+2,2) \
ST(i+2,2) \
XO2(i+3,3) \
ST(i+3,3)
" .align 32 ;\n"
" 1: ;\n"
BLOCK(0)
BLOCK(4)
BLOCK(8)
BLOCK(12)
" addl $128, %1 ;\n"
" addl $128, %2 ;\n"
" addl $128, %3 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r" (p2), "+r" (p3)
:
: "memory");
FPU_RESTORE;
}
static void
xor_pII_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4)
{
unsigned long lines = bytes >> 7;
char fpu_save[108];
FPU_SAVE;
__asm__ __volatile__ (
#undef BLOCK
#define BLOCK(i) \
LD(i,0) \
LD(i+1,1) \
LD(i+2,2) \
LD(i+3,3) \
XO1(i,0) \
XO1(i+1,1) \
XO1(i+2,2) \
XO1(i+3,3) \
XO2(i,0) \
XO2(i+1,1) \
XO2(i+2,2) \
XO2(i+3,3) \
XO3(i,0) \
ST(i,0) \
XO3(i+1,1) \
ST(i+1,1) \
XO3(i+2,2) \
ST(i+2,2) \
XO3(i+3,3) \
ST(i+3,3)
" .align 32 ;\n"
" 1: ;\n"
BLOCK(0)
BLOCK(4)
BLOCK(8)
BLOCK(12)
" addl $128, %1 ;\n"
" addl $128, %2 ;\n"
" addl $128, %3 ;\n"
" addl $128, %4 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4)
:
: "memory");
FPU_RESTORE;
}
static void
xor_pII_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4, unsigned long *p5)
{
unsigned long lines = bytes >> 7;
char fpu_save[108];
FPU_SAVE;
/* need to save/restore p4/p5 manually otherwise gcc's 10 argument
limit gets exceeded (+ counts as two arguments) */
__asm__ __volatile__ (
" pushl %4\n"
" pushl %5\n"
#undef BLOCK
#define BLOCK(i) \
LD(i,0) \
LD(i+1,1) \
LD(i+2,2) \
LD(i+3,3) \
XO1(i,0) \
XO1(i+1,1) \
XO1(i+2,2) \
XO1(i+3,3) \
XO2(i,0) \
XO2(i+1,1) \
XO2(i+2,2) \
XO2(i+3,3) \
XO3(i,0) \
XO3(i+1,1) \
XO3(i+2,2) \
XO3(i+3,3) \
XO4(i,0) \
ST(i,0) \
XO4(i+1,1) \
ST(i+1,1) \
XO4(i+2,2) \
ST(i+2,2) \
XO4(i+3,3) \
ST(i+3,3)
" .align 32 ;\n"
" 1: ;\n"
BLOCK(0)
BLOCK(4)
BLOCK(8)
BLOCK(12)
" addl $128, %1 ;\n"
" addl $128, %2 ;\n"
" addl $128, %3 ;\n"
" addl $128, %4 ;\n"
" addl $128, %5 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
" popl %5\n"
" popl %4\n"
: "+r" (lines),
"+r" (p1), "+r" (p2), "+r" (p3)
: "r" (p4), "r" (p5)
: "memory");
FPU_RESTORE;
}
#undef LD
#undef XO1
#undef XO2
#undef XO3
#undef XO4
#undef ST
#undef BLOCK
static void
xor_p5_mmx_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
{
unsigned long lines = bytes >> 6;
char fpu_save[108];
FPU_SAVE;
__asm__ __volatile__ (
" .align 32 ;\n"
" 1: ;\n"
" movq (%1), %%mm0 ;\n"
" movq 8(%1), %%mm1 ;\n"
" pxor (%2), %%mm0 ;\n"
" movq 16(%1), %%mm2 ;\n"
" movq %%mm0, (%1) ;\n"
" pxor 8(%2), %%mm1 ;\n"
" movq 24(%1), %%mm3 ;\n"
" movq %%mm1, 8(%1) ;\n"
" pxor 16(%2), %%mm2 ;\n"
" movq 32(%1), %%mm4 ;\n"
" movq %%mm2, 16(%1) ;\n"
" pxor 24(%2), %%mm3 ;\n"
" movq 40(%1), %%mm5 ;\n"
" movq %%mm3, 24(%1) ;\n"
" pxor 32(%2), %%mm4 ;\n"
" movq 48(%1), %%mm6 ;\n"
" movq %%mm4, 32(%1) ;\n"
" pxor 40(%2), %%mm5 ;\n"
" movq 56(%1), %%mm7 ;\n"
" movq %%mm5, 40(%1) ;\n"
" pxor 48(%2), %%mm6 ;\n"
" pxor 56(%2), %%mm7 ;\n"
" movq %%mm6, 48(%1) ;\n"
" movq %%mm7, 56(%1) ;\n"
" addl $64, %1 ;\n"
" addl $64, %2 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r" (p2)
:
: "memory");
FPU_RESTORE;
}
static void
xor_p5_mmx_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3)
{
unsigned long lines = bytes >> 6;
char fpu_save[108];
FPU_SAVE;
__asm__ __volatile__ (
" .align 32,0x90 ;\n"
" 1: ;\n"
" movq (%1), %%mm0 ;\n"
" movq 8(%1), %%mm1 ;\n"
" pxor (%2), %%mm0 ;\n"
" movq 16(%1), %%mm2 ;\n"
" pxor 8(%2), %%mm1 ;\n"
" pxor (%3), %%mm0 ;\n"
" pxor 16(%2), %%mm2 ;\n"
" movq %%mm0, (%1) ;\n"
" pxor 8(%3), %%mm1 ;\n"
" pxor 16(%3), %%mm2 ;\n"
" movq 24(%1), %%mm3 ;\n"
" movq %%mm1, 8(%1) ;\n"
" movq 32(%1), %%mm4 ;\n"
" movq 40(%1), %%mm5 ;\n"
" pxor 24(%2), %%mm3 ;\n"
" movq %%mm2, 16(%1) ;\n"
" pxor 32(%2), %%mm4 ;\n"
" pxor 24(%3), %%mm3 ;\n"
" pxor 40(%2), %%mm5 ;\n"
" movq %%mm3, 24(%1) ;\n"
" pxor 32(%3), %%mm4 ;\n"
" pxor 40(%3), %%mm5 ;\n"
" movq 48(%1), %%mm6 ;\n"
" movq %%mm4, 32(%1) ;\n"
" movq 56(%1), %%mm7 ;\n"
" pxor 48(%2), %%mm6 ;\n"
" movq %%mm5, 40(%1) ;\n"
" pxor 56(%2), %%mm7 ;\n"
" pxor 48(%3), %%mm6 ;\n"
" pxor 56(%3), %%mm7 ;\n"
" movq %%mm6, 48(%1) ;\n"
" movq %%mm7, 56(%1) ;\n"
" addl $64, %1 ;\n"
" addl $64, %2 ;\n"
" addl $64, %3 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r" (p2), "+r" (p3)
:
: "memory" );
FPU_RESTORE;
}
static void
xor_p5_mmx_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4)
{
unsigned long lines = bytes >> 6;
char fpu_save[108];
FPU_SAVE;
__asm__ __volatile__ (
" .align 32,0x90 ;\n"
" 1: ;\n"
" movq (%1), %%mm0 ;\n"
" movq 8(%1), %%mm1 ;\n"
" pxor (%2), %%mm0 ;\n"
" movq 16(%1), %%mm2 ;\n"
" pxor 8(%2), %%mm1 ;\n"
" pxor (%3), %%mm0 ;\n"
" pxor 16(%2), %%mm2 ;\n"
" pxor 8(%3), %%mm1 ;\n"
" pxor (%4), %%mm0 ;\n"
" movq 24(%1), %%mm3 ;\n"
" pxor 16(%3), %%mm2 ;\n"
" pxor 8(%4), %%mm1 ;\n"
" movq %%mm0, (%1) ;\n"
" movq 32(%1), %%mm4 ;\n"
" pxor 24(%2), %%mm3 ;\n"
" pxor 16(%4), %%mm2 ;\n"
" movq %%mm1, 8(%1) ;\n"
" movq 40(%1), %%mm5 ;\n"
" pxor 32(%2), %%mm4 ;\n"
" pxor 24(%3), %%mm3 ;\n"
" movq %%mm2, 16(%1) ;\n"
" pxor 40(%2), %%mm5 ;\n"
" pxor 32(%3), %%mm4 ;\n"
" pxor 24(%4), %%mm3 ;\n"
" movq %%mm3, 24(%1) ;\n"
" movq 56(%1), %%mm7 ;\n"
" movq 48(%1), %%mm6 ;\n"
" pxor 40(%3), %%mm5 ;\n"
" pxor 32(%4), %%mm4 ;\n"
" pxor 48(%2), %%mm6 ;\n"
" movq %%mm4, 32(%1) ;\n"
" pxor 56(%2), %%mm7 ;\n"
" pxor 40(%4), %%mm5 ;\n"
" pxor 48(%3), %%mm6 ;\n"
" pxor 56(%3), %%mm7 ;\n"
" movq %%mm5, 40(%1) ;\n"
" pxor 48(%4), %%mm6 ;\n"
" pxor 56(%4), %%mm7 ;\n"
" movq %%mm6, 48(%1) ;\n"
" movq %%mm7, 56(%1) ;\n"
" addl $64, %1 ;\n"
" addl $64, %2 ;\n"
" addl $64, %3 ;\n"
" addl $64, %4 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4)
:
: "memory");
FPU_RESTORE;
}
static void
xor_p5_mmx_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4, unsigned long *p5)
{
unsigned long lines = bytes >> 6;
char fpu_save[108];
FPU_SAVE;
/* need to save p4/p5 manually to not exceed gcc's 10 argument limit */
__asm__ __volatile__ (
" pushl %4\n"
" pushl %5\n"
" .align 32,0x90 ;\n"
" 1: ;\n"
" movq (%1), %%mm0 ;\n"
" movq 8(%1), %%mm1 ;\n"
" pxor (%2), %%mm0 ;\n"
" pxor 8(%2), %%mm1 ;\n"
" movq 16(%1), %%mm2 ;\n"
" pxor (%3), %%mm0 ;\n"
" pxor 8(%3), %%mm1 ;\n"
" pxor 16(%2), %%mm2 ;\n"
" pxor (%4), %%mm0 ;\n"
" pxor 8(%4), %%mm1 ;\n"
" pxor 16(%3), %%mm2 ;\n"
" movq 24(%1), %%mm3 ;\n"
" pxor (%5), %%mm0 ;\n"
" pxor 8(%5), %%mm1 ;\n"
" movq %%mm0, (%1) ;\n"
" pxor 16(%4), %%mm2 ;\n"
" pxor 24(%2), %%mm3 ;\n"
" movq %%mm1, 8(%1) ;\n"
" pxor 16(%5), %%mm2 ;\n"
" pxor 24(%3), %%mm3 ;\n"
" movq 32(%1), %%mm4 ;\n"
" movq %%mm2, 16(%1) ;\n"
" pxor 24(%4), %%mm3 ;\n"
" pxor 32(%2), %%mm4 ;\n"
" movq 40(%1), %%mm5 ;\n"
" pxor 24(%5), %%mm3 ;\n"
" pxor 32(%3), %%mm4 ;\n"
" pxor 40(%2), %%mm5 ;\n"
" movq %%mm3, 24(%1) ;\n"
" pxor 32(%4), %%mm4 ;\n"
" pxor 40(%3), %%mm5 ;\n"
" movq 48(%1), %%mm6 ;\n"
" movq 56(%1), %%mm7 ;\n"
" pxor 32(%5), %%mm4 ;\n"
" pxor 40(%4), %%mm5 ;\n"
" pxor 48(%2), %%mm6 ;\n"
" pxor 56(%2), %%mm7 ;\n"
" movq %%mm4, 32(%1) ;\n"
" pxor 48(%3), %%mm6 ;\n"
" pxor 56(%3), %%mm7 ;\n"
" pxor 40(%5), %%mm5 ;\n"
" pxor 48(%4), %%mm6 ;\n"
" pxor 56(%4), %%mm7 ;\n"
" movq %%mm5, 40(%1) ;\n"
" pxor 48(%5), %%mm6 ;\n"
" pxor 56(%5), %%mm7 ;\n"
" movq %%mm6, 48(%1) ;\n"
" movq %%mm7, 56(%1) ;\n"
" addl $64, %1 ;\n"
" addl $64, %2 ;\n"
" addl $64, %3 ;\n"
" addl $64, %4 ;\n"
" addl $64, %5 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
" popl %5\n"
" popl %4\n"
: "+g" (lines),
"+r" (p1), "+r" (p2), "+r" (p3)
: "r" (p4), "r" (p5)
: "memory");
FPU_RESTORE;
}
static struct xor_block_template xor_block_pII_mmx = {
name: "pII_mmx",
do_2: xor_pII_mmx_2,
do_3: xor_pII_mmx_3,
do_4: xor_pII_mmx_4,
do_5: xor_pII_mmx_5,
};
static struct xor_block_template xor_block_p5_mmx = {
name: "p5_mmx",
do_2: xor_p5_mmx_2,
do_3: xor_p5_mmx_3,
do_4: xor_p5_mmx_4,
do_5: xor_p5_mmx_5,
};
#undef FPU_SAVE
#undef FPU_RESTORE
/*
* Cache avoiding checksumming functions utilizing KNI instructions
* Copyright (C) 1999 Zach Brown (with obvious credit due Ingo)
*/
#define XMMS_SAVE \
if (!(current->flags & PF_USEDFPU)) \
clts(); \
__asm__ __volatile__ ( \
"movups %%xmm0,(%1) ;\n\t" \
"movups %%xmm1,0x10(%1) ;\n\t" \
"movups %%xmm2,0x20(%1) ;\n\t" \
"movups %%xmm3,0x30(%1) ;\n\t" \
: "=&r" (cr0) \
: "r" (xmm_save) \
: "memory")
#define XMMS_RESTORE \
__asm__ __volatile__ ( \
"sfence ;\n\t" \
"movups (%1),%%xmm0 ;\n\t" \
"movups 0x10(%1),%%xmm1 ;\n\t" \
"movups 0x20(%1),%%xmm2 ;\n\t" \
"movups 0x30(%1),%%xmm3 ;\n\t" \
: \
: "r" (cr0), "r" (xmm_save) \
: "memory"); \
if (!(current->flags & PF_USEDFPU)) \
stts()
#define ALIGN16 __attribute__((aligned(16)))
#define OFFS(x) "16*("#x")"
#define PF_OFFS(x) "256+16*("#x")"
#define PF0(x) " prefetchnta "PF_OFFS(x)"(%1) ;\n"
#define LD(x,y) " movaps "OFFS(x)"(%1), %%xmm"#y" ;\n"
#define ST(x,y) " movaps %%xmm"#y", "OFFS(x)"(%1) ;\n"
#define PF1(x) " prefetchnta "PF_OFFS(x)"(%2) ;\n"
#define PF2(x) " prefetchnta "PF_OFFS(x)"(%3) ;\n"
#define PF3(x) " prefetchnta "PF_OFFS(x)"(%4) ;\n"
#define PF4(x) " prefetchnta "PF_OFFS(x)"(%5) ;\n"
#define PF5(x) " prefetchnta "PF_OFFS(x)"(%6) ;\n"
#define XO1(x,y) " xorps "OFFS(x)"(%2), %%xmm"#y" ;\n"
#define XO2(x,y) " xorps "OFFS(x)"(%3), %%xmm"#y" ;\n"
#define XO3(x,y) " xorps "OFFS(x)"(%4), %%xmm"#y" ;\n"
#define XO4(x,y) " xorps "OFFS(x)"(%5), %%xmm"#y" ;\n"
#define XO5(x,y) " xorps "OFFS(x)"(%6), %%xmm"#y" ;\n"
static void
xor_sse_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
{
unsigned long lines = bytes >> 8;
char xmm_save[16*4] ALIGN16;
int cr0;
XMMS_SAVE;
__asm__ __volatile__ (
#undef BLOCK
#define BLOCK(i) \
LD(i,0) \
LD(i+1,1) \
PF1(i) \
PF1(i+2) \
LD(i+2,2) \
LD(i+3,3) \
PF0(i+4) \
PF0(i+6) \
XO1(i,0) \
XO1(i+1,1) \
XO1(i+2,2) \
XO1(i+3,3) \
ST(i,0) \
ST(i+1,1) \
ST(i+2,2) \
ST(i+3,3) \
PF0(0)
PF0(2)
" .align 32 ;\n"
" 1: ;\n"
BLOCK(0)
BLOCK(4)
BLOCK(8)
BLOCK(12)
" addl $256, %1 ;\n"
" addl $256, %2 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r" (p2)
:
: "memory");
XMMS_RESTORE;
}
static void
xor_sse_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3)
{
unsigned long lines = bytes >> 8;
char xmm_save[16*4] ALIGN16;
int cr0;
XMMS_SAVE;
__asm__ __volatile__ (
#undef BLOCK
#define BLOCK(i) \
PF1(i) \
PF1(i+2) \
LD(i,0) \
LD(i+1,1) \
LD(i+2,2) \
LD(i+3,3) \
PF2(i) \
PF2(i+2) \
PF0(i+4) \
PF0(i+6) \
XO1(i,0) \
XO1(i+1,1) \
XO1(i+2,2) \
XO1(i+3,3) \
XO2(i,0) \
XO2(i+1,1) \
XO2(i+2,2) \
XO2(i+3,3) \
ST(i,0) \
ST(i+1,1) \
ST(i+2,2) \
ST(i+3,3) \
PF0(0)
PF0(2)
" .align 32 ;\n"
" 1: ;\n"
BLOCK(0)
BLOCK(4)
BLOCK(8)
BLOCK(12)
" addl $256, %1 ;\n"
" addl $256, %2 ;\n"
" addl $256, %3 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r"(p2), "+r"(p3)
:
: "memory" );
XMMS_RESTORE;
}
static void
xor_sse_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4)
{
unsigned long lines = bytes >> 8;
char xmm_save[16*4] ALIGN16;
int cr0;
XMMS_SAVE;
__asm__ __volatile__ (
#undef BLOCK
#define BLOCK(i) \
PF1(i) \
PF1(i+2) \
LD(i,0) \
LD(i+1,1) \
LD(i+2,2) \
LD(i+3,3) \
PF2(i) \
PF2(i+2) \
XO1(i,0) \
XO1(i+1,1) \
XO1(i+2,2) \
XO1(i+3,3) \
PF3(i) \
PF3(i+2) \
PF0(i+4) \
PF0(i+6) \
XO2(i,0) \
XO2(i+1,1) \
XO2(i+2,2) \
XO2(i+3,3) \
XO3(i,0) \
XO3(i+1,1) \
XO3(i+2,2) \
XO3(i+3,3) \
ST(i,0) \
ST(i+1,1) \
ST(i+2,2) \
ST(i+3,3) \
PF0(0)
PF0(2)
" .align 32 ;\n"
" 1: ;\n"
BLOCK(0)
BLOCK(4)
BLOCK(8)
BLOCK(12)
" addl $256, %1 ;\n"
" addl $256, %2 ;\n"
" addl $256, %3 ;\n"
" addl $256, %4 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
: "+r" (lines),
"+r" (p1), "+r" (p2), "+r" (p3), "+r" (p4)
:
: "memory" );
XMMS_RESTORE;
}
static void
xor_sse_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4, unsigned long *p5)
{
unsigned long lines = bytes >> 8;
char xmm_save[16*4] ALIGN16;
int cr0;
XMMS_SAVE;
/* need to save p4/p5 manually to not exceed gcc's 10 argument limit */
__asm__ __volatile__ (
" pushl %4\n"
" pushl %5\n"
#undef BLOCK
#define BLOCK(i) \
PF1(i) \
PF1(i+2) \
LD(i,0) \
LD(i+1,1) \
LD(i+2,2) \
LD(i+3,3) \
PF2(i) \
PF2(i+2) \
XO1(i,0) \
XO1(i+1,1) \
XO1(i+2,2) \
XO1(i+3,3) \
PF3(i) \
PF3(i+2) \
XO2(i,0) \
XO2(i+1,1) \
XO2(i+2,2) \
XO2(i+3,3) \
PF4(i) \
PF4(i+2) \
PF0(i+4) \
PF0(i+6) \
XO3(i,0) \
XO3(i+1,1) \
XO3(i+2,2) \
XO3(i+3,3) \
XO4(i,0) \
XO4(i+1,1) \
XO4(i+2,2) \
XO4(i+3,3) \
ST(i,0) \
ST(i+1,1) \
ST(i+2,2) \
ST(i+3,3) \
PF0(0)
PF0(2)
" .align 32 ;\n"
" 1: ;\n"
BLOCK(0)
BLOCK(4)
BLOCK(8)
BLOCK(12)
" addl $256, %1 ;\n"
" addl $256, %2 ;\n"
" addl $256, %3 ;\n"
" addl $256, %4 ;\n"
" addl $256, %5 ;\n"
" decl %0 ;\n"
" jnz 1b ;\n"
" popl %5\n"
" popl %4\n"
: "+r" (lines),
"+r" (p1), "+r" (p2), "+r" (p3)
: "r" (p4), "r" (p5)
: "memory");
XMMS_RESTORE;
}
static struct xor_block_template xor_block_pIII_sse = {
name: "pIII_sse",
do_2: xor_sse_2,
do_3: xor_sse_3,
do_4: xor_sse_4,
do_5: xor_sse_5,
};
/* Also try the generic routines. */
#include <asm-generic/xor.h>
#undef XOR_TRY_TEMPLATES
#define XOR_TRY_TEMPLATES \
do { \
xor_speed(&xor_block_8regs); \
xor_speed(&xor_block_32regs); \
if (cpu_has_xmm) \
xor_speed(&xor_block_pIII_sse); \
if (md_cpu_has_mmx()) { \
xor_speed(&xor_block_pII_mmx); \
xor_speed(&xor_block_p5_mmx); \
} \
} while (0)
/* We force the use of the SSE xor block because it can write around L2.
We may also be able to load into the L1 only depending on how the cpu
deals with a load to a line that is being prefetched. */
#define XOR_SELECT_TEMPLATE(FASTEST) \
(cpu_has_xmm ? &xor_block_pIII_sse : FASTEST)
-409
View File
@@ -1,409 +0,0 @@
#ifndef _BLK_H
#define _BLK_H
#include <linux/blkdev.h>
#include <linux/locks.h>
#include <linux/config.h>
#include <linux/spinlock.h>
/*
* Spinlock for protecting the request queue which
* is mucked around with in interrupts on potentially
* multiple CPU's..
*/
extern spinlock_t io_request_lock;
/*
* Initialization functions.
*/
extern int isp16_init(void);
extern int cdu31a_init(void);
extern int acsi_init(void);
extern int mcd_init(void);
extern int mcdx_init(void);
extern int sbpcd_init(void);
extern int aztcd_init(void);
extern int sony535_init(void);
extern int gscd_init(void);
extern int cm206_init(void);
extern int optcd_init(void);
extern int sjcd_init(void);
extern int cdi_init(void);
extern int hd_init(void);
extern int ide_init(void);
extern int xd_init(void);
extern int mfm_init(void);
extern int loop_init(void);
extern int md_init(void);
extern int ap_init(void);
extern int ddv_init(void);
extern int z2_init(void);
extern int swim3_init(void);
extern int swimiop_init(void);
extern int amiga_floppy_init(void);
extern int atari_floppy_init(void);
extern int ez_init(void);
extern int bpcd_init(void);
extern int ps2esdi_init(void);
extern int jsfd_init(void);
extern int viodasd_init(void);
extern int viocd_init(void);
#if defined(CONFIG_ARCH_S390)
extern int dasd_init(void);
extern int xpram_init(void);
extern int tapeblock_init(void);
#endif /* CONFIG_ARCH_S390 */
#if defined(CONFIG_XEN)
extern int xlblk_init(void);
#endif /* CONFIG_XEN */
extern void set_device_ro(kdev_t dev,int flag);
void add_blkdev_randomness(int major);
extern int floppy_init(void);
extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
extern int rd_image_start; /* starting block # of image */
#ifdef CONFIG_BLK_DEV_INITRD
#define INITRD_MINOR 250 /* shouldn't collide with /dev/ram* too soon ... */
extern unsigned long initrd_start,initrd_end;
extern int initrd_below_start_ok; /* 1 if it is not an error if initrd_start < memory_start */
void initrd_init(void);
#endif
/*
* end_request() and friends. Must be called with the request queue spinlock
* acquired. All functions called within end_request() _must_be_ atomic.
*
* Several drivers define their own end_request and call
* end_that_request_first() and end_that_request_last()
* for parts of the original function. This prevents
* code duplication in drivers.
*/
static inline void blkdev_dequeue_request(struct request * req)
{
list_del(&req->queue);
}
int end_that_request_first(struct request *req, int uptodate, char *name);
void end_that_request_last(struct request *req);
#if defined(MAJOR_NR) || defined(IDE_DRIVER)
#undef DEVICE_ON
#undef DEVICE_OFF
/*
* Add entries as needed.
*/
#ifdef IDE_DRIVER
#define DEVICE_NR(device) (MINOR(device) >> PARTN_BITS)
#define DEVICE_NAME "ide"
#elif (MAJOR_NR == RAMDISK_MAJOR)
/* ram disk */
#define DEVICE_NAME "ramdisk"
#define DEVICE_NR(device) (MINOR(device))
#define DEVICE_NO_RANDOM
#elif (MAJOR_NR == Z2RAM_MAJOR)
/* Zorro II Ram */
#define DEVICE_NAME "Z2RAM"
#define DEVICE_REQUEST do_z2_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == FLOPPY_MAJOR)
static void floppy_off(unsigned int nr);
#define DEVICE_NAME "floppy"
#define DEVICE_INTR do_floppy
#define DEVICE_REQUEST do_fd_request
#define DEVICE_NR(device) ( (MINOR(device) & 3) | ((MINOR(device) & 0x80 ) >> 5 ))
#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device))
#elif (MAJOR_NR == HD_MAJOR)
/* Hard disk: timeout is 6 seconds. */
#define DEVICE_NAME "hard disk"
#define DEVICE_INTR do_hd
#define TIMEOUT_VALUE (6*HZ)
#define DEVICE_REQUEST do_hd_request
#define DEVICE_NR(device) (MINOR(device)>>6)
#elif (SCSI_DISK_MAJOR(MAJOR_NR))
#define DEVICE_NAME "scsidisk"
#define TIMEOUT_VALUE (2*HZ)
#define DEVICE_NR(device) (((MAJOR(device) & SD_MAJOR_MASK) << (8 - 4)) + (MINOR(device) >> 4))
/* Kludge to use the same number for both char and block major numbers */
#elif (MAJOR_NR == MD_MAJOR) && defined(MD_DRIVER)
#define DEVICE_NAME "Multiple devices driver"
#define DEVICE_REQUEST do_md_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == SCSI_TAPE_MAJOR)
#define DEVICE_NAME "scsitape"
#define DEVICE_INTR do_st
#define DEVICE_NR(device) (MINOR(device) & 0x7f)
#elif (MAJOR_NR == OSST_MAJOR)
#define DEVICE_NAME "onstream"
#define DEVICE_INTR do_osst
#define DEVICE_NR(device) (MINOR(device) & 0x7f)
#define DEVICE_ON(device)
#define DEVICE_OFF(device)
#elif (MAJOR_NR == SCSI_CDROM_MAJOR)
#define DEVICE_NAME "CD-ROM"
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == XT_DISK_MAJOR)
#define DEVICE_NAME "xt disk"
#define DEVICE_REQUEST do_xd_request
#define DEVICE_NR(device) (MINOR(device) >> 6)
#elif (MAJOR_NR == PS2ESDI_MAJOR)
#define DEVICE_NAME "PS/2 ESDI"
#define DEVICE_REQUEST do_ps2esdi_request
#define DEVICE_NR(device) (MINOR(device) >> 6)
#elif (MAJOR_NR == CDU31A_CDROM_MAJOR)
#define DEVICE_NAME "CDU31A"
#define DEVICE_REQUEST do_cdu31a_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == ACSI_MAJOR) && (defined(CONFIG_ATARI_ACSI) || defined(CONFIG_ATARI_ACSI_MODULE))
#define DEVICE_NAME "ACSI"
#define DEVICE_INTR do_acsi
#define DEVICE_REQUEST do_acsi_request
#define DEVICE_NR(device) (MINOR(device) >> 4)
#elif (MAJOR_NR == MITSUMI_CDROM_MAJOR)
#define DEVICE_NAME "Mitsumi CD-ROM"
/* #define DEVICE_INTR do_mcd */
#define DEVICE_REQUEST do_mcd_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == MITSUMI_X_CDROM_MAJOR)
#define DEVICE_NAME "Mitsumi CD-ROM"
/* #define DEVICE_INTR do_mcdx */
#define DEVICE_REQUEST do_mcdx_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == MATSUSHITA_CDROM_MAJOR)
#define DEVICE_NAME "Matsushita CD-ROM controller #1"
#define DEVICE_REQUEST do_sbpcd_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == MATSUSHITA_CDROM2_MAJOR)
#define DEVICE_NAME "Matsushita CD-ROM controller #2"
#define DEVICE_REQUEST do_sbpcd2_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == MATSUSHITA_CDROM3_MAJOR)
#define DEVICE_NAME "Matsushita CD-ROM controller #3"
#define DEVICE_REQUEST do_sbpcd3_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == MATSUSHITA_CDROM4_MAJOR)
#define DEVICE_NAME "Matsushita CD-ROM controller #4"
#define DEVICE_REQUEST do_sbpcd4_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == AZTECH_CDROM_MAJOR)
#define DEVICE_NAME "Aztech CD-ROM"
#define DEVICE_REQUEST do_aztcd_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == CDU535_CDROM_MAJOR)
#define DEVICE_NAME "SONY-CDU535"
#define DEVICE_INTR do_cdu535
#define DEVICE_REQUEST do_cdu535_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == GOLDSTAR_CDROM_MAJOR)
#define DEVICE_NAME "Goldstar R420"
#define DEVICE_REQUEST do_gscd_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == CM206_CDROM_MAJOR)
#define DEVICE_NAME "Philips/LMS CD-ROM cm206"
#define DEVICE_REQUEST do_cm206_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == OPTICS_CDROM_MAJOR)
#define DEVICE_NAME "DOLPHIN 8000AT CD-ROM"
#define DEVICE_REQUEST do_optcd_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == SANYO_CDROM_MAJOR)
#define DEVICE_NAME "Sanyo H94A CD-ROM"
#define DEVICE_REQUEST do_sjcd_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == APBLOCK_MAJOR)
#define DEVICE_NAME "apblock"
#define DEVICE_REQUEST ap_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == DDV_MAJOR)
#define DEVICE_NAME "ddv"
#define DEVICE_REQUEST ddv_request
#define DEVICE_NR(device) (MINOR(device)>>PARTN_BITS)
#elif (MAJOR_NR == MFM_ACORN_MAJOR)
#define DEVICE_NAME "mfm disk"
#define DEVICE_INTR do_mfm
#define DEVICE_REQUEST do_mfm_request
#define DEVICE_NR(device) (MINOR(device) >> 6)
#elif (MAJOR_NR == NBD_MAJOR)
#define DEVICE_NAME "nbd"
#define DEVICE_REQUEST do_nbd_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == MDISK_MAJOR)
#define DEVICE_NAME "mdisk"
#define DEVICE_REQUEST mdisk_request
#define DEVICE_NR(device) (MINOR(device))
#elif (MAJOR_NR == DASD_MAJOR)
#define DEVICE_NAME "dasd"
#define DEVICE_REQUEST do_dasd_request
#define DEVICE_NR(device) (MINOR(device) >> PARTN_BITS)
#elif (MAJOR_NR == I2O_MAJOR)
#define DEVICE_NAME "I2O block"
#define DEVICE_REQUEST i2ob_request
#define DEVICE_NR(device) (MINOR(device)>>4)
#elif (MAJOR_NR == COMPAQ_SMART2_MAJOR)
#define DEVICE_NAME "ida"
#define TIMEOUT_VALUE (25*HZ)
#define DEVICE_REQUEST do_ida_request
#define DEVICE_NR(device) (MINOR(device) >> 4)
#endif /* MAJOR_NR == whatever */
/* provide DEVICE_xxx defaults, if not explicitly defined
* above in the MAJOR_NR==xxx if-elif tree */
#ifndef DEVICE_ON
#define DEVICE_ON(device) do {} while (0)
#endif
#ifndef DEVICE_OFF
#define DEVICE_OFF(device) do {} while (0)
#endif
#if (MAJOR_NR != SCSI_TAPE_MAJOR) && (MAJOR_NR != OSST_MAJOR)
#if !defined(IDE_DRIVER)
#ifndef CURRENT
#define CURRENT blkdev_entry_next_request(&blk_dev[MAJOR_NR].request_queue.queue_head)
#endif
#ifndef QUEUE_EMPTY
#define QUEUE_EMPTY list_empty(&blk_dev[MAJOR_NR].request_queue.queue_head)
#endif
#ifndef DEVICE_NAME
#define DEVICE_NAME "unknown"
#endif
#define CURRENT_DEV DEVICE_NR(CURRENT->rq_dev)
#ifdef DEVICE_INTR
static void (*DEVICE_INTR)(void) = NULL;
#endif
#define SET_INTR(x) (DEVICE_INTR = (x))
#ifdef DEVICE_REQUEST
static void (DEVICE_REQUEST)(request_queue_t *);
#endif
#ifdef DEVICE_INTR
#define CLEAR_INTR SET_INTR(NULL)
#else
#define CLEAR_INTR
#endif
#define INIT_REQUEST \
if (QUEUE_EMPTY) {\
CLEAR_INTR; \
return; \
} \
if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
panic(DEVICE_NAME ": request list destroyed"); \
if (CURRENT->bh) { \
if (!buffer_locked(CURRENT->bh)) \
panic(DEVICE_NAME ": block not locked"); \
}
#endif /* !defined(IDE_DRIVER) */
#ifndef LOCAL_END_REQUEST /* If we have our own end_request, we do not want to include this mess */
#if ! SCSI_BLK_MAJOR(MAJOR_NR) && (MAJOR_NR != COMPAQ_SMART2_MAJOR)
static inline void end_request(int uptodate) {
struct request *req = CURRENT;
if (end_that_request_first(req, uptodate, DEVICE_NAME))
return;
#ifndef DEVICE_NO_RANDOM
add_blkdev_randomness(MAJOR(req->rq_dev));
#endif
DEVICE_OFF(req->rq_dev);
blkdev_dequeue_request(req);
end_that_request_last(req);
}
#endif /* ! SCSI_BLK_MAJOR(MAJOR_NR) */
#endif /* LOCAL_END_REQUEST */
#endif /* (MAJOR_NR != SCSI_TAPE_MAJOR) */
#endif /* defined(MAJOR_NR) || defined(IDE_DRIVER) */
#endif /* _BLK_H */
@@ -1,137 +0,0 @@
#ifndef _LINUX_HIGHMEM_H
#define _LINUX_HIGHMEM_H
#include <linux/config.h>
#include <asm/pgalloc.h>
#ifdef CONFIG_HIGHMEM
extern struct page *highmem_start_page;
#include <asm/highmem.h>
/* declarations for linux/mm/highmem.c */
unsigned int nr_free_highpages(void);
void kmap_flush_unused(void);
extern struct buffer_head *create_bounce(int rw, struct buffer_head * bh_orig);
static inline char *bh_kmap(struct buffer_head *bh)
{
return kmap(bh->b_page) + bh_offset(bh);
}
static inline void bh_kunmap(struct buffer_head *bh)
{
kunmap(bh->b_page);
}
/*
* remember to add offset! and never ever reenable interrupts between a
* bh_kmap_irq and bh_kunmap_irq!!
*/
static inline char *bh_kmap_irq(struct buffer_head *bh, unsigned long *flags)
{
unsigned long addr;
__save_flags(*flags);
/*
* could be low
*/
if (!PageHighMem(bh->b_page))
return bh->b_data;
/*
* it's a highmem page
*/
__cli();
addr = (unsigned long) kmap_atomic(bh->b_page, KM_BH_IRQ);
if (addr & ~PAGE_MASK)
BUG();
return (char *) addr + bh_offset(bh);
}
static inline void bh_kunmap_irq(char *buffer, unsigned long *flags)
{
unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
kunmap_atomic((void *) ptr, KM_BH_IRQ);
__restore_flags(*flags);
}
#else /* CONFIG_HIGHMEM */
static inline unsigned int nr_free_highpages(void) { return 0; }
static inline void kmap_flush_unused(void) { }
static inline void *kmap(struct page *page) { return page_address(page); }
#define kunmap(page) do { } while (0)
#define kmap_atomic(page,idx) kmap(page)
#define kunmap_atomic(page,idx) kunmap(page)
#define bh_kmap(bh) ((bh)->b_data)
#define bh_kunmap(bh) do { } while (0)
#define kmap_nonblock(page) kmap(page)
#define bh_kmap_irq(bh, flags) ((bh)->b_data)
#define bh_kunmap_irq(bh, flags) do { *(flags) = 0; } while (0)
#endif /* CONFIG_HIGHMEM */
/* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
{
void *addr = kmap_atomic(page, KM_USER0);
clear_user_page(addr, vaddr);
kunmap_atomic(addr, KM_USER0);
}
static inline void clear_highpage(struct page *page)
{
clear_page(kmap(page));
kunmap(page);
}
/*
* Same but also flushes aliased cache contents to RAM.
*/
static inline void memclear_highpage_flush(struct page *page, unsigned int offset, unsigned int size)
{
char *kaddr;
if (offset + size > PAGE_SIZE)
out_of_line_bug();
kaddr = kmap(page);
memset(kaddr + offset, 0, size);
flush_dcache_page(page);
flush_page_to_ram(page);
kunmap(page);
}
static inline void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr)
{
char *vfrom, *vto;
vfrom = kmap_atomic(from, KM_USER0);
vto = kmap_atomic(to, KM_USER1);
copy_user_page(vto, vfrom, vaddr);
kunmap_atomic(vfrom, KM_USER0);
kunmap_atomic(vto, KM_USER1);
}
static inline void copy_highpage(struct page *to, struct page *from)
{
char *vfrom, *vto;
vfrom = kmap_atomic(from, KM_USER0);
vto = kmap_atomic(to, KM_USER1);
copy_page(vto, vfrom);
kunmap_atomic(vfrom, KM_USER0);
kunmap_atomic(vto, KM_USER1);
}
#endif /* _LINUX_HIGHMEM_H */
-80
View File
@@ -1,80 +0,0 @@
#ifndef __irq_h
#define __irq_h
/*
* Please do not include this file in generic code. There is currently
* no requirement for any architecture to implement anything held
* within this file.
*
* Thanks. --rmk
*/
#include <linux/config.h>
#if !defined(CONFIG_ARCH_S390)
#include <linux/cache.h>
#include <linux/spinlock.h>
#include <asm/irq.h>
#include <asm/ptrace.h>
/*
* IRQ line status.
*/
#define IRQ_INPROGRESS 1 /* IRQ handler active - do not enter! */
#define IRQ_DISABLED 2 /* IRQ disabled - do not enter! */
#define IRQ_PENDING 4 /* IRQ pending - replay on enable */
#define IRQ_REPLAY 8 /* IRQ has been replayed but not acked yet */
#define IRQ_AUTODETECT 16 /* IRQ is being autodetected */
#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */
#define IRQ_LEVEL 64 /* IRQ level triggered */
#define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */
#define IRQ_PER_CPU 256 /* IRQ is per CPU */
/*
* Interrupt controller descriptor. This is all we need
* to describe about the low-level hardware.
*/
struct hw_interrupt_type {
const char * typename;
unsigned int (*startup)(unsigned int irq);
void (*shutdown)(unsigned int irq);
void (*enable)(unsigned int irq);
void (*disable)(unsigned int irq);
void (*ack)(unsigned int irq);
void (*end)(unsigned int irq);
void (*set_affinity)(unsigned int irq, unsigned long mask);
};
typedef struct hw_interrupt_type hw_irq_controller;
/*
* This is the "IRQ descriptor", which contains various information
* about the irq, including what kind of hardware handling it has,
* whether it is disabled etc etc.
*
* Pad this out to 32 bytes for cache and indexing reasons.
*/
typedef struct {
unsigned int status; /* IRQ status */
hw_irq_controller *handler;
struct irqaction *action; /* IRQ action list */
unsigned int depth; /* nested irq disables */
spinlock_t lock;
} ____cacheline_aligned irq_desc_t;
extern irq_desc_t irq_desc [NR_IRQS];
#include <asm/hw_irq.h> /* the arch dependent stuff */
extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
extern int setup_irq(unsigned int , struct irqaction * );
extern int teardown_irq(unsigned int , struct irqaction * );
extern hw_irq_controller no_irq_type; /* needed in every arch ? */
extern void no_action(int cpl, void *dev_id, struct pt_regs *regs);
#endif
#endif /* __irq_h */
-727
View File
@@ -1,727 +0,0 @@
#ifndef _LINUX_MM_H
#define _LINUX_MM_H
#include <linux/sched.h>
#include <linux/errno.h>
#ifdef __KERNEL__
#include <linux/config.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/mmzone.h>
#include <linux/swap.h>
#include <linux/rbtree.h>
extern unsigned long max_mapnr;
extern unsigned long num_physpages;
extern unsigned long num_mappedpages;
extern void * high_memory;
extern int page_cluster;
/* The inactive_clean lists are per zone. */
extern struct list_head active_list;
extern struct list_head inactive_list;
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/atomic.h>
/*
* Linux kernel virtual memory manager primitives.
* The idea being to have a "virtual" mm in the same way
* we have a virtual fs - giving a cleaner interface to the
* mm details, and allowing different kinds of memory mappings
* (from shared memory to executable loading to arbitrary
* mmap() functions).
*/
/*
* This struct defines a memory VMM memory area. There is one of these
* per VM-area/task. A VM area is any part of the process virtual memory
* space that has a special rule for the page-fault handlers (ie a shared
* library, the executable area etc).
*/
struct vm_area_struct {
struct mm_struct * vm_mm; /* The address space we belong to. */
unsigned long vm_start; /* Our start address within vm_mm. */
unsigned long vm_end; /* The first byte after our end address
within vm_mm. */
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct *vm_next;
pgprot_t vm_page_prot; /* Access permissions of this VMA. */
unsigned long vm_flags; /* Flags, listed below. */
rb_node_t vm_rb;
/*
* For areas with an address space and backing store,
* one of the address_space->i_mmap{,shared} lists,
* for shm areas, the list of attaches, otherwise unused.
*/
struct vm_area_struct *vm_next_share;
struct vm_area_struct **vm_pprev_share;
/* Function pointers to deal with this struct. */
struct vm_operations_struct * vm_ops;
/* Information about our backing store: */
unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
units, *not* PAGE_CACHE_SIZE */
struct file * vm_file; /* File we map to (can be NULL). */
unsigned long vm_raend; /* XXX: put full readahead info here. */
void * vm_private_data; /* was vm_pte (shared mem) */
};
/*
* vm_flags..
*/
#define VM_READ 0x00000001 /* currently active flags */
#define VM_WRITE 0x00000002
#define VM_EXEC 0x00000004
#define VM_SHARED 0x00000008
#define VM_MAYREAD 0x00000010 /* limits for mprotect() etc */
#define VM_MAYWRITE 0x00000020
#define VM_MAYEXEC 0x00000040
#define VM_MAYSHARE 0x00000080
#define VM_GROWSDOWN 0x00000100 /* general info on the segment */
#define VM_GROWSUP 0x00000200
#define VM_SHM 0x00000400 /* shared memory area, don't swap out */
#define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */
#define VM_EXECUTABLE 0x00001000
#define VM_LOCKED 0x00002000
#define VM_IO 0x00004000 /* Memory mapped I/O or similar */
/* Used by sys_madvise() */
#define VM_SEQ_READ 0x00008000 /* App will access data sequentially */
#define VM_RAND_READ 0x00010000 /* App will not benefit from clustered reads */
#define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
#define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
#define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
#ifndef VM_STACK_FLAGS
#define VM_STACK_FLAGS 0x00000177
#endif
#define VM_READHINTMASK (VM_SEQ_READ | VM_RAND_READ)
#define VM_ClearReadHint(v) (v)->vm_flags &= ~VM_READHINTMASK
#define VM_NormalReadHint(v) (!((v)->vm_flags & VM_READHINTMASK))
#define VM_SequentialReadHint(v) ((v)->vm_flags & VM_SEQ_READ)
#define VM_RandomReadHint(v) ((v)->vm_flags & VM_RAND_READ)
/* read ahead limits */
extern int vm_min_readahead;
extern int vm_max_readahead;
/*
* mapping from the currently active vm_flags protection bits (the
* low four bits) to a page protection mask..
*/
extern pgprot_t protection_map[16];
/*
* These are the virtual MM functions - opening of an area, closing and
* unmapping it (needed to keep files on disk up-to-date etc), pointer
* to the functions called when a no-page or a wp-page exception occurs.
*/
struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
void (*close)(struct vm_area_struct * area);
struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);
};
/*
* Each physical page in the system has a struct page associated with
* it to keep track of whatever it is we are using the page for at the
* moment. Note that we have no way to track which tasks are using
* a page.
*
* Try to keep the most commonly accessed fields in single cache lines
* here (16 bytes or greater). This ordering should be particularly
* beneficial on 32-bit processors.
*
* The first line is data used in page cache lookup, the second line
* is used for linear searches (eg. clock algorithm scans).
*
* TODO: make this structure smaller, it could be as small as 32 bytes.
*/
typedef struct page {
struct list_head list; /* ->mapping has some page lists. */
struct address_space *mapping; /* The inode (or ...) we belong to. */
unsigned long index; /* Our offset within mapping. */
struct page *next_hash; /* Next page sharing our hash bucket in
the pagecache hash table. */
atomic_t count; /* Usage count, see below. */
unsigned long flags; /* atomic flags, some possibly
updated asynchronously */
struct list_head lru; /* Pageout list, eg. active_list;
protected by pagemap_lru_lock !! */
struct page **pprev_hash; /* Complement to *next_hash. */
struct buffer_head * buffers; /* Buffer maps us to a disk block. */
/*
* On machines where all RAM is mapped into kernel address space,
* we can simply calculate the virtual address. On machines with
* highmem some memory is mapped into kernel virtual memory
* dynamically, so we need a place to store that address.
* Note that this field could be 16 bits on x86 ... ;)
*
* Architectures with slow multiplication can define
* WANT_PAGE_VIRTUAL in asm/page.h
*/
#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
void *virtual; /* Kernel virtual address (NULL if
not kmapped, ie. highmem) */
#endif /* CONFIG_HIGMEM || WANT_PAGE_VIRTUAL */
} mem_map_t;
/*
* Methods to modify the page usage count.
*
* What counts for a page usage:
* - cache mapping (page->mapping)
* - disk mapping (page->buffers)
* - page mapped in a task's page tables, each mapping
* is counted separately
*
* Also, many kernel routines increase the page count before a critical
* routine so they can be sure the page doesn't go away from under them.
*/
#define get_page(p) atomic_inc(&(p)->count)
#define put_page(p) __free_page(p)
#define put_page_testzero(p) atomic_dec_and_test(&(p)->count)
#define page_count(p) atomic_read(&(p)->count)
#define set_page_count(p,v) atomic_set(&(p)->count, v)
static inline struct page *nth_page(struct page *page, int n)
{
return page + n;
}
/*
* Various page->flags bits:
*
* PG_reserved is set for special pages, which can never be swapped
* out. Some of them might not even exist (eg empty_bad_page)...
*
* Multiple processes may "see" the same page. E.g. for untouched
* mappings of /dev/null, all processes see the same page full of
* zeroes, and text pages of executables and shared libraries have
* only one copy in memory, at most, normally.
*
* For the non-reserved pages, page->count denotes a reference count.
* page->count == 0 means the page is free.
* page->count == 1 means the page is used for exactly one purpose
* (e.g. a private data page of one process).
*
* A page may be used for kmalloc() or anyone else who does a
* __get_free_page(). In this case the page->count is at least 1, and
* all other fields are unused but should be 0 or NULL. The
* management of this page is the responsibility of the one who uses
* it.
*
* The other pages (we may call them "process pages") are completely
* managed by the Linux memory manager: I/O, buffers, swapping etc.
* The following discussion applies only to them.
*
* A page may belong to an inode's memory mapping. In this case,
* page->mapping is the pointer to the inode, and page->index is the
* file offset of the page, in units of PAGE_CACHE_SIZE.
*
* A page may have buffers allocated to it. In this case,
* page->buffers is a circular list of these buffer heads. Else,
* page->buffers == NULL.
*
* For pages belonging to inodes, the page->count is the number of
* attaches, plus 1 if buffers are allocated to the page, plus one
* for the page cache itself.
*
* All pages belonging to an inode are in these doubly linked lists:
* mapping->clean_pages, mapping->dirty_pages and mapping->locked_pages;
* using the page->list list_head. These fields are also used for
* freelist managemet (when page->count==0).
*
* There is also a hash table mapping (mapping,index) to the page
* in memory if present. The lists for this hash table use the fields
* page->next_hash and page->pprev_hash.
*
* All process pages can do I/O:
* - inode pages may need to be read from disk,
* - inode pages which have been modified and are MAP_SHARED may need
* to be written to disk,
* - private pages which have been modified may need to be swapped out
* to swap space and (later) to be read back into memory.
* During disk I/O, PG_locked is used. This bit is set before I/O
* and reset when I/O completes. page_waitqueue(page) is a wait queue of all
* tasks waiting for the I/O on this page to complete.
* PG_uptodate tells whether the page's contents is valid.
* When a read completes, the page becomes uptodate, unless a disk I/O
* error happened.
*
* For choosing which pages to swap out, inode pages carry a
* PG_referenced bit, which is set any time the system accesses
* that page through the (mapping,index) hash table. This referenced
* bit, together with the referenced bit in the page tables, is used
* to manipulate page->age and move the page across the active,
* inactive_dirty and inactive_clean lists.
*
* Note that the referenced bit, the page->lru list_head and the
* active, inactive_dirty and inactive_clean lists are protected by
* the pagemap_lru_lock, and *NOT* by the usual PG_locked bit!
*
* PG_skip is used on sparc/sparc64 architectures to "skip" certain
* parts of the address space.
*
* PG_error is set to indicate that an I/O error occurred on this page.
*
* PG_arch_1 is an architecture specific page state bit. The generic
* code guarantees that this bit is cleared for a page when it first
* is entered into the page cache.
*
* PG_highmem pages are not permanently mapped into the kernel virtual
* address space, they need to be kmapped separately for doing IO on
* the pages. The struct page (these bits with information) are always
* mapped into kernel address space...
*/
#define PG_locked 0 /* Page is locked. Don't touch. */
#define PG_error 1
#define PG_referenced 2
#define PG_uptodate 3
#define PG_dirty 4
#define PG_unused 5
#define PG_lru 6
#define PG_active 7
#define PG_slab 8
#define PG_skip 10
#define PG_highmem 11
#define PG_checked 12 /* kill me in 2.5.<early>. */
#define PG_arch_1 13
#define PG_reserved 14
#define PG_launder 15 /* written out by VM pressure.. */
#define PG_fs_1 16 /* Filesystem specific */
#define PG_foreign 21 /* Page belongs to foreign allocator */
#ifndef arch_set_page_uptodate
#define arch_set_page_uptodate(page)
#endif
/* Make it prettier to test the above... */
#define UnlockPage(page) unlock_page(page)
#define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags)
#ifndef SetPageUptodate
#define SetPageUptodate(page) set_bit(PG_uptodate, &(page)->flags)
#endif
#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags)
#define PageDirty(page) test_bit(PG_dirty, &(page)->flags)
#define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags)
#define ClearPageDirty(page) clear_bit(PG_dirty, &(page)->flags)
#define PageLocked(page) test_bit(PG_locked, &(page)->flags)
#define LockPage(page) set_bit(PG_locked, &(page)->flags)
#define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags)
#define PageChecked(page) test_bit(PG_checked, &(page)->flags)
#define SetPageChecked(page) set_bit(PG_checked, &(page)->flags)
#define ClearPageChecked(page) clear_bit(PG_checked, &(page)->flags)
#define PageLaunder(page) test_bit(PG_launder, &(page)->flags)
#define SetPageLaunder(page) set_bit(PG_launder, &(page)->flags)
#define ClearPageLaunder(page) clear_bit(PG_launder, &(page)->flags)
#define ClearPageArch1(page) clear_bit(PG_arch_1, &(page)->flags)
/* A foreign page uses a custom destructor rather than the buddy allocator. */
#ifdef CONFIG_FOREIGN_PAGES
#define PageForeign(page) test_bit(PG_foreign, &(page)->flags)
#define SetPageForeign(page, dtor) do { \
set_bit(PG_foreign, &(page)->flags); \
(page)->mapping = (void *)dtor; \
} while (0)
#define ClearPageForeign(page) do { \
clear_bit(PG_foreign, &(page)->flags); \
(page)->mapping = NULL; \
} while (0)
#define PageForeignDestructor(page) \
( (void (*) (struct page *)) (page)->mapping )
#else
#define PageForeign(page) 0
#define PageForeignDestructor(page) void
#endif
/*
* The zone field is never updated after free_area_init_core()
* sets it, so none of the operations on it need to be atomic.
*/
#define NODE_SHIFT 4
#define ZONE_SHIFT (BITS_PER_LONG - 8)
struct zone_struct;
extern struct zone_struct *zone_table[];
static inline zone_t *page_zone(struct page *page)
{
return zone_table[page->flags >> ZONE_SHIFT];
}
static inline void set_page_zone(struct page *page, unsigned long zone_num)
{
page->flags &= ~(~0UL << ZONE_SHIFT);
page->flags |= zone_num << ZONE_SHIFT;
}
/*
* In order to avoid #ifdefs within C code itself, we define
* set_page_address to a noop for non-highmem machines, where
* the field isn't useful.
* The same is true for page_address() in arch-dependent code.
*/
#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
#define set_page_address(page, address) \
do { \
(page)->virtual = (address); \
} while(0)
#else /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
#define set_page_address(page, address) do { } while(0)
#endif /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
/*
* Permanent address of a page. Obviously must never be
* called on a highmem page.
*/
#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
#define page_address(page) ((page)->virtual)
#else /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
#define page_address(page) \
__va( (((page) - page_zone(page)->zone_mem_map) << PAGE_SHIFT) \
+ page_zone(page)->zone_start_paddr)
#endif /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
extern void FASTCALL(set_page_dirty(struct page *));
/*
* The first mb is necessary to safely close the critical section opened by the
* TryLockPage(), the second mb is necessary to enforce ordering between
* the clear_bit and the read of the waitqueue (to avoid SMP races with a
* parallel wait_on_page).
*/
#define PageError(page) test_bit(PG_error, &(page)->flags)
#define SetPageError(page) set_bit(PG_error, &(page)->flags)
#define ClearPageError(page) clear_bit(PG_error, &(page)->flags)
#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags)
#define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags)
#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags)
#define PageTestandClearReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
#define PageSlab(page) test_bit(PG_slab, &(page)->flags)
#define PageSetSlab(page) set_bit(PG_slab, &(page)->flags)
#define PageClearSlab(page) clear_bit(PG_slab, &(page)->flags)
#define PageReserved(page) test_bit(PG_reserved, &(page)->flags)
#define PageActive(page) test_bit(PG_active, &(page)->flags)
#define SetPageActive(page) set_bit(PG_active, &(page)->flags)
#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags)
#define PageLRU(page) test_bit(PG_lru, &(page)->flags)
#define TestSetPageLRU(page) test_and_set_bit(PG_lru, &(page)->flags)
#define TestClearPageLRU(page) test_and_clear_bit(PG_lru, &(page)->flags)
#ifdef CONFIG_HIGHMEM
#define PageHighMem(page) test_bit(PG_highmem, &(page)->flags)
#else
#define PageHighMem(page) 0 /* needed to optimize away at compile time */
#endif
#define SetPageReserved(page) set_bit(PG_reserved, &(page)->flags)
#define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags)
/*
* Error return values for the *_nopage functions
*/
#define NOPAGE_SIGBUS (NULL)
#define NOPAGE_OOM ((struct page *) (-1))
/* The array of struct pages */
extern mem_map_t * mem_map;
/*
* There is only one page-allocator function, and two main namespaces to
* it. The alloc_page*() variants return 'struct page *' and as such
* can allocate highmem pages, the *get*page*() variants return
* virtual kernel addresses to the allocated page(s).
*/
extern struct page * FASTCALL(_alloc_pages(unsigned int gfp_mask, unsigned int order));
extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist));
extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
{
/*
* Gets optimized away by the compiler.
*/
if (order >= MAX_ORDER)
return NULL;
return _alloc_pages(gfp_mask, order);
}
#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
extern unsigned long FASTCALL(__get_free_pages(unsigned int gfp_mask, unsigned int order));
extern unsigned long FASTCALL(get_zeroed_page(unsigned int gfp_mask));
#define __get_free_page(gfp_mask) \
__get_free_pages((gfp_mask),0)
#define __get_dma_pages(gfp_mask, order) \
__get_free_pages((gfp_mask) | GFP_DMA,(order))
/*
* The old interface name will be removed in 2.5:
*/
#define get_free_page get_zeroed_page
/*
* There is only one 'core' page-freeing function.
*/
extern void FASTCALL(__free_pages(struct page *page, unsigned int order));
extern void FASTCALL(free_pages(unsigned long addr, unsigned int order));
#define __free_page(page) __free_pages((page), 0)
#define free_page(addr) free_pages((addr),0)
extern void show_free_areas(void);
extern void show_free_areas_node(pg_data_t *pgdat);
extern void clear_page_tables(struct mm_struct *, unsigned long, int);
extern int fail_writepage(struct page *);
struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int unused);
struct file *shmem_file_setup(char * name, loff_t size);
extern void shmem_lock(struct file * file, int lock);
extern int shmem_zero_setup(struct vm_area_struct *);
extern void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size);
extern int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma);
extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot);
extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t prot);
extern int vmtruncate(struct inode * inode, loff_t offset);
extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address));
extern pte_t *FASTCALL(pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
extern int make_pages_present(unsigned long addr, unsigned long end);
extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len);
extern int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int len);
extern int ptrace_attach(struct task_struct *tsk);
extern int ptrace_detach(struct task_struct *, unsigned int);
extern void ptrace_disable(struct task_struct *);
extern int ptrace_check_attach(struct task_struct *task, int kill);
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
/*
* On a two-level page table, this ends up being trivial. Thus the
* inlining and the symmetry break with pte_alloc() that does all
* of this out-of-line.
*/
static inline pmd_t *pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
{
if (pgd_none(*pgd))
return __pmd_alloc(mm, pgd, address);
return pmd_offset(pgd, address);
}
extern int pgt_cache_water[2];
extern int check_pgt_cache(void);
extern void free_area_init(unsigned long * zones_size);
extern void free_area_init_node(int nid, pg_data_t *pgdat, struct page *pmap,
unsigned long * zones_size, unsigned long zone_start_paddr,
unsigned long *zholes_size);
extern void mem_init(void);
extern void show_mem(void);
extern void si_meminfo(struct sysinfo * val);
extern void swapin_readahead(swp_entry_t);
extern struct address_space swapper_space;
#define PageSwapCache(page) ((page)->mapping == &swapper_space)
static inline int is_page_cache_freeable(struct page * page)
{
return page_count(page) - !!page->buffers == 1;
}
extern int FASTCALL(can_share_swap_page(struct page *));
extern int FASTCALL(remove_exclusive_swap_page(struct page *));
extern void __free_pte(pte_t);
/* mmap.c */
extern void lock_vma_mappings(struct vm_area_struct *);
extern void unlock_vma_mappings(struct vm_area_struct *);
extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
extern void __insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
extern void build_mmap_rb(struct mm_struct *);
extern void exit_mmap(struct mm_struct *);
extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long pgoff);
static inline unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
{
unsigned long ret = -EINVAL;
if ((offset + PAGE_ALIGN(len)) < offset)
goto out;
if (!(offset & ~PAGE_MASK))
ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
out:
return ret;
}
extern int do_munmap(struct mm_struct *, unsigned long, size_t);
extern unsigned long do_brk(unsigned long, unsigned long);
static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev)
{
prev->vm_next = vma->vm_next;
rb_erase(&vma->vm_rb, &mm->mm_rb);
if (mm->mmap_cache == vma)
mm->mmap_cache = prev;
}
static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags)
{
if (!vma->vm_file && vma->vm_flags == vm_flags)
return 1;
else
return 0;
}
struct zone_t;
/* filemap.c */
extern void remove_inode_page(struct page *);
extern unsigned long page_unuse(struct page *);
extern void truncate_inode_pages(struct address_space *, loff_t);
/* generic vm_area_ops exported for stackable file systems */
extern int filemap_sync(struct vm_area_struct *, unsigned long, size_t, unsigned int);
extern struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int);
/*
* GFP bitmasks..
*/
/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low four bits) */
#define __GFP_DMA 0x01
#define __GFP_HIGHMEM 0x02
/* Action modifiers - doesn't change the zoning */
#define __GFP_WAIT 0x10 /* Can wait and reschedule? */
#define __GFP_HIGH 0x20 /* Should access emergency pools? */
#define __GFP_IO 0x40 /* Can start low memory physical IO? */
#define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */
#define __GFP_FS 0x100 /* Can call down to low-level FS? */
#define GFP_NOHIGHIO (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
#define GFP_NOIO (__GFP_HIGH | __GFP_WAIT)
#define GFP_NOFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO)
#define GFP_ATOMIC (__GFP_HIGH)
#define GFP_USER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
#define GFP_HIGHUSER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS | __GFP_HIGHMEM)
#define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
#define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
#define GFP_KSWAPD ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS)
/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some
platforms, used as appropriate on others */
#define GFP_DMA __GFP_DMA
static inline unsigned int pf_gfp_mask(unsigned int gfp_mask)
{
/* avoid all memory balancing I/O methods if this task cannot block on I/O */
if (current->flags & PF_NOIO)
gfp_mask &= ~(__GFP_IO | __GFP_HIGHIO | __GFP_FS);
return gfp_mask;
}
/* vma is the first one with address < vma->vm_end,
* and even address < vma->vm_start. Have to extend vma. */
static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
{
unsigned long grow;
/*
* vma->vm_start/vm_end cannot change under us because the caller
* is required to hold the mmap_sem in read mode. We need the
* page_table_lock lock to serialize against concurrent expand_stacks.
*/
address &= PAGE_MASK;
spin_lock(&vma->vm_mm->page_table_lock);
/* already expanded while we were spinning? */
if (vma->vm_start <= address) {
spin_unlock(&vma->vm_mm->page_table_lock);
return 0;
}
grow = (vma->vm_start - address) >> PAGE_SHIFT;
if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
spin_unlock(&vma->vm_mm->page_table_lock);
return -ENOMEM;
}
if ((vma->vm_flags & VM_LOCKED) &&
((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_MEMLOCK].rlim_cur) {
spin_unlock(&vma->vm_mm->page_table_lock);
return -ENOMEM;
}
vma->vm_start = address;
vma->vm_pgoff -= grow;
vma->vm_mm->total_vm += grow;
if (vma->vm_flags & VM_LOCKED)
vma->vm_mm->locked_vm += grow;
spin_unlock(&vma->vm_mm->page_table_lock);
return 0;
}
/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
struct vm_area_struct **pprev);
/* Look up the first VMA which intersects the interval start_addr..end_addr-1,
NULL if none. Assume start_addr < end_addr. */
static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
{
struct vm_area_struct * vma = find_vma(mm,start_addr);
if (vma && end_addr <= vma->vm_start)
vma = NULL;
return vma;
}
extern struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr);
extern struct page * vmalloc_to_page(void *addr);
#endif /* __KERNEL__ */
#endif
-971
View File
@@ -1,971 +0,0 @@
#ifndef _LINUX_SCHED_H
#define _LINUX_SCHED_H
#include <asm/param.h> /* for HZ */
extern unsigned long event;
#include <linux/config.h>
#include <linux/binfmts.h>
#include <linux/threads.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/times.h>
#include <linux/timex.h>
#include <linux/rbtree.h>
#include <asm/system.h>
#include <asm/semaphore.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/mmu.h>
#include <linux/smp.h>
#include <linux/tty.h>
#include <linux/sem.h>
#include <linux/signal.h>
#include <linux/securebits.h>
#include <linux/fs_struct.h>
struct exec_domain;
/*
* cloning flags:
*/
#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
#define CLONE_VM 0x00000100 /* set if VM shared between processes */
#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
#define CLONE_PID 0x00001000 /* set if pid shared */
#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
#define CLONE_THREAD 0x00010000 /* Same thread group? */
#define CLONE_NEWNS 0x00020000 /* New namespace group? */
#define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
/*
* These are the constant used to fake the fixed-point load-average
* counting. Some notes:
* - 11 bit fractions expand to 22 bits by the multiplies: this gives
* a load-average precision of 10 bits integer + 11 bits fractional
* - if you want to count load-averages more often, you need more
* precision, or rounding will get you. With 2-second counting freq,
* the EXP_n values would be 1981, 2034 and 2043 if still using only
* 11 bit fractions.
*/
extern unsigned long avenrun[]; /* Load averages */
#define FSHIFT 11 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5 2014 /* 1/exp(5sec/5min) */
#define EXP_15 2037 /* 1/exp(5sec/15min) */
#define CALC_LOAD(load,exp,n) \
load *= exp; \
load += n*(FIXED_1-exp); \
load >>= FSHIFT;
#define CT_TO_SECS(x) ((x) / HZ)
#define CT_TO_USECS(x) (((x) % HZ) * 1000000/HZ)
extern int nr_running, nr_threads;
extern int last_pid;
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/param.h>
#include <linux/resource.h>
#ifdef __KERNEL__
#include <linux/timer.h>
#endif
#include <asm/processor.h>
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define TASK_ZOMBIE 4
#define TASK_STOPPED 8
#define __set_task_state(tsk, state_value) \
do { (tsk)->state = (state_value); } while (0)
#define set_task_state(tsk, state_value) \
set_mb((tsk)->state, (state_value))
#define __set_current_state(state_value) \
do { current->state = (state_value); } while (0)
#define set_current_state(state_value) \
set_mb(current->state, (state_value))
/*
* Scheduling policies
*/
#define SCHED_OTHER 0
#define SCHED_FIFO 1
#define SCHED_RR 2
/*
* This is an additional bit set when we want to
* yield the CPU for one re-schedule..
*/
#define SCHED_YIELD 0x10
struct sched_param {
int sched_priority;
};
struct completion;
#ifdef __KERNEL__
#include <linux/spinlock.h>
/*
* This serializes "schedule()" and also protects
* the run-queue from deletions/modifications (but
* _adding_ to the beginning of the run-queue has
* a separate lock).
*/
extern rwlock_t tasklist_lock;
extern spinlock_t runqueue_lock;
extern spinlock_t mmlist_lock;
extern void sched_init(void);
extern void init_idle(void);
extern void show_state(void);
extern void cpu_init (void);
extern void trap_init(void);
extern void update_process_times(int user);
#ifdef CONFIG_NO_IDLE_HZ
extern void update_process_times_us(int user, int system);
#endif
extern void update_one_process(struct task_struct *p, unsigned long user,
unsigned long system, int cpu);
#define MAX_SCHEDULE_TIMEOUT LONG_MAX
extern signed long FASTCALL(schedule_timeout(signed long timeout));
asmlinkage void schedule(void);
extern int schedule_task(struct tq_struct *task);
extern void flush_scheduled_tasks(void);
extern int start_context_thread(void);
extern int current_is_keventd(void);
#if CONFIG_SMP
extern void set_cpus_allowed(struct task_struct *p, unsigned long new_mask);
#else
# define set_cpus_allowed(p, new_mask) do { } while (0)
#endif
/*
* The default fd array needs to be at least BITS_PER_LONG,
* as this is the granularity returned by copy_fdset().
*/
#define NR_OPEN_DEFAULT BITS_PER_LONG
struct namespace;
/*
* Open file table structure
*/
struct files_struct {
atomic_t count;
rwlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */
int max_fds;
int max_fdset;
int next_fd;
struct file ** fd; /* current fd array */
fd_set *close_on_exec;
fd_set *open_fds;
fd_set close_on_exec_init;
fd_set open_fds_init;
struct file * fd_array[NR_OPEN_DEFAULT];
};
#define INIT_FILES \
{ \
count: ATOMIC_INIT(1), \
file_lock: RW_LOCK_UNLOCKED, \
max_fds: NR_OPEN_DEFAULT, \
max_fdset: __FD_SETSIZE, \
next_fd: 0, \
fd: &init_files.fd_array[0], \
close_on_exec: &init_files.close_on_exec_init, \
open_fds: &init_files.open_fds_init, \
close_on_exec_init: { { 0, } }, \
open_fds_init: { { 0, } }, \
fd_array: { NULL, } \
}
/* Maximum number of active map areas.. This is a random (large) number */
#define DEFAULT_MAX_MAP_COUNT (65536)
extern int max_map_count;
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
rb_root_t mm_rb;
struct vm_area_struct * mmap_cache; /* last find_vma result */
pgd_t * pgd;
atomic_t mm_users; /* How many users with user space? */
atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
int map_count; /* number of VMAs */
struct rw_semaphore mmap_sem;
spinlock_t page_table_lock; /* Protects task page tables and mm->rss */
struct list_head mmlist; /* List of all active mm's. These are globally strung
* together off init_mm.mmlist, and are protected
* by mmlist_lock
*/
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
unsigned long arg_start, arg_end, env_start, env_end;
unsigned long rss, total_vm, locked_vm;
unsigned long def_flags;
unsigned long cpu_vm_mask;
unsigned long swap_address;
unsigned dumpable:1;
/* Architecture-specific MM context */
mm_context_t context;
};
extern int mmlist_nr;
#define INIT_MM(name) \
{ \
mm_rb: RB_ROOT, \
pgd: swapper_pg_dir, \
mm_users: ATOMIC_INIT(2), \
mm_count: ATOMIC_INIT(1), \
mmap_sem: __RWSEM_INITIALIZER(name.mmap_sem), \
page_table_lock: SPIN_LOCK_UNLOCKED, \
mmlist: LIST_HEAD_INIT(name.mmlist), \
}
struct signal_struct {
atomic_t count;
struct k_sigaction action[_NSIG];
spinlock_t siglock;
};
#define INIT_SIGNALS { \
count: ATOMIC_INIT(1), \
action: { {{0,}}, }, \
siglock: SPIN_LOCK_UNLOCKED \
}
/*
* Some day this will be a full-fledged user tracking system..
*/
struct user_struct {
atomic_t __count; /* reference count */
atomic_t processes; /* How many processes does this user have? */
atomic_t files; /* How many open files does this user have? */
/* Hash table maintenance information */
struct user_struct *next, **pprev;
uid_t uid;
};
#define get_current_user() ({ \
struct user_struct *__tmp_user = current->user; \
atomic_inc(&__tmp_user->__count); \
__tmp_user; })
extern struct user_struct root_user;
#define INIT_USER (&root_user)
struct task_struct {
/*
* offsets of these are hardcoded elsewhere - touch with care
*/
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
unsigned long flags; /* per process flags, defined below */
int sigpending;
mm_segment_t addr_limit; /* thread address space:
0-0xBFFFFFFF for user-thead
0-0xFFFFFFFF for kernel-thread
*/
struct exec_domain *exec_domain;
volatile long need_resched;
unsigned long ptrace;
int lock_depth; /* Lock depth */
/*
* offset 32 begins here on 32-bit platforms. We keep
* all fields in a single cacheline that are needed for
* the goodness() loop in schedule().
*/
long counter;
long nice;
unsigned long policy;
struct mm_struct *mm;
int processor;
/*
* cpus_runnable is ~0 if the process is not running on any
* CPU. It's (1 << cpu) if it's running on a CPU. This mask
* is updated under the runqueue lock.
*
* To determine whether a process might run on a CPU, this
* mask is AND-ed with cpus_allowed.
*/
unsigned long cpus_runnable, cpus_allowed;
/*
* (only the 'next' pointer fits into the cacheline, but
* that's just fine.)
*/
struct list_head run_list;
unsigned long sleep_time;
struct task_struct *next_task, *prev_task;
struct mm_struct *active_mm;
struct list_head local_pages;
unsigned int allocation_order, nr_local_pages;
/* task state */
struct linux_binfmt *binfmt;
int exit_code, exit_signal;
int pdeath_signal; /* The signal sent when the parent dies */
/* ??? */
unsigned long personality;
int did_exec:1;
unsigned task_dumpable:1;
pid_t pid;
pid_t pgrp;
pid_t tty_old_pgrp;
pid_t session;
pid_t tgid;
/* boolean value for session group leader */
int leader;
/*
* pointers to (original) parent process, youngest child, younger sibling,
* older sibling, respectively. (p->father can be replaced with
* p->p_pptr->pid)
*/
struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
struct list_head thread_group;
/* PID hash table linkage. */
struct task_struct *pidhash_next;
struct task_struct **pidhash_pprev;
wait_queue_head_t wait_chldexit; /* for wait4() */
struct completion *vfork_done; /* for vfork() */
unsigned long rt_priority;
unsigned long it_real_value, it_prof_value, it_virt_value;
unsigned long it_real_incr, it_prof_incr, it_virt_incr;
struct timer_list real_timer;
struct tms times;
unsigned long start_time;
long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
int swappable:1;
/* process credentials */
uid_t uid,euid,suid,fsuid;
gid_t gid,egid,sgid,fsgid;
int ngroups;
gid_t groups[NGROUPS];
kernel_cap_t cap_effective, cap_inheritable, cap_permitted;
int keep_capabilities:1;
struct user_struct *user;
/* limits */
struct rlimit rlim[RLIM_NLIMITS];
unsigned short used_math;
char comm[16];
/* file system info */
int link_count, total_link_count;
struct tty_struct *tty; /* NULL if no tty */
unsigned int locks; /* How many file locks are being held */
/* ipc stuff */
struct sem_undo *semundo;
struct sem_queue *semsleeping;
/* CPU-specific state of this task */
struct thread_struct thread;
/* filesystem information */
struct fs_struct *fs;
/* open file information */
struct files_struct *files;
/* namespace */
struct namespace *namespace;
/* signal handlers */
spinlock_t sigmask_lock; /* Protects signal and blocked */
struct signal_struct *sig;
sigset_t blocked;
struct sigpending pending;
unsigned long sas_ss_sp;
size_t sas_ss_size;
int (*notifier)(void *priv);
void *notifier_data;
sigset_t *notifier_mask;
/* Thread group tracking */
u32 parent_exec_id;
u32 self_exec_id;
/* Protection of (de-)allocation: mm, files, fs, tty */
spinlock_t alloc_lock;
/* journalling filesystem info */
void *journal_info;
};
/*
* Per process flags
*/
#define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */
/* Not implemented yet, only for 486*/
#define PF_STARTING 0x00000002 /* being created */
#define PF_EXITING 0x00000004 /* getting shut down */
#define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */
#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */
#define PF_DUMPCORE 0x00000200 /* dumped core */
#define PF_SIGNALED 0x00000400 /* killed by a signal */
#define PF_MEMALLOC 0x00000800 /* Allocating memory */
#define PF_MEMDIE 0x00001000 /* Killed for out-of-memory */
#define PF_FREE_PAGES 0x00002000 /* per process page freeing */
#define PF_NOIO 0x00004000 /* avoid generating further I/O */
#define PF_FSTRANS 0x00008000 /* inside a filesystem transaction */
#define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */
/*
* Ptrace flags
*/
#define PT_PTRACED 0x00000001
#define PT_TRACESYS 0x00000002
#define PT_DTRACE 0x00000004 /* delayed trace (used on m68k, i386) */
#define PT_TRACESYSGOOD 0x00000008
#define PT_PTRACE_CAP 0x00000010 /* ptracer can follow suid-exec */
#define is_dumpable(tsk) ((tsk)->task_dumpable && (tsk)->mm && (tsk)->mm->dumpable)
/*
* Limit the stack by to some sane default: root can always
* increase this limit if needed.. 8MB seems reasonable.
*/
#define _STK_LIM (8*1024*1024)
#define DEF_COUNTER (10*HZ/100) /* 100 ms time slice */
#define MAX_COUNTER (20*HZ/100)
#define DEF_NICE (0)
extern void yield(void);
/*
* The default (Linux) execution domain.
*/
extern struct exec_domain default_exec_domain;
/*
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x1fffff (=2MB)
*/
#define INIT_TASK(tsk) \
{ \
state: 0, \
flags: 0, \
sigpending: 0, \
addr_limit: KERNEL_DS, \
exec_domain: &default_exec_domain, \
lock_depth: -1, \
counter: DEF_COUNTER, \
nice: DEF_NICE, \
policy: SCHED_OTHER, \
mm: NULL, \
active_mm: &init_mm, \
cpus_runnable: ~0UL, \
cpus_allowed: ~0UL, \
run_list: LIST_HEAD_INIT(tsk.run_list), \
next_task: &tsk, \
prev_task: &tsk, \
p_opptr: &tsk, \
p_pptr: &tsk, \
thread_group: LIST_HEAD_INIT(tsk.thread_group), \
wait_chldexit: __WAIT_QUEUE_HEAD_INITIALIZER(tsk.wait_chldexit),\
real_timer: { \
function: it_real_fn \
}, \
cap_effective: CAP_INIT_EFF_SET, \
cap_inheritable: CAP_INIT_INH_SET, \
cap_permitted: CAP_FULL_SET, \
keep_capabilities: 0, \
rlim: INIT_RLIMITS, \
user: INIT_USER, \
comm: "swapper", \
thread: INIT_THREAD, \
fs: &init_fs, \
files: &init_files, \
sigmask_lock: SPIN_LOCK_UNLOCKED, \
sig: &init_signals, \
pending: { NULL, &tsk.pending.head, {{0}}}, \
blocked: {{0}}, \
alloc_lock: SPIN_LOCK_UNLOCKED, \
journal_info: NULL, \
}
#ifndef INIT_TASK_SIZE
# define INIT_TASK_SIZE 2048*sizeof(long)
#endif
union task_union {
struct task_struct task;
unsigned long stack[INIT_TASK_SIZE/sizeof(long)];
};
extern union task_union init_task_union;
extern struct mm_struct init_mm;
extern struct task_struct *init_tasks[NR_CPUS];
/* PID hashing. (shouldnt this be dynamic?) */
#define PIDHASH_SZ (4096 >> 2)
extern struct task_struct *pidhash[PIDHASH_SZ];
#define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
static inline void hash_pid(struct task_struct *p)
{
struct task_struct **htable = &pidhash[pid_hashfn(p->pid)];
if((p->pidhash_next = *htable) != NULL)
(*htable)->pidhash_pprev = &p->pidhash_next;
*htable = p;
p->pidhash_pprev = htable;
}
static inline void unhash_pid(struct task_struct *p)
{
if(p->pidhash_next)
p->pidhash_next->pidhash_pprev = p->pidhash_pprev;
*p->pidhash_pprev = p->pidhash_next;
}
static inline struct task_struct *find_task_by_pid(int pid)
{
struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];
for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
;
return p;
}
#define task_has_cpu(tsk) ((tsk)->cpus_runnable != ~0UL)
static inline void task_set_cpu(struct task_struct *tsk, unsigned int cpu)
{
tsk->processor = cpu;
tsk->cpus_runnable = 1UL << cpu;
}
static inline void task_release_cpu(struct task_struct *tsk)
{
tsk->cpus_runnable = ~0UL;
}
/* per-UID process charging. */
extern struct user_struct * alloc_uid(uid_t);
extern void free_uid(struct user_struct *);
extern void switch_uid(struct user_struct *);
#include <asm/current.h>
extern unsigned long volatile jiffies;
extern unsigned long itimer_ticks;
extern unsigned long itimer_next;
extern struct timeval xtime;
extern void do_timer(struct pt_regs *);
#ifdef CONFIG_NO_IDLE_HZ
extern void do_timer_ticks(int ticks);
#endif
extern unsigned int * prof_buffer;
extern unsigned long prof_len;
extern unsigned long prof_shift;
#define CURRENT_TIME (xtime.tv_sec)
extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr));
extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr));
extern void FASTCALL(sleep_on(wait_queue_head_t *q));
extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
signed long timeout));
extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
signed long timeout));
extern int FASTCALL(wake_up_process(struct task_struct * tsk));
#define wake_up(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1)
#define wake_up_nr(x, nr) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)
#define wake_up_all(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0)
#define wake_up_sync(x) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1)
#define wake_up_sync_nr(x, nr) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)
#define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE, 1)
#define wake_up_interruptible_nr(x, nr) __wake_up((x),TASK_INTERRUPTIBLE, nr)
#define wake_up_interruptible_all(x) __wake_up((x),TASK_INTERRUPTIBLE, 0)
#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
#define wake_up_interruptible_sync_nr(x, nr) __wake_up_sync((x),TASK_INTERRUPTIBLE, nr)
asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru);
extern int in_group_p(gid_t);
extern int in_egroup_p(gid_t);
extern void proc_caches_init(void);
extern void flush_signals(struct task_struct *);
extern void flush_signal_handlers(struct task_struct *);
extern void sig_exit(int, int, struct siginfo *);
extern int dequeue_signal(sigset_t *, siginfo_t *);
extern void block_all_signals(int (*notifier)(void *priv), void *priv,
sigset_t *mask);
extern void unblock_all_signals(void);
extern int send_sig_info(int, struct siginfo *, struct task_struct *);
extern int force_sig_info(int, struct siginfo *, struct task_struct *);
extern int kill_pg_info(int, struct siginfo *, pid_t);
extern int kill_sl_info(int, struct siginfo *, pid_t);
extern int kill_proc_info(int, struct siginfo *, pid_t);
extern void notify_parent(struct task_struct *, int);
extern void do_notify_parent(struct task_struct *, int);
extern void force_sig(int, struct task_struct *);
extern int send_sig(int, struct task_struct *, int);
extern int kill_pg(pid_t, int, int);
extern int kill_sl(pid_t, int, int);
extern int kill_proc(pid_t, int, int);
extern int do_sigaction(int, const struct k_sigaction *, struct k_sigaction *);
extern int do_sigaltstack(const stack_t *, stack_t *, unsigned long);
static inline int signal_pending(struct task_struct *p)
{
return (p->sigpending != 0);
}
/*
* Re-calculate pending state from the set of locally pending
* signals, globally pending signals, and blocked signals.
*/
static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
{
unsigned long ready;
long i;
switch (_NSIG_WORDS) {
default:
for (i = _NSIG_WORDS, ready = 0; --i >= 0 ;)
ready |= signal->sig[i] &~ blocked->sig[i];
break;
case 4: ready = signal->sig[3] &~ blocked->sig[3];
ready |= signal->sig[2] &~ blocked->sig[2];
ready |= signal->sig[1] &~ blocked->sig[1];
ready |= signal->sig[0] &~ blocked->sig[0];
break;
case 2: ready = signal->sig[1] &~ blocked->sig[1];
ready |= signal->sig[0] &~ blocked->sig[0];
break;
case 1: ready = signal->sig[0] &~ blocked->sig[0];
}
return ready != 0;
}
/* Reevaluate whether the task has signals pending delivery.
This is required every time the blocked sigset_t changes.
All callers should have t->sigmask_lock. */
static inline void recalc_sigpending(struct task_struct *t)
{
t->sigpending = has_pending_signals(&t->pending.signal, &t->blocked);
}
/* True if we are on the alternate signal stack. */
static inline int on_sig_stack(unsigned long sp)
{
return (sp - current->sas_ss_sp < current->sas_ss_size);
}
static inline int sas_ss_flags(unsigned long sp)
{
return (current->sas_ss_size == 0 ? SS_DISABLE
: on_sig_stack(sp) ? SS_ONSTACK : 0);
}
extern int request_irq(unsigned int,
void (*handler)(int, void *, struct pt_regs *),
unsigned long, const char *, void *);
extern void free_irq(unsigned int, void *);
/*
* This has now become a routine instead of a macro, it sets a flag if
* it returns true (to do BSD-style accounting where the process is flagged
* if it uses root privs). The implication of this is that you should do
* normal permissions checks first, and check suser() last.
*
* [Dec 1997 -- Chris Evans]
* For correctness, the above considerations need to be extended to
* fsuser(). This is done, along with moving fsuser() checks to be
* last.
*
* These will be removed, but in the mean time, when the SECURE_NOROOT
* flag is set, uids don't grant privilege.
*/
static inline int suser(void)
{
if (!issecure(SECURE_NOROOT) && current->euid == 0) {
current->flags |= PF_SUPERPRIV;
return 1;
}
return 0;
}
static inline int fsuser(void)
{
if (!issecure(SECURE_NOROOT) && current->fsuid == 0) {
current->flags |= PF_SUPERPRIV;
return 1;
}
return 0;
}
/*
* capable() checks for a particular capability.
* New privilege checks should use this interface, rather than suser() or
* fsuser(). See include/linux/capability.h for defined capabilities.
*/
static inline int capable(int cap)
{
#if 1 /* ok now */
if (cap_raised(current->cap_effective, cap))
#else
if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
#endif
{
current->flags |= PF_SUPERPRIV;
return 1;
}
return 0;
}
/*
* Routines for handling mm_structs
*/
extern struct mm_struct * mm_alloc(void);
extern struct mm_struct * start_lazy_tlb(void);
extern void end_lazy_tlb(struct mm_struct *mm);
/* mmdrop drops the mm and the page tables */
extern void FASTCALL(__mmdrop(struct mm_struct *));
static inline void mmdrop(struct mm_struct * mm)
{
if (atomic_dec_and_test(&mm->mm_count))
__mmdrop(mm);
}
/* mmput gets rid of the mappings and all user-space */
extern void mmput(struct mm_struct *);
/* Remove the current tasks stale references to the old mm_struct */
extern void mm_release(void);
/*
* Routines for handling the fd arrays
*/
extern struct file ** alloc_fd_array(int);
extern int expand_fd_array(struct files_struct *, int nr);
extern void free_fd_array(struct file **, int);
extern fd_set *alloc_fdset(int);
extern int expand_fdset(struct files_struct *, int nr);
extern void free_fdset(fd_set *, int);
extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
extern void flush_thread(void);
extern void exit_thread(void);
extern void exit_mm(struct task_struct *);
extern void exit_files(struct task_struct *);
extern void exit_sighand(struct task_struct *);
extern void reparent_to_init(void);
extern void daemonize(void);
extern int do_execve(char *, char **, char **, struct pt_regs *);
extern int do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long);
extern void set_task_comm(struct task_struct *tsk, char *from);
extern void get_task_comm(char *to, struct task_struct *tsk);
extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
#define __wait_event(wq, condition) \
do { \
wait_queue_t __wait; \
init_waitqueue_entry(&__wait, current); \
\
add_wait_queue(&wq, &__wait); \
for (;;) { \
set_current_state(TASK_UNINTERRUPTIBLE); \
if (condition) \
break; \
schedule(); \
} \
current->state = TASK_RUNNING; \
remove_wait_queue(&wq, &__wait); \
} while (0)
#define wait_event(wq, condition) \
do { \
if (condition) \
break; \
__wait_event(wq, condition); \
} while (0)
#define __wait_event_interruptible(wq, condition, ret) \
do { \
wait_queue_t __wait; \
init_waitqueue_entry(&__wait, current); \
\
add_wait_queue(&wq, &__wait); \
for (;;) { \
set_current_state(TASK_INTERRUPTIBLE); \
if (condition) \
break; \
if (!signal_pending(current)) { \
schedule(); \
continue; \
} \
ret = -ERESTARTSYS; \
break; \
} \
current->state = TASK_RUNNING; \
remove_wait_queue(&wq, &__wait); \
} while (0)
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
#define REMOVE_LINKS(p) do { \
(p)->next_task->prev_task = (p)->prev_task; \
(p)->prev_task->next_task = (p)->next_task; \
if ((p)->p_osptr) \
(p)->p_osptr->p_ysptr = (p)->p_ysptr; \
if ((p)->p_ysptr) \
(p)->p_ysptr->p_osptr = (p)->p_osptr; \
else \
(p)->p_pptr->p_cptr = (p)->p_osptr; \
} while (0)
#define SET_LINKS(p) do { \
(p)->next_task = &init_task; \
(p)->prev_task = init_task.prev_task; \
init_task.prev_task->next_task = (p); \
init_task.prev_task = (p); \
(p)->p_ysptr = NULL; \
if (((p)->p_osptr = (p)->p_pptr->p_cptr) != NULL) \
(p)->p_osptr->p_ysptr = p; \
(p)->p_pptr->p_cptr = p; \
} while (0)
#define for_each_task(p) \
for (p = &init_task ; (p = p->next_task) != &init_task ; )
#define for_each_thread(task) \
for (task = next_thread(current) ; task != current ; task = next_thread(task))
#define next_thread(p) \
list_entry((p)->thread_group.next, struct task_struct, thread_group)
#define thread_group_leader(p) (p->pid == p->tgid)
static inline void del_from_runqueue(struct task_struct * p)
{
nr_running--;
p->sleep_time = jiffies;
list_del(&p->run_list);
p->run_list.next = NULL;
}
static inline int task_on_runqueue(struct task_struct *p)
{
return (p->run_list.next != NULL);
}
static inline void unhash_process(struct task_struct *p)
{
if (task_on_runqueue(p))
out_of_line_bug();
write_lock_irq(&tasklist_lock);
nr_threads--;
unhash_pid(p);
REMOVE_LINKS(p);
list_del(&p->thread_group);
write_unlock_irq(&tasklist_lock);
}
/* Protects ->fs, ->files, ->mm, and synchronises with wait4(). Nests inside tasklist_lock */
static inline void task_lock(struct task_struct *p)
{
spin_lock(&p->alloc_lock);
}
static inline void task_unlock(struct task_struct *p)
{
spin_unlock(&p->alloc_lock);
}
/* write full pathname into buffer and return start of pathname */
static inline char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
char *buf, int buflen)
{
char *res;
struct vfsmount *rootmnt;
struct dentry *root;
read_lock(&current->fs->lock);
rootmnt = mntget(current->fs->rootmnt);
root = dget(current->fs->root);
read_unlock(&current->fs->lock);
spin_lock(&dcache_lock);
res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
spin_unlock(&dcache_lock);
dput(root);
mntput(rootmnt);
return res;
}
static inline int need_resched(void)
{
return (unlikely(current->need_resched));
}
extern void __cond_resched(void);
static inline void cond_resched(void)
{
if (need_resched())
__cond_resched();
}
#endif /* __KERNEL__ */
#endif
File diff suppressed because it is too large. Load diff
@@ -1,77 +0,0 @@
#ifndef _LINUX_TIMER_H
#define _LINUX_TIMER_H
#include <linux/config.h>
#include <linux/list.h>
/*
* In Linux 2.4, static timers have been removed from the kernel.
* Timers may be dynamically created and destroyed, and should be initialized
* by a call to init_timer() upon creation.
*
* The "data" field enables use of a common timeout function for several
* timeouts. You can use this field to distinguish between the different
* invocations.
*/
struct timer_list {
struct list_head list;
unsigned long expires;
unsigned long data;
void (*function)(unsigned long);
};
extern void add_timer(struct timer_list * timer);
extern int del_timer(struct timer_list * timer);
#ifdef CONFIG_NO_IDLE_HZ
extern struct timer_list *next_timer_event(void);
#endif
#ifdef CONFIG_SMP
extern int del_timer_sync(struct timer_list * timer);
extern void sync_timers(void);
#else
#define del_timer_sync(t) del_timer(t)
#define sync_timers() do { } while (0)
#endif
/*
* mod_timer is a more efficient way to update the expire field of an
* active timer (if the timer is inactive it will be activated)
* mod_timer(a,b) is equivalent to del_timer(a); a->expires = b; add_timer(a).
* If the timer is known to be not pending (ie, in the handler), mod_timer
* is less efficient than a->expires = b; add_timer(a).
*/
int mod_timer(struct timer_list *timer, unsigned long expires);
extern void it_real_fn(unsigned long);
static inline void init_timer(struct timer_list * timer)
{
timer->list.next = timer->list.prev = NULL;
}
static inline int timer_pending (const struct timer_list * timer)
{
return timer->list.next != NULL;
}
/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
* 1. Because people otherwise forget
* 2. Because if the timer wrap changes in future you wont have to
* alter your driver code.
*
* time_after(a,b) returns true if the time a is after time b.
*
* Do this with "<0" and ">=0" to only test the sign of the result. A
* good compiler would generate better code (and a really good compiler
* wouldn't care). Gcc is currently neither.
*/
#define time_after(a,b) ((long)(b) - (long)(a) < 0)
#define time_before(a,b) time_after(b,a)
#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0)
#define time_before_eq(a,b) time_after_eq(b,a)
#endif
-415
View File
@@ -1,415 +0,0 @@
/*
* linux/kernel/time.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* This file contains the interface functions for the various
* time related system calls: time, stime, gettimeofday, settimeofday,
* adjtime
*/
/*
* Modification history kernel/time.c
*
* 1993-09-02 Philip Gladstone
* Created file with time related functions from sched.c and adjtimex()
* 1993-10-08 Torsten Duwe
* adjtime interface update and CMOS clock write code
* 1995-08-13 Torsten Duwe
* kernel PLL updated to 1994-12-13 specs (rfc-1589)
* 1999-01-16 Ulrich Windl
* Introduced error checking for many cases in adjtimex().
* Updated NTP code according to technical memorandum Jan '96
* "A Kernel Model for Precision Timekeeping" by Dave Mills
* Allow time_constant larger than MAXTC(6) for NTP v4 (MAXTC == 10)
* (Even though the technical memorandum forbids it)
*/
#include <linux/mm.h>
#include <linux/timex.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
/*
* The timezone where the local system is located. Used as a default by some
* programs who obtain this value by using gettimeofday.
*/
struct timezone sys_tz;
/* The xtime_lock is not only serializing the xtime read/writes but it's also
serializing all accesses to the global NTP variables now. */
extern rwlock_t xtime_lock;
#if !defined(__alpha__) && !defined(__ia64__)
/*
* sys_time() can be implemented in user-level using
* sys_gettimeofday(). Is this for backwards compatibility? If so,
* why not move it into the appropriate arch directory (for those
* architectures that need it).
*
* XXX This function is NOT 64-bit clean!
*/
asmlinkage long sys_time(int * tloc)
{
struct timeval now;
int i;
do_gettimeofday(&now);
i = now.tv_sec;
if (tloc) {
if (put_user(i,tloc))
i = -EFAULT;
}
return i;
}
#if !defined(CONFIG_XEN)
/*
* sys_stime() can be implemented in user-level using
* sys_settimeofday(). Is this for backwards compatibility? If so,
* why not move it into the appropriate arch directory (for those
* architectures that need it).
*/
asmlinkage long sys_stime(int * tptr)
{
int value;
if (!capable(CAP_SYS_TIME))
return -EPERM;
if (get_user(value, tptr))
return -EFAULT;
write_lock_irq(&xtime_lock);
vxtime_lock();
xtime.tv_sec = value;
xtime.tv_usec = 0;
vxtime_unlock();
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
write_unlock_irq(&xtime_lock);
return 0;
}
#endif
#endif
asmlinkage long sys_gettimeofday(struct timeval *tv, struct timezone *tz)
{
if (tv) {
struct timeval ktv;
do_gettimeofday(&ktv);
if (copy_to_user(tv, &ktv, sizeof(ktv)))
return -EFAULT;
}
if (tz) {
if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
return -EFAULT;
}
return 0;
}
/*
* Adjust the time obtained from the CMOS to be UTC time instead of
* local time.
*
* This is ugly, but preferable to the alternatives. Otherwise we
* would either need to write a program to do it in /etc/rc (and risk
* confusion if the program gets run more than once; it would also be
* hard to make the program warp the clock precisely n hours) or
* compile in the timezone information into the kernel. Bad, bad....
*
* - TYT, 1992-01-01
*
* The best thing to do is to keep the CMOS clock in universal time (UTC)
* as real UNIX machines always do it. This avoids all headaches about
* daylight saving times and warping kernel clocks.
*/
inline static void warp_clock(void)
{
write_lock_irq(&xtime_lock);
vxtime_lock();
xtime.tv_sec += sys_tz.tz_minuteswest * 60;
vxtime_unlock();
write_unlock_irq(&xtime_lock);
}
/*
* In case for some reason the CMOS clock has not already been running
* in UTC, but in some local time: The first time we set the timezone,
* we will warp the clock so that it is ticking UTC time instead of
* local time. Presumably, if someone is setting the timezone then we
* are running in an environment where the programs understand about
* timezones. This should be done at boot time in the /etc/rc script,
* as soon as possible, so that the clock can be set right. Otherwise,
* various programs will get confused when the clock gets warped.
*/
int do_sys_settimeofday(struct timeval *tv, struct timezone *tz)
{
static int firsttime = 1;
if (!capable(CAP_SYS_TIME))
return -EPERM;
if (tz) {
/* SMP safe, global irq locking makes it work. */
sys_tz = *tz;
if (firsttime) {
firsttime = 0;
if (!tv)
warp_clock();
}
}
if (tv)
{
/* SMP safe, again the code in arch/foo/time.c should
* globally block out interrupts when it runs.
*/
do_settimeofday(tv);
}
return 0;
}
asmlinkage long sys_settimeofday(struct timeval *tv, struct timezone *tz)
{
struct timeval new_tv;
struct timezone new_tz;
if (tv) {
if (copy_from_user(&new_tv, tv, sizeof(*tv)))
return -EFAULT;
}
if (tz) {
if (copy_from_user(&new_tz, tz, sizeof(*tz)))
return -EFAULT;
}
return do_sys_settimeofday(tv ? &new_tv : NULL, tz ? &new_tz : NULL);
}
long pps_offset; /* pps time offset (us) */
long pps_jitter = MAXTIME; /* time dispersion (jitter) (us) */
long pps_freq; /* frequency offset (scaled ppm) */
long pps_stabil = MAXFREQ; /* frequency dispersion (scaled ppm) */
long pps_valid = PPS_VALID; /* pps signal watchdog counter */
int pps_shift = PPS_SHIFT; /* interval duration (s) (shift) */
long pps_jitcnt; /* jitter limit exceeded */
long pps_calcnt; /* calibration intervals */
long pps_errcnt; /* calibration errors */
long pps_stbcnt; /* stability limit exceeded */
/* hook for a loadable hardpps kernel module */
void (*hardpps_ptr)(struct timeval *);
/* adjtimex mainly allows reading (and writing, if superuser) of
* kernel time-keeping variables. used by xntpd.
*/
int do_adjtimex(struct timex *txc)
{
long ltemp, mtemp, save_adjust;
int result;
/* In order to modify anything, you gotta be super-user! */
if (txc->modes && !capable(CAP_SYS_TIME))
return -EPERM;
/* Now we validate the data before disabling interrupts */
if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
/* singleshot must not be used with any other mode bits */
if (txc->modes != ADJ_OFFSET_SINGLESHOT)
return -EINVAL;
if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
/* adjustment Offset limited to +- .512 seconds */
if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
return -EINVAL;
/* if the quartz is off by more than 10% something is VERY wrong ! */
if (txc->modes & ADJ_TICK)
if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ)
return -EINVAL;
write_lock_irq(&xtime_lock);
result = time_state; /* mostly `TIME_OK' */
/* Save for later - semantics of adjtime is to return old value */
save_adjust = time_adjust;
#if 0 /* STA_CLOCKERR is never set yet */
time_status &= ~STA_CLOCKERR; /* reset STA_CLOCKERR */
#endif
/* If there are input parameters, then process them */
if (txc->modes)
{
if (txc->modes & ADJ_STATUS) /* only set allowed bits */
time_status = (txc->status & ~STA_RONLY) |
(time_status & STA_RONLY);
if (txc->modes & ADJ_FREQUENCY) { /* p. 22 */
if (txc->freq > MAXFREQ || txc->freq < -MAXFREQ) {
result = -EINVAL;
goto leave;
}
time_freq = txc->freq - pps_freq;
}
if (txc->modes & ADJ_MAXERROR) {
if (txc->maxerror < 0 || txc->maxerror >= NTP_PHASE_LIMIT) {
result = -EINVAL;
goto leave;
}
time_maxerror = txc->maxerror;
}
if (txc->modes & ADJ_ESTERROR) {
if (txc->esterror < 0 || txc->esterror >= NTP_PHASE_LIMIT) {
result = -EINVAL;
goto leave;
}
time_esterror = txc->esterror;
}
if (txc->modes & ADJ_TIMECONST) { /* p. 24 */
if (txc->constant < 0) { /* NTP v4 uses values > 6 */
result = -EINVAL;
goto leave;
}
time_constant = txc->constant;
}
if (txc->modes & ADJ_OFFSET) { /* values checked earlier */
if (txc->modes == ADJ_OFFSET_SINGLESHOT) {
/* adjtime() is independent from ntp_adjtime() */
time_adjust = txc->offset;
}
else if ( time_status & (STA_PLL | STA_PPSTIME) ) {
ltemp = (time_status & (STA_PPSTIME | STA_PPSSIGNAL)) ==
(STA_PPSTIME | STA_PPSSIGNAL) ?
pps_offset : txc->offset;
/*
* Scale the phase adjustment and
* clamp to the operating range.
*/
if (ltemp > MAXPHASE)
time_offset = MAXPHASE << SHIFT_UPDATE;
else if (ltemp < -MAXPHASE)
time_offset = -(MAXPHASE << SHIFT_UPDATE);
else
time_offset = ltemp << SHIFT_UPDATE;
/*
* Select whether the frequency is to be controlled
* and in which mode (PLL or FLL). Clamp to the operating
* range. Ugly multiply/divide should be replaced someday.
*/
if (time_status & STA_FREQHOLD || time_reftime == 0)
time_reftime = xtime.tv_sec;
mtemp = xtime.tv_sec - time_reftime;
time_reftime = xtime.tv_sec;
if (time_status & STA_FLL) {
if (mtemp >= MINSEC) {
ltemp = (time_offset / mtemp) << (SHIFT_USEC -
SHIFT_UPDATE);
if (ltemp < 0)
time_freq -= -ltemp >> SHIFT_KH;
else
time_freq += ltemp >> SHIFT_KH;
} else /* calibration interval too short (p. 12) */
result = TIME_ERROR;
} else { /* PLL mode */
if (mtemp < MAXSEC) {
ltemp *= mtemp;
if (ltemp < 0)
time_freq -= -ltemp >> (time_constant +
time_constant +
SHIFT_KF - SHIFT_USEC);
else
time_freq += ltemp >> (time_constant +
time_constant +
SHIFT_KF - SHIFT_USEC);
} else /* calibration interval too long (p. 12) */
result = TIME_ERROR;
}
if (time_freq > time_tolerance)
time_freq = time_tolerance;
else if (time_freq < -time_tolerance)
time_freq = -time_tolerance;
} /* STA_PLL || STA_PPSTIME */
} /* txc->modes & ADJ_OFFSET */
if (txc->modes & ADJ_TICK) {
/* if the quartz is off by more than 10% something is
VERY wrong ! */
if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ) {
result = -EINVAL;
goto leave;
}
tick = txc->tick;
}
} /* txc->modes */
leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
|| ((time_status & (STA_PPSFREQ|STA_PPSTIME)) != 0
&& (time_status & STA_PPSSIGNAL) == 0)
/* p. 24, (b) */
|| ((time_status & (STA_PPSTIME|STA_PPSJITTER))
== (STA_PPSTIME|STA_PPSJITTER))
/* p. 24, (c) */
|| ((time_status & STA_PPSFREQ) != 0
&& (time_status & (STA_PPSWANDER|STA_PPSERROR)) != 0))
/* p. 24, (d) */
result = TIME_ERROR;
if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
txc->offset = save_adjust;
else {
if (time_offset < 0)
txc->offset = -(-time_offset >> SHIFT_UPDATE);
else
txc->offset = time_offset >> SHIFT_UPDATE;
}
txc->freq = time_freq + pps_freq;
txc->maxerror = time_maxerror;
txc->esterror = time_esterror;
txc->status = time_status;
txc->constant = time_constant;
txc->precision = time_precision;
txc->tolerance = time_tolerance;
txc->tick = tick;
txc->ppsfreq = pps_freq;
txc->jitter = pps_jitter >> PPS_AVG;
txc->shift = pps_shift;
txc->stabil = pps_stabil;
txc->jitcnt = pps_jitcnt;
txc->calcnt = pps_calcnt;
txc->errcnt = pps_errcnt;
txc->stbcnt = pps_stbcnt;
write_unlock_irq(&xtime_lock);
do_gettimeofday(&txc->time);
return(result);
}
asmlinkage long sys_adjtimex(struct timex *txc_p)
{
struct timex txc; /* Local copy of parameter */
int ret;
/* Copy the user data space into the kernel copy
* structure. But bear in mind that the structures
* may change
*/
if(copy_from_user(&txc, txc_p, sizeof(struct timex)))
return -EFAULT;
ret = do_adjtimex(&txc);
return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
}
-968
View File
@@ -1,968 +0,0 @@
/*
* linux/kernel/timer.c
*
* Kernel internal timers, kernel timekeeping, basic process system calls
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* 1997-01-28 Modified by Finn Arne Gangstad to make timers scale better.
*
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
* "A Kernel Model for Precision Timekeeping" by Dave Mills
* 1998-12-24 Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
* serialize accesses to xtime/lost_ticks).
* Copyright (C) 1998 Andrea Arcangeli
* 1999-03-10 Improved NTP compatibility by Ulrich Windl
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/timex.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <asm/uaccess.h>
/*
* Timekeeping variables
*/
long tick = (1000000 + HZ/2) / HZ; /* timer interrupt period */
/* The current time */
struct timeval xtime __attribute__ ((aligned (16)));
/* Don't completely fail for HZ > 500. */
int tickadj = 500/HZ ? : 1; /* microsecs */
DECLARE_TASK_QUEUE(tq_timer);
DECLARE_TASK_QUEUE(tq_immediate);
/*
* phase-lock loop variables
*/
/* TIME_ERROR prevents overwriting the CMOS clock */
int time_state = TIME_OK; /* clock synchronization status */
int time_status = STA_UNSYNC; /* clock status bits */
long time_offset; /* time adjustment (us) */
long time_constant = 2; /* pll time constant */
long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */
long time_precision = 1; /* clock precision (us) */
long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */
long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */
long time_phase; /* phase offset (scaled us) */
long time_freq = ((1000000 + HZ/2) % HZ - HZ/2) << SHIFT_USEC;
/* frequency offset (scaled ppm)*/
long time_adj; /* tick adjust (scaled 1 / HZ) */
long time_reftime; /* time at last adjustment (s) */
long time_adjust;
long time_adjust_step;
unsigned long event;
extern int do_setitimer(int, struct itimerval *, struct itimerval *);
unsigned long volatile jiffies;
unsigned int * prof_buffer;
unsigned long prof_len;
unsigned long prof_shift;
/*
* Event timer code
*/
#define TVN_BITS 6
#define TVR_BITS 8
#define TVN_SIZE (1 << TVN_BITS)
#define TVR_SIZE (1 << TVR_BITS)
#define TVN_MASK (TVN_SIZE - 1)
#define TVR_MASK (TVR_SIZE - 1)
struct timer_vec {
int index;
struct list_head vec[TVN_SIZE];
};
struct timer_vec_root {
int index;
struct list_head vec[TVR_SIZE];
};
static struct timer_vec tv5;
static struct timer_vec tv4;
static struct timer_vec tv3;
static struct timer_vec tv2;
static struct timer_vec_root tv1;
static struct timer_vec * const tvecs[] = {
(struct timer_vec *)&tv1, &tv2, &tv3, &tv4, &tv5
};
static struct list_head * run_timer_list_running;
#define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0]))
void init_timervecs (void)
{
int i;
for (i = 0; i < TVN_SIZE; i++) {
INIT_LIST_HEAD(tv5.vec + i);
INIT_LIST_HEAD(tv4.vec + i);
INIT_LIST_HEAD(tv3.vec + i);
INIT_LIST_HEAD(tv2.vec + i);
}
for (i = 0; i < TVR_SIZE; i++)
INIT_LIST_HEAD(tv1.vec + i);
}
static unsigned long timer_jiffies;
static inline void internal_add_timer(struct timer_list *timer)
{
/*
* must be cli-ed when calling this
*/
unsigned long expires = timer->expires;
unsigned long idx = expires - timer_jiffies;
struct list_head * vec;
if (run_timer_list_running)
vec = run_timer_list_running;
else if (idx < TVR_SIZE) {
int i = expires & TVR_MASK;
vec = tv1.vec + i;
} else if (idx < 1 << (TVR_BITS + TVN_BITS)) {
int i = (expires >> TVR_BITS) & TVN_MASK;
vec = tv2.vec + i;
} else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS)) {
int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK;
vec = tv3.vec + i;
} else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) {
int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
vec = tv4.vec + i;
} else if ((signed long) idx < 0) {
/* can happen if you add a timer with expires == jiffies,
* or you set a timer to go off in the past
*/
vec = tv1.vec + tv1.index;
} else if (idx <= 0xffffffffUL) {
int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
vec = tv5.vec + i;
} else {
/* Can only get here on architectures with 64-bit jiffies */
INIT_LIST_HEAD(&timer->list);
return;
}
/*
* Timers are FIFO!
*/
list_add(&timer->list, vec->prev);
}
/* Initialize both explicitly - let's try to have them in the same cache line */
spinlock_t timerlist_lock = SPIN_LOCK_UNLOCKED;
#ifdef CONFIG_SMP
volatile struct timer_list * volatile running_timer;
#define timer_enter(t) do { running_timer = t; mb(); } while (0)
#define timer_exit() do { running_timer = NULL; } while (0)
#define timer_is_running(t) (running_timer == t)
#define timer_synchronize(t) while (timer_is_running(t)) barrier()
#else
#define timer_enter(t) do { } while (0)
#define timer_exit() do { } while (0)
#endif
void add_timer(struct timer_list *timer)
{
unsigned long flags;
spin_lock_irqsave(&timerlist_lock, flags);
if (timer_pending(timer))
goto bug;
internal_add_timer(timer);
spin_unlock_irqrestore(&timerlist_lock, flags);
return;
bug:
spin_unlock_irqrestore(&timerlist_lock, flags);
printk("bug: kernel timer added twice at %p.\n",
__builtin_return_address(0));
}
static inline int detach_timer (struct timer_list *timer)
{
if (!timer_pending(timer))
return 0;
list_del(&timer->list);
return 1;
}
int mod_timer(struct timer_list *timer, unsigned long expires)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&timerlist_lock, flags);
timer->expires = expires;
ret = detach_timer(timer);
internal_add_timer(timer);
spin_unlock_irqrestore(&timerlist_lock, flags);
return ret;
}
int del_timer(struct timer_list * timer)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&timerlist_lock, flags);
ret = detach_timer(timer);
timer->list.next = timer->list.prev = NULL;
spin_unlock_irqrestore(&timerlist_lock, flags);
return ret;
}
#ifdef CONFIG_SMP
void sync_timers(void)
{
spin_unlock_wait(&global_bh_lock);
}
/*
* SMP specific function to delete periodic timer.
* Caller must disable by some means restarting the timer
* for new. Upon exit the timer is not queued and handler is not running
* on any CPU. It returns number of times, which timer was deleted
* (for reference counting).
*/
int del_timer_sync(struct timer_list * timer)
{
int ret = 0;
for (;;) {
unsigned long flags;
int running;
spin_lock_irqsave(&timerlist_lock, flags);
ret += detach_timer(timer);
timer->list.next = timer->list.prev = 0;
running = timer_is_running(timer);
spin_unlock_irqrestore(&timerlist_lock, flags);
if (!running)
break;
timer_synchronize(timer);
}
return ret;
}
#endif
static inline void cascade_timers(struct timer_vec *tv)
{
/* cascade all the timers from tv up one level */
struct list_head *head, *curr, *next;
head = tv->vec + tv->index;
curr = head->next;
/*
* We are removing _all_ timers from the list, so we don't have to
* detach them individually, just clear the list afterwards.
*/
while (curr != head) {
struct timer_list *tmp;
tmp = list_entry(curr, struct timer_list, list);
next = curr->next;
list_del(curr); // not needed
internal_add_timer(tmp);
curr = next;
}
INIT_LIST_HEAD(head);
tv->index = (tv->index + 1) & TVN_MASK;
}
static inline void run_timer_list(void)
{
spin_lock_irq(&timerlist_lock);
while ((long)(jiffies - timer_jiffies) >= 0) {
LIST_HEAD(queued);
struct list_head *head, *curr;
if (!tv1.index) {
int n = 1;
do {
cascade_timers(tvecs[n]);
} while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
}
run_timer_list_running = &queued;
repeat:
head = tv1.vec + tv1.index;
curr = head->next;
if (curr != head) {
struct timer_list *timer;
void (*fn)(unsigned long);
unsigned long data;
timer = list_entry(curr, struct timer_list, list);
fn = timer->function;
data= timer->data;
detach_timer(timer);
timer->list.next = timer->list.prev = NULL;
timer_enter(timer);
spin_unlock_irq(&timerlist_lock);
fn(data);
spin_lock_irq(&timerlist_lock);
timer_exit();
goto repeat;
}
run_timer_list_running = NULL;
++timer_jiffies;
tv1.index = (tv1.index + 1) & TVR_MASK;
curr = queued.next;
while (curr != &queued) {
struct timer_list *timer;
timer = list_entry(curr, struct timer_list, list);
curr = curr->next;
internal_add_timer(timer);
}
}
spin_unlock_irq(&timerlist_lock);
}
#ifdef CONFIG_NO_IDLE_HZ
/*
* Find out when the next timer event is due to happen. This
* is used on S/390 to stop all activity when all cpus are idle.
* And in XenoLinux to achieve the same.
* The timerlist_lock must be acquired before calling this function.
*/
struct timer_list *next_timer_event(void)
{
struct timer_list *nte, *tmp;
struct list_head *lst;
int i, j;
/* Look for the next timer event in tv1. */
i = 0;
j = tvecs[0]->index;
do {
struct list_head *head = tvecs[0]->vec + j;
if (!list_empty(head)) {
nte = list_entry(head->next, struct timer_list, list);
goto found;
}
j = (j + 1) & TVR_MASK;
} while (j != tv1.index);
/* No event found in tv1. Check tv2-tv5. */
for (i = 1; i < NOOF_TVECS; i++) {
j = tvecs[i]->index;
do {
nte = NULL;
list_for_each(lst, tvecs[i]->vec + j) {
tmp = list_entry(lst, struct timer_list, list);
if (nte == NULL ||
time_before(tmp->expires, nte->expires))
nte = tmp;
}
if (nte)
goto found;
j = (j + 1) & TVN_MASK;
} while (j != tvecs[i]->index);
}
return NULL;
found:
/* Found timer event in tvecs[i]->vec[j] */
if (j < tvecs[i]->index && i < NOOF_TVECS-1) {
/*
* The search wrapped. We need to look at the next list
* from tvecs[i+1] that would cascade into tvecs[i].
*/
list_for_each(lst, tvecs[i+1]->vec+tvecs[i+1]->index) {
tmp = list_entry(lst, struct timer_list, list);
if (time_before(tmp->expires, nte->expires))
nte = tmp;
}
}
return nte;
}
#endif
spinlock_t tqueue_lock = SPIN_LOCK_UNLOCKED;
void tqueue_bh(void)
{
run_task_queue(&tq_timer);
}
void immediate_bh(void)
{
run_task_queue(&tq_immediate);
}
/*
* this routine handles the overflow of the microsecond field
*
* The tricky bits of code to handle the accurate clock support
* were provided by Dave Mills (Mills@UDEL.EDU) of NTP fame.
* They were originally developed for SUN and DEC kernels.
* All the kudos should go to Dave for this stuff.
*
*/
static void second_overflow(void)
{
long ltemp;
/* Bump the maxerror field */
time_maxerror += time_tolerance >> SHIFT_USEC;
if ( time_maxerror > NTP_PHASE_LIMIT ) {
time_maxerror = NTP_PHASE_LIMIT;
time_status |= STA_UNSYNC;
}
/*
* Leap second processing. If in leap-insert state at
* the end of the day, the system clock is set back one
* second; if in leap-delete state, the system clock is
* set ahead one second. The microtime() routine or
* external clock driver will insure that reported time
* is always monotonic. The ugly divides should be
* replaced.
*/
switch (time_state) {
case TIME_OK:
if (time_status & STA_INS)
time_state = TIME_INS;
else if (time_status & STA_DEL)
time_state = TIME_DEL;
break;
case TIME_INS:
if (xtime.tv_sec % 86400 == 0) {
xtime.tv_sec--;
time_state = TIME_OOP;
printk(KERN_NOTICE "Clock: inserting leap second 23:59:60 UTC\n");
}
break;
case TIME_DEL:
if ((xtime.tv_sec + 1) % 86400 == 0) {
xtime.tv_sec++;
time_state = TIME_WAIT;
printk(KERN_NOTICE "Clock: deleting leap second 23:59:59 UTC\n");
}
break;
case TIME_OOP:
time_state = TIME_WAIT;
break;
case TIME_WAIT:
if (!(time_status & (STA_INS | STA_DEL)))
time_state = TIME_OK;
}
/*
* Compute the phase adjustment for the next second. In
* PLL mode, the offset is reduced by a fixed factor
* times the time constant. In FLL mode the offset is
* used directly. In either mode, the maximum phase
* adjustment for each second is clamped so as to spread
* the adjustment over not more than the number of
* seconds between updates.
*/
if (time_offset < 0) {
ltemp = -time_offset;
if (!(time_status & STA_FLL))
ltemp >>= SHIFT_KG + time_constant;
if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
time_offset += ltemp;
time_adj = -ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
} else {
ltemp = time_offset;
if (!(time_status & STA_FLL))
ltemp >>= SHIFT_KG + time_constant;
if (ltemp > (MAXPHASE / MINSEC) << SHIFT_UPDATE)
ltemp = (MAXPHASE / MINSEC) << SHIFT_UPDATE;
time_offset -= ltemp;
time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
}
/*
* Compute the frequency estimate and additional phase
* adjustment due to frequency error for the next
* second. When the PPS signal is engaged, gnaw on the
* watchdog counter and update the frequency computed by
* the pll and the PPS signal.
*/
pps_valid++;
if (pps_valid == PPS_VALID) { /* PPS signal lost */
pps_jitter = MAXTIME;
pps_stabil = MAXFREQ;
time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
STA_PPSWANDER | STA_PPSERROR);
}
ltemp = time_freq + pps_freq;
if (ltemp < 0)
time_adj -= -ltemp >>
(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
else
time_adj += ltemp >>
(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE);
#if HZ == 100
/* Compensate for (HZ==100) != (1 << SHIFT_HZ).
* Add 25% and 3.125% to get 128.125; => only 0.125% error (p. 14)
*/
if (time_adj < 0)
time_adj -= (-time_adj >> 2) + (-time_adj >> 5);
else
time_adj += (time_adj >> 2) + (time_adj >> 5);
#endif
}
/* in the NTP reference this is called "hardclock()" */
static void update_wall_time_one_tick(void)
{
if ( (time_adjust_step = time_adjust) != 0 ) {
/* We are doing an adjtime thing.
*
* Prepare time_adjust_step to be within bounds.
* Note that a positive time_adjust means we want the clock
* to run faster.
*
* Limit the amount of the step to be in the range
* -tickadj .. +tickadj
*/
if (time_adjust > tickadj)
time_adjust_step = tickadj;
else if (time_adjust < -tickadj)
time_adjust_step = -tickadj;
/* Reduce by this step the amount of time left */
time_adjust -= time_adjust_step;
}
xtime.tv_usec += tick + time_adjust_step;
/*
* Advance the phase, once it gets to one microsecond, then
* advance the tick more.
*/
time_phase += time_adj;
if (time_phase <= -FINEUSEC) {
long ltemp = -time_phase >> SHIFT_SCALE;
time_phase += ltemp << SHIFT_SCALE;
xtime.tv_usec -= ltemp;
}
else if (time_phase >= FINEUSEC) {
long ltemp = time_phase >> SHIFT_SCALE;
time_phase -= ltemp << SHIFT_SCALE;
xtime.tv_usec += ltemp;
}
}
/*
* Using a loop looks inefficient, but "ticks" is
* usually just one (we shouldn't be losing ticks,
* we're doing this this way mainly for interrupt
* latency reasons, not because we think we'll
* have lots of lost timer ticks
*/
static void update_wall_time(unsigned long ticks)
{
do {
ticks--;
update_wall_time_one_tick();
} while (ticks);
while (xtime.tv_usec >= 1000000) {
xtime.tv_usec -= 1000000;
xtime.tv_sec++;
second_overflow();
}
}
static inline void do_process_times(struct task_struct *p,
unsigned long user, unsigned long system)
{
unsigned long psecs;
psecs = (p->times.tms_utime += user);
psecs += (p->times.tms_stime += system);
if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
/* Send SIGXCPU every second.. */
if (!(psecs % HZ))
send_sig(SIGXCPU, p, 1);
/* and SIGKILL when we go over max.. */
if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_max)
send_sig(SIGKILL, p, 1);
}
}
static inline void do_it_virt(struct task_struct * p, unsigned long ticks)
{
unsigned long it_virt = p->it_virt_value;
if (it_virt) {
it_virt -= ticks;
if (!it_virt) {
it_virt = p->it_virt_incr;
send_sig(SIGVTALRM, p, 1);
}
p->it_virt_value = it_virt;
}
}
static inline void do_it_prof(struct task_struct *p)
{
unsigned long it_prof = p->it_prof_value;
if (it_prof) {
if (--it_prof == 0) {
it_prof = p->it_prof_incr;
send_sig(SIGPROF, p, 1);
}
p->it_prof_value = it_prof;
}
}
void update_one_process(struct task_struct *p, unsigned long user,
unsigned long system, int cpu)
{
p->per_cpu_utime[cpu] += user;
p->per_cpu_stime[cpu] += system;
do_process_times(p, user, system);
do_it_virt(p, user);
do_it_prof(p);
}
/*
* Called from the timer interrupt handler to charge one tick to the current
* process. user_tick is 1 if the tick is user time, 0 for system.
*/
void update_process_times(int user_tick)
{
struct task_struct *p = current;
int cpu = smp_processor_id(), system = user_tick ^ 1;
update_one_process(p, user_tick, system, cpu);
if (p->pid) {
if (--p->counter <= 0) {
p->counter = 0;
/*
* SCHED_FIFO is priority preemption, so this is
* not the place to decide whether to reschedule a
* SCHED_FIFO task or not - Bhavesh Davda
*/
if (p->policy != SCHED_FIFO) {
p->need_resched = 1;
}
}
if (p->nice > 0)
kstat.per_cpu_nice[cpu] += user_tick;
else
kstat.per_cpu_user[cpu] += user_tick;
kstat.per_cpu_system[cpu] += system;
} else if (local_bh_count(cpu) || local_irq_count(cpu) > 1)
kstat.per_cpu_system[cpu] += system;
}
/*
* Called from the timer interrupt handler to charge a couple of ticks
* to the current process.
*/
void update_process_times_us(int user_ticks, int system_ticks)
{
struct task_struct *p = current;
int cpu = smp_processor_id();
update_one_process(p, user_ticks, system_ticks, cpu);
if (p->pid) {
p->counter -= user_ticks + system_ticks;
if (p->counter <= 0) {
p->counter = 0;
p->need_resched = 1;
}
if (p->nice > 0)
kstat.per_cpu_nice[cpu] += user_ticks;
else
kstat.per_cpu_user[cpu] += user_ticks;
kstat.per_cpu_system[cpu] += system_ticks;
} else if (local_bh_count(cpu) || local_irq_count(cpu) > 1)
kstat.per_cpu_system[cpu] += system_ticks;
}
/*
* Nr of active tasks - counted in fixed-point numbers
*/
static unsigned long count_active_tasks(void)
{
struct task_struct *p;
unsigned long nr = 0;
read_lock(&tasklist_lock);
for_each_task(p) {
if ((p->state == TASK_RUNNING ||
(p->state & TASK_UNINTERRUPTIBLE)))
nr += FIXED_1;
}
read_unlock(&tasklist_lock);
return nr;
}
/*
* Hmm.. Changed this, as the GNU make sources (load.c) seems to
* imply that avenrun[] is the standard name for this kind of thing.
* Nothing else seems to be standardized: the fractional size etc
* all seem to differ on different machines.
*/
unsigned long avenrun[3];
static inline void calc_load(unsigned long ticks)
{
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;
count -= ticks;
while (count < 0) {
count += LOAD_FREQ;
active_tasks = count_active_tasks();
CALC_LOAD(avenrun[0], EXP_1, active_tasks);
CALC_LOAD(avenrun[1], EXP_5, active_tasks);
CALC_LOAD(avenrun[2], EXP_15, active_tasks);
}
}
/* jiffies at the most recent update of wall time */
unsigned long wall_jiffies;
/*
* This spinlock protect us from races in SMP while playing with xtime. -arca
*/
rwlock_t xtime_lock = RW_LOCK_UNLOCKED;
static inline void update_times(void)
{
unsigned long ticks;
/*
* update_times() is run from the raw timer_bh handler so we
* just know that the irqs are locally enabled and so we don't
* need to save/restore the flags of the local CPU here. -arca
*/
write_lock_irq(&xtime_lock);
vxtime_lock();
ticks = jiffies - wall_jiffies;
if (ticks) {
wall_jiffies += ticks;
update_wall_time(ticks);
}
vxtime_unlock();
write_unlock_irq(&xtime_lock);
calc_load(ticks);
}
void timer_bh(void)
{
update_times();
run_timer_list();
}
void do_timer(struct pt_regs *regs)
{
(*(unsigned long *)&jiffies)++;
#ifndef CONFIG_SMP
/* SMP process accounting uses the local APIC timer */
update_process_times(user_mode(regs));
#endif
mark_bh(TIMER_BH);
if (TQ_ACTIVE(tq_timer))
mark_bh(TQUEUE_BH);
}
void do_timer_ticks(int ticks)
{
(*(unsigned long *)&jiffies) += ticks;
mark_bh(TIMER_BH);
if (TQ_ACTIVE(tq_timer))
mark_bh(TQUEUE_BH);
}
#if !defined(__alpha__) && !defined(__ia64__)
/*
* For backwards compatibility? This can be done in libc so Alpha
* and all newer ports shouldn't need it.
*/
asmlinkage unsigned long sys_alarm(unsigned int seconds)
{
struct itimerval it_new, it_old;
unsigned int oldalarm;
it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
it_new.it_value.tv_sec = seconds;
it_new.it_value.tv_usec = 0;
do_setitimer(ITIMER_REAL, &it_new, &it_old);
oldalarm = it_old.it_value.tv_sec;
/* ehhh.. We can't return 0 if we have an alarm pending.. */
/* And we'd better return too much than too little anyway */
if (it_old.it_value.tv_usec)
oldalarm++;
return oldalarm;
}
#endif
#ifndef __alpha__
/*
* The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this
* should be moved into arch/i386 instead?
*/
/**
* sys_getpid - return the thread group id of the current process
*
* Note, despite the name, this returns the tgid not the pid. The tgid and
* the pid are identical unless CLONE_THREAD was specified on clone() in
* which case the tgid is the same in all threads of the same group.
*
* This is SMP safe as current->tgid does not change.
*/
asmlinkage long sys_getpid(void)
{
return current->tgid;
}
/*
* This is not strictly SMP safe: p_opptr could change
* from under us. However, rather than getting any lock
* we can use an optimistic algorithm: get the parent
* pid, and go back and check that the parent is still
* the same. If it has changed (which is extremely unlikely
* indeed), we just try again..
*
* NOTE! This depends on the fact that even if we _do_
* get an old value of "parent", we can happily dereference
* the pointer: we just can't necessarily trust the result
* until we know that the parent pointer is valid.
*
* The "mb()" macro is a memory barrier - a synchronizing
* event. It also makes sure that gcc doesn't optimize
* away the necessary memory references.. The barrier doesn't
* have to have all that strong semantics: on x86 we don't
* really require a synchronizing instruction, for example.
* The barrier is more important for code generation than
* for any real memory ordering semantics (even if there is
* a small window for a race, using the old pointer is
* harmless for a while).
*/
asmlinkage long sys_getppid(void)
{
int pid;
struct task_struct * me = current;
struct task_struct * parent;
parent = me->p_opptr;
for (;;) {
pid = parent->pid;
#if CONFIG_SMP
{
struct task_struct *old = parent;
mb();
parent = me->p_opptr;
if (old != parent)
continue;
}
#endif
break;
}
return pid;
}
asmlinkage long sys_getuid(void)
{
/* Only we change this so SMP safe */
return current->uid;
}
asmlinkage long sys_geteuid(void)
{
/* Only we change this so SMP safe */
return current->euid;
}
asmlinkage long sys_getgid(void)
{
/* Only we change this so SMP safe */
return current->gid;
}
asmlinkage long sys_getegid(void)
{
/* Only we change this so SMP safe */
return current->egid;
}
#endif
/* Thread ID - the internal kernel "pid" */
asmlinkage long sys_gettid(void)
{
return current->pid;
}
asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
{
struct timespec t;
unsigned long expire;
if(copy_from_user(&t, rqtp, sizeof(struct timespec)))
return -EFAULT;
if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
return -EINVAL;
if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
current->policy != SCHED_OTHER)
{
/*
* Short delay requests up to 2 ms will be handled with
* high precision by a busy wait for all real-time processes.
*
* Its important on SMP not to do this holding locks.
*/
udelay((t.tv_nsec + 999) / 1000);
return 0;
}
expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
current->state = TASK_INTERRUPTIBLE;
expire = schedule_timeout(expire);
if (expire) {
if (rmtp) {
jiffies_to_timespec(expire, &t);
if (copy_to_user(rmtp, &t, sizeof(struct timespec)))
return -EFAULT;
}
return -EINTR;
}
return 0;
}
-291
View File
@@ -1,291 +0,0 @@
#!/bin/bash
# mkbuildtree <build tree>
#
# Creates symbolic links in <build tree> for the sparse tree
# in the current directory.
# Script to determine the relative path between two directories.
# Copyright (c) D. J. Hawkey Jr. 2002
# Fixed for Xen project by K. Fraser in 2003.
abs_to_rel ()
{
local CWD SRCPATH
if [ "$1" != "/" -a "${1##*[^/]}" = "/" ]; then
SRCPATH=${1%?}
else
SRCPATH=$1
fi
if [ "$2" != "/" -a "${2##*[^/]}" = "/" ]; then
DESTPATH=${2%?}
else
DESTPATH=$2
fi
CWD=$PWD
[ "${1%%[^/]*}" != "/" ] && cd $1 && SRCPATH=$PWD
[ "${2%%[^/]*}" != "/" ] && cd $2 && DESTPATH=$PWD
[ "$CWD" != "$PWD" ] && cd $CWD
BASEPATH=$SRCPATH
[ "$SRCPATH" = "$DESTPATH" ] && DESTPATH="." && return
[ "$SRCPATH" = "/" ] && DESTPATH=${DESTPATH#?} && return
while [ "$BASEPATH/" != "${DESTPATH%${DESTPATH#$BASEPATH/}}" ]; do
BASEPATH=${BASEPATH%/*}
done
SRCPATH=${SRCPATH#$BASEPATH}
DESTPATH=${DESTPATH#$BASEPATH}
DESTPATH=${DESTPATH#?}
while [ -n "$SRCPATH" ]; do
SRCPATH=${SRCPATH%/*}
DESTPATH="../$DESTPATH"
done
[ -z "$BASEPATH" ] && BASEPATH="/"
[ "${DESTPATH##*[^/]}" = "/" ] && DESTPATH=${DESTPATH%?}
}
# relative_lndir <target_dir>
# Creates a tree of symlinks in the current working directory that mirror
# real files in <target_dir>. <target_dir> should be relative to the current
# working directory. Symlinks in <target_dir> are ignored. Source-control files
# are ignored.
relative_lndir ()
{
local SYMLINK_DIR REAL_DIR pref i j
SYMLINK_DIR=$PWD
REAL_DIR=$1
(
cd $REAL_DIR
for i in `find . -type d | grep -v SCCS`; do
[ -d $SYMLINK_DIR/$i ] || mkdir -p $SYMLINK_DIR/$i
(
cd $i
pref=`echo $i | sed -e 's#/[^/]*#../#g' -e 's#^\.##'`
for j in `find . -maxdepth 1 -type f -o -type l`; do
ln -sf ${pref}${REAL_DIR}/$i/$j ${SYMLINK_DIR}/$i/$j
done
)
done
)
}
[ "$1" == "" ] && { echo "Syntax: $0 <linux tree to xenify>"; exit 1; }
# Get absolute path to the destination directory
pushd . >/dev/null
cd ${1} || { echo "cannot cd to ${1}"; exit 1; }
AD=$PWD
popd >/dev/null
# Get absolute path to the source directory
AS=`pwd`
# Get path to source, relative to destination
abs_to_rel ${AD} ${AS}
RS=$DESTPATH
# Remove old copies of files and directories at the destination
for i in `find . -type f -o -type l` ; do rm -f ${AD}/${i#./} ; done
# We now work from the destination directory
cd ${AD} || { echo "cannot cd to ${AD}"; exit 1; }
# Remove old symlinks
for i in `find . -type l`; do rm -f $i; done
# Create symlinks of files and directories which exist in the sparse source
relative_lndir ${RS}
rm -f mkbuildtree
LINUX_26=${RS}/../linux-2.6-xen-sparse
[ -d $LINUX_26 ] || { echo "no Linux 2.6 sparse tree at ${RS}/../linux-2.6-xen-sparse"; exit 1; }
# Create links to the shared definitions of the Xen interfaces.
rm -rf ${AD}/include/asm-xen/xen-public
mkdir ${AD}/include/asm-xen/xen-public
cd ${AD}/include/asm-xen/xen-public
relative_lndir ../../../${RS}/../xen/include/public
# Create a link to the shared definitions for the control interface
cd ${AD}/include/asm-xen
## Symlinks for files:
## - which are identical in the i386 and xen-i386 architecture-dependent
## subdirectories.
## - which are identical in the Linux 2.6 and Linux 2.4 ports.
cd ${AD}/include/asm-xen
ln -sf ../asm-i386/a.out.h
ln -sf ../asm-i386/apicdef.h
ln -sf ../asm-i386/apic.h
ln -sf ../asm-i386/atomic.h
ln -sf ../asm-i386/bitops.h
ln -sf ../asm-i386/boot.h
ln -sf ../asm-i386/byteorder.h
ln -sf ../asm-i386/cache.h
ln -sf ../asm-i386/checksum.h
ln -sf ../asm-i386/cpufeature.h
ln -sf ../asm-i386/current.h
ln -sf ../asm-i386/debugreg.h
ln -sf ../asm-i386/delay.h
ln -sf ../asm-i386/div64.h
ln -sf ../asm-i386/dma.h
ln -sf ../asm-i386/elf.h
ln -sf ../asm-i386/errno.h
ln -sf ../asm-i386/fcntl.h
ln -sf ../asm-i386/floppy.h
ln -sf ../asm-i386/hardirq.h
ln -sf ../asm-i386/hdreg.h
ln -sf ../asm-i386/i387.h
ln -sf ../asm-i386/ide.h
ln -sf ../asm-i386/init.h
ln -sf ../asm-i386/io_apic.h
ln -sf ../asm-i386/ioctl.h
ln -sf ../asm-i386/ioctls.h
ln -sf ../asm-i386/ipcbuf.h
ln -sf ../asm-i386/ipc.h
ln -sf ../asm-i386/kmap_types.h
ln -sf ../asm-i386/ldt.h
ln -sf ../asm-i386/linux_logo.h
ln -sf ../asm-i386/locks.h
ln -sf ../asm-i386/math_emu.h
ln -sf ../asm-i386/mc146818rtc.h
ln -sf ../asm-i386/mca_dma.h
ln -sf ../asm-i386/mman.h
ln -sf ../asm-i386/mmu.h
ln -sf ../asm-i386/mmx.h
ln -sf ../asm-i386/mpspec.h
ln -sf ../asm-i386/msgbuf.h
ln -sf ../asm-i386/msr.h
ln -sf ../asm-i386/mtrr.h
ln -sf ../asm-i386/namei.h
ln -sf ../asm-i386/param.h
ln -sf ../asm-i386/parport.h
ln -sf ../asm-i386/pgtable-3level.h
ln -sf ../asm-i386/poll.h
ln -sf ../asm-i386/posix_types.h
ln -sf ../asm-i386/ptrace.h
ln -sf ../asm-i386/resource.h
ln -sf ../asm-i386/rwlock.h
ln -sf ../asm-i386/rwsem.h
ln -sf ../asm-i386/scatterlist.h
ln -sf ../asm-i386/semaphore.h
ln -sf ../asm-i386/sembuf.h
ln -sf ../asm-i386/serial.h
ln -sf ../asm-i386/setup.h
ln -sf ../asm-i386/shmbuf.h
ln -sf ../asm-i386/shmparam.h
ln -sf ../asm-i386/sigcontext.h
ln -sf ../asm-i386/siginfo.h
ln -sf ../asm-i386/signal.h
ln -sf ../asm-i386/smplock.h
ln -sf ../asm-i386/socket.h
ln -sf ../asm-i386/sockios.h
ln -sf ../asm-i386/softirq.h
ln -sf ../asm-i386/spinlock.h
ln -sf ../asm-i386/statfs.h
ln -sf ../asm-i386/stat.h
ln -sf ../asm-i386/string-486.h
ln -sf ../asm-i386/string.h
ln -sf ../asm-i386/termbits.h
ln -sf ../asm-i386/termios.h
ln -sf ../asm-i386/timex.h
ln -sf ../asm-i386/tlb.h
ln -sf ../asm-i386/types.h
ln -sf ../asm-i386/uaccess.h
ln -sf ../asm-i386/ucontext.h
ln -sf ../asm-i386/unaligned.h
ln -sf ../asm-i386/unistd.h
ln -sf ../asm-i386/user.h
ln -sf ../asm-i386/vm86.h
ln -sf ../../${LINUX_26}/include/asm-xen/balloon.h
ln -sf ../../${LINUX_26}/include/asm-xen/ctrl_if.h
ln -sf ../../${LINUX_26}/include/asm-xen/evtchn.h
ln -sf ../../${LINUX_26}/include/asm-xen/gnttab.h
ln -sf ../../${LINUX_26}/include/asm-xen/hypervisor.h
ln -sf ../../${LINUX_26}/include/asm-xen/xen_proc.h
ln -sf ../../${LINUX_26}/include/asm-xen/asm-i386/synch_bitops.h
ln -sf ../../${LINUX_26}/include/asm-xen/asm-i386/hypercall.h
mkdir -p linux-public && cd linux-public
ln -sf ../../../${LINUX_26}/include/asm-xen/linux-public/privcmd.h
ln -sf ../../../${LINUX_26}/include/asm-xen/linux-public/suspend.h
cd ${AD}/arch/xen/kernel
ln -sf ../../i386/kernel/i387.c
ln -sf ../../i386/kernel/init_task.c
ln -sf ../../i386/kernel/pci-i386.c
ln -sf ../../i386/kernel/pci-i386.h
ln -sf ../../i386/kernel/ptrace.c
ln -sf ../../i386/kernel/semaphore.c
ln -sf ../../i386/kernel/sys_i386.c
ln -sf ../../../${LINUX_26}/arch/xen/kernel/ctrl_if.c
ln -sf ../../../${LINUX_26}/arch/xen/kernel/evtchn.c
ln -sf ../../../${LINUX_26}/arch/xen/kernel/fixup.c
ln -sf ../../../${LINUX_26}/arch/xen/kernel/gnttab.c
ln -sf ../../../${LINUX_26}/arch/xen/kernel/reboot.c
ln -sf ../../../${LINUX_26}/arch/xen/kernel/skbuff.c
cd ${AD}/arch/xen/lib
ln -sf ../../i386/lib/checksum.S
ln -sf ../../i386/lib/dec_and_lock.c
ln -sf ../../i386/lib/getuser.S
ln -sf ../../i386/lib/iodebug.c
ln -sf ../../i386/lib/memcpy.c
ln -sf ../../i386/lib/mmx.c
ln -sf ../../i386/lib/old-checksum.c
ln -sf ../../i386/lib/strstr.c
ln -sf ../../i386/lib/usercopy.c
ln -sf ../../../${LINUX_26}/arch/xen/kernel/xen_proc.c
cd ${AD}/arch/xen/mm
ln -sf ../../i386/mm/extable.c
ln -sf ../../i386/mm/pageattr.c
ln -sf ../../../${LINUX_26}/arch/xen/i386/mm/hypervisor.c
cd ${AD}/arch/xen/drivers/balloon
ln -sf ../../../../${LINUX_26}/drivers/xen/balloon/balloon.c
cd ${AD}/arch/xen/drivers/console
ln -sf ../../../../${LINUX_26}/drivers/xen/console/console.c
cd ${AD}/arch/xen/drivers/dom0
ln -sf ../../../../${LINUX_26}/drivers/xen/privcmd/privcmd.c core.c
cd ${AD}/arch/xen/drivers/evtchn
ln -sf ../../../../${LINUX_26}/drivers/xen/evtchn/evtchn.c
cd ${AD}/arch/xen/drivers/netif/frontend
ln -sf ../../../../../${LINUX_26}/drivers/xen/netfront/netfront.c main.c
cd ${AD}/arch/xen/drivers/netif/backend
ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/common.h
ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/control.c
ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/interface.c
ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/netback.c main.c
cd ${AD}/arch/xen/drivers/blkif/backend
ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/common.h
ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/blkback.c main.c
ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/control.c
ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/interface.c
ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/vbd.c
cd ${AD}/arch/xen/drivers/blkif/frontend
ln -sf ../../../../../${LINUX_26}/drivers/xen/blkfront/blkfront.c
cd ${AD}/arch/xen/drivers/usbif/frontend
ln -sf ../../../../../${LINUX_26}/drivers/xen/usbfront/usbfront.c main.c
ln -sf ../../../../../${LINUX_26}/drivers/xen/usbfront/xhci.h
cd ${AD}/arch/xen/drivers/usbif/backend
ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/common.h
ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/control.c
ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/interface.c
ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/usbback.c main.c
-461
View File
@@ -1,461 +0,0 @@
/*
* High memory handling common code and variables.
*
* (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de
* Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de
*
*
* Redesigned the x86 32-bit VM architecture to deal with
* 64-bit physical space. With current x86 CPUs this
* means up to 64 Gigabytes physical RAM.
*
* Rewrote high memory support to move the page cache into
* high memory. Implemented permanent (schedulable) kmaps
* based on Linus' idea.
*
* Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
*/
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/swap.h>
#include <linux/slab.h>
/*
* Virtual_count is not a pure "count".
* 0 means that it is not mapped, and has not been mapped
* since a TLB flush - it is usable.
* 1 means that there are no users, but it has been mapped
* since the last TLB flush - so we can't use it.
* n means that there are (n-1) current users of it.
*/
static int pkmap_count[LAST_PKMAP];
static unsigned int last_pkmap_nr;
static spinlock_cacheline_t kmap_lock_cacheline = {SPIN_LOCK_UNLOCKED};
#define kmap_lock kmap_lock_cacheline.lock
pte_t * pkmap_page_table;
static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait);
static void flush_all_zero_pkmaps(void)
{
int i;
flush_cache_all();
for (i = 0; i < LAST_PKMAP; i++) {
struct page *page;
/*
* zero means we don't have anything to do,
* >1 means that it is still in use. Only
* a count of 1 means that it is free but
* needs to be unmapped
*/
if (pkmap_count[i] != 1)
continue;
pkmap_count[i] = 0;
/* sanity check */
if (pte_none(pkmap_page_table[i]))
BUG();
/*
* Don't need an atomic fetch-and-clear op here;
* no-one has the page mapped, and cannot get at
* its virtual address (and hence PTE) without first
* getting the kmap_lock (which is held here).
* So no dangers, even with speculative execution.
*/
page = pte_page(pkmap_page_table[i]);
pte_clear(&pkmap_page_table[i]);
page->virtual = NULL;
}
flush_tlb_all();
}
static inline unsigned long map_new_virtual(struct page *page, int nonblocking)
{
unsigned long vaddr;
int count;
start:
count = LAST_PKMAP;
/* Find an empty entry */
for (;;) {
last_pkmap_nr = (last_pkmap_nr + 1) & LAST_PKMAP_MASK;
if (!last_pkmap_nr) {
flush_all_zero_pkmaps();
count = LAST_PKMAP;
}
if (!pkmap_count[last_pkmap_nr])
break; /* Found a usable entry */
if (--count)
continue;
if (nonblocking)
return 0;
/*
* Sleep for somebody else to unmap their entries
*/
{
DECLARE_WAITQUEUE(wait, current);
current->state = TASK_UNINTERRUPTIBLE;
add_wait_queue(&pkmap_map_wait, &wait);
spin_unlock(&kmap_lock);
schedule();
remove_wait_queue(&pkmap_map_wait, &wait);
spin_lock(&kmap_lock);
/* Somebody else might have mapped it while we slept */
if (page->virtual)
return (unsigned long) page->virtual;
/* Re-start */
goto start;
}
}
vaddr = PKMAP_ADDR(last_pkmap_nr);
set_pte(&(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot));
pkmap_count[last_pkmap_nr] = 1;
page->virtual = (void *) vaddr;
return vaddr;
}
void kmap_flush_unused(void)
{
spin_lock(&kmap_lock);
flush_all_zero_pkmaps();
spin_unlock(&kmap_lock);
}
void fastcall *kmap_high(struct page *page, int nonblocking)
{
unsigned long vaddr;
/*
* For highmem pages, we can't trust "virtual" until
* after we have the lock.
*
* We cannot call this from interrupts, as it may block
*/
spin_lock(&kmap_lock);
vaddr = (unsigned long) page->virtual;
if (!vaddr) {
vaddr = map_new_virtual(page, nonblocking);
if (!vaddr)
goto out;
}
pkmap_count[PKMAP_NR(vaddr)]++;
if (pkmap_count[PKMAP_NR(vaddr)] < 2)
BUG();
out:
spin_unlock(&kmap_lock);
return (void*) vaddr;
}
void fastcall kunmap_high(struct page *page)
{
unsigned long vaddr;
unsigned long nr;
int need_wakeup;
spin_lock(&kmap_lock);
vaddr = (unsigned long) page->virtual;
if (!vaddr)
BUG();
nr = PKMAP_NR(vaddr);
/*
* A count must never go down to zero
* without a TLB flush!
*/
need_wakeup = 0;
switch (--pkmap_count[nr]) {
case 0:
BUG();
case 1:
/*
* Avoid an unnecessary wake_up() function call.
* The common case is pkmap_count[] == 1, but
* no waiters.
* The tasks queued in the wait-queue are guarded
* by both the lock in the wait-queue-head and by
* the kmap_lock. As the kmap_lock is held here,
* no need for the wait-queue-head's lock. Simply
* test if the queue is empty.
*/
need_wakeup = waitqueue_active(&pkmap_map_wait);
}
spin_unlock(&kmap_lock);
/* do wake-up, if needed, race-free outside of the spin lock */
if (need_wakeup)
wake_up(&pkmap_map_wait);
}
#define POOL_SIZE 32
/*
* This lock gets no contention at all, normally.
*/
static spinlock_t emergency_lock = SPIN_LOCK_UNLOCKED;
int nr_emergency_pages;
static LIST_HEAD(emergency_pages);
int nr_emergency_bhs;
static LIST_HEAD(emergency_bhs);
/*
* Simple bounce buffer support for highmem pages.
* This will be moved to the block layer in 2.5.
*/
static inline void copy_from_high_bh (struct buffer_head *to,
struct buffer_head *from)
{
struct page *p_from;
char *vfrom;
p_from = from->b_page;
vfrom = kmap_atomic(p_from, KM_USER0);
memcpy(to->b_data, vfrom + bh_offset(from), to->b_size);
kunmap_atomic(vfrom, KM_USER0);
}
static inline void copy_to_high_bh_irq (struct buffer_head *to,
struct buffer_head *from)
{
struct page *p_to;
char *vto;
unsigned long flags;
p_to = to->b_page;
__save_flags(flags);
__cli();
vto = kmap_atomic(p_to, KM_BOUNCE_READ);
memcpy(vto + bh_offset(to), from->b_data, to->b_size);
kunmap_atomic(vto, KM_BOUNCE_READ);
__restore_flags(flags);
}
static inline void bounce_end_io (struct buffer_head *bh, int uptodate)
{
struct page *page;
struct buffer_head *bh_orig = (struct buffer_head *)(bh->b_private);
unsigned long flags;
bh_orig->b_end_io(bh_orig, uptodate);
page = bh->b_page;
spin_lock_irqsave(&emergency_lock, flags);
if (nr_emergency_pages >= POOL_SIZE)
__free_page(page);
else {
/*
* We are abusing page->list to manage
* the highmem emergency pool:
*/
list_add(&page->list, &emergency_pages);
nr_emergency_pages++;
}
if (nr_emergency_bhs >= POOL_SIZE) {
#ifdef HIGHMEM_DEBUG
/* Don't clobber the constructed slab cache */
init_waitqueue_head(&bh->b_wait);
#endif
kmem_cache_free(bh_cachep, bh);
} else {
/*
* Ditto in the bh case, here we abuse b_inode_buffers:
*/
list_add(&bh->b_inode_buffers, &emergency_bhs);
nr_emergency_bhs++;
}
spin_unlock_irqrestore(&emergency_lock, flags);
}
static __init int init_emergency_pool(void)
{
struct sysinfo i;
si_meminfo(&i);
si_swapinfo(&i);
if (!i.totalhigh)
return 0;
spin_lock_irq(&emergency_lock);
while (nr_emergency_pages < POOL_SIZE) {
struct page * page = alloc_page(GFP_ATOMIC);
if (!page) {
printk("couldn't refill highmem emergency pages");
break;
}
list_add(&page->list, &emergency_pages);
nr_emergency_pages++;
}
while (nr_emergency_bhs < POOL_SIZE) {
struct buffer_head * bh = kmem_cache_alloc(bh_cachep, SLAB_ATOMIC);
if (!bh) {
printk("couldn't refill highmem emergency bhs");
break;
}
list_add(&bh->b_inode_buffers, &emergency_bhs);
nr_emergency_bhs++;
}
spin_unlock_irq(&emergency_lock);
printk("allocated %d pages and %d bhs reserved for the highmem bounces\n",
nr_emergency_pages, nr_emergency_bhs);
return 0;
}
__initcall(init_emergency_pool);
static void bounce_end_io_write (struct buffer_head *bh, int uptodate)
{
bounce_end_io(bh, uptodate);
}
static void bounce_end_io_read (struct buffer_head *bh, int uptodate)
{
struct buffer_head *bh_orig = (struct buffer_head *)(bh->b_private);
if (uptodate)
copy_to_high_bh_irq(bh_orig, bh);
bounce_end_io(bh, uptodate);
}
struct page *alloc_bounce_page (void)
{
struct list_head *tmp;
struct page *page;
page = alloc_page(GFP_NOHIGHIO);
if (page)
return page;
/*
* No luck. First, kick the VM so it doesn't idle around while
* we are using up our emergency rations.
*/
wakeup_bdflush();
repeat_alloc:
/*
* Try to allocate from the emergency pool.
*/
tmp = &emergency_pages;
spin_lock_irq(&emergency_lock);
if (!list_empty(tmp)) {
page = list_entry(tmp->next, struct page, list);
list_del(tmp->next);
nr_emergency_pages--;
}
spin_unlock_irq(&emergency_lock);
if (page)
return page;
/* we need to wait I/O completion */
run_task_queue(&tq_disk);
yield();
goto repeat_alloc;
}
struct buffer_head *alloc_bounce_bh (void)
{
struct list_head *tmp;
struct buffer_head *bh;
bh = kmem_cache_alloc(bh_cachep, SLAB_NOHIGHIO);
if (bh)
return bh;
/*
* No luck. First, kick the VM so it doesn't idle around while
* we are using up our emergency rations.
*/
wakeup_bdflush();
repeat_alloc:
/*
* Try to allocate from the emergency pool.
*/
tmp = &emergency_bhs;
spin_lock_irq(&emergency_lock);
if (!list_empty(tmp)) {
bh = list_entry(tmp->next, struct buffer_head, b_inode_buffers);
list_del(tmp->next);
nr_emergency_bhs--;
}
spin_unlock_irq(&emergency_lock);
if (bh)
return bh;
/* we need to wait I/O completion */
run_task_queue(&tq_disk);
yield();
goto repeat_alloc;
}
struct buffer_head * create_bounce(int rw, struct buffer_head * bh_orig)
{
struct page *page;
struct buffer_head *bh;
if (!PageHighMem(bh_orig->b_page))
return bh_orig;
bh = alloc_bounce_bh();
/*
* This is wasteful for 1k buffers, but this is a stopgap measure
* and we are being ineffective anyway. This approach simplifies
* things immensly. On boxes with more than 4GB RAM this should
* not be an issue anyway.
*/
page = alloc_bounce_page();
set_bh_page(bh, page, 0);
bh->b_next = NULL;
bh->b_blocknr = bh_orig->b_blocknr;
bh->b_size = bh_orig->b_size;
bh->b_list = -1;
bh->b_dev = bh_orig->b_dev;
bh->b_count = bh_orig->b_count;
bh->b_rdev = bh_orig->b_rdev;
bh->b_state = bh_orig->b_state;
#ifdef HIGHMEM_DEBUG
bh->b_flushtime = jiffies;
bh->b_next_free = NULL;
bh->b_prev_free = NULL;
/* bh->b_this_page */
bh->b_reqnext = NULL;
bh->b_pprev = NULL;
#endif
/* bh->b_page */
if (rw == WRITE) {
bh->b_end_io = bounce_end_io_write;
copy_from_high_bh(bh, bh_orig);
} else
bh->b_end_io = bounce_end_io_read;
bh->b_private = (void *)bh_orig;
bh->b_rsector = bh_orig->b_rsector;
#ifdef HIGHMEM_DEBUG
memset(&bh->b_wait, -1, sizeof(bh->b_wait));
#endif
return bh;
}
File diff suppressed because it is too large. Load diff
-344
View File
@@ -1,344 +0,0 @@
/*
* linux/mm/mprotect.c
*
* (C) Copyright 1994 Linus Torvalds
*/
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/shm.h>
#include <linux/mman.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
static inline void change_pte_range(pmd_t * pmd, unsigned long address,
unsigned long size, pgprot_t newprot)
{
pte_t * pte;
unsigned long end;
if (pmd_none(*pmd))
return;
if (pmd_bad(*pmd)) {
pmd_ERROR(*pmd);
pmd_clear(pmd);
return;
}
pte = pte_offset(pmd, address);
address &= ~PMD_MASK;
end = address + size;
if (end > PMD_SIZE)
end = PMD_SIZE;
do {
if (pte_present(*pte)) {
pte_t entry;
/* Avoid an SMP race with hardware updated dirty/clean
* bits by wiping the pte and then setting the new pte
* into place.
*/
entry = ptep_get_and_clear(pte);
set_pte(pte, pte_modify(entry, newprot));
}
address += PAGE_SIZE;
pte++;
} while (address && (address < end));
}
static inline void change_pmd_range(pgd_t * pgd, unsigned long address,
unsigned long size, pgprot_t newprot)
{
pmd_t * pmd;
unsigned long end;
if (pgd_none(*pgd))
return;
if (pgd_bad(*pgd)) {
pgd_ERROR(*pgd);
pgd_clear(pgd);
return;
}
pmd = pmd_offset(pgd, address);
address &= ~PGDIR_MASK;
end = address + size;
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
do {
change_pte_range(pmd, address, end - address, newprot);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address && (address < end));
}
static void change_protection(unsigned long start, unsigned long end, pgprot_t newprot)
{
pgd_t *dir;
unsigned long beg = start;
dir = pgd_offset(current->mm, start);
flush_cache_range(current->mm, beg, end);
if (start >= end)
BUG();
spin_lock(&current->mm->page_table_lock);
do {
change_pmd_range(dir, start, end - start, newprot);
start = (start + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (start && (start < end));
spin_unlock(&current->mm->page_table_lock);
flush_tlb_range(current->mm, beg, end);
return;
}
static inline int mprotect_fixup_all(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
int newflags, pgprot_t prot)
{
struct vm_area_struct * prev = *pprev;
struct mm_struct * mm = vma->vm_mm;
if (prev && prev->vm_end == vma->vm_start && can_vma_merge(prev, newflags) &&
!vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
spin_lock(&mm->page_table_lock);
prev->vm_end = vma->vm_end;
__vma_unlink(mm, vma, prev);
spin_unlock(&mm->page_table_lock);
kmem_cache_free(vm_area_cachep, vma);
mm->map_count--;
return 0;
}
spin_lock(&mm->page_table_lock);
vma->vm_flags = newflags;
vma->vm_page_prot = prot;
spin_unlock(&mm->page_table_lock);
*pprev = vma;
return 0;
}
static inline int mprotect_fixup_start(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
unsigned long end,
int newflags, pgprot_t prot)
{
struct vm_area_struct * n, * prev = *pprev;
*pprev = vma;
if (prev && prev->vm_end == vma->vm_start && can_vma_merge(prev, newflags) &&
!vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
spin_lock(&vma->vm_mm->page_table_lock);
prev->vm_end = end;
vma->vm_start = end;
spin_unlock(&vma->vm_mm->page_table_lock);
return 0;
}
n = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!n)
return -ENOMEM;
*n = *vma;
n->vm_end = end;
n->vm_flags = newflags;
n->vm_raend = 0;
n->vm_page_prot = prot;
if (n->vm_file)
get_file(n->vm_file);
if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n);
vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT;
lock_vma_mappings(vma);
spin_lock(&vma->vm_mm->page_table_lock);
vma->vm_start = end;
__insert_vm_struct(current->mm, n);
spin_unlock(&vma->vm_mm->page_table_lock);
unlock_vma_mappings(vma);
return 0;
}
static inline int mprotect_fixup_end(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
unsigned long start,
int newflags, pgprot_t prot)
{
struct vm_area_struct * n;
n = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
if (!n)
return -ENOMEM;
*n = *vma;
n->vm_start = start;
n->vm_pgoff += (n->vm_start - vma->vm_start) >> PAGE_SHIFT;
n->vm_flags = newflags;
n->vm_raend = 0;
n->vm_page_prot = prot;
if (n->vm_file)
get_file(n->vm_file);
if (n->vm_ops && n->vm_ops->open)
n->vm_ops->open(n);
lock_vma_mappings(vma);
spin_lock(&vma->vm_mm->page_table_lock);
vma->vm_end = start;
__insert_vm_struct(current->mm, n);
spin_unlock(&vma->vm_mm->page_table_lock);
unlock_vma_mappings(vma);
*pprev = n;
return 0;
}
static inline int mprotect_fixup_middle(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
unsigned long start, unsigned long end,
int newflags, pgprot_t prot)
{
struct vm_area_struct * left, * right;
left = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!left)
return -ENOMEM;
right = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!right) {
kmem_cache_free(vm_area_cachep, left);
return -ENOMEM;
}
*left = *vma;
*right = *vma;
left->vm_end = start;
right->vm_start = end;
right->vm_pgoff += (right->vm_start - left->vm_start) >> PAGE_SHIFT;
left->vm_raend = 0;
right->vm_raend = 0;
if (vma->vm_file)
atomic_add(2,&vma->vm_file->f_count);
if (vma->vm_ops && vma->vm_ops->open) {
vma->vm_ops->open(left);
vma->vm_ops->open(right);
}
vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT;
vma->vm_raend = 0;
vma->vm_page_prot = prot;
lock_vma_mappings(vma);
spin_lock(&vma->vm_mm->page_table_lock);
vma->vm_start = start;
vma->vm_end = end;
vma->vm_flags = newflags;
__insert_vm_struct(current->mm, left);
__insert_vm_struct(current->mm, right);
spin_unlock(&vma->vm_mm->page_table_lock);
unlock_vma_mappings(vma);
*pprev = right;
return 0;
}
static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
unsigned long start, unsigned long end, unsigned int newflags)
{
pgprot_t newprot;
int error;
if (newflags == vma->vm_flags) {
*pprev = vma;
return 0;
}
newprot = protection_map[newflags & 0xf];
if (start == vma->vm_start) {
if (end == vma->vm_end)
error = mprotect_fixup_all(vma, pprev, newflags, newprot);
else
error = mprotect_fixup_start(vma, pprev, end, newflags, newprot);
} else if (end == vma->vm_end)
error = mprotect_fixup_end(vma, pprev, start, newflags, newprot);
else
error = mprotect_fixup_middle(vma, pprev, start, end, newflags, newprot);
if (error)
return error;
change_protection(start, end, newprot);
return 0;
}
asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
{
unsigned long nstart, end, tmp;
struct vm_area_struct * vma, * next, * prev;
int error = -EINVAL;
if (start & ~PAGE_MASK)
return -EINVAL;
len = PAGE_ALIGN(len);
end = start + len;
if (end < start)
return -ENOMEM;
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
return -EINVAL;
if (end == start)
return 0;
down_write(&current->mm->mmap_sem);
vma = find_vma_prev(current->mm, start, &prev);
error = -ENOMEM;
if (!vma || vma->vm_start > start)
goto out;
#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
/* mprotect() unsupported for I/O mappings in Xenolinux. */
error = -EINVAL;
if (vma->vm_flags & VM_IO)
goto out;
#endif
for (nstart = start ; ; ) {
unsigned int newflags;
int last = 0;
/* Here we know that vma->vm_start <= nstart < vma->vm_end. */
newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
if ((newflags & ~(newflags >> 4)) & 0xf) {
error = -EACCES;
goto out;
}
if (vma->vm_end > end) {
error = mprotect_fixup(vma, &prev, nstart, end, newflags);
goto out;
}
if (vma->vm_end == end)
last = 1;
tmp = vma->vm_end;
next = vma->vm_next;
error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
if (error)
goto out;
if (last)
break;
nstart = tmp;
vma = next;
if (!vma || vma->vm_start != nstart) {
error = -ENOMEM;
goto out;
}
}
if (next && prev->vm_end == next->vm_start && can_vma_merge(next, prev->vm_flags) &&
!prev->vm_file && !(prev->vm_flags & VM_SHARED)) {
spin_lock(&prev->vm_mm->page_table_lock);
prev->vm_end = next->vm_end;
__vma_unlink(prev->vm_mm, next, prev);
spin_unlock(&prev->vm_mm->page_table_lock);
kmem_cache_free(vm_area_cachep, next);
prev->vm_mm->map_count--;
}
out:
up_write(&current->mm->mmap_sem);
return error;
}
-390
View File
@@ -1,390 +0,0 @@
/*
* linux/mm/remap.c
*
* (C) Copyright 1996 Linus Torvalds
*/
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/shm.h>
#include <linux/mman.h>
#include <linux/swap.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
extern int vm_enough_memory(long pages);
static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr)
{
pgd_t * pgd;
pmd_t * pmd;
pte_t * pte = NULL;
pgd = pgd_offset(mm, addr);
if (pgd_none(*pgd))
goto end;
if (pgd_bad(*pgd)) {
pgd_ERROR(*pgd);
pgd_clear(pgd);
goto end;
}
pmd = pmd_offset(pgd, addr);
if (pmd_none(*pmd))
goto end;
if (pmd_bad(*pmd)) {
pmd_ERROR(*pmd);
pmd_clear(pmd);
goto end;
}
pte = pte_offset(pmd, addr);
if (pte_none(*pte))
pte = NULL;
end:
return pte;
}
static inline pte_t *alloc_one_pte(struct mm_struct *mm, unsigned long addr)
{
pmd_t * pmd;
pte_t * pte = NULL;
pmd = pmd_alloc(mm, pgd_offset(mm, addr), addr);
if (pmd)
pte = pte_alloc(mm, pmd, addr);
return pte;
}
static inline int copy_one_pte(struct mm_struct *mm, pte_t * src, pte_t * dst)
{
int error = 0;
pte_t pte;
if (!pte_none(*src)) {
pte = ptep_get_and_clear(src);
if (!dst) {
/* No dest? We must put it back. */
dst = src;
error++;
}
set_pte(dst, pte);
}
return error;
}
static int move_one_page(struct mm_struct *mm, unsigned long old_addr, unsigned long new_addr)
{
int error = 0;
pte_t * src, * dst;
spin_lock(&mm->page_table_lock);
src = get_one_pte(mm, old_addr);
if (src) {
dst = alloc_one_pte(mm, new_addr);
src = get_one_pte(mm, old_addr);
if (src)
error = copy_one_pte(mm, src, dst);
}
spin_unlock(&mm->page_table_lock);
return error;
}
static int move_page_tables(struct mm_struct * mm,
unsigned long new_addr, unsigned long old_addr, unsigned long len)
{
unsigned long offset = len;
flush_cache_range(mm, old_addr, old_addr + len);
/*
* This is not the clever way to do this, but we're taking the
* easy way out on the assumption that most remappings will be
* only a few pages.. This also makes error recovery easier.
*/
while (offset) {
offset -= PAGE_SIZE;
if (move_one_page(mm, old_addr + offset, new_addr + offset))
goto oops_we_failed;
}
flush_tlb_range(mm, old_addr, old_addr + len);
return 0;
/*
* Ok, the move failed because we didn't have enough pages for
* the new page table tree. This is unlikely, but we have to
* take the possibility into account. In that case we just move
* all the pages back (this will work, because we still have
* the old page tables)
*/
oops_we_failed:
flush_cache_range(mm, new_addr, new_addr + len);
while ((offset += PAGE_SIZE) < len)
move_one_page(mm, new_addr + offset, old_addr + offset);
zap_page_range(mm, new_addr, len);
return -1;
}
static inline unsigned long move_vma(struct vm_area_struct * vma,
unsigned long addr, unsigned long old_len, unsigned long new_len,
unsigned long new_addr)
{
struct mm_struct * mm = vma->vm_mm;
struct vm_area_struct * new_vma, * next, * prev;
int allocated_vma;
new_vma = NULL;
next = find_vma_prev(mm, new_addr, &prev);
if (next) {
if (prev && prev->vm_end == new_addr &&
can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
spin_lock(&mm->page_table_lock);
prev->vm_end = new_addr + new_len;
spin_unlock(&mm->page_table_lock);
new_vma = prev;
if (next != prev->vm_next)
BUG();
if (prev->vm_end == next->vm_start && can_vma_merge(next, prev->vm_flags)) {
spin_lock(&mm->page_table_lock);
prev->vm_end = next->vm_end;
__vma_unlink(mm, next, prev);
spin_unlock(&mm->page_table_lock);
mm->map_count--;
kmem_cache_free(vm_area_cachep, next);
}
} else if (next->vm_start == new_addr + new_len &&
can_vma_merge(next, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
spin_lock(&mm->page_table_lock);
next->vm_start = new_addr;
spin_unlock(&mm->page_table_lock);
new_vma = next;
}
} else {
prev = find_vma(mm, new_addr-1);
if (prev && prev->vm_end == new_addr &&
can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
spin_lock(&mm->page_table_lock);
prev->vm_end = new_addr + new_len;
spin_unlock(&mm->page_table_lock);
new_vma = prev;
}
}
allocated_vma = 0;
if (!new_vma) {
new_vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!new_vma)
goto out;
allocated_vma = 1;
}
if (!move_page_tables(current->mm, new_addr, addr, old_len)) {
unsigned long vm_locked = vma->vm_flags & VM_LOCKED;
if (allocated_vma) {
*new_vma = *vma;
new_vma->vm_start = new_addr;
new_vma->vm_end = new_addr+new_len;
new_vma->vm_pgoff += (addr-vma->vm_start) >> PAGE_SHIFT;
new_vma->vm_raend = 0;
if (new_vma->vm_file)
get_file(new_vma->vm_file);
if (new_vma->vm_ops && new_vma->vm_ops->open)
new_vma->vm_ops->open(new_vma);
insert_vm_struct(current->mm, new_vma);
}
/* XXX: possible errors masked, mapping might remain */
do_munmap(current->mm, addr, old_len);
current->mm->total_vm += new_len >> PAGE_SHIFT;
if (vm_locked) {
current->mm->locked_vm += new_len >> PAGE_SHIFT;
if (new_len > old_len)
make_pages_present(new_addr + old_len,
new_addr + new_len);
}
return new_addr;
}
if (allocated_vma)
kmem_cache_free(vm_area_cachep, new_vma);
out:
return -ENOMEM;
}
/*
* Expand (or shrink) an existing mapping, potentially moving it at the
* same time (controlled by the MREMAP_MAYMOVE flag and available VM space)
*
* MREMAP_FIXED option added 5-Dec-1999 by Benjamin LaHaise
* This option implies MREMAP_MAYMOVE.
*/
unsigned long do_mremap(unsigned long addr,
unsigned long old_len, unsigned long new_len,
unsigned long flags, unsigned long new_addr)
{
struct vm_area_struct *vma;
unsigned long ret = -EINVAL;
if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
goto out;
if (addr & ~PAGE_MASK)
goto out;
old_len = PAGE_ALIGN(old_len);
new_len = PAGE_ALIGN(new_len);
if (old_len > TASK_SIZE || addr > TASK_SIZE - old_len)
goto out;
if (addr >= TASK_SIZE)
goto out;
/* new_addr is only valid if MREMAP_FIXED is specified */
if (flags & MREMAP_FIXED) {
if (new_addr & ~PAGE_MASK)
goto out;
if (!(flags & MREMAP_MAYMOVE))
goto out;
if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
goto out;
if (new_addr >= TASK_SIZE)
goto out;
/*
* Allow new_len == 0 only if new_addr == addr
* to preserve truncation in place (that was working
* safe and some app may depend on it).
*/
if (unlikely(!new_len && new_addr != addr))
goto out;
/* Check if the location we're moving into overlaps the
* old location at all, and fail if it does.
*/
if ((new_addr <= addr) && (new_addr+new_len) > addr)
goto out;
if ((addr <= new_addr) && (addr+old_len) > new_addr)
goto out;
ret = do_munmap(current->mm, new_addr, new_len);
if (ret && new_len)
goto out;
}
/*
* Always allow a shrinking remap: that just unmaps
* the unnecessary pages..
*/
if (old_len >= new_len) {
ret = do_munmap(current->mm, addr+new_len, old_len - new_len);
if (ret && old_len != new_len)
goto out;
ret = addr;
if (!(flags & MREMAP_FIXED) || (new_addr == addr))
goto out;
}
/*
* Ok, we need to grow.. or relocate.
*/
ret = -EFAULT;
vma = find_vma(current->mm, addr);
if (!vma || vma->vm_start > addr)
goto out;
/* We can't remap across vm area boundaries */
if (old_len > vma->vm_end - addr)
goto out;
if (vma->vm_flags & VM_DONTEXPAND) {
if (new_len > old_len)
goto out;
}
if (vma->vm_flags & VM_LOCKED) {
unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
locked += new_len - old_len;
ret = -EAGAIN;
if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
goto out;
}
ret = -ENOMEM;
if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
> current->rlim[RLIMIT_AS].rlim_cur)
goto out;
/* Private writable mapping? Check memory availability.. */
if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
!(flags & MAP_NORESERVE) &&
!vm_enough_memory((new_len - old_len) >> PAGE_SHIFT))
goto out;
#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
/* mremap() unsupported for I/O mappings in Xenolinux. */
ret = -EINVAL;
if (vma->vm_flags & VM_IO)
goto out;
#endif
/* old_len exactly to the end of the area..
* And we're not relocating the area.
*/
if (old_len == vma->vm_end - addr &&
!((flags & MREMAP_FIXED) && (addr != new_addr)) &&
(old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
unsigned long max_addr = TASK_SIZE;
if (vma->vm_next)
max_addr = vma->vm_next->vm_start;
/* can we just expand the current mapping? */
if (max_addr - addr >= new_len) {
int pages = (new_len - old_len) >> PAGE_SHIFT;
spin_lock(&vma->vm_mm->page_table_lock);
vma->vm_end = addr + new_len;
spin_unlock(&vma->vm_mm->page_table_lock);
current->mm->total_vm += pages;
if (vma->vm_flags & VM_LOCKED) {
current->mm->locked_vm += pages;
make_pages_present(addr + old_len,
addr + new_len);
}
ret = addr;
goto out;
}
}
/*
* We weren't able to just expand or shrink the area,
* we need to create a new one and move it..
*/
ret = -ENOMEM;
if (flags & MREMAP_MAYMOVE) {
if (!(flags & MREMAP_FIXED)) {
unsigned long map_flags = 0;
if (vma->vm_flags & VM_SHARED)
map_flags |= MAP_SHARED;
new_addr = get_unmapped_area(vma->vm_file, 0, new_len, vma->vm_pgoff, map_flags);
ret = new_addr;
if (new_addr & ~PAGE_MASK)
goto out;
}
ret = move_vma(vma, addr, old_len, new_len, new_addr);
}
out:
return ret;
}
asmlinkage unsigned long sys_mremap(unsigned long addr,
unsigned long old_len, unsigned long new_len,
unsigned long flags, unsigned long new_addr)
{
unsigned long ret;
down_write(&current->mm->mmap_sem);
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
up_write(&current->mm->mmap_sem);
return ret;
}
-972
View File
@@ -1,972 +0,0 @@
/*
* linux/mm/page_alloc.c
*
* Manages the free list, the system allocates free pages here.
* Note that kmalloc() lives in slab.c
*
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
* Swap reorganised 29.12.95, Stephen Tweedie
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
* Reshaped it to be a zoned allocator, Ingo Molnar, Red Hat, 1999
* Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
* Zone balancing, Kanoj Sarcar, SGI, Jan 2000
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/swapctl.h>
#include <linux/interrupt.h>
#include <linux/pagemap.h>
#include <linux/bootmem.h>
#include <linux/slab.h>
#include <linux/module.h>
int nr_swap_pages;
int nr_active_pages;
int nr_inactive_pages;
LIST_HEAD(inactive_list);
LIST_HEAD(active_list);
pg_data_t *pgdat_list;
/*
*
* The zone_table array is used to look up the address of the
* struct zone corresponding to a given zone number (ZONE_DMA,
* ZONE_NORMAL, or ZONE_HIGHMEM).
*/
zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
EXPORT_SYMBOL(zone_table);
static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
static int zone_balance_ratio[MAX_NR_ZONES] __initdata = { 128, 128, 128, };
static int zone_balance_min[MAX_NR_ZONES] __initdata = { 20 , 20, 20, };
static int zone_balance_max[MAX_NR_ZONES] __initdata = { 255 , 255, 255, };
static int lower_zone_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 };
int vm_gfp_debug = 0;
static void FASTCALL(__free_pages_ok (struct page *page, unsigned int order));
static spinlock_t free_pages_ok_no_irq_lock = SPIN_LOCK_UNLOCKED;
struct page * free_pages_ok_no_irq_head;
static void do_free_pages_ok_no_irq(void * arg)
{
struct page * page, * __page;
spin_lock_irq(&free_pages_ok_no_irq_lock);
page = free_pages_ok_no_irq_head;
free_pages_ok_no_irq_head = NULL;
spin_unlock_irq(&free_pages_ok_no_irq_lock);
while (page) {
__page = page;
page = page->next_hash;
__free_pages_ok(__page, __page->index);
}
}
static struct tq_struct free_pages_ok_no_irq_task = {
.routine = do_free_pages_ok_no_irq,
};
/*
* Temporary debugging check.
*/
#define BAD_RANGE(zone, page) \
( \
(((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \
|| (((page) - mem_map) < (zone)->zone_start_mapnr) \
|| ((zone) != page_zone(page)) \
)
/*
* Freeing function for a buddy system allocator.
* Contrary to prior comments, this is *NOT* hairy, and there
* is no reason for anyone not to understand it.
*
* The concept of a buddy system is to maintain direct-mapped tables
* (containing bit values) for memory blocks of various "orders".
* The bottom level table contains the map for the smallest allocatable
* units of memory (here, pages), and each level above it describes
* pairs of units from the levels below, hence, "buddies".
* At a high level, all that happens here is marking the table entry
* at the bottom level available, and propagating the changes upward
* as necessary, plus some accounting needed to play nicely with other
* parts of the VM system.
* At each level, we keep one bit for each pair of blocks, which
* is set to 1 iff only one of the pair is allocated. So when we
* are allocating or freeing one, we can derive the state of the
* other. That is, if we allocate a small block, and both were
* free, the remainder of the region must be split into blocks.
* If a block is freed, and its buddy is also free, then this
* triggers coalescing into a block of larger size.
*
* -- wli
*/
static void fastcall __free_pages_ok (struct page *page, unsigned int order)
{
unsigned long index, page_idx, mask, flags;
free_area_t *area;
struct page *base;
zone_t *zone;
if (PageForeign(page))
return (PageForeignDestructor(page))(page);
/*
* Yes, think what happens when other parts of the kernel take
* a reference to a page in order to pin it for io. -ben
*/
if (PageLRU(page)) {
if (unlikely(in_interrupt())) {
unsigned long flags;
spin_lock_irqsave(&free_pages_ok_no_irq_lock, flags);
page->next_hash = free_pages_ok_no_irq_head;
free_pages_ok_no_irq_head = page;
page->index = order;
spin_unlock_irqrestore(&free_pages_ok_no_irq_lock, flags);
schedule_task(&free_pages_ok_no_irq_task);
return;
}
lru_cache_del(page);
}
if (page->buffers)
BUG();
if (page->mapping)
BUG();
if (!VALID_PAGE(page))
BUG();
if (PageLocked(page))
BUG();
if (PageActive(page))
BUG();
ClearPageReferenced(page);
ClearPageDirty(page);
if (current->flags & PF_FREE_PAGES)
goto local_freelist;
back_local_freelist:
zone = page_zone(page);
mask = (~0UL) << order;
base = zone->zone_mem_map;
page_idx = page - base;
if (page_idx & ~mask)
BUG();
index = page_idx >> (1 + order);
area = zone->free_area + order;
spin_lock_irqsave(&zone->lock, flags);
zone->free_pages -= mask;
while (mask + (1 << (MAX_ORDER-1))) {
struct page *buddy1, *buddy2;
if (area >= zone->free_area + MAX_ORDER)
BUG();
if (!__test_and_change_bit(index, area->map))
/*
* the buddy page is still allocated.
*/
break;
/*
* Move the buddy up one level.
* This code is taking advantage of the identity:
* -mask = 1+~mask
*/
buddy1 = base + (page_idx ^ -mask);
buddy2 = base + page_idx;
if (BAD_RANGE(zone,buddy1))
BUG();
if (BAD_RANGE(zone,buddy2))
BUG();
list_del(&buddy1->list);
mask <<= 1;
area++;
index >>= 1;
page_idx &= mask;
}
list_add(&(base + page_idx)->list, &area->free_list);
spin_unlock_irqrestore(&zone->lock, flags);
return;
local_freelist:
if (current->nr_local_pages)
goto back_local_freelist;
if (in_interrupt())
goto back_local_freelist;
list_add(&page->list, &current->local_pages);
page->index = order;
current->nr_local_pages++;
}
#define MARK_USED(index, order, area) \
__change_bit((index) >> (1+(order)), (area)->map)
static inline struct page * expand (zone_t *zone, struct page *page,
unsigned long index, int low, int high, free_area_t * area)
{
unsigned long size = 1 << high;
while (high > low) {
if (BAD_RANGE(zone,page))
BUG();
area--;
high--;
size >>= 1;
list_add(&(page)->list, &(area)->free_list);
MARK_USED(index, high, area);
index += size;
page += size;
}
if (BAD_RANGE(zone,page))
BUG();
return page;
}
static FASTCALL(struct page * rmqueue(zone_t *zone, unsigned int order));
static struct page * fastcall rmqueue(zone_t *zone, unsigned int order)
{
free_area_t * area = zone->free_area + order;
unsigned int curr_order = order;
struct list_head *head, *curr;
unsigned long flags;
struct page *page;
spin_lock_irqsave(&zone->lock, flags);
do {
head = &area->free_list;
curr = head->next;
if (curr != head) {
unsigned int index;
page = list_entry(curr, struct page, list);
if (BAD_RANGE(zone,page))
BUG();
list_del(curr);
index = page - zone->zone_mem_map;
if (curr_order != MAX_ORDER-1)
MARK_USED(index, curr_order, area);
zone->free_pages -= 1UL << order;
page = expand(zone, page, index, order, curr_order, area);
spin_unlock_irqrestore(&zone->lock, flags);
set_page_count(page, 1);
if (BAD_RANGE(zone,page))
BUG();
if (PageLRU(page))
BUG();
if (PageActive(page))
BUG();
return page;
}
curr_order++;
area++;
} while (curr_order < MAX_ORDER);
spin_unlock_irqrestore(&zone->lock, flags);
return NULL;
}
#ifndef CONFIG_DISCONTIGMEM
struct page * fastcall _alloc_pages(unsigned int gfp_mask, unsigned int order)
{
return __alloc_pages(gfp_mask, order,
contig_page_data.node_zonelists+(gfp_mask & GFP_ZONEMASK));
}
#endif
static struct page * FASTCALL(balance_classzone(zone_t *, unsigned int, unsigned int, int *));
static struct page * fastcall balance_classzone(zone_t * classzone, unsigned int gfp_mask, unsigned int order, int * freed)
{
struct page * page = NULL;
int __freed;
if (in_interrupt())
BUG();
current->allocation_order = order;
current->flags |= PF_MEMALLOC | PF_FREE_PAGES;
__freed = try_to_free_pages_zone(classzone, gfp_mask);
current->flags &= ~(PF_MEMALLOC | PF_FREE_PAGES);
if (current->nr_local_pages) {
struct list_head * entry, * local_pages;
struct page * tmp;
int nr_pages;
local_pages = &current->local_pages;
if (likely(__freed)) {
/* pick from the last inserted so we're lifo */
entry = local_pages->next;
do {
tmp = list_entry(entry, struct page, list);
if (tmp->index == order && memclass(page_zone(tmp), classzone)) {
list_del(entry);
current->nr_local_pages--;
set_page_count(tmp, 1);
page = tmp;
if (page->buffers)
BUG();
if (page->mapping)
BUG();
if (!VALID_PAGE(page))
BUG();
if (PageLocked(page))
BUG();
if (PageLRU(page))
BUG();
if (PageActive(page))
BUG();
if (PageDirty(page))
BUG();
break;
}
} while ((entry = entry->next) != local_pages);
}
nr_pages = current->nr_local_pages;
/* free in reverse order so that the global order will be lifo */
while ((entry = local_pages->prev) != local_pages) {
list_del(entry);
tmp = list_entry(entry, struct page, list);
__free_pages_ok(tmp, tmp->index);
if (!nr_pages--)
BUG();
}
current->nr_local_pages = 0;
}
*freed = __freed;
return page;
}
static inline unsigned long zone_free_pages(zone_t * zone, unsigned int order)
{
long free = zone->free_pages - (1UL << order);
return free >= 0 ? free : 0;
}
/*
* This is the 'heart' of the zoned buddy allocator:
*/
struct page * fastcall __alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist)
{
zone_t **zone, * classzone;
struct page * page;
int freed, class_idx;
zone = zonelist->zones;
classzone = *zone;
class_idx = zone_idx(classzone);
for (;;) {
zone_t *z = *(zone++);
if (!z)
break;
if (zone_free_pages(z, order) > z->watermarks[class_idx].low) {
page = rmqueue(z, order);
if (page)
return page;
}
}
classzone->need_balance = 1;
mb();
if (waitqueue_active(&kswapd_wait))
wake_up_interruptible(&kswapd_wait);
zone = zonelist->zones;
for (;;) {
unsigned long min;
zone_t *z = *(zone++);
if (!z)
break;
min = z->watermarks[class_idx].min;
if (!(gfp_mask & __GFP_WAIT))
min >>= 2;
if (zone_free_pages(z, order) > min) {
page = rmqueue(z, order);
if (page)
return page;
}
}
/* here we're in the low on memory slow path */
if ((current->flags & PF_MEMALLOC) &&
(!in_interrupt() || (current->flags & PF_MEMDIE))) {
zone = zonelist->zones;
for (;;) {
zone_t *z = *(zone++);
if (!z)
break;
page = rmqueue(z, order);
if (page)
return page;
}
return NULL;
}
/* Atomic allocations - we can't balance anything */
if (!(gfp_mask & __GFP_WAIT))
goto out;
rebalance:
page = balance_classzone(classzone, gfp_mask, order, &freed);
if (page)
return page;
zone = zonelist->zones;
if (likely(freed)) {
for (;;) {
zone_t *z = *(zone++);
if (!z)
break;
if (zone_free_pages(z, order) > z->watermarks[class_idx].min) {
page = rmqueue(z, order);
if (page)
return page;
}
}
goto rebalance;
} else {
/*
* Check that no other task is been killed meanwhile,
* in such a case we can succeed the allocation.
*/
for (;;) {
zone_t *z = *(zone++);
if (!z)
break;
if (zone_free_pages(z, order) > z->watermarks[class_idx].high) {
page = rmqueue(z, order);
if (page)
return page;
}
}
}
out:
printk(KERN_NOTICE "__alloc_pages: %u-order allocation failed (gfp=0x%x/%i)\n",
order, gfp_mask, !!(current->flags & PF_MEMALLOC));
if (unlikely(vm_gfp_debug))
dump_stack();
return NULL;
}
/*
* Common helper functions.
*/
fastcall unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)
{
struct page * page;
page = alloc_pages(gfp_mask, order);
if (!page)
return 0;
return (unsigned long) page_address(page);
}
fastcall unsigned long get_zeroed_page(unsigned int gfp_mask)
{
struct page * page;
page = alloc_pages(gfp_mask, 0);
if (page) {
void *address = page_address(page);
clear_page(address);
return (unsigned long) address;
}
return 0;
}
fastcall void __free_pages(struct page *page, unsigned int order)
{
if (!PageReserved(page) && put_page_testzero(page))
__free_pages_ok(page, order);
}
fastcall void free_pages(unsigned long addr, unsigned int order)
{
if (addr != 0)
__free_pages(virt_to_page(addr), order);
}
/*
* Total amount of free (allocatable) RAM:
*/
unsigned int nr_free_pages (void)
{
unsigned int sum = 0;
zone_t *zone;
for_each_zone(zone)
sum += zone->free_pages;
return sum;
}
/*
* Amount of free RAM allocatable as buffer memory:
*/
unsigned int nr_free_buffer_pages (void)
{
pg_data_t *pgdat;
unsigned int sum = 0;
zonelist_t *zonelist;
zone_t **zonep, *zone;
for_each_pgdat(pgdat) {
int class_idx;
zonelist = pgdat->node_zonelists + (GFP_USER & GFP_ZONEMASK);
zonep = zonelist->zones;
zone = *zonep;
class_idx = zone_idx(zone);
sum += zone->nr_cache_pages;
for (; zone; zone = *zonep++) {
int free = zone->free_pages - zone->watermarks[class_idx].high;
if (free <= 0)
continue;
sum += free;
}
}
return sum;
}
#if CONFIG_HIGHMEM
unsigned int nr_free_highpages (void)
{
pg_data_t *pgdat;
unsigned int pages = 0;
for_each_pgdat(pgdat)
pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages;
return pages;
}
unsigned int freeable_lowmem(void)
{
unsigned int pages = 0;
pg_data_t *pgdat;
for_each_pgdat(pgdat) {
pages += pgdat->node_zones[ZONE_DMA].free_pages;
pages += pgdat->node_zones[ZONE_DMA].nr_active_pages;
pages += pgdat->node_zones[ZONE_DMA].nr_inactive_pages;
pages += pgdat->node_zones[ZONE_NORMAL].free_pages;
pages += pgdat->node_zones[ZONE_NORMAL].nr_active_pages;
pages += pgdat->node_zones[ZONE_NORMAL].nr_inactive_pages;
}
return pages;
}
#endif
#define K(x) ((x) << (PAGE_SHIFT-10))
/*
* Show free area list (used inside shift_scroll-lock stuff)
* We also calculate the percentage fragmentation. We do this by counting the
* memory on each free list with the exception of the first item on the list.
*/
void show_free_areas_core(pg_data_t *pgdat)
{
unsigned int order;
unsigned type;
pg_data_t *tmpdat = pgdat;
printk("Free pages: %6dkB (%6dkB HighMem)\n",
K(nr_free_pages()),
K(nr_free_highpages()));
while (tmpdat) {
zone_t *zone;
for (zone = tmpdat->node_zones;
zone < tmpdat->node_zones + MAX_NR_ZONES; zone++)
printk("Zone:%s freepages:%6lukB\n",
zone->name,
K(zone->free_pages));
tmpdat = tmpdat->node_next;
}
printk("( Active: %d, inactive: %d, free: %d )\n",
nr_active_pages,
nr_inactive_pages,
nr_free_pages());
for (type = 0; type < MAX_NR_ZONES; type++) {
struct list_head *head, *curr;
zone_t *zone = pgdat->node_zones + type;
unsigned long nr, total, flags;
total = 0;
if (zone->size) {
spin_lock_irqsave(&zone->lock, flags);
for (order = 0; order < MAX_ORDER; order++) {
head = &(zone->free_area + order)->free_list;
curr = head;
nr = 0;
for (;;) {
if ((curr = curr->next) == head)
break;
nr++;
}
total += nr * (1 << order);
printk("%lu*%lukB ", nr, K(1UL) << order);
}
spin_unlock_irqrestore(&zone->lock, flags);
}
printk("= %lukB)\n", K(total));
}
#ifdef SWAP_CACHE_INFO
show_swap_cache_info();
#endif
}
void show_free_areas(void)
{
show_free_areas_core(pgdat_list);
}
/*
* Builds allocation fallback zone lists.
*/
static inline void build_zonelists(pg_data_t *pgdat)
{
int i, j, k;
for (i = 0; i <= GFP_ZONEMASK; i++) {
zonelist_t *zonelist;
zone_t *zone;
zonelist = pgdat->node_zonelists + i;
memset(zonelist, 0, sizeof(*zonelist));
j = 0;
k = ZONE_NORMAL;
if (i & __GFP_HIGHMEM)
k = ZONE_HIGHMEM;
if (i & __GFP_DMA)
k = ZONE_DMA;
switch (k) {
default:
BUG();
/*
* fallthrough:
*/
case ZONE_HIGHMEM:
zone = pgdat->node_zones + ZONE_HIGHMEM;
if (zone->size) {
#ifndef CONFIG_HIGHMEM
BUG();
#endif
zonelist->zones[j++] = zone;
}
case ZONE_NORMAL:
zone = pgdat->node_zones + ZONE_NORMAL;
if (zone->size)
zonelist->zones[j++] = zone;
case ZONE_DMA:
zone = pgdat->node_zones + ZONE_DMA;
if (zone->size)
zonelist->zones[j++] = zone;
}
zonelist->zones[j++] = NULL;
}
}
/*
* Helper functions to size the waitqueue hash table.
* Essentially these want to choose hash table sizes sufficiently
* large so that collisions trying to wait on pages are rare.
* But in fact, the number of active page waitqueues on typical
* systems is ridiculously low, less than 200. So this is even
* conservative, even though it seems large.
*
* The constant PAGES_PER_WAITQUEUE specifies the ratio of pages to
* waitqueues, i.e. the size of the waitq table given the number of pages.
*/
#define PAGES_PER_WAITQUEUE 256
static inline unsigned long wait_table_size(unsigned long pages)
{
unsigned long size = 1;
pages /= PAGES_PER_WAITQUEUE;
while (size < pages)
size <<= 1;
/*
* Once we have dozens or even hundreds of threads sleeping
* on IO we've got bigger problems than wait queue collision.
* Limit the size of the wait table to a reasonable size.
*/
size = min(size, 4096UL);
return size;
}
/*
* This is an integer logarithm so that shifts can be used later
* to extract the more random high bits from the multiplicative
* hash function before the remainder is taken.
*/
static inline unsigned long wait_table_bits(unsigned long size)
{
return ffz(~size);
}
#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
/*
* Set up the zone data structures:
* - mark all pages reserved
* - mark all memory queues empty
* - clear the memory bitmaps
*/
void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
unsigned long *zones_size, unsigned long zone_start_paddr,
unsigned long *zholes_size, struct page *lmem_map)
{
unsigned long i, j;
unsigned long map_size;
unsigned long totalpages, offset, realtotalpages;
const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
if (zone_start_paddr & ~PAGE_MASK)
BUG();
totalpages = 0;
for (i = 0; i < MAX_NR_ZONES; i++) {
unsigned long size = zones_size[i];
totalpages += size;
}
realtotalpages = totalpages;
if (zholes_size)
for (i = 0; i < MAX_NR_ZONES; i++)
realtotalpages -= zholes_size[i];
printk("On node %d totalpages: %lu\n", nid, realtotalpages);
/*
* Some architectures (with lots of mem and discontinous memory
* maps) have to search for a good mem_map area:
* For discontigmem, the conceptual mem map array starts from
* PAGE_OFFSET, we need to align the actual array onto a mem map
* boundary, so that MAP_NR works.
*/
map_size = (totalpages + 1)*sizeof(struct page);
if (lmem_map == (struct page *)0) {
lmem_map = (struct page *) alloc_bootmem_node(pgdat, map_size);
lmem_map = (struct page *)(PAGE_OFFSET +
MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET));
}
*gmap = pgdat->node_mem_map = lmem_map;
pgdat->node_size = totalpages;
pgdat->node_start_paddr = zone_start_paddr;
pgdat->node_start_mapnr = (lmem_map - mem_map);
pgdat->nr_zones = 0;
offset = lmem_map - mem_map;
for (j = 0; j < MAX_NR_ZONES; j++) {
zone_t *zone = pgdat->node_zones + j;
unsigned long mask;
unsigned long size, realsize;
int idx;
zone_table[nid * MAX_NR_ZONES + j] = zone;
realsize = size = zones_size[j];
if (zholes_size)
realsize -= zholes_size[j];
printk("zone(%lu): %lu pages.\n", j, size);
zone->size = size;
zone->realsize = realsize;
zone->name = zone_names[j];
zone->lock = SPIN_LOCK_UNLOCKED;
zone->zone_pgdat = pgdat;
zone->free_pages = 0;
zone->need_balance = 0;
zone->nr_active_pages = zone->nr_inactive_pages = 0;
if (!size)
continue;
/*
* The per-page waitqueue mechanism uses hashed waitqueues
* per zone.
*/
zone->wait_table_size = wait_table_size(size);
zone->wait_table_shift =
BITS_PER_LONG - wait_table_bits(zone->wait_table_size);
zone->wait_table = (wait_queue_head_t *)
alloc_bootmem_node(pgdat, zone->wait_table_size
* sizeof(wait_queue_head_t));
for(i = 0; i < zone->wait_table_size; ++i)
init_waitqueue_head(zone->wait_table + i);
pgdat->nr_zones = j+1;
mask = (realsize / zone_balance_ratio[j]);
if (mask < zone_balance_min[j])
mask = zone_balance_min[j];
else if (mask > zone_balance_max[j])
mask = zone_balance_max[j];
zone->watermarks[j].min = mask;
zone->watermarks[j].low = mask*2;
zone->watermarks[j].high = mask*3;
/* now set the watermarks of the lower zones in the "j" classzone */
for (idx = j-1; idx >= 0; idx--) {
zone_t * lower_zone = pgdat->node_zones + idx;
unsigned long lower_zone_reserve;
if (!lower_zone->size)
continue;
mask = lower_zone->watermarks[idx].min;
lower_zone->watermarks[j].min = mask;
lower_zone->watermarks[j].low = mask*2;
lower_zone->watermarks[j].high = mask*3;
/* now the brainer part */
lower_zone_reserve = realsize / lower_zone_reserve_ratio[idx];
lower_zone->watermarks[j].min += lower_zone_reserve;
lower_zone->watermarks[j].low += lower_zone_reserve;
lower_zone->watermarks[j].high += lower_zone_reserve;
realsize += lower_zone->realsize;
}
zone->zone_mem_map = mem_map + offset;
zone->zone_start_mapnr = offset;
zone->zone_start_paddr = zone_start_paddr;
if ((zone_start_paddr >> PAGE_SHIFT) & (zone_required_alignment-1))
printk("BUG: wrong zone alignment, it will crash\n");
/*
* Initially all pages are reserved - free ones are freed
* up by free_all_bootmem() once the early boot process is
* done. Non-atomic initialization, single-pass.
*/
for (i = 0; i < size; i++) {
struct page *page = mem_map + offset + i;
set_page_zone(page, nid * MAX_NR_ZONES + j);
set_page_count(page, 0);
SetPageReserved(page);
INIT_LIST_HEAD(&page->list);
if (j != ZONE_HIGHMEM)
set_page_address(page, __va(zone_start_paddr));
zone_start_paddr += PAGE_SIZE;
}
offset += size;
for (i = 0; ; i++) {
unsigned long bitmap_size;
INIT_LIST_HEAD(&zone->free_area[i].free_list);
if (i == MAX_ORDER-1) {
zone->free_area[i].map = NULL;
break;
}
/*
* Page buddy system uses "index >> (i+1)",
* where "index" is at most "size-1".
*
* The extra "+3" is to round down to byte
* size (8 bits per byte assumption). Thus
* we get "(size-1) >> (i+4)" as the last byte
* we can access.
*
* The "+1" is because we want to round the
* byte allocation up rather than down. So
* we should have had a "+7" before we shifted
* down by three. Also, we have to add one as
* we actually _use_ the last bit (it's [0,n]
* inclusive, not [0,n[).
*
* So we actually had +7+1 before we shift
* down by 3. But (n+8) >> 3 == (n >> 3) + 1
* (modulo overflows, which we do not have).
*
* Finally, we LONG_ALIGN because all bitmap
* operations are on longs.
*/
bitmap_size = (size-1) >> (i+4);
bitmap_size = LONG_ALIGN(bitmap_size+1);
zone->free_area[i].map =
(unsigned long *) alloc_bootmem_node(pgdat, bitmap_size);
}
}
build_zonelists(pgdat);
}
void __init free_area_init(unsigned long *zones_size)
{
free_area_init_core(0, &contig_page_data, &mem_map, zones_size, 0, 0, 0);
}
static int __init setup_mem_frac(char *str)
{
int j = 0;
while (get_option(&str, &zone_balance_ratio[j++]) == 2);
printk("setup_mem_frac: ");
for (j = 0; j < MAX_NR_ZONES; j++) printk("%d ", zone_balance_ratio[j]);
printk("\n");
return 1;
}
__setup("memfrac=", setup_mem_frac);
static int __init setup_lower_zone_reserve(char *str)
{
int j = 0;
while (get_option(&str, &lower_zone_reserve_ratio[j++]) == 2);
printk("setup_lower_zone_reserve: ");
for (j = 0; j < MAX_NR_ZONES-1; j++) printk("%d ", lower_zone_reserve_ratio[j]);
printk("\n");
return 1;
}
__setup("lower_zone_reserve=", setup_lower_zone_reserve);
File diff suppressed because it is too large. Load diff
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.