diff -Nru a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
--- a/Documentation/DocBook/kernel-hacking.tmpl Tue Jun 18 19:12:02 2002
+++ b/Documentation/DocBook/kernel-hacking.tmpl Tue Jun 18 19:12:02 2002
@@ -702,19 +702,14 @@
- smp_processor_id()/cpu_[number/logical]_map()
+ smp_processor_id()
smp_processor_id() returns the current
processor number, between 0 and NR_CPUS (the
maximum number of CPUs supported by Linux, currently 32). These
- values are not necessarily continuous: to get a number between 0
- and smp_num_cpus() (the number of actual
- processors in this machine), the
- cpu_number_map() function is used to map the
- processor id to a logical number.
- cpu_logical_map() does the reverse.
+ values are not necessarily continuous.
diff -Nru a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
--- a/Documentation/filesystems/Locking Tue Jun 18 19:12:02 2002
+++ b/Documentation/filesystems/Locking Tue Jun 18 19:12:02 2002
@@ -50,27 +50,27 @@
int (*removexattr) (struct dentry *, const char *);
locking rules:
- all may block
- BKL i_sem(inode)
-lookup: no yes
-create: no yes
-link: no yes (both)
-mknod: no yes
-symlink: no yes
-mkdir: no yes
-unlink: no yes (both)
-rmdir: no yes (both) (see below)
-rename: no yes (all) (see below)
-readlink: no no
-follow_link: no no
-truncate: no yes (see below)
-setattr: no yes
-permission: yes no
-getattr: no no
-setxattr: no yes
-getxattr: no yes
-listxattr: no yes
-removexattr: no yes
+ all may block, none have BKL
+ i_sem(inode)
+lookup: yes
+create: yes
+link: yes (both)
+mknod: yes
+symlink: yes
+mkdir: yes
+unlink: yes (both)
+rmdir: yes (both) (see below)
+rename: yes (all) (see below)
+readlink: no
+follow_link: no
+truncate: yes (see below)
+setattr: yes
+permission: no
+getattr: no
+setxattr: yes
+getxattr: yes
+listxattr: yes
+removexattr: yes
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_sem on
victim.
cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
diff -Nru a/Documentation/filesystems/porting b/Documentation/filesystems/porting
--- a/Documentation/filesystems/porting Tue Jun 18 19:12:02 2002
+++ b/Documentation/filesystems/porting Tue Jun 18 19:12:02 2002
@@ -81,9 +81,9 @@
[mandatory]
->lookup(), ->truncate(), ->create(), ->unlink(), ->mknod(), ->mkdir(),
-->rmdir(), ->link(), ->lseek(), ->symlink(), ->rename() and ->readdir()
-are called without BKL now. Grab it on the entry, drop upon return - that
-will guarantee the same locking you used to have. If your method or its
+->rmdir(), ->link(), ->lseek(), ->symlink(), ->rename(), ->permission()
+and ->readdir() are called without BKL now. Grab it on entry, drop upon return
+- that will guarantee the same locking you used to have. If your method or its
parts do not need BKL - better yet, now you can shift lock_kernel() and
unlock_kernel() so that they would protect exactly what needs to be
protected.
diff -Nru a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
--- a/Documentation/filesystems/proc.txt Tue Jun 18 19:12:02 2002
+++ b/Documentation/filesystems/proc.txt Tue Jun 18 19:12:02 2002
@@ -948,120 +948,43 @@
-----------------------------------------------
The files in this directory can be used to tune the operation of the virtual
-memory (VM) subsystem of the Linux kernel. In addition, one of the files
-(bdflush) has some influence on disk usage.
+memory (VM) subsystem of the Linux kernel.
-bdflush
--------
+dirty_background_ratio
+----------------------
-This file controls the operation of the bdflush kernel daemon. It currently
-contains nine integer values, six of which are actually used by the kernel.
-They are listed in table 2-2.
-
-
-Table 2-2: Parameters in /proc/sys/vm/bdflush
-..............................................................................
- Value Meaning
- nfract Percentage of buffer cache dirty to activate bdflush
- ndirty Maximum number of dirty blocks to write out per wake-cycle
- nrefill Number of clean buffers to try to obtain each time we call refill
- nref_dirt buffer threshold for activating bdflush when trying to refill
- buffers.
- dummy Unused
- age_buffer Time for normal buffer to age before we flush it
- age_super Time for superblock to age before we flush it
- dummy Unused
- dummy Unused
-..............................................................................
+Contains, as a percentage of total system memory, the number of pages at which
+the pdflush background writeback daemon will start writing out dirty data.
-nfract
-------
-
-This parameter governs the maximum number of dirty buffers in the buffer
-cache. Dirty means that the contents of the buffer still have to be written to
-disk (as opposed to a clean buffer, which can just be forgotten about).
-Setting this to a higher value means that Linux can delay disk writes for a
-long time, but it also means that it will have to do a lot of I/O at once when
-memory becomes short. A lower value will spread out disk I/O more evenly.
-
-ndirty
-------
-
-Ndirty gives the maximum number of dirty buffers that bdflush can write to the
-disk at one time. A high value will mean delayed, bursty I/O, while a small
-value can lead to memory shortage when bdflush isn't woken up often enough.
-
-nrefill
--------
-
-This is the number of buffers that bdflush will add to the list of free
-buffers when refill_freelist() is called. It is necessary to allocate free
-buffers beforehand, since the buffers are often different sizes than the
-memory pages and some bookkeeping needs to be done beforehand. The higher the
-number, the more memory will be wasted and the less often refill_freelist()
-will need to run.
-
-nref_dirt
----------
-
-When refill_freelist() comes across more than nref_dirt dirty buffers, it will
-wake up bdflush.
-
-age_buffer and age_super
-------------------------
-
-Finally, the age_buffer and age_super parameters govern the maximum time Linux
-waits before writing out a dirty buffer to disk. The value is expressed in
-jiffies (clockticks), the number of jiffies per second is 100. Age_buffer is
-the maximum age for data blocks, while age_super is for filesystems meta data.
-
-buffermem
----------
-
-The three values in this file control how much memory should be used for
-buffer memory. The percentage is calculated as a percentage of total system
-memory.
-
-The values are:
-
-min_percent
------------
-
-This is the minimum percentage of memory that should be spent on buffer
-memory.
-
-borrow_percent
---------------
-
-When Linux is short on memory, and the buffer cache uses more than it has been
-allotted, the memory management (MM) subsystem will prune the buffer cache
-more heavily than other memory to compensate.
-
-max_percent
------------
-
-This is the maximum amount of memory that can be used for buffer memory.
-
-freepages
----------
+dirty_async_ratio
+-----------------
-This file contains three values: min, low and high:
+Contains, as a percentage of total system memory, the number of pages at which
+a process which is generating disk writes will itself start writing out dirty
+data.
+
+dirty_sync_ratio
+----------------
+
+Contains, as a percentage of total system memory, the number of pages at which
+a process which is generating disk writes will itself start writing out dirty
+data and waiting upon completion of that writeout.
+
+dirty_writeback_centisecs
+-------------------------
+
+The pdflush writeback daemons will periodically wake up and write `old' data
+out to disk. This tunable expresses the interval between those wakeups, in
+100'ths of a second.
+
+dirty_expire_centisecs
+----------------------
+
+This tunable is used to define when dirty data is old enough to be eligible
+for writeout by the pdflush daemons. It is expressed in 100'ths of a second.
+Data which has been dirty in-memory for longer than this interval will be
+written out next time a pdflush daemon wakes up.
-min
----
-When the number of free pages in the system reaches this number, only the
-kernel can allocate more memory.
-
-low
----
-If the number of free pages falls below this point, the kernel starts swapping
-aggressively.
-
-high
-----
-The kernel tries to keep up to this amount of memory free; if memory falls
-below this point, the kernel starts gently swapping in the hopes that it never
-has to do really aggressive swapping.
kswapd
------
@@ -1112,79 +1035,6 @@
On the other hand, enabling this feature can cause you to run out of memory
and thrash the system to death, so large and/or important servers will want to
set this value to 0.
-
-pagecache
----------
-
-This file does exactly the same job as buffermem, only this file controls the
-amount of memory allowed for memory mapping and generic caching of files.
-
-You don't want the minimum level to be too low, otherwise your system might
-thrash when memory is tight or fragmentation is high.
-
-pagetable_cache
----------------
-
-The kernel keeps a number of page tables in a per-processor cache (this helps
-a lot on SMP systems). The cache size for each processor will be between the
-low and the high value.
-
-On a low-memory, single CPU system, you can safely set these values to 0 so
-you don't waste memory. It is used on SMP systems so that the system can
-perform fast pagetable allocations without having to acquire the kernel memory
-lock.
-
-For large systems, the settings are probably fine. For normal systems they
-won't hurt a bit. For small systems ( less than 16MB ram) it might be
-advantageous to set both values to 0.
-
-swapctl
--------
-
-This file contains no less than 8 variables. All of these values are used by
-kswapd.
-
-The first four variables
-* sc_max_page_age,
-* sc_page_advance,
-* sc_page_decline and
-* sc_page_initial_age
-are used to keep track of Linux's page aging. Page aging is a bookkeeping
-method to track which pages of memory are often used, and which pages can be
-swapped out without consequences.
-
-When a page is swapped in, it starts at sc_page_initial_age (default 3) and
-when the page is scanned by kswapd, its age is adjusted according to the
-following scheme:
-
-* If the page was used since the last time we scanned, its age is increased
- by sc_page_advance (default 3). Where the maximum value is given by
- sc_max_page_age (default 20).
-* Otherwise (meaning it wasn't used) its age is decreased by sc_page_decline
- (default 1).
-
-When a page reaches age 0, it's ready to be swapped out.
-
-The variables sc_age_cluster_fract, sc_age_cluster_min, sc_pageout_weight and
-sc_bufferout_weight, can be used to control kswapd's aggressiveness in
-swapping out pages.
-
-Sc_age_cluster_fract is used to calculate how many pages from a process are to
-be scanned by kswapd. The formula used is
-
-(sc_age_cluster_fract divided by 1024) times resident set size
-
-So if you want kswapd to scan the whole process, sc_age_cluster_fract needs to
-have a value of 1024. The minimum number of pages kswapd will scan is
-represented by sc_age_cluster_min, which is done so that kswapd will also scan
-small processes.
-
-The values of sc_pageout_weight and sc_bufferout_weight are used to control
-how many tries kswapd will make in order to swap out one page/buffer. These
-values can be used to fine-tune the ratio between user pages and buffer/cache
-memory. When you find that your Linux system is swapping out too many process
-pages in order to satisfy buffer memory demands, you may want to either
-increase sc_bufferout_weight, or decrease the value of sc_pageout_weight.
2.5 /proc/sys/dev - Device specific parameters
----------------------------------------------
diff -Nru a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
--- a/Documentation/networking/ip-sysctl.txt Tue Jun 18 19:12:02 2002
+++ b/Documentation/networking/ip-sysctl.txt Tue Jun 18 19:12:02 2002
@@ -43,23 +43,23 @@
Minimum time-to-live of entries. Should be enough to cover fragment
time-to-live on the reassembling side. This minimum time-to-live is
guaranteed if the pool size is less than inet_peer_threshold.
- Measured in jiffies.
+ Measured in jiffies(1).
inet_peer_maxttl - INTEGER
Maximum time-to-live of entries. Unused entries will expire after
this period of time if there is no memory pressure on the pool (i.e.
when the number of entries in the pool is very small).
- Measured in jiffies.
+ Measured in jiffies(1).
inet_peer_gc_mintime - INTEGER
Minimum interval between garbage collection passes. This interval is
in effect under high memory pressure on the pool.
- Measured in jiffies.
+ Measured in jiffies(1).
inet_peer_gc_maxtime - INTEGER
Minimum interval between garbage collection passes. This interval is
in effect under low (or absent) memory pressure on the pool.
- Measured in jiffies.
+ Measured in jiffies(1).
TCP variables:
@@ -81,7 +81,7 @@
How many keepalive probes TCP sends out, until it decides that the
connection is broken. Default value: 9.
-tcp_keepalive_interval - INTEGER
+tcp_keepalive_intvl - INTEGER
How frequently the probes are send out. Multiplied by
tcp_keepalive_probes it is time to kill not responding connection,
after probes started. Default value: 75sec i.e. connection
@@ -316,28 +316,37 @@
Limit the maximal rates for sending ICMP packets whose type matches
icmp_ratemask (see below) to specific targets.
0 to disable any limiting, otherwise the maximal rate in jiffies(1)
- Default: 1
+ Default: 100
icmp_ratemask - INTEGER
Mask made of ICMP types for which rates are being limited.
- Default: 6168
- Note: 6168 = 0x1818 = 1</{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"; \
+ echo ""; \
+ echo "#endif" )
+endef
+
# RPM target
# ---------------------------------------------------------------------------
@@ -461,6 +479,8 @@
else # ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
+ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)
+
# Targets which don't need .config
# ===========================================================================
#
@@ -519,23 +539,6 @@
defconfig:
yes '' | $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
-# How we generate .config depends on which *config the
-# user chose when calling make
-
-.config: $(filter oldconfig xconfig menuconfig config,$(MAKECMDGOALS)) ;
-
-# If the user gave commands from both the need / need not
-# .config sections, we need to call make again after
-# .config is generated, now to take care of the remaining
-# targets we know nothing about in this section
-
-remaining_targets := $(filter-out $(noconfig_targets),$(MAKECMDGOALS))
-
-$(remaining_targets) : make_with_config
-
-make_with_config: .config
- @$(MAKE) $(remaining_targets)
-
# Cleaning up
# ---------------------------------------------------------------------------
@@ -604,7 +607,8 @@
mrproper: clean archmrproper
@echo 'Making mrproper'
- @find . \( -size 0 -o -name .depend \) -type f -print | xargs rm -f
+ @find . \( -size 0 -o -name .depend -o -name .\*.cmd \) \
+ -type f -print | xargs rm -f
@rm -f $(MRPROPER_FILES)
@rm -rf $(MRPROPER_DIRS)
@$(MAKE) -C Documentation/DocBook mrproper
@@ -639,8 +643,6 @@
@$(MAKE) -C Documentation/DocBook $@
-endif # ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
-
# Scripts to check various things for consistency
# ---------------------------------------------------------------------------
@@ -652,6 +654,18 @@
checkincludes:
find * -name '*.[hcS]' -type f -print | sort | xargs $(PERL) -w scripts/checkincludes.pl
+
+else # ifneq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)
+
+# We're called with both targets which do and do not need
+# .config included. Handle them one after the other.
+# ===========================================================================
+
+%:: FORCE
+ $(MAKE) $@
+
+endif # ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)
+endif # ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
# FIXME Should go into a make.lib or something
# ===========================================================================
diff -Nru a/Rules.make b/Rules.make
--- a/Rules.make Tue Jun 18 19:12:02 2002
+++ b/Rules.make Tue Jun 18 19:12:02 2002
@@ -131,9 +131,13 @@
genksyms_smp_prefix :=
endif
-$(MODVERDIR)/$(real-objs-y:.o=.ver): modkern_cflags := $(CFLAGS_KERNEL)
-$(MODVERDIR)/$(real-objs-m:.o=.ver): modkern_cflags := $(CFLAGS_MODULE)
-$(MODVERDIR)/$(export-objs:.o=.ver): export_flags := -D__GENKSYMS__
+# Don't include modversions.h, we're just about to generate it here.
+
+CFLAGS_MODULE := $(filter-out -include $(HPATH)/linux/modversions.h,$(CFLAGS_MODULE))
+
+$(addprefix $(MODVERDIR)/,$(real-objs-y:.o=.ver)): modkern_cflags := $(CFLAGS_KERNEL)
+$(addprefix $(MODVERDIR)/,$(real-objs-m:.o=.ver)): modkern_cflags := $(CFLAGS_MODULE)
+$(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)): export_flags := -D__GENKSYMS__
c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
$(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
@@ -145,18 +149,34 @@
# files changes
quiet_cmd_cc_ver_c = MKVER include/linux/modules/$(RELDIR)/$*.ver
-define cmd_cc_ver_c
- mkdir -p $(dir $@); \
- $(CPP) $(c_flags) $< | $(GENKSYMS) $(genksyms_smp_prefix) \
- -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp; \
+cmd_cc_ver_c = $(CPP) $(c_flags) $< | $(GENKSYMS) $(genksyms_smp_prefix) \
+ -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp
+
+# Okay, let's explain what's happening in rule_make_cc_ver_c:
+# o echo the command
+# o execute the command
+# o If the $(CPP) fails, we won't notice because it's output is piped
+# to $(GENKSYMS) which does not fail. We recognize this case by
+# looking if the generated $(depfile) exists, though.
+# o If the .ver file changed, touch modversions.h, which is our maker
+# of any changed .ver files.
+# o Move command line and deps into their normal .*.cmd place.
+
+define rule_cc_ver_c
+ $(if $($(quiet)cmd_cc_ver_c),echo ' $($(quiet)cmd_cc_ver_c)';) \
+ $(cmd_cc_ver_c); \
+ if [ ! -r $(depfile) ]; then exit 1; fi; \
+ $(TOPDIR)/scripts/fixdep $(depfile) $@ $(TOPDIR) '$(cmd_cc_ver_c)' > $(@D)/.$(@F).tmp; \
+ rm -f $(depfile); \
if [ ! -r $@ ] || cmp -s $@ $@.tmp; then \
touch $(TOPDIR)/include/linux/modversions.h; \
fi; \
mv -f $@.tmp $@
+ mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
endef
$(MODVERDIR)/%.ver: %.c FORCE
- @$(call if_changed_dep,cc_ver_c)
+ @$(call if_changed_rule,cc_ver_c)
targets := $(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver))
@@ -446,7 +466,7 @@
# execute the command and also postprocess generated .d dependencies
# file
-if_changed_dep = $(if $(strip $? \
+if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
$(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
@set -e; \
@@ -455,6 +475,17 @@
$(TOPDIR)/scripts/fixdep $(depfile) $@ $(TOPDIR) '$(cmd_$(1))' > $(@D)/.$(@F).tmp; \
rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
+
+# Usage: $(call if_changed_rule,foo)
+# will check if $(cmd_foo) changed, or any of the prequisites changed,
+# and if so will execute $(rule_foo)
+
+if_changed_rule = $(if $(strip $? \
+ $(filter-out $(cmd_$(1)),$(cmd_$@))\
+ $(filter-out $(cmd_$@),$(cmd_$(1)))),\
+ @set -e; \
+ mkdir -p $(dir $@); \
+ $(rule_$(1)))
# If quiet is set, only print short version of command
diff -Nru a/arch/alpha/Makefile b/arch/alpha/Makefile
--- a/arch/alpha/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/alpha/Makefile Tue Jun 18 19:12:01 2002
@@ -127,10 +127,6 @@
rm -f arch/alpha/vmlinux.lds
rm -f include/asm-alpha/asm_offsets.h
-archdep:
- $(MAKE) -C arch/alpha/kernel asm_offsets
- @$(MAKEBOOT) dep
-
vmlinux: arch/alpha/vmlinux.lds
arch/alpha/vmlinux.lds: arch/alpha/vmlinux.lds.in
@@ -138,3 +134,19 @@
bootpfile:
@$(MAKEBOOT) bootpfile
+
+
+prepare: include/asm-$(ARCH)/asm_offsets.h
+
+arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
+ include/config/MARKER
+
+include/asm-$(ARCH)/asm_offsets.h.tmp: arch/$(ARCH)/kernel/asm-offsets.s
+ @$(generate-asm-offsets.h) < $< > $@
+
+include/asm-$(ARCH)/asm_offsets.h: include/asm-$(ARCH)/asm_offsets.h.tmp
+ @echo -n ' Generating $@'
+ @$(update-if-changed)
+
+CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \
+ include/asm-$(ARCH)/offset.h
diff -Nru a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile
--- a/arch/alpha/boot/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/alpha/boot/Makefile Tue Jun 18 19:12:01 2002
@@ -96,6 +96,4 @@
rm -f tools/mkbb tools/bootlx tools/lxboot tools/bootph
rm -f vmlinux.nh ksize.h
-dep:
-
FORCE:
diff -Nru a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
--- a/arch/alpha/kernel/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/alpha/kernel/Makefile Tue Jun 18 19:12:02 2002
@@ -94,17 +94,3 @@
endif # GENERIC
include $(TOPDIR)/Rules.make
-
-ASM_OFFSETS_H = $(TOPDIR)/include/asm-alpha/asm_offsets.h
-asm_offsets:
- $(CC) $(CFLAGS) -S -o - check_asm.c | \
- sed -e '/xyzzy/ { s/xyzzy //; p; }; d;' > asm_offsets.tmp
- @if cmp -s asm_offsets.tmp $(ASM_OFFSETS_H); then \
- set -x; rm asm_offsets.tmp; \
- else \
- set -x; mv asm_offsets.tmp $(ASM_OFFSETS_H); \
- fi
-
-clean::
- rm -f check_asm
-
diff -Nru a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/asm-offsets.c Tue Jun 18 19:12:03 2002
@@ -0,0 +1,29 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ */
+
+#include
+#include
+#include
+#include
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+void foo(void)
+{
+ DEFINE(TI_TASK, offsetof(struct thread_info, task));
+ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+ BLANK();
+ DEFINE(PT_PTRACED, PT_PTRACED);
+ DEFINE(CLONE_VM, CLONE_VM);
+ DEFINE(SIGCHLD, SIGCHLD);
+ BLANK();
+ DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache));
+ DEFINE(HAE_REG, offsetof(struct alpha_machine_vector, hae_register));
+}
diff -Nru a/arch/alpha/kernel/check_asm.c b/arch/alpha/kernel/check_asm.c
--- a/arch/alpha/kernel/check_asm.c Tue Jun 18 19:12:03 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,30 +0,0 @@
-#include
-#include
-#include
-#include
-
-#define OUT(x) \
- asm ("\nxyzzy " x)
-#define DEF(name, val) \
- asm volatile ("\nxyzzy #define " name " %0" : : "i"(val))
-
-void foo(void)
-{
- OUT("#ifndef __ASM_OFFSETS_H__");
- OUT("#define __ASM_OFFSETS_H__");
- OUT("");
-
- DEF("TI_TASK", offsetof(struct thread_info, task));
- DEF("TI_FLAGS", offsetof(struct thread_info, flags));
- DEF("TI_CPU", offsetof(struct thread_info, cpu));
-
- DEF("PT_PTRACED", PT_PTRACED);
- DEF("CLONE_VM", CLONE_VM);
- DEF("SIGCHLD", SIGCHLD);
-
- DEF("HAE_CACHE", offsetof(struct alpha_machine_vector, hae_cache));
- DEF("HAE_REG", offsetof(struct alpha_machine_vector, hae_register));
-
- OUT("");
- OUT("#endif /* __ASM_OFFSETS_H__ */");
-}
diff -Nru a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
--- a/arch/alpha/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/alpha/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -48,6 +48,8 @@
#include "proto.h"
#include "irq_impl.h"
+u64 jiffies_64;
+
extern rwlock_t xtime_lock;
extern unsigned long wall_jiffies; /* kernel/timer.c */
diff -Nru a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
--- a/arch/alpha/lib/Makefile Tue Jun 18 19:12:03 2002
+++ b/arch/alpha/lib/Makefile Tue Jun 18 19:12:03 2002
@@ -65,6 +65,4 @@
__remlu.o: $(ev6)divide.S
$(CC) $(AFLAGS) -DREM -DINTSIZE -c -o __remlu.o $(ev6)divide.S
-dep:
-
include $(TOPDIR)/Rules.make
diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile
--- a/arch/arm/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/arm/Makefile Tue Jun 18 19:12:02 2002
@@ -195,29 +195,25 @@
MAKEBOOT =$(MAKE) -C arch/$(ARCH)/boot
MAKETOOLS =$(MAKE) -C arch/$(ARCH)/tools
-# The following is a hack to get 'constants.h' up
-# to date before starting compilation
-
-$(patsubst %,_dir_%, $(SUBDIRS)): maketools
-$(patsubst %,_modsubdir_%,$(MOD_DIRS)): maketools
-
# Update machine arch and proc symlinks if something which affects
# them changed. We use .arch and .proc to indicate when they were
# updated last, otherwise make uses the target directory mtime.
include/asm-arm/.arch: $(wildcard include/config/arch/*.h)
- @echo 'Making asm-arm/arch -> asm-arm/arch-$(INCDIR) symlink'
+ @echo ' Making asm-arm/arch -> asm-arm/arch-$(INCDIR) symlink'
@rm -f include/asm-arm/arch
@ln -sf arch-$(INCDIR) include/asm-arm/arch
@touch $@
include/asm-arm/.proc: $(wildcard include/config/cpu/32.h) $(wildcard include/config/cpu/26.h)
- @echo 'Making asm-arm/proc -> asm-arm/proc-$(PROCESSOR) symlink'
+ @echo ' Making asm-arm/proc -> asm-arm/proc-$(PROCESSOR) symlink'
@rm -f include/asm-arm/proc
@ln -sf proc-$(PROCESSOR) include/asm-arm/proc
@touch $@
-.hdepend: include/asm-arm/.arch include/asm-arm/.proc
+prepare: include/asm-arm/.arch include/asm-arm/.proc \
+ include/asm-arm/constants.h
+ @$(MAKETOOLS)
vmlinux: arch/arm/vmlinux.lds
@@ -234,7 +230,6 @@
arch/arm/vmlinux.lds
MRPROPER_FILES += \
- arch/arm/tools/constants.h* \
include/asm-arm/arch include/asm-arm/.arch \
include/asm-arm/proc include/asm-arm/.proc \
include/asm-arm/constants.h* \
@@ -247,13 +242,9 @@
archclean: FORCE
@$(MAKEBOOT) clean
-archdep: FORCE
- @$(MAKETOOLS) dep
- @$(MAKEBOOT) dep
-
# we need version.h
maketools: include/linux/version.h FORCE
- @$(MAKETOOLS) all
+ @$(MAKETOOLS)
# My testing targets (that short circuit a few dependencies)
zImg:; @$(MAKEBOOT) zImage
@@ -277,3 +268,13 @@
echo "$$CFG does not exist"; \
fi; \
)
+
+arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
+ include/config/MARKER
+
+include/asm-$(ARCH)/constants.h.tmp: arch/$(ARCH)/kernel/asm-offsets.s
+ @$(generate-asm-offsets.h) < $< > $@
+
+include/asm-$(ARCH)/constants.h: include/asm-$(ARCH)/constants.h.tmp
+ @echo -n ' Generating $@'
+ @$(update-if-changed)
diff -Nru a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
--- a/arch/arm/boot/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/arm/boot/Makefile Tue Jun 18 19:12:01 2002
@@ -125,7 +125,7 @@
bootpImage: bootp/bootp
$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
-compressed/vmlinux: $(TOPDIR)/vmlinux dep
+compressed/vmlinux: $(TOPDIR)/vmlinux
@$(MAKE) -C compressed vmlinux
bootp/bootp: zImage initrd
@@ -145,5 +145,3 @@
$(RM) Image zImage bootpImage
@$(MAKE) -C compressed clean
@$(MAKE) -C bootp clean
-
-dep:
diff -Nru a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/arm/kernel/asm-offsets.c Tue Jun 18 19:12:03 2002
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 1995-2001 Russell King
+ * 2001-2002 Keith Owens
+ *
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+/*
+ * Make sure that the compiler and target are compatible.
+ */
+#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
+#error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26
+#endif
+#if defined(__APCS_26__) && defined(CONFIG_CPU_32)
+#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
+#endif
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
+#error Sorry, your compiler is known to miscompile kernels. Only use gcc 2.95.3 and later.
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
+/* shame we can't detect the .1 or .2 releases */
+#warning GCC 2.95.2 and earlier miscompiles kernels.
+#endif
+
+/* Use marker if you need to separate the values later */
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+ DEFINE(TSK_USED_MATH, offsetof(struct task_struct, used_math));
+ DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+ BLANK();
+ DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
+ DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
+ BLANK();
+ DEFINE(VM_EXEC, VM_EXEC);
+ BLANK();
+#ifdef CONFIG_CPU_32
+ DEFINE(HPTE_TYPE_SMALL, PTE_TYPE_SMALL);
+ DEFINE(HPTE_AP_READ, PTE_AP_READ);
+ DEFINE(HPTE_AP_WRITE, PTE_AP_WRITE);
+ BLANK();
+ DEFINE(LPTE_PRESENT, L_PTE_PRESENT);
+ DEFINE(LPTE_YOUNG, L_PTE_YOUNG);
+ DEFINE(LPTE_BUFFERABLE, L_PTE_BUFFERABLE);
+ DEFINE(LPTE_CACHEABLE, L_PTE_CACHEABLE);
+ DEFINE(LPTE_USER, L_PTE_USER);
+ DEFINE(LPTE_WRITE, L_PTE_WRITE);
+ DEFINE(LPTE_EXEC, L_PTE_EXEC);
+ DEFINE(LPTE_DIRTY, L_PTE_DIRTY);
+#endif
+ BLANK();
+#ifdef CONFIG_CPU_26
+ DEFINE(PAGE_PRESENT, _PAGE_PRESENT);
+ DEFINE(PAGE_READONLY, _PAGE_READONLY);
+ DEFINE(PAGE_NOT_USER, _PAGE_NOT_USER);
+ DEFINE(PAGE_OLD, _PAGE_OLD);
+ DEFINE(PAGE_CLEAN, _PAGE_CLEAN);
+#endif
+ BLANK();
+ DEFINE(PAGE_SZ, PAGE_SIZE);
+ BLANK();
+ DEFINE(SYS_ERROR0, 0x9f0000);
+ return 0;
+}
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/arm/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -32,6 +32,8 @@
#include
#include
+u64 jiffies_64;
+
extern rwlock_t xtime_lock;
extern unsigned long wall_jiffies;
diff -Nru a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
--- a/arch/arm/tools/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/arm/tools/Makefile Tue Jun 18 19:12:01 2002
@@ -4,40 +4,9 @@
# Copyright (C) 2001 Russell King
#
-all: $(TOPDIR)/include/asm-arm/mach-types.h \
- $(TOPDIR)/include/asm-arm/constants.h
+all: $(TOPDIR)/include/asm-arm/mach-types.h
$(TOPDIR)/include/asm-arm/mach-types.h: mach-types gen-mach-types
awk -f gen-mach-types mach-types > $@
-# Generate the constants.h header file using the compiler. We get
-# the compiler to spit out assembly code, and then mundge it into
-# what we want. We do this in several stages so make picks up on
-# any errors that occur along the way.
-
-constants.h: constants-hdr getconstants.c
- $(CC) $(CFLAGS) -S -o $@.tmp.1 getconstants.c
- sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' $@.tmp.1 > $@.tmp.2
- cat constants-hdr $@.tmp.2 > $@
- $(RM) $@.tmp*
-
-# Only update include/asm-arm/constants.h when it has actually changed.
-
-$(TOPDIR)/include/asm-arm/constants.h: constants.h
- cmp constants.h $@ >/dev/null 2>&1 || cp -p constants.h $@
-
-# Build our dependencies, and then generate the constants and
-# mach-types header files. If we do it now, mkdep will pick
-# the dependencies up later on when it runs through the other
-# directories
-
-dep:
- $(TOPDIR)/scripts/mkdep $(CFLAGS) $(EXTRA_CFLAGS) -- getconstants.c |\
- sed s,getconstants.o,constants.h, > .depend
- $(MAKE) all
-
-.PHONY: all dep
-
-ifneq ($(wildcard .depend),)
-include .depend
-endif
+.PHONY: all
diff -Nru a/arch/arm/tools/constants-hdr b/arch/arm/tools/constants-hdr
--- a/arch/arm/tools/constants-hdr Tue Jun 18 19:12:01 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,5 +0,0 @@
-/*
- * This file is automatically generated from arch/arm/tools/getconstants.c.
- * Do not edit! Only include this file in assembly (.S) files!
- */
-
diff -Nru a/arch/arm/tools/getconstants.c b/arch/arm/tools/getconstants.c
--- a/arch/arm/tools/getconstants.c Tue Jun 18 19:12:02 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,75 +0,0 @@
-/*
- * linux/arch/arm/tools/getconsdata.c
- *
- * Copyright (C) 1995-2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include
-#include
-#include
-
-#include
-#include
-
-/*
- * Make sure that the compiler and target are compatible.
- */
-#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
-#error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26
-#endif
-#if defined(__APCS_26__) && defined(CONFIG_CPU_32)
-#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
-#endif
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
-#error Sorry, your compiler is known to miscompile kernels. Only use gcc 2.95.3 and later.
-#endif
-#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
-/* shame we can't detect the .1 or .2 releases */
-#warning GCC 2.95.2 and earlier miscompiles kernels.
-#endif
-
-#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
-#define OFF_VMA(n) (unsigned long)&(((struct vm_area_struct *)0)->n)
-
-#define DEFN(name,off) asm("\n#define "name" %0" :: "I" (off))
-
-void func(void)
-{
-DEFN("TSK_USED_MATH", OFF_TSK(used_math));
-DEFN("TSK_ACTIVE_MM", OFF_TSK(active_mm));
-
-DEFN("VMA_VM_MM", OFF_VMA(vm_mm));
-DEFN("VMA_VM_FLAGS", OFF_VMA(vm_flags));
-
-DEFN("VM_EXEC", VM_EXEC);
-
-#ifdef CONFIG_CPU_32
-DEFN("HPTE_TYPE_SMALL", PTE_TYPE_SMALL);
-DEFN("HPTE_AP_READ", PTE_AP_READ);
-DEFN("HPTE_AP_WRITE", PTE_AP_WRITE);
-
-DEFN("LPTE_PRESENT", L_PTE_PRESENT);
-DEFN("LPTE_YOUNG", L_PTE_YOUNG);
-DEFN("LPTE_BUFFERABLE", L_PTE_BUFFERABLE);
-DEFN("LPTE_CACHEABLE", L_PTE_CACHEABLE);
-DEFN("LPTE_USER", L_PTE_USER);
-DEFN("LPTE_WRITE", L_PTE_WRITE);
-DEFN("LPTE_EXEC", L_PTE_EXEC);
-DEFN("LPTE_DIRTY", L_PTE_DIRTY);
-#endif
-
-#ifdef CONFIG_CPU_26
-DEFN("PAGE_PRESENT", _PAGE_PRESENT);
-DEFN("PAGE_READONLY", _PAGE_READONLY);
-DEFN("PAGE_NOT_USER", _PAGE_NOT_USER);
-DEFN("PAGE_OLD", _PAGE_OLD);
-DEFN("PAGE_CLEAN", _PAGE_CLEAN);
-#endif
-
-DEFN("PAGE_SZ", PAGE_SIZE);
-
-DEFN("SYS_ERROR0", 0x9f0000);
-}
diff -Nru a/arch/cris/Makefile b/arch/cris/Makefile
--- a/arch/cris/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/cris/Makefile Tue Jun 18 19:12:02 2002
@@ -100,6 +100,3 @@
rm -rf $(LD_SCRIPT).tmp
archmrproper:
-
-archdep:
- @$(MAKEBOOT) dep
diff -Nru a/arch/cris/boot/Makefile b/arch/cris/boot/Makefile
--- a/arch/cris/boot/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/cris/boot/Makefile Tue Jun 18 19:12:02 2002
@@ -7,8 +7,6 @@
compressed/vmlinuz: $(TOPDIR)/vmlinux
@$(MAKE) -C compressed vmlinuz
-dep:
-
clean:
rm -f zImage tools/build compressed/vmlinux.out
@$(MAKE) -C compressed clean
diff -Nru a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
--- a/arch/cris/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/cris/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -44,6 +44,8 @@
#include
+u64 jiffies_64;
+
static int have_rtc; /* used to remember if we have an RTC or not */
/* define this if you need to use print_timestamp */
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/i386/Makefile Tue Jun 18 19:12:02 2002
@@ -108,7 +108,7 @@
vmlinux: arch/i386/vmlinux.lds
.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
- clean archclean archmrproper archdep
+ clean archclean archmrproper
zImage: vmlinux
@$(MAKEBOOT) zImage
@@ -140,6 +140,3 @@
@$(MAKEBOOT) clean
archmrproper:
-
-archdep:
- @$(MAKEBOOT) dep
diff -Nru a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
--- a/arch/i386/boot/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/i386/boot/Makefile Tue Jun 18 19:12:02 2002
@@ -23,7 +23,7 @@
# If you want the RAM disk device, define this to be the size in blocks.
-RAMDISK := -DRAMDISK=512
+#RAMDISK := -DRAMDISK=512
# ---------------------------------------------------------------------------
@@ -96,8 +96,6 @@
bsetup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
$(CPP) $(CPPFLAGS) -D__BIG_KERNEL__ -D__ASSEMBLY__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
-
-dep:
clean:
@echo 'Cleaning up (boot)'
diff -Nru a/arch/i386/config.in b/arch/i386/config.in
--- a/arch/i386/config.in Tue Jun 18 19:12:02 2002
+++ b/arch/i386/config.in Tue Jun 18 19:12:02 2002
@@ -153,9 +153,24 @@
define_bool CONFIG_X86_OOSTORE y
fi
+bool 'Symmetric multi-processing support' CONFIG_SMP
+bool 'Preemptible Kernel' CONFIG_PREEMPT
+if [ "$CONFIG_SMP" != "y" ]; then
+ bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
+ dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
+ if [ "$CONFIG_X86_UP_APIC" = "y" ]; then
+ define_bool CONFIG_X86_LOCAL_APIC y
+ fi
+ if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then
+ define_bool CONFIG_X86_IO_APIC y
+ fi
+else
+ bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
+fi
+
bool 'Machine Check Exception' CONFIG_X86_MCE
dep_bool 'Check for non-fatal errors on Athlon/Duron' CONFIG_X86_MCE_NONFATAL $CONFIG_X86_MCE
-dep_bool 'check for P4 thermal throttling interrupt.' CONFIG_X86_MCE_P4THERMAL $CONFIG_X86_MCE $CONFIG_X86_LOCAL_APIC
+dep_bool 'check for P4 thermal throttling interrupt.' CONFIG_X86_MCE_P4THERMAL $CONFIG_X86_MCE $CONFIG_X86_UP_APIC
tristate 'Toshiba Laptop support' CONFIG_TOSHIBA
@@ -185,20 +200,6 @@
bool 'Math emulation' CONFIG_MATH_EMULATION
bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
-bool 'Symmetric multi-processing support' CONFIG_SMP
-bool 'Preemptible Kernel' CONFIG_PREEMPT
-if [ "$CONFIG_SMP" != "y" ]; then
- bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
- dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
- if [ "$CONFIG_X86_UP_APIC" = "y" ]; then
- define_bool CONFIG_X86_LOCAL_APIC y
- fi
- if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then
- define_bool CONFIG_X86_IO_APIC y
- fi
-else
- bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
-fi
if [ "$CONFIG_SMP" = "y" -o "$CONFIG_PREEMPT" = "y" ]; then
if [ "$CONFIG_X86_CMPXCHG" = "y" ]; then
diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
--- a/arch/i386/kernel/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/i386/kernel/Makefile Tue Jun 18 19:12:01 2002
@@ -15,7 +15,6 @@
obj-y += cpu/
obj-$(CONFIG_MCA) += mca.o
-obj-$(CONFIG_EISA) += eisa.o
obj-$(CONFIG_MTRR) += mtrr.o
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c Tue Jun 18 19:12:02 2002
+++ b/arch/i386/kernel/apic.c Tue Jun 18 19:12:02 2002
@@ -813,10 +813,10 @@
* IRQ APIC event being in synchron with the APIC clock we
* introduce an interrupt skew to spread out timer events.
*
- * The number of slices within a 'big' timeslice is smp_num_cpus+1
+ * The number of slices within a 'big' timeslice is NR_CPUS+1
*/
- slice = clocks / (smp_num_cpus+1);
+ slice = clocks / (NR_CPUS+1);
printk("cpu: %d, clocks: %d, slice: %d\n", smp_processor_id(), clocks, slice);
/*
diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c Tue Jun 18 19:12:01 2002
+++ b/arch/i386/kernel/apm.c Tue Jun 18 19:12:01 2002
@@ -899,7 +899,7 @@
*/
#ifdef CONFIG_SMP
/* Some bioses don't like being called from CPU != 0 */
- while (cpu_number_map(smp_processor_id()) != 0) {
+ while (smp_processor_id() != 0) {
kernel_thread(apm_magic, NULL,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
schedule();
@@ -1586,7 +1586,7 @@
p = buf;
- if ((smp_num_cpus == 1) &&
+ if ((num_online_cpus() == 1) &&
!(error = apm_get_power_status(&bx, &cx, &dx))) {
ac_line_status = (bx >> 8) & 0xff;
battery_status = bx & 0xff;
@@ -1717,7 +1717,7 @@
}
}
- if (debug && (smp_num_cpus == 1)) {
+ if (debug && (num_online_cpus() == 1)) {
error = apm_get_power_status(&bx, &cx, &dx);
if (error)
printk(KERN_INFO "apm: power status not available\n");
@@ -1761,7 +1761,7 @@
pm_power_off = apm_power_off;
register_sysrq_key('o', &sysrq_poweroff_op);
- if (smp_num_cpus == 1) {
+ if (num_online_cpus() == 1) {
#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
console_blank_hook = apm_console_blank;
#endif
@@ -1904,7 +1904,9 @@
printk(KERN_NOTICE "apm: disabled on user request.\n");
return -ENODEV;
}
- if ((smp_num_cpus > 1) && !power_off) {
+ /* FIXME: When boot code changes, this will need to be
+ deactivated when/if a CPU comes up --RR */
+ if ((num_online_cpus() > 1) && !power_off) {
printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
return -ENODEV;
}
@@ -1958,7 +1960,9 @@
kernel_thread(apm, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
- if (smp_num_cpus > 1) {
+ /* FIXME: When boot code changes, this will need to be
+ deactivated when/if a CPU comes up --RR */
+ if (num_online_cpus() > 1) {
printk(KERN_NOTICE
"apm: disabled - APM is not SMP safe (power off active).\n");
return 0;
diff -Nru a/arch/i386/kernel/bluesmoke.c b/arch/i386/kernel/bluesmoke.c
--- a/arch/i386/kernel/bluesmoke.c Tue Jun 18 19:12:02 2002
+++ b/arch/i386/kernel/bluesmoke.c Tue Jun 18 19:12:02 2002
@@ -298,7 +298,9 @@
{
unsigned int i;
- for (i=0; i= smp_num_cpus)
+ if (cpu >= NR_CPUS)
cpu = 0;
} else {
cpu--;
if (cpu == -1)
- cpu = smp_num_cpus-1;
+ cpu = NR_CPUS-1;
}
- } while (!IRQ_ALLOWED(cpu,allowed_mask) ||
+ } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu,allowed_mask) ||
(search_idle && !IDLE_ENOUGH(cpu,now)));
return cpu;
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c Tue Jun 18 19:12:01 2002
+++ b/arch/i386/kernel/irq.c Tue Jun 18 19:12:01 2002
@@ -138,8 +138,9 @@
struct irqaction * action;
seq_printf(p, " ");
- for (j=0; jtypename);
seq_printf(p, " %s", action->name);
@@ -162,13 +164,15 @@
seq_putc(p, '\n');
}
seq_printf(p, "NMI: ");
- for (j = 0; j < smp_num_cpus; j++)
- seq_printf(p, "%10u ", nmi_count(cpu_logical_map(j)));
+ for (j = 0; j < NR_CPUS; j++)
+ if (cpu_online(j))
+ p += seq_printf(p, "%10u ", nmi_count(j));
seq_putc(p, '\n');
#if CONFIG_X86_LOCAL_APIC
seq_printf(p, "LOC: ");
- for (j = 0; j < smp_num_cpus; j++)
- seq_printf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]);
+ for (j = 0; j < NR_CPUS; j++)
+ if (cpu_online(j))
+ p += seq_printf(p, "%10u ", apic_timer_irqs[j]);
seq_putc(p, '\n');
#endif
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
@@ -198,14 +202,14 @@
printk("\n%s, CPU %d:\n", str, cpu);
printk("irq: %d [",irqs_running());
- for(i=0;i < smp_num_cpus;i++)
+ for(i=0;i < NR_CPUS;i++)
printk(" %d",local_irq_count(i));
printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
- for(i=0;i < smp_num_cpus;i++)
+ for(i=0;i < NR_CPUS;i++)
printk(" %d",local_bh_count(i));
printk(" ]\nStack dumps:");
- for(i = 0; i < smp_num_cpus; i++) {
+ for(i = 0; i < NR_CPUS; i++) {
unsigned long esp;
if (i == cpu)
continue;
@@ -356,8 +360,9 @@
__save_flags(flags);
if (flags & (1 << EFLAGS_IF_SHIFT)) {
- int cpu = smp_processor_id();
+ int cpu;
__cli();
+ cpu = smp_processor_id();
if (!local_irq_count(cpu))
get_irqlock(cpu);
}
@@ -365,11 +370,12 @@
void __global_sti(void)
{
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
if (!local_irq_count(cpu))
release_irqlock(cpu);
__sti();
+ put_cpu();
}
/*
diff -Nru a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
--- a/arch/i386/kernel/microcode.c Tue Jun 18 19:12:02 2002
+++ b/arch/i386/kernel/microcode.c Tue Jun 18 19:12:02 2002
@@ -188,7 +188,7 @@
}
do_update_one(NULL);
- for (i=0; i 0) { rep_nop(); barrier(); }
/* Set up for completion wait and then release other CPUs to change MTRRs*/
- atomic_set (&undone_count, smp_num_cpus - 1);
+ atomic_set (&undone_count, num_online_cpus() - 1);
wait_barrier_cache_disable = FALSE;
set_mtrr_cache_disable (&ctxt);
/* Wait for all other CPUs to flush and disable their caches */
while (atomic_read (&undone_count) > 0) { rep_nop(); barrier(); }
/* Set up for completion wait and then release other CPUs to change MTRRs*/
- atomic_set (&undone_count, smp_num_cpus - 1);
+ atomic_set (&undone_count, num_online_cpus() - 1);
wait_barrier_execute = FALSE;
(*set_mtrr_up) (reg, base, size, type, FALSE);
/* Now wait for other CPUs to complete the function */
diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c Tue Jun 18 19:12:02 2002
+++ b/arch/i386/kernel/nmi.c Tue Jun 18 19:12:02 2002
@@ -73,7 +73,7 @@
int __init check_nmi_watchdog (void)
{
irq_cpustat_t tmp[NR_CPUS];
- int j, cpu;
+ int cpu;
printk(KERN_INFO "testing NMI watchdog ... ");
@@ -81,8 +81,9 @@
sti();
mdelay((10*1000)/nmi_hz); // wait 10 ticks
- for (j = 0; j < smp_num_cpus; j++) {
- cpu = cpu_logical_map(j);
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (!cpu_online(cpu))
+ continue;
if (nmi_count(cpu) - tmp[cpu].__nmi_count <= 5) {
printk("CPU#%d: NMI appears to be stuck!\n", cpu);
return -1;
@@ -330,7 +331,7 @@
* Just reset the alert counters, (other CPUs might be
* spinning on locks we hold):
*/
- for (i = 0; i < smp_num_cpus; i++)
+ for (i = 0; i < NR_CPUS; i++)
alert_counter[i] = 0;
}
diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
--- a/arch/i386/kernel/smp.c Tue Jun 18 19:12:01 2002
+++ b/arch/i386/kernel/smp.c Tue Jun 18 19:12:01 2002
@@ -247,18 +247,16 @@
* we get an APIC send error if we try to broadcast.
* thus we have to avoid sending IPIs in this case.
*/
- if (!(smp_num_cpus > 1))
+ if (!(num_online_cpus() > 1))
return;
if (clustered_apic_mode) {
// Pointless. Use send_IPI_mask to do this instead
int cpu;
- if (smp_num_cpus > 1) {
- for (cpu = 0; cpu < smp_num_cpus; ++cpu) {
- if (cpu != smp_processor_id())
- send_IPI_mask(1 << cpu, vector);
- }
+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ if (cpu_online(cpu) && cpu != smp_processor_id())
+ send_IPI_mask(1 << cpu, vector);
}
} else {
__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
@@ -272,7 +270,9 @@
// Pointless. Use send_IPI_mask to do this instead
int cpu;
- for (cpu = 0; cpu < smp_num_cpus; ++cpu) {
+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ if (!cpu_online(cpu))
+ continue;
send_IPI_mask(1 << cpu, vector);
}
} else {
@@ -567,7 +567,7 @@
*/
{
struct call_data_struct data;
- int cpus = smp_num_cpus-1;
+ int cpus = num_online_cpus()-1;
if (!cpus)
return 0;
@@ -617,7 +617,6 @@
void smp_send_stop(void)
{
smp_call_function(stop_this_cpu, NULL, 1, 0);
- smp_num_cpus = 1;
__cli();
disable_local_APIC();
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c Tue Jun 18 19:12:02 2002
+++ b/arch/i386/kernel/smpboot.c Tue Jun 18 19:12:02 2002
@@ -56,9 +56,6 @@
/* Setup configured maximum number of CPUs to activate */
static int max_cpus = -1;
-/* Total count of live CPUs */
-int smp_num_cpus = 1;
-
/* Number of siblings per CPU package */
int smp_num_siblings = 1;
int __initdata phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
@@ -292,7 +289,8 @@
/*
* all APs synchronize but they loop on '== num_cpus'
*/
- while (atomic_read(&tsc_count_start) != smp_num_cpus-1) mb();
+ while (atomic_read(&tsc_count_start) != num_online_cpus()-1)
+ mb();
atomic_set(&tsc_count_stop, 0);
wmb();
/*
@@ -310,21 +308,26 @@
/*
* Wait for all APs to leave the synchronization point:
*/
- while (atomic_read(&tsc_count_stop) != smp_num_cpus-1) mb();
+ while (atomic_read(&tsc_count_stop) != num_online_cpus()-1)
+ mb();
atomic_set(&tsc_count_start, 0);
wmb();
atomic_inc(&tsc_count_stop);
}
sum = 0;
- for (i = 0; i < smp_num_cpus; i++) {
- t0 = tsc_values[i];
- sum += t0;
+ for (i = 0; i < NR_CPUS; i++) {
+ if (cpu_online(i)) {
+ t0 = tsc_values[i];
+ sum += t0;
+ }
}
- avg = div64(sum, smp_num_cpus);
+ avg = div64(sum, num_online_cpus());
sum = 0;
- for (i = 0; i < smp_num_cpus; i++) {
+ for (i = 0; i < NR_CPUS; i++) {
+ if (!cpu_online(i))
+ continue;
delta = tsc_values[i] - avg;
if (delta < 0)
delta = -delta;
@@ -356,7 +359,7 @@
int i;
/*
- * smp_num_cpus is not necessarily known at the time
+ * num_online_cpus is not necessarily known at the time
* this gets called, so we first wait for the BP to
* finish SMP initialization:
*/
@@ -364,14 +367,15 @@
for (i = 0; i < NR_LOOPS; i++) {
atomic_inc(&tsc_count_start);
- while (atomic_read(&tsc_count_start) != smp_num_cpus) mb();
+ while (atomic_read(&tsc_count_start) != num_online_cpus())
+ mb();
rdtscll(tsc_values[smp_processor_id()]);
if (i == NR_LOOPS-1)
write_tsc(0, 0);
atomic_inc(&tsc_count_stop);
- while (atomic_read(&tsc_count_stop) != smp_num_cpus) mb();
+ while (atomic_read(&tsc_count_stop) != num_online_cpus()) mb();
}
}
#undef NR_LOOPS
@@ -1070,7 +1074,6 @@
io_apic_irqs = 0;
#endif
cpu_online_map = phys_cpu_present_map = 1;
- smp_num_cpus = 1;
if (APIC_init_uniprocessor())
printk(KERN_NOTICE "Local APIC not detected."
" Using dummy APIC emulation.\n");
@@ -1100,7 +1103,6 @@
io_apic_irqs = 0;
#endif
cpu_online_map = phys_cpu_present_map = 1;
- smp_num_cpus = 1;
goto smp_done;
}
@@ -1116,7 +1118,6 @@
io_apic_irqs = 0;
#endif
cpu_online_map = phys_cpu_present_map = 1;
- smp_num_cpus = 1;
goto smp_done;
}
@@ -1197,7 +1198,6 @@
(bogosum/(5000/HZ))%100);
Dprintk("Before bogocount - setting activated=1.\n");
}
- smp_num_cpus = cpucount + 1;
if (smp_b_stepping)
printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
@@ -1211,11 +1211,12 @@
for (cpu = 0; cpu < NR_CPUS; cpu++)
cpu_sibling_map[cpu] = NO_PROC_ID;
- for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
int i;
-
- for (i = 0; i < smp_num_cpus; i++) {
- if (i == cpu)
+ if (!cpu_online(cpu)) continue;
+
+ for (i = 0; i < NR_CPUS; i++) {
+ if (i == cpu || !cpu_online(i))
continue;
if (phys_proc_id[cpu] == phys_proc_id[i]) {
cpu_sibling_map[cpu] = i;
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/i386/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -65,6 +65,7 @@
*/
#include
+u64 jiffies_64;
unsigned long cpu_khz; /* Detected as we calibrate the TSC */
diff -Nru a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile
--- a/arch/i386/mm/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/i386/mm/Makefile Tue Jun 18 19:12:02 2002
@@ -9,6 +9,7 @@
O_TARGET := mm.o
-obj-y := init.o fault.o ioremap.o extable.o
+obj-y := init.o fault.o ioremap.o extable.o pageattr.o
+export-objs := pageattr.o
include $(TOPDIR)/Rules.make
diff -Nru a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
--- a/arch/i386/mm/ioremap.c Tue Jun 18 19:12:02 2002
+++ b/arch/i386/mm/ioremap.c Tue Jun 18 19:12:02 2002
@@ -10,12 +10,13 @@
#include
#include
+#include
#include
#include
#include
#include
#include
-
+#include
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
@@ -155,6 +156,7 @@
area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;
+ area->phys_addr = phys_addr;
addr = area->addr;
if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
vfree(addr);
@@ -163,10 +165,69 @@
return (void *) (offset + (char *)addr);
}
+
+/**
+ * ioremap_nocache - map bus memory into CPU space
+ * @offset: bus address of the memory
+ * @size: size of the resource to map
+ *
+ * ioremap_nocache performs a platform specific sequence of operations to
+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
+ * writew/writel functions and the other mmio helpers. The returned
+ * address is not guaranteed to be usable directly as a virtual
+ * address.
+ *
+ * This version of ioremap ensures that the memory is marked uncachable
+ * on the CPU as well as honouring existing caching rules from things like
+ * the PCI bus. Note that there are other caches and buffers on many
+ * busses. In particular driver authors should read up on PCI writes
+ *
+ * It's useful if some control registers are in such an area and
+ * write combining or read caching is not desirable:
+ *
+ * Must be freed with iounmap.
+ */
+
+void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
+{
+ void *p = __ioremap(phys_addr, size, _PAGE_PCD);
+ if (!p)
+ return p;
+
+ if (phys_addr + size < virt_to_phys(high_memory)) {
+ struct page *ppage = virt_to_page(__va(phys_addr));
+ unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+ BUG_ON(phys_addr+size > (unsigned long)high_memory);
+ BUG_ON(phys_addr + size < phys_addr);
+
+ if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) {
+ iounmap(p);
+ p = NULL;
+ }
+ }
+
+ return p;
+}
+
void iounmap(void *addr)
{
- if (addr > high_memory)
- return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+ struct vm_struct *p;
+ if (addr < high_memory)
+ return;
+ p = remove_kernel_area(addr);
+ if (!p) {
+ printk("__iounmap: bad address %p\n", addr);
+ return;
+ }
+
+ vmfree_area_pages(VMALLOC_VMADDR(p->addr), p->size);
+ if (p->flags && p->phys_addr < virt_to_phys(high_memory)) {
+ change_page_attr(virt_to_page(__va(p->phys_addr)),
+ p->size >> PAGE_SHIFT,
+ PAGE_KERNEL);
+ }
+ kfree(p);
}
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
diff -Nru a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/i386/mm/pageattr.c Tue Jun 18 19:12:03 2002
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ * Thanks to Ben LaHaise for precious feedback.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static inline pte_t *lookup_address(unsigned long address)
+{
+ pgd_t *pgd = pgd_offset_k(address);
+ pmd_t *pmd = pmd_offset(pgd, address);
+ if (pmd_large(*pmd))
+ return (pte_t *)pmd;
+ return pte_offset_kernel(pmd, address);
+}
+
+static struct page *split_large_page(unsigned long address, pgprot_t prot)
+{
+ int i;
+ unsigned long addr;
+ struct page *base = alloc_pages(GFP_KERNEL, 0);
+ pte_t *pbase;
+ if (!base)
+ return NULL;
+ address = __pa(address);
+ addr = address & LARGE_PAGE_MASK;
+ pbase = (pte_t *)page_address(base);
+ for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
+ pbase[i] = pfn_pte(addr >> PAGE_SHIFT,
+ addr == address ? prot : PAGE_KERNEL);
+ }
+ return base;
+}
+
+static void flush_kernel_map(void *dummy)
+{
+ /* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */
+ if (boot_cpu_data.x86_model >= 4)
+ asm volatile("wbinvd":::"memory");
+ /* Flush all to work around Errata in early athlons regarding
+ * large page flushing.
+ */
+ __flush_tlb_all();
+}
+
+static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
+{
+ set_pte_atomic(kpte, pte); /* change init_mm */
+#ifndef CONFIG_X86_PAE
+ {
+ struct list_head *l;
+ spin_lock(&mmlist_lock);
+ list_for_each(l, &init_mm.mmlist) {
+ struct mm_struct *mm = list_entry(l, struct mm_struct, mmlist);
+ pmd_t *pmd = pmd_offset(pgd_offset(mm, address), address);
+ set_pte_atomic((pte_t *)pmd, pte);
+ }
+ spin_unlock(&mmlist_lock);
+ }
+#endif
+}
+
+/*
+ * No more special protections in this 2/4MB area - revert to a
+ * large page again.
+ */
+static inline void revert_page(struct page *kpte_page, unsigned long address)
+{
+ pte_t *linear = (pte_t *)
+ pmd_offset(pgd_offset(&init_mm, address), address);
+ set_pmd_pte(linear, address,
+ pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
+ PAGE_KERNEL_LARGE));
+}
+
+static int
+__change_page_attr(struct page *page, pgprot_t prot, struct page **oldpage)
+{
+ pte_t *kpte;
+ unsigned long address;
+ struct page *kpte_page;
+
+#ifdef CONFIG_HIGHMEM
+ if (page >= highmem_start_page)
+ BUG();
+#endif
+ address = (unsigned long)page_address(page);
+
+ kpte = lookup_address(address);
+ kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
+ if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) {
+ if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
+ pte_t old = *kpte;
+ pte_t standard = mk_pte(page, PAGE_KERNEL);
+
+ set_pte_atomic(kpte, mk_pte(page, prot));
+ if (pte_same(old,standard))
+ atomic_inc(&kpte_page->count);
+ } else {
+ struct page *split = split_large_page(address, prot);
+ if (!split)
+ return -ENOMEM;
+ set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+ }
+ } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
+ set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
+ atomic_dec(&kpte_page->count);
+ }
+
+ if (cpu_has_pse && (atomic_read(&kpte_page->count) == 1)) {
+ *oldpage = kpte_page;
+ revert_page(kpte_page, address);
+ }
+ return 0;
+}
+
+static inline void flush_map(void)
+{
+#ifdef CONFIG_SMP
+ smp_call_function(flush_kernel_map, NULL, 1, 1);
+#endif
+ flush_kernel_map(NULL);
+}
+
+struct deferred_page {
+ struct deferred_page *next;
+ struct page *fpage;
+};
+static struct deferred_page *df_list; /* protected by init_mm.mmap_sem */
+
+/*
+ * Change the page attributes of an page in the linear mapping.
+ *
+ * This should be used when a page is mapped with a different caching policy
+ * than write-back somewhere - some CPUs do not like it when mappings with
+ * different caching policies exist. This changes the page attributes of the
+ * in kernel linear mapping too.
+ *
+ * The caller needs to ensure that there are no conflicting mappings elsewhere.
+ * This function only deals with the kernel linear map.
+ *
+ * Caller must call global_flush_tlb() after this.
+ */
+int change_page_attr(struct page *page, int numpages, pgprot_t prot)
+{
+ int err = 0;
+ struct page *fpage;
+ int i;
+
+ down_write(&init_mm.mmap_sem);
+ for (i = 0; i < numpages; i++, page++) {
+ fpage = NULL;
+ err = __change_page_attr(page, prot, &fpage);
+ if (err)
+ break;
+ if (fpage) {
+ struct deferred_page *df;
+ df = kmalloc(sizeof(struct deferred_page), GFP_KERNEL);
+ if (!df) {
+ flush_map();
+ __free_page(fpage);
+ } else {
+ df->next = df_list;
+ df->fpage = fpage;
+ df_list = df;
+ }
+ }
+ }
+ up_write(&init_mm.mmap_sem);
+ return err;
+}
+
+void global_flush_tlb(void)
+{
+ struct deferred_page *df, *next_df;
+
+ down_read(&init_mm.mmap_sem);
+ df = xchg(&df_list, NULL);
+ up_read(&init_mm.mmap_sem);
+ flush_map();
+ for (; df; df = next_df) {
+ next_df = df->next;
+ if (df->fpage)
+ __free_page(df->fpage);
+ kfree(df);
+ }
+}
+
+EXPORT_SYMBOL(change_page_attr);
+EXPORT_SYMBOL(global_flush_tlb);
diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile
--- a/arch/ia64/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/ia64/Makefile Tue Jun 18 19:12:01 2002
@@ -127,8 +127,11 @@
rm -f arch/$(ARCH)/vmlinux.lds
@$(MAKE) -C arch/$(ARCH)/tools mrproper
-archdep:
- @$(MAKEBOOT) dep
-
bootpfile:
@$(MAKEBOOT) bootpfile
+
+prepare: $(TOPDIR)/include/asm-ia64/offsets.h
+
+$(TOPDIR)/include/asm-ia64/offsets.h: include/asm include/linux/version.h \
+ include/config/MARKER
+ @$(MAKE) -C arch/$(ARCH)/tools $@
\ No newline at end of file
diff -Nru a/arch/ia64/boot/Makefile b/arch/ia64/boot/Makefile
--- a/arch/ia64/boot/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/ia64/boot/Makefile Tue Jun 18 19:12:02 2002
@@ -23,5 +23,3 @@
clean:
rm -f $(TARGETS)
-
-dep:
diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
--- a/arch/ia64/ia32/sys_ia32.c Tue Jun 18 19:12:02 2002
+++ b/arch/ia64/ia32/sys_ia32.c Tue Jun 18 19:12:02 2002
@@ -3629,47 +3629,6 @@
return ret;
}
-/* In order to reduce some races, while at the same time doing additional
- * checking and hopefully speeding things up, we copy filenames to the
- * kernel data space before using them..
- *
- * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
- */
-static inline int
-do_getname32 (const char *filename, char *page)
-{
- int retval;
-
- /* 32bit pointer will be always far below TASK_SIZE :)) */
- retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
- if (retval > 0) {
- if (retval < PAGE_SIZE)
- return 0;
- return -ENAMETOOLONG;
- } else if (!retval)
- retval = -ENOENT;
- return retval;
-}
-
-static char *
-getname32 (const char *filename)
-{
- char *tmp, *result;
-
- result = ERR_PTR(-ENOMEM);
- tmp = (char *)__get_free_page(GFP_KERNEL);
- if (tmp) {
- int retval = do_getname32(filename, tmp);
-
- result = tmp;
- if (retval < 0) {
- putname(tmp);
- result = ERR_PTR(retval);
- }
- }
- return result;
-}
-
asmlinkage long
sys32_sched_rr_get_interval (pid_t pid, struct timespec32 *interval)
{
diff -Nru a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
--- a/arch/ia64/kernel/ia64_ksyms.c Tue Jun 18 19:12:02 2002
+++ b/arch/ia64/kernel/ia64_ksyms.c Tue Jun 18 19:12:02 2002
@@ -85,9 +85,6 @@
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(ia64_cpu_to_sapicid);
-#include
-EXPORT_SYMBOL(smp_num_cpus);
-
#include
EXPORT_SYMBOL(kernel_flag);
diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
--- a/arch/ia64/kernel/iosapic.c Tue Jun 18 19:12:02 2002
+++ b/arch/ia64/kernel/iosapic.c Tue Jun 18 19:12:02 2002
@@ -256,7 +256,7 @@
char *addr;
int redir = (irq & (1<<31)) ? 1 : 0;
- mask &= (1UL << smp_num_cpus) - 1;
+ mask &= cpu_online_map;
if (!mask || irq >= IA64_NUM_VECTORS)
return;
@@ -759,9 +759,8 @@
set_rte(vector, cpu_physical_id(cpu_index) & 0xffff);
- cpu_index++;
- if (cpu_index >= smp_num_cpus)
- cpu_index = 0;
+ for (cpu_index++; !cpu_online(cpu_index % NR_CPUS); cpu_index++);
+ cpu_index %= NR_CPUS;
} else {
/*
* Direct the interrupt vector to the current cpu,
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c Tue Jun 18 19:12:02 2002
+++ b/arch/ia64/kernel/irq.c Tue Jun 18 19:12:02 2002
@@ -156,8 +156,9 @@
irq_desc_t *idesc;
seq_puts(p, " ");
- for (j=0; jhandler->typename);
seq_printf(p, " %s", action->name);
@@ -181,15 +182,15 @@
seq_putc(p, '\n');
}
seq_puts(p, "NMI: ");
- for (j = 0; j < smp_num_cpus; j++)
- seq_printf(p, "%10u ",
- nmi_count(cpu_logical_map(j)));
+ for (j = 0; j < NR_CPUS; j++)
+ if (cpu_online(j))
+ seq_printf(p, "%10u ", nmi_count(j));
seq_putc(p, '\n');
#if defined(CONFIG_SMP) && defined(CONFIG_X86)
seq_puts(p, "LOC: ");
- for (j = 0; j < smp_num_cpus; j++)
- seq_printf(p, "%10u ",
- apic_timer_irqs[cpu_logical_map(j)]);
+ for (j = 0; j < NR_CPUS; j++)
+ if (cpu_online(j))
+ seq_printf(p, "%10u ", apic_timer_irqs[j]);
seq_putc(p, '\n');
#endif
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
@@ -218,10 +219,10 @@
printk("\n%s, CPU %d:\n", str, cpu);
printk("irq: %d [",irqs_running());
- for(i=0;i < smp_num_cpus;i++)
+ for(i=0;i < NR_CPUS;i++)
printk(" %d",irq_count(i));
printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
- for(i=0;i < smp_num_cpus;i++)
+ for(i=0;i < NR_CPUS;i++)
printk(" %d",bh_count(i));
printk(" ]\nStack dumps:");
@@ -233,7 +234,7 @@
* idea.
*/
#elif defined(CONFIG_X86)
- for(i=0;i< smp_num_cpus;i++) {
+ for(i=0;i< NR_CPUS;i++) {
unsigned long esp;
if(i==cpu)
continue;
diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
--- a/arch/ia64/kernel/mca.c Tue Jun 18 19:12:02 2002
+++ b/arch/ia64/kernel/mca.c Tue Jun 18 19:12:02 2002
@@ -604,9 +604,12 @@
int cpu;
/* Clear the Rendez checkin flag for all cpus */
- for(cpu = 0; cpu < smp_num_cpus; cpu++)
+ for(cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (!cpu_online(cpu))
+ continue;
if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE)
ia64_mca_wakeup(cpu);
+ }
}
diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c Tue Jun 18 19:12:03 2002
+++ b/arch/ia64/kernel/perfmon.c Tue Jun 18 19:12:03 2002
@@ -903,7 +903,7 @@
* and it must be a valid CPU
*/
cpu = ffs(pfx->ctx_cpu_mask);
- if (cpu > smp_num_cpus) {
+ if (!cpu_online(cpu)) {
DBprintk(("CPU%d is not online\n", cpu));
return -EINVAL;
}
diff -Nru a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
--- a/arch/ia64/kernel/smp.c Tue Jun 18 19:12:03 2002
+++ b/arch/ia64/kernel/smp.c Tue Jun 18 19:12:03 2002
@@ -168,8 +168,8 @@
{
int i;
- for (i = 0; i < smp_num_cpus; i++) {
- if (i != smp_processor_id())
+ for (i = 0; i < NR_CPUS; i++) {
+ if (cpu_online(i) && i != smp_processor_id())
send_IPI_single(i, op);
}
}
@@ -179,8 +179,9 @@
{
int i;
- for (i = 0; i < smp_num_cpus; i++)
- send_IPI_single(i, op);
+ for (i = 0; i < NR_CPUS; i++)
+ if (cpu_online(i))
+ send_IPI_single(i, op);
}
static inline void
@@ -205,8 +206,8 @@
{
int i;
- for (i = 0; i < smp_num_cpus; i++)
- if (i != smp_processor_id())
+ for (i = 0; i < NR_CPUS; i++)
+ if (cpu_online(i) && i != smp_processor_id())
smp_send_reschedule(i);
}
@@ -290,7 +291,7 @@
smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait)
{
struct call_data_struct data;
- int cpus = smp_num_cpus-1;
+ int cpus = num_online_cpus()-1;
if (!cpus)
return 0;
@@ -339,7 +340,6 @@
smp_send_stop (void)
{
send_IPI_allbutself(IPI_CPU_STOP);
- smp_num_cpus = 1;
}
int __init
diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
--- a/arch/ia64/kernel/smpboot.c Tue Jun 18 19:12:02 2002
+++ b/arch/ia64/kernel/smpboot.c Tue Jun 18 19:12:02 2002
@@ -76,9 +76,6 @@
/* Setup configured maximum number of CPUs to activate */
static int max_cpus = -1;
-/* Total count of live CPUs */
-int smp_num_cpus = 1;
-
/* Bitmask of currently online CPUs */
volatile unsigned long cpu_online_map;
@@ -505,7 +502,6 @@
if (!max_cpus || (max_cpus < -1)) {
printk(KERN_INFO "SMP mode deactivated.\n");
cpu_online_map = 1;
- smp_num_cpus = 1;
goto smp_done;
}
if (max_cpus != -1)
@@ -535,8 +531,6 @@
printk("phys CPU#%d not responding - cannot use it.\n", cpu);
}
- smp_num_cpus = cpucount + 1;
-
/*
* Allow the user to impress friends.
*/
@@ -581,6 +575,5 @@
printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n Forcing UP mode\n",
ia64_sal_strerror(sal_ret));
max_cpus = 0;
- smp_num_cpus = 1;
}
}
diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
--- a/arch/ia64/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/ia64/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -27,6 +27,8 @@
extern unsigned long wall_jiffies;
extern unsigned long last_time_offset;
+u64 jiffies_64;
+
#ifdef CONFIG_IA64_DEBUG_IRQ
unsigned long last_cli_ip;
diff -Nru a/arch/ia64/sn/io/sgi_io_init.c b/arch/ia64/sn/io/sgi_io_init.c
--- a/arch/ia64/sn/io/sgi_io_init.c Tue Jun 18 19:12:01 2002
+++ b/arch/ia64/sn/io/sgi_io_init.c Tue Jun 18 19:12:01 2002
@@ -255,7 +255,7 @@
cnodeid_t cnode;
cpuid_t cpu;
- for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
/* Skip holes in CPU space */
if (cpu_enabled(cpu)) {
init_platform_pda(cpu);
diff -Nru a/arch/ia64/sn/io/sn1/ml_SN_intr.c b/arch/ia64/sn/io/sn1/ml_SN_intr.c
--- a/arch/ia64/sn/io/sn1/ml_SN_intr.c Tue Jun 18 19:12:01 2002
+++ b/arch/ia64/sn/io/sn1/ml_SN_intr.c Tue Jun 18 19:12:01 2002
@@ -987,12 +987,13 @@
char subnode_done[NUM_SUBNODES];
// cpu = cnodetocpu(cnode);
- for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (!cpu_online(cpu)) continue;
if (cpuid_to_cnodeid(cpu) == cnode) {
break;
}
}
- if (cpu == smp_num_cpus) cpu = CPU_NONE;
+ if (cpu == NR_CPUS) cpu = CPU_NONE;
if (cpu == CPU_NONE) {
printk("Node %d has no CPUs", cnode);
return;
@@ -1001,7 +1002,7 @@
for (i=0; iend = end;
params->nbits = nbits;
params->rid = (unsigned int) ia64_get_rr(start);
- atomic_set(¶ms->unfinished_count, smp_num_cpus);
+ atomic_set(¶ms->unfinished_count, num_online_cpus());
/* The atomic_set above can hit memory *after* the update
* to ptcParamsEmpty below, which opens a timing window
@@ -425,7 +425,7 @@
{
if (!ia64_ptc_domain_info) {
printk("SMP: Can't find PTC domain info. Forcing UP mode\n");
- smp_num_cpus = 1;
+ cpu_online_map = 1;
return;
}
diff -Nru a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile
--- a/arch/ia64/tools/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/ia64/tools/Makefile Tue Jun 18 19:12:01 2002
@@ -9,7 +9,7 @@
clean:
rm -f print_offsets.s print_offsets offsets.h
-fastdep: offsets.h
+$(TARGET): offsets.h
@if ! cmp -s offsets.h ${TARGET}; then \
echo -e "*** Updating ${TARGET}..."; \
cp offsets.h ${TARGET}; \
diff -Nru a/arch/m68k/Makefile b/arch/m68k/Makefile
--- a/arch/m68k/Makefile Tue Jun 18 19:12:03 2002
+++ b/arch/m68k/Makefile Tue Jun 18 19:12:03 2002
@@ -172,5 +172,3 @@
rm -f arch/m68k/kernel/m68k_defs.h arch/m68k/kernel/m68k_defs.d
archmrproper:
-
-archdep:
diff -Nru a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
--- a/arch/m68k/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/m68k/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -24,6 +24,7 @@
#include
+u64 jiffies_64;
static inline int set_rtc_mmss(unsigned long nowtime)
{
diff -Nru a/arch/mips/Makefile b/arch/mips/Makefile
--- a/arch/mips/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/mips/Makefile Tue Jun 18 19:12:01 2002
@@ -308,9 +308,3 @@
archmrproper:
@$(MAKEBOOT) mrproper
$(MAKE) -C arch/$(ARCH)/tools mrproper
-
-archdep:
- if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \
- touch $(TOPDIR)/include/asm-$(ARCH)/offset.h; \
- fi;
- @$(MAKEBOOT) dep
diff -Nru a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
--- a/arch/mips/boot/Makefile Tue Jun 18 19:12:03 2002
+++ b/arch/mips/boot/Makefile Tue Jun 18 19:12:03 2002
@@ -35,9 +35,6 @@
addinitrd: addinitrd.c
$(HOSTCC) -o $@ $^
-# Don't build dependencies, this may die if $(CC) isn't gcc
-dep:
-
clean:
rm -f vmlinux.ecoff
rm -f zImage zImage.tmp
diff -Nru a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
--- a/arch/mips/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/mips/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -32,6 +32,8 @@
#define USECS_PER_JIFFY (1000000/HZ)
#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff)
+u64 jiffies_64;
+
/*
* forward reference
*/
diff -Nru a/arch/mips64/Makefile b/arch/mips64/Makefile
--- a/arch/mips64/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/mips64/Makefile Tue Jun 18 19:12:02 2002
@@ -176,9 +176,3 @@
archmrproper:
@$(MAKEBOOT) mrproper
$(MAKE) -C arch/$(ARCH)/tools mrproper
-
-archdep:
- if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \
- touch $(TOPDIR)/include/asm-$(ARCH)/offset.h; \
- fi;
- @$(MAKEBOOT) dep
diff -Nru a/arch/mips64/boot/Makefile b/arch/mips64/boot/Makefile
--- a/arch/mips64/boot/Makefile Tue Jun 18 19:12:03 2002
+++ b/arch/mips64/boot/Makefile Tue Jun 18 19:12:03 2002
@@ -26,9 +26,6 @@
addinitrd: addinitrd.c
$(HOSTCC) -o $@ $^
-# Don't build dependencies, this may die if $(CC) isn't gcc
-dep:
-
clean:
rm -f vmlinux.ecoff
diff -Nru a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c
--- a/arch/mips64/kernel/syscall.c Tue Jun 18 19:12:02 2002
+++ b/arch/mips64/kernel/syscall.c Tue Jun 18 19:12:02 2002
@@ -32,6 +32,8 @@
#include
#include
+u64 jiffies_64;
+
extern asmlinkage void syscall_trace(void);
asmlinkage int sys_pipe(abi64_no_regargs, struct pt_regs regs)
diff -Nru a/arch/parisc/Makefile b/arch/parisc/Makefile
--- a/arch/parisc/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/parisc/Makefile Tue Jun 18 19:12:02 2002
@@ -78,5 +78,3 @@
archclean:
archmrproper:
-
-archdep:
diff -Nru a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
--- a/arch/parisc/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/parisc/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -30,6 +30,8 @@
#include
+u64 jiffies_64;
+
extern rwlock_t xtime_lock;
static int timer_value;
diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/ppc/Makefile Tue Jun 18 19:12:01 2002
@@ -116,6 +116,3 @@
@$(MAKEBOOT) clean
archmrproper:
-
-archdep: scripts/mkdep
- $(MAKEBOOT) fastdep
diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
--- a/arch/ppc/kernel/irq.c Tue Jun 18 19:12:02 2002
+++ b/arch/ppc/kernel/irq.c Tue Jun 18 19:12:02 2002
@@ -370,8 +370,9 @@
struct irqaction * action;
seq_puts(p, " ");
- for (j=0; j>= 1)
- mask |= (cpumask & 1) << smp_hw_index[i];
+ for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1)
+ if (cpu_online(i))
+ mask |= (cpumask & 1) << smp_hw_index[i];
return mask;
}
#else
diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
--- a/arch/ppc/kernel/ppc_ksyms.c Tue Jun 18 19:12:03 2002
+++ b/arch/ppc/kernel/ppc_ksyms.c Tue Jun 18 19:12:03 2002
@@ -228,7 +228,6 @@
#endif
EXPORT_SYMBOL(smp_call_function);
EXPORT_SYMBOL(smp_hw_index);
-EXPORT_SYMBOL(smp_num_cpus);
EXPORT_SYMBOL(synchronize_irq);
#endif
diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
--- a/arch/ppc/kernel/setup.c Tue Jun 18 19:12:03 2002
+++ b/arch/ppc/kernel/setup.c Tue Jun 18 19:12:03 2002
@@ -147,8 +147,8 @@
/* Show summary information */
#ifdef CONFIG_SMP
unsigned long bogosum = 0;
- for (i = 0; i < smp_num_cpus; ++i)
- if (cpu_online_map & (1 << i))
+ for (i = 0; i < NR_CPUS; ++i)
+ if (cpu_online(i))
bogosum += cpu_data[i].loops_per_jiffy;
seq_printf(m, "total bogomips\t: %lu.%02lu\n",
bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
--- a/arch/ppc/kernel/smp.c Tue Jun 18 19:12:03 2002
+++ b/arch/ppc/kernel/smp.c Tue Jun 18 19:12:03 2002
@@ -42,7 +42,6 @@
int smp_threads_ready;
volatile int smp_commenced;
-int smp_num_cpus = 1;
int smp_tb_synchronized;
struct cpuinfo_PPC cpu_data[NR_CPUS];
struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
@@ -68,7 +67,6 @@
int start_secondary(void *);
extern int cpu_idle(void *unused);
void smp_call_function_interrupt(void);
-void smp_message_pass(int target, int msg, unsigned long data, int wait);
static int __smp_call_function(void (*func) (void *info), void *info,
int wait, int target);
@@ -174,7 +172,6 @@
void smp_send_stop(void)
{
smp_call_function(stop_this_cpu, NULL, 1, 0);
- smp_num_cpus = 1;
}
/*
@@ -212,7 +209,9 @@
* hardware interrupt handler or from a bottom half handler.
*/
{
- if (smp_num_cpus <= 1)
+ /* FIXME: get cpu lock with hotplug cpus, or change this to
+ bitmask. --RR */
+ if (num_online_cpus() <= 1)
return 0;
return __smp_call_function(func, info, wait, MSG_ALL_BUT_SELF);
}
@@ -226,9 +225,9 @@
int ncpus = 1;
if (target == MSG_ALL_BUT_SELF)
- ncpus = smp_num_cpus - 1;
+ ncpus = num_online_cpus() - 1;
else if (target == MSG_ALL)
- ncpus = smp_num_cpus;
+ ncpus = num_online_cpus();
data.func = func;
data.info = info;
@@ -298,7 +297,6 @@
struct task_struct *p;
printk("Entering SMP Mode...\n");
- smp_num_cpus = 1;
smp_store_cpu_info(0);
cpu_online_map = 1UL;
@@ -375,7 +373,6 @@
sprintf(buf, "found cpu %d", i);
if (ppc_md.progress) ppc_md.progress(buf, 0x350+i);
printk("Processor %d found.\n", i);
- smp_num_cpus++;
} else {
char buf[32];
sprintf(buf, "didn't find cpu %d", i);
@@ -387,7 +384,8 @@
/* Setup CPU 0 last (important) */
smp_ops->setup_cpu(0);
- if (smp_num_cpus < 2)
+ /* FIXME: Not with hotplug CPUS --RR */
+ if (num_online_cpus() < 2)
smp_tb_synchronized = 1;
}
@@ -413,7 +411,7 @@
for (pass = 2; pass < 2+PASSES; pass++){
if (cpu == 0){
mb();
- for (i = j = 1; i < smp_num_cpus; i++, j++){
+ for (i = j = 1; i < NR_CPUS; i++, j++){
/* skip stuck cpus */
while (!cpu_callin_map[j])
++j;
@@ -487,7 +485,8 @@
*
* NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus/BenH
*/
- if (!smp_tb_synchronized && smp_num_cpus == 2) {
+ /* FIXME: This doesn't work with hotplug CPUs --RR */
+ if (!smp_tb_synchronized && num_online_cpus() == 2) {
unsigned long flags;
__save_and_cli(flags);
smp_software_tb_sync(0);
@@ -501,24 +500,18 @@
smp_store_cpu_info(cpu);
set_dec(tb_ticks_per_jiffy);
+ /* Set online before we acknowledge. */
+ set_bit(cpu, &cpu_online_map);
+ wmb();
cpu_callin_map[cpu] = 1;
smp_ops->setup_cpu(cpu);
- /*
- * This cpu is now "online". Only set them online
- * before they enter the loop below since write access
- * to the below variable is _not_ guaranteed to be
- * atomic.
- * -- Cort
- */
- cpu_online_map |= 1UL << smp_processor_id();
-
while (!smp_commenced)
barrier();
/* see smp_commence for more info */
- if (!smp_tb_synchronized && smp_num_cpus == 2) {
+ if (!smp_tb_synchronized && num_online_cpus() == 2) {
smp_software_tb_sync(cpu);
}
__sti();
diff -Nru a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
--- a/arch/ppc/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/ppc/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -70,6 +70,9 @@
#include
+/* XXX false sharing with below? */
+u64 jiffies_64;
+
unsigned long disarm_decr[NR_CPUS];
extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
diff -Nru a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c
--- a/arch/ppc/platforms/chrp_smp.c Tue Jun 18 19:12:02 2002
+++ b/arch/ppc/platforms/chrp_smp.c Tue Jun 18 19:12:02 2002
@@ -63,9 +63,10 @@
static atomic_t ready = ATOMIC_INIT(1);
static volatile int frozen = 0;
+ /* FIXME: Hotplug cpu breaks all this --RR */
if (cpu_nr == 0) {
/* wait for all the others */
- while (atomic_read(&ready) < smp_num_cpus)
+ while (atomic_read(&ready) < num_online_cpus())
barrier();
atomic_set(&ready, 1);
/* freeze the timebase */
@@ -75,7 +76,7 @@
/* XXX assumes this is not a 601 */
set_tb(0, 0);
last_jiffy_stamp(0) = 0;
- while (atomic_read(&ready) < smp_num_cpus)
+ while (atomic_read(&ready) < num_online_cpus())
barrier();
/* thaw the timebase again */
call_rtas("thaw-time-base", 0, 1, NULL);
diff -Nru a/arch/ppc/platforms/iSeries_smp.c b/arch/ppc/platforms/iSeries_smp.c
--- a/arch/ppc/platforms/iSeries_smp.c Tue Jun 18 19:12:01 2002
+++ b/arch/ppc/platforms/iSeries_smp.c Tue Jun 18 19:12:01 2002
@@ -50,7 +50,7 @@
int cpu = smp_processor_id();
int msg;
- if ( smp_num_cpus < 2 )
+ if ( num_online_cpus() < 2 )
return;
for ( msg = 0; msg < 4; ++msg )
@@ -62,7 +62,10 @@
static void smp_iSeries_message_pass(int target, int msg, unsigned long data, int wait)
{
int i;
- for (i = 0; i < smp_num_cpus; ++i) {
+ for (i = 0; i < NR_CPUS; ++i) {
+ if (!cpu_online(i))
+ continue;
+
if ( (target == MSG_ALL) ||
(target == i) ||
((target == MSG_ALL_BUT_SELF) && (i != smp_processor_id())) ) {
diff -Nru a/arch/ppc/platforms/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c
--- a/arch/ppc/platforms/pmac_smp.c Tue Jun 18 19:12:02 2002
+++ b/arch/ppc/platforms/pmac_smp.c Tue Jun 18 19:12:02 2002
@@ -282,7 +282,7 @@
/* clear interrupt */
psurge_clr_ipi(cpu);
- if (smp_num_cpus < 2)
+ if (num_online_cpus() < 2)
return;
/* make sure there is a message there */
@@ -302,10 +302,12 @@
{
int i;
- if (smp_num_cpus < 2)
+ if (num_online_cpus() < 2)
return;
- for (i = 0; i < smp_num_cpus; i++) {
+ for (i = 0; i < NR_CPUS; i++) {
+ if (!cpu_online(i))
+ continue;
if (target == MSG_ALL
|| (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
|| target == i) {
@@ -497,7 +499,7 @@
{
if (cpu_nr == 0) {
- if (smp_num_cpus < 2)
+ if (num_online_cpus() < 2)
return;
/* reset the entry point so if we get another intr we won't
* try to startup again */
diff -Nru a/arch/ppc64/Makefile b/arch/ppc64/Makefile
--- a/arch/ppc64/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/ppc64/Makefile Tue Jun 18 19:12:01 2002
@@ -66,5 +66,5 @@
archmrproper:
-archdep:
- $(MAKEBOOT) fastdep
+prepare:
+ $(MAKEBOOT) dep
diff -Nru a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
--- a/arch/ppc64/boot/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/ppc64/boot/Makefile Tue Jun 18 19:12:02 2002
@@ -121,9 +121,6 @@
clean:
rm -f piggyback note addnote $(OBJS) zImage zImage.initrd vmlinux.gz no_initrd.o imagesize.c addSystemMap vmlinux.sm addRamDisk vmlinux.initrd vmlinux.sminitrd
-fastdep:
- $(TOPDIR)/scripts/mkdep *.[Sch] > .depend
-
dep:
$(CPP) $(CPPFLAGS) -M *.S *.c > .depend
diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c Tue Jun 18 19:12:02 2002
+++ b/arch/ppc64/kernel/sys_ppc32.c Tue Jun 18 19:12:02 2002
@@ -82,47 +82,6 @@
*/
#define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
-/* In order to reduce some races, while at the same time doing additional
- * checking and hopefully speeding things up, we copy filenames to the
- * kernel data space before using them..
- *
- * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
- */
-static inline int do_getname32(const char *filename, char *page)
-{
- int retval;
-
- /* 32bit pointer will be always far below TASK_SIZE :)) */
- retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
- if (retval > 0) {
- if (retval < PAGE_SIZE)
- return 0;
- return -ENAMETOOLONG;
- } else if (!retval)
- retval = -ENOENT;
- return retval;
-}
-
-char * getname32(const char *filename)
-{
- char *tmp, *result;
-
- result = ERR_PTR(-ENOMEM);
- tmp = __getname();
- if (tmp) {
- int retval = do_getname32(filename, tmp);
-
- result = tmp;
- if (retval < 0) {
- putname(tmp);
- result = ERR_PTR(retval);
- }
- }
- return result;
-}
-
-
-
extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
@@ -142,7 +101,7 @@
return sys_utime(filename, NULL);
if (get_user(t.actime, ×->actime) || __get_user(t.modtime, ×->modtime))
return -EFAULT;
- filenam = getname32(filename);
+ filenam = getname(filename);
ret = PTR_ERR(filenam);
if (!IS_ERR(filenam)) {
@@ -937,7 +896,7 @@
PPCDBG(PPCDBG_SYS32X, "sys32_statfs - entered - pid=%ld current=%lx comm=%s\n", current->pid, current, current->comm);
- pth = getname32 (path);
+ pth = getname (path);
ret = PTR_ERR(pth);
if (!IS_ERR(pth)) {
set_fs (KERNEL_DS);
diff -Nru a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
--- a/arch/ppc64/kernel/time.c Tue Jun 18 19:12:03 2002
+++ b/arch/ppc64/kernel/time.c Tue Jun 18 19:12:03 2002
@@ -64,6 +64,8 @@
void smp_local_timer_interrupt(struct pt_regs *);
+u64 jiffies_64;
+
/* keep track of when we need to update the rtc */
time_t last_rtc_update;
extern rwlock_t xtime_lock;
diff -Nru a/arch/s390/Makefile b/arch/s390/Makefile
--- a/arch/s390/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/s390/Makefile Tue Jun 18 19:12:01 2002
@@ -58,8 +58,5 @@
archmrproper:
-archdep:
- @$(MAKEBOOT) dep
-
install: vmlinux
@$(MAKEBOOT) BOOTIMAGE=image install
diff -Nru a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
--- a/arch/s390/boot/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/s390/boot/Makefile Tue Jun 18 19:12:02 2002
@@ -22,8 +22,6 @@
listing: ../../../vmlinux
$(OBJDUMP) --disassemble --disassemble-all --disassemble-zeroes --reloc $(TOPDIR)/vmlinux > listing
-dep:
-
clean:
rm -f image listing iplfba.boot ipleckd.boot ipldump.boot
diff -Nru a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
--- a/arch/s390/kernel/time.c Tue Jun 18 19:12:01 2002
+++ b/arch/s390/kernel/time.c Tue Jun 18 19:12:01 2002
@@ -39,6 +39,8 @@
#define TICK_SIZE tick
+u64 jiffies_64;
+
static ext_int_info_t ext_int_info_timer;
static uint64_t init_timer_cc;
diff -Nru a/arch/s390/math-emu/Makefile b/arch/s390/math-emu/Makefile
--- a/arch/s390/math-emu/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/s390/math-emu/Makefile Tue Jun 18 19:12:02 2002
@@ -6,6 +6,7 @@
obj-$(CONFIG_MATHEMU) := math.o qrnnd.o
EXTRA_CFLAGS = -I. -I$(TOPDIR)/include/math-emu -w
+EXTRA_AFLAGS := -traditional
include $(TOPDIR)/Rules.make
diff -Nru a/arch/s390/mm/ioremap.c b/arch/s390/mm/ioremap.c
--- a/arch/s390/mm/ioremap.c Tue Jun 18 19:12:01 2002
+++ b/arch/s390/mm/ioremap.c Tue Jun 18 19:12:01 2002
@@ -14,6 +14,7 @@
*/
#include
+#include
#include
#include
#include
diff -Nru a/arch/s390x/Makefile b/arch/s390x/Makefile
--- a/arch/s390x/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/s390x/Makefile Tue Jun 18 19:12:02 2002
@@ -56,6 +56,3 @@
$(MAKE) -C arch/$(ARCH)/kernel clean
archmrproper:
-
-archdep:
- @$(MAKEBOOT) dep
diff -Nru a/arch/s390x/boot/Makefile b/arch/s390x/boot/Makefile
--- a/arch/s390x/boot/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/s390x/boot/Makefile Tue Jun 18 19:12:02 2002
@@ -24,8 +24,6 @@
listing: ../../../vmlinux
$(OBJDUMP) --disassemble --disassemble-all --disassemble-zeroes --reloc $(TOPDIR)/vmlinux > listing
-dep:
-
clean:
rm -f image listing iplfba.boot ipleckd.boot ipldump.boot
diff -Nru a/arch/s390x/kernel/time.c b/arch/s390x/kernel/time.c
--- a/arch/s390x/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/s390x/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -39,6 +39,8 @@
#define TICK_SIZE tick
+u64 jiffies_64;
+
static ext_int_info_t ext_int_info_timer;
static uint64_t init_timer_cc;
diff -Nru a/arch/s390x/kernel/wrapper32.S b/arch/s390x/kernel/wrapper32.S
--- a/arch/s390x/kernel/wrapper32.S Tue Jun 18 19:12:02 2002
+++ b/arch/s390x/kernel/wrapper32.S Tue Jun 18 19:12:02 2002
@@ -1112,6 +1112,8 @@
sys32_futex_wrapper:
llgtr %r2,%r2 # void *
lgfr %r3,%r3 # int
+ lgfr %r4,%r4 # int
+ llgtr %r5,%r5 # struct timespec *
jg sys_futex # branch to system call
.globl sys32_setxattr_wrapper
diff -Nru a/arch/s390x/mm/ioremap.c b/arch/s390x/mm/ioremap.c
--- a/arch/s390x/mm/ioremap.c Tue Jun 18 19:12:02 2002
+++ b/arch/s390x/mm/ioremap.c Tue Jun 18 19:12:02 2002
@@ -14,6 +14,7 @@
*/
#include
+#include
#include
#include
#include
diff -Nru a/arch/sh/Makefile b/arch/sh/Makefile
--- a/arch/sh/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/sh/Makefile Tue Jun 18 19:12:02 2002
@@ -94,6 +94,3 @@
archmrproper:
rm -f arch/sh/vmlinux.lds
-
-archdep:
- @$(MAKEBOOT) dep
diff -Nru a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
--- a/arch/sh/boot/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/sh/boot/Makefile Tue Jun 18 19:12:01 2002
@@ -25,8 +25,6 @@
zinstall: zImage
sh -x ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
-dep:
-
clean:
rm -f tools/build
rm -f setup bootsect zImage compressed/vmlinux.out
diff -Nru a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
--- a/arch/sh/kernel/time.c Tue Jun 18 19:12:01 2002
+++ b/arch/sh/kernel/time.c Tue Jun 18 19:12:01 2002
@@ -70,6 +70,8 @@
#endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */
#endif /* __sh3__ or __SH4__ */
+u64 jiffies_64;
+
extern rwlock_t xtime_lock;
extern unsigned long wall_jiffies;
#define TICK_SIZE tick
diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile
--- a/arch/sparc/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/sparc/Makefile Tue Jun 18 19:12:01 2002
@@ -58,9 +58,9 @@
archmrproper:
rm -f $(TOPDIR)/include/asm-sparc/asm_offsets.h
-archdep: check_asm
+prepare: check_asm
-check_asm: include/linux/version.h
+check_asm: include/linux/version.h include/linux/asm include/config/MARKER
$(MAKE) -C arch/sparc/kernel check_asm
tftpboot.img:
diff -Nru a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
--- a/arch/sparc/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/sparc/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -43,6 +43,8 @@
extern rwlock_t xtime_lock;
+u64 jiffies_64;
+
enum sparc_clock_type sp_clock_typ;
spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
unsigned long mstk48t02_regs = 0UL;
diff -Nru a/arch/sparc64/Makefile b/arch/sparc64/Makefile
--- a/arch/sparc64/Makefile Tue Jun 18 19:12:03 2002
+++ b/arch/sparc64/Makefile Tue Jun 18 19:12:03 2002
@@ -85,7 +85,5 @@
archmrproper:
-archdep:
-
tftpboot.img:
$(MAKE) -C arch/sparc64/boot tftpboot.img
diff -Nru a/arch/sparc64/boot/Makefile b/arch/sparc64/boot/Makefile
--- a/arch/sparc64/boot/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/sparc64/boot/Makefile Tue Jun 18 19:12:01 2002
@@ -18,6 +18,3 @@
piggyback: piggyback.c
$(HOSTCC) $(HOSTCFLAGS) -o piggyback piggyback.c
-
-dep:
-
diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig
--- a/arch/sparc64/defconfig Tue Jun 18 19:12:02 2002
+++ b/arch/sparc64/defconfig Tue Jun 18 19:12:02 2002
@@ -19,7 +19,7 @@
# Loadable module support
#
CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
#
@@ -96,12 +96,10 @@
#
CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_RIVA is not set
# CONFIG_FB_CLGEN is not set
-CONFIG_FB_PM2=y
-# CONFIG_FB_PM2_FIFO_DISCONNECT is not set
-CONFIG_FB_PM2_PCI=y
+# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
CONFIG_FB_ATY=y
# CONFIG_FB_ATY_GX is not set
@@ -112,6 +110,8 @@
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_PM3 is not set
CONFIG_FB_SBUS=y
CONFIG_FB_CREATOR=y
CONFIG_FB_CGSIX=y
@@ -215,7 +215,8 @@
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
+CONFIG_LLC=m
+CONFIG_LLC_UI=y
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -292,7 +293,7 @@
# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_AEC6280_BURST is not set
CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
@@ -315,6 +316,7 @@
# CONFIG_BLK_DEV_SL82C105 is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_IDEDMA_IVB is not set
+CONFIG_ATAPI=y
CONFIG_IDEDMA_AUTO=y
# CONFIG_BLK_DEV_ATARAID is not set
# CONFIG_BLK_DEV_ATARAID_PDC is not set
@@ -539,7 +541,7 @@
# CONFIG_WAN is not set
#
-# "Tulip" family network device support
+# Tulip family network device support
#
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
@@ -617,7 +619,6 @@
# CONFIG_QUOTA is not set
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
-# CONFIG_QIFACE_COMPAT is not set
CONFIG_AUTOFS_FS=m
CONFIG_AUTOFS4_FS=m
# CONFIG_REISERFS_FS is not set
@@ -781,14 +782,13 @@
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=m
# CONFIG_USB_UHCI_HCD_ALT is not set
-CONFIG_USB_UHCI=y
-# CONFIG_USB_UHCI_ALT is not set
#
# USB Device Class drivers
#
# CONFIG_USB_AUDIO is not set
CONFIG_USB_BLUETOOTH_TTY=m
+# CONFIG_USB_MIDI is not set
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
CONFIG_USB_STORAGE=m
@@ -808,6 +808,7 @@
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
CONFIG_USB_WACOM=m
#
@@ -821,15 +822,15 @@
#
# USB Multimedia devices
#
-CONFIG_USB_DABUSB=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_DSBR=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
+# CONFIG_USB_DABUSB is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
#
# USB Network adaptors
diff -Nru a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
--- a/arch/sparc64/kernel/entry.S Tue Jun 18 19:12:01 2002
+++ b/arch/sparc64/kernel/entry.S Tue Jun 18 19:12:01 2002
@@ -1436,10 +1436,11 @@
* %o7 for us. Check performance counter stuff too.
*/
andn %o7, _TIF_NEWCHILD, %l0
+ stx %l0, [%g6 + TI_FLAGS]
#if CONFIG_SMP || CONFIG_PREEMPT
call schedule_tail
+ mov %g5, %o0
#endif
- stx %l0, [%g6 + TI_FLAGS]
andcc %l0, _TIF_PERFCTR, %g0
be,pt %icc, 1f
nop
diff -Nru a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
--- a/arch/sparc64/kernel/power.c Tue Jun 18 19:12:03 2002
+++ b/arch/sparc64/kernel/power.c Tue Jun 18 19:12:03 2002
@@ -34,20 +34,28 @@
#endif /* CONFIG_PCI */
extern void machine_halt(void);
+extern void machine_alt_power_off(void);
+static void (*poweroff_method)(void) = machine_alt_power_off;
extern int serial_console;
void machine_power_off(void)
{
+ if (!serial_console) {
#ifdef CONFIG_PCI
- if (power_reg != 0UL && !serial_console) {
- /* Both register bits seem to have the
- * same effect, so until I figure out
- * what the difference is...
- */
- writel(POWER_COURTESY_OFF | POWER_SYSTEM_OFF, power_reg);
- }
+ if (power_reg != 0UL) {
+ /* Both register bits seem to have the
+ * same effect, so until I figure out
+ * what the difference is...
+ */
+ writel(POWER_COURTESY_OFF | POWER_SYSTEM_OFF, power_reg);
+ } else
#endif /* CONFIG_PCI */
+ if (poweroff_method != NULL) {
+ poweroff_method();
+ /* not reached */
+ }
+ }
machine_halt();
}
@@ -98,6 +106,7 @@
found:
power_reg = (unsigned long)ioremap(edev->resource[0].start, 0x4);
printk("power: Control reg at %016lx ... ", power_reg);
+ poweroff_method = machine_halt; /* able to use the standard halt */
if (edev->irqs[0] != PCI_IRQ_NONE) {
if (kernel_thread(powerd, 0, CLONE_FS) < 0) {
printk("Failed to start power daemon.\n");
diff -Nru a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
--- a/arch/sparc64/kernel/process.c Tue Jun 18 19:12:02 2002
+++ b/arch/sparc64/kernel/process.c Tue Jun 18 19:12:02 2002
@@ -142,6 +142,21 @@
panic("Halt failed!");
}
+void machine_alt_power_off(void)
+{
+ sti();
+ mdelay(8);
+ cli();
+#ifdef CONFIG_SUN_CONSOLE
+ if (!serial_console && prom_palette)
+ prom_palette(1);
+#endif
+ if (prom_keyboard)
+ prom_keyboard();
+ prom_halt_power_off();
+ panic("Power-off failed!");
+}
+
void machine_restart(char * cmd)
{
char *p;
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c Tue Jun 18 19:12:02 2002
+++ b/arch/sparc64/kernel/time.c Tue Jun 18 19:12:02 2002
@@ -44,6 +44,8 @@
unsigned long ds1287_regs = 0UL;
#endif
+u64 jiffies_64;
+
static unsigned long mstk48t08_regs = 0UL;
static unsigned long mstk48t59_regs = 0UL;
diff -Nru a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
--- a/arch/sparc64/prom/misc.c Tue Jun 18 19:12:03 2002
+++ b/arch/sparc64/prom/misc.c Tue Jun 18 19:12:03 2002
@@ -97,6 +97,19 @@
goto again; /* PROM is out to get me -DaveM */
}
+void
+prom_halt_power_off(void)
+{
+#ifdef CONFIG_SMP
+ smp_promstop_others();
+ udelay(8000);
+#endif
+ p1275_cmd ("SUNW,power-off", P1275_INOUT(0,0));
+
+ /* if nothing else helps, we just halt */
+ prom_halt ();
+}
+
/* Set prom sync handler to call function 'funcp'. */
void
prom_setcallback(callback_func_t funcp)
diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile
--- a/arch/x86_64/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/Makefile Tue Jun 18 19:12:02 2002
@@ -43,18 +43,12 @@
CFLAGS += -pipe
# this makes reading assembly source easier
CFLAGS += -fno-reorder-blocks
-# needed for later gcc 3.1
CFLAGS += -finline-limit=2000
-# needed for earlier gcc 3.1
-#CFLAGS += -fno-strength-reduce
#CFLAGS += -g
-# prevent gcc from keeping the stack 16 byte aligned (FIXME)
-#CFLAGS += -mpreferred-stack-boundary=2
-
HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
-SUBDIRS := arch/x86_64/tools $(SUBDIRS) arch/x86_64/kernel arch/x86_64/mm arch/x86_64/lib
+SUBDIRS += arch/x86_64/kernel arch/x86_64/mm arch/x86_64/lib
CORE_FILES := arch/x86_64/kernel/kernel.o $(CORE_FILES)
CORE_FILES += arch/x86_64/mm/mm.o
LIBS := $(TOPDIR)/arch/x86_64/lib/lib.a $(LIBS)
@@ -76,38 +70,43 @@
vmlinux: arch/x86_64/vmlinux.lds
.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
- clean archclean archmrproper archdep checkoffset
-
-checkoffset: FORCE include/asm
- make -C arch/$(ARCH)/tools $(TOPDIR)/include/asm-x86_64/offset.h
+ clean archclean archmrproper
-bzImage: checkoffset vmlinux
+bzImage: vmlinux
@$(MAKEBOOT) bzImage
-bzImage-padded: checkoffset vmlinux
+bzImage-padded: vmlinux
@$(MAKEBOOT) bzImage-padded
tmp:
@$(MAKEBOOT) BOOTIMAGE=bzImage zlilo
-bzlilo: checkoffset vmlinux
+bzlilo: vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage zlilo
-bzdisk: checkoffset vmlinux
+bzdisk: vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage zdisk
-install: checkoffset vmlinux
+install: vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage install
archclean:
@$(MAKEBOOT) clean
- @$(MAKE) -C $(TOPDIR)/arch/x86_64/tools clean
archmrproper:
- rm -f $(TOPDIR)/arch/x86_64/tools/offset.h
- rm -f $(TOPDIR)/arch/x86_64/tools/offset.tmp
- rm -f $(TOPDIR)/include/asm-x86_64/offset.h
-
-archdep:
- @$(MAKE) -C $(TOPDIR)/arch/x86_64/tools all
- @$(MAKEBOOT) dep
+
+
+prepare: include/asm-$(ARCH)/offset.h
+
+arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
+ include/config/MARKER
+
+include/asm-$(ARCH)/offset.h.tmp: arch/$(ARCH)/kernel/asm-offsets.s
+ @$(generate-asm-offsets.h) < $< > $@
+
+include/asm-$(ARCH)/offset.h: include/asm-$(ARCH)/offset.h.tmp
+ @echo -n ' Generating $@'
+ @$(update-if-changed)
+
+CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \
+ include/asm-$(ARCH)/offset.h
\ No newline at end of file
diff -Nru a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
--- a/arch/x86_64/boot/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/boot/Makefile Tue Jun 18 19:12:02 2002
@@ -21,10 +21,6 @@
SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
-# If you want the RAM disk device, define this to be the size in blocks.
-
-RAMDISK := -DRAMDISK=512
-
# ---------------------------------------------------------------------------
BOOT_INCL = $(TOPDIR)/include/linux/config.h \
@@ -100,12 +96,8 @@
bsetup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
$(IA32_CPP) $(CPPFLAGS) -D__BIG_KERNEL__ -D__ASSEMBLY__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
-dep:
-
clean:
rm -f tools/build
rm -f setup bootsect zImage compressed/vmlinux.out
rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
@$(MAKE) -C compressed clean
-
-
diff -Nru a/arch/x86_64/config.in b/arch/x86_64/config.in
--- a/arch/x86_64/config.in Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/config.in Tue Jun 18 19:12:02 2002
@@ -47,8 +47,7 @@
define_bool CONFIG_X86_IO_APIC y
define_bool CONFIG_X86_LOCAL_APIC y
-#currently broken:
-#bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
+bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
bool 'Symmetric multi-processing support' CONFIG_SMP
if [ "$CONFIG_SMP" = "n" ]; then
bool 'Preemptible Kernel' CONFIG_PREEMPT
@@ -226,6 +225,7 @@
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Additional run-time checks' CONFIG_CHECKING
bool ' Debug __init statements' CONFIG_INIT_DEBUG
+ bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
fi
endmenu
diff -Nru a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile
--- a/arch/x86_64/ia32/Makefile Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/ia32/Makefile Tue Jun 18 19:12:02 2002
@@ -9,8 +9,9 @@
all: ia32.o
O_TARGET := ia32.o
-obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o \
- ia32_binfmt.o fpu32.o socket32.o ptrace32.o
+obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
+ ia32_signal.o \
+ ia32_binfmt.o fpu32.o socket32.o ptrace32.o ipc32.o
clean::
diff -Nru a/arch/x86_64/ia32/ipc32.c b/arch/x86_64/ia32/ipc32.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/ia32/ipc32.c Tue Jun 18 19:12:03 2002
@@ -0,0 +1,645 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/*
+ * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
+ *
+ * This is really horribly ugly.
+ */
+
+struct msgbuf32 {
+ s32 mtype;
+ char mtext[1];
+};
+
+struct ipc_perm32 {
+ int key;
+ __kernel_uid_t32 uid;
+ __kernel_gid_t32 gid;
+ __kernel_uid_t32 cuid;
+ __kernel_gid_t32 cgid;
+ unsigned short mode;
+ unsigned short seq;
+};
+
+struct ipc64_perm32 {
+ unsigned key;
+ __kernel_uid32_t32 uid;
+ __kernel_gid32_t32 gid;
+ __kernel_uid32_t32 cuid;
+ __kernel_gid32_t32 cgid;
+ unsigned short mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned int unused1;
+ unsigned int unused2;
+};
+
+struct semid_ds32 {
+ struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t32 sem_otime; /* last semop time */
+ __kernel_time_t32 sem_ctime; /* last change time */
+ u32 sem_base; /* ptr to first semaphore in array */
+ u32 sem_pending; /* pending operations to be processed */
+ u32 sem_pending_last; /* last pending operation */
+ u32 undo; /* undo requests on this array */
+ unsigned short sem_nsems; /* no. of semaphores in array */
+};
+
+struct semid64_ds32 {
+ struct ipc64_perm32 sem_perm;
+ __kernel_time_t32 sem_otime;
+ unsigned int __unused1;
+ __kernel_time_t32 sem_ctime;
+ unsigned int __unused2;
+ unsigned int sem_nsems;
+ unsigned int __unused3;
+ unsigned int __unused4;
+};
+
+struct msqid_ds32 {
+ struct ipc_perm32 msg_perm;
+ u32 msg_first;
+ u32 msg_last;
+ __kernel_time_t32 msg_stime;
+ __kernel_time_t32 msg_rtime;
+ __kernel_time_t32 msg_ctime;
+ u32 wwait;
+ u32 rwait;
+ unsigned short msg_cbytes;
+ unsigned short msg_qnum;
+ unsigned short msg_qbytes;
+ __kernel_ipc_pid_t32 msg_lspid;
+ __kernel_ipc_pid_t32 msg_lrpid;
+};
+
+struct msqid64_ds32 {
+ struct ipc64_perm32 msg_perm;
+ __kernel_time_t32 msg_stime;
+ unsigned int __unused1;
+ __kernel_time_t32 msg_rtime;
+ unsigned int __unused2;
+ __kernel_time_t32 msg_ctime;
+ unsigned int __unused3;
+ unsigned int msg_cbytes;
+ unsigned int msg_qnum;
+ unsigned int msg_qbytes;
+ __kernel_pid_t32 msg_lspid;
+ __kernel_pid_t32 msg_lrpid;
+ unsigned int __unused4;
+ unsigned int __unused5;
+};
+
+struct shmid_ds32 {
+ struct ipc_perm32 shm_perm;
+ int shm_segsz;
+ __kernel_time_t32 shm_atime;
+ __kernel_time_t32 shm_dtime;
+ __kernel_time_t32 shm_ctime;
+ __kernel_ipc_pid_t32 shm_cpid;
+ __kernel_ipc_pid_t32 shm_lpid;
+ unsigned short shm_nattch;
+};
+
+struct shmid64_ds32 {
+ struct ipc64_perm32 shm_perm;
+ __kernel_size_t32 shm_segsz;
+ __kernel_time_t32 shm_atime;
+ unsigned int __unused1;
+ __kernel_time_t32 shm_dtime;
+ unsigned int __unused2;
+ __kernel_time_t32 shm_ctime;
+ unsigned int __unused3;
+ __kernel_pid_t32 shm_cpid;
+ __kernel_pid_t32 shm_lpid;
+ unsigned int shm_nattch;
+ unsigned int __unused4;
+ unsigned int __unused5;
+};
+
+struct shminfo64_32 {
+ unsigned int shmmax;
+ unsigned int shmmin;
+ unsigned int shmmni;
+ unsigned int shmseg;
+ unsigned int shmall;
+ unsigned int __unused1;
+ unsigned int __unused2;
+ unsigned int __unused3;
+ unsigned int __unused4;
+};
+
+struct shm_info32 {
+ int used_ids;
+ u32 shm_tot, shm_rss, shm_swp;
+ u32 swap_attempts, swap_successes;
+};
+
+struct ipc_kludge {
+ struct msgbuf *msgp;
+ int msgtyp;
+};
+
+
+#define A(__x) ((unsigned long)(__x))
+#define AA(__x) ((unsigned long)(__x))
+
+#define SEMOP 1
+#define SEMGET 2
+#define SEMCTL 3
+#define MSGSND 11
+#define MSGRCV 12
+#define MSGGET 13
+#define MSGCTL 14
+#define SHMAT 21
+#define SHMDT 22
+#define SHMGET 23
+#define SHMCTL 24
+
+#define IPCOP_MASK(__x) (1UL << (__x))
+
+static int
+ipc_parse_version32 (int *cmd)
+{
+ if (*cmd & IPC_64) {
+ *cmd ^= IPC_64;
+ return IPC_64;
+ } else {
+ return IPC_OLD;
+ }
+}
+
+static int
+semctl32 (int first, int second, int third, void *uptr)
+{
+ union semun fourth;
+ u32 pad;
+ int err = 0, err2;
+ struct semid64_ds s;
+ mm_segment_t old_fs;
+ int version = ipc_parse_version32(&third);
+
+ if (!uptr)
+ return -EINVAL;
+ if (get_user(pad, (u32 *)uptr))
+ return -EFAULT;
+ if (third == SETVAL)
+ fourth.val = (int)pad;
+ else
+ fourth.__pad = (void *)A(pad);
+ switch (third) {
+ case IPC_INFO:
+ case IPC_RMID:
+ case IPC_SET:
+ case SEM_INFO:
+ case GETVAL:
+ case GETPID:
+ case GETNCNT:
+ case GETZCNT:
+ case GETALL:
+ case SETVAL:
+ case SETALL:
+ err = sys_semctl(first, second, third, fourth);
+ break;
+
+ case IPC_STAT:
+ case SEM_STAT:
+ fourth.__pad = &s;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_semctl(first, second|IPC_64, third, fourth);
+ set_fs(old_fs);
+
+ if (version == IPC_64) {
+ struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad);
+
+ if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
+ err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
+ err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
+ err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
+ err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
+ err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
+ err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
+ err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
+ err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
+ err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
+ } else {
+ struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad);
+
+ if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
+ err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
+ err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
+ err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
+ err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
+ err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
+ err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
+ err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
+ err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
+ err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
+ }
+ if (err2)
+ err = -EFAULT;
+ break;
+ }
+ return err;
+}
+
+static int
+do_sys32_msgsnd (int first, int second, int third, void *uptr)
+{
+ struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+ struct msgbuf32 *up = (struct msgbuf32 *)uptr;
+ mm_segment_t old_fs;
+ int err;
+
+ if (!p)
+ return -ENOMEM;
+ err = get_user(p->mtype, &up->mtype);
+ err |= copy_from_user(p->mtext, &up->mtext, second);
+ if (err)
+ goto out;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_msgsnd(first, p, second, third);
+ set_fs(old_fs);
+ out:
+ kfree(p);
+ return err;
+}
+
+static int
+do_sys32_msgrcv (int first, int second, int msgtyp, int third, int version, void *uptr)
+{
+ struct msgbuf32 *up;
+ struct msgbuf *p;
+ mm_segment_t old_fs;
+ int err;
+
+ if (!version) {
+ struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
+ struct ipc_kludge ipck;
+
+ err = -EINVAL;
+ if (!uptr)
+ goto out;
+ err = -EFAULT;
+ if (copy_from_user(&ipck, uipck, sizeof(struct ipc_kludge)))
+ goto out;
+ uptr = (void *)A(ipck.msgp);
+ msgtyp = ipck.msgtyp;
+ }
+ err = -ENOMEM;
+ p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+ if (!p)
+ goto out;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_msgrcv(first, p, second + 4, msgtyp, third);
+ set_fs(old_fs);
+ if (err < 0)
+ goto free_then_out;
+ up = (struct msgbuf32 *)uptr;
+ if (put_user(p->mtype, &up->mtype) || copy_to_user(&up->mtext, p->mtext, err))
+ err = -EFAULT;
+free_then_out:
+ kfree(p);
+out:
+ return err;
+}
+
+static int
+msgctl32 (int first, int second, void *uptr)
+{
+ int err = -EINVAL, err2;
+ struct msqid_ds m;
+ struct msqid64_ds m64;
+ struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
+ struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
+ mm_segment_t old_fs;
+ int version = ipc_parse_version32(&second);
+
+ switch (second) {
+ case IPC_INFO:
+ case IPC_RMID:
+ case MSG_INFO:
+ err = sys_msgctl(first, second, (struct msqid_ds *)uptr);
+ break;
+
+ case IPC_SET:
+ if (version == IPC_64) {
+ err = get_user(m.msg_perm.uid, &up64->msg_perm.uid);
+ err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid);
+ err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode);
+ err |= get_user(m.msg_qbytes, &up64->msg_qbytes);
+ } else {
+ err = get_user(m.msg_perm.uid, &up32->msg_perm.uid);
+ err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid);
+ err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode);
+ err |= get_user(m.msg_qbytes, &up32->msg_qbytes);
+ }
+ if (err)
+ break;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_msgctl(first, second, &m);
+ set_fs(old_fs);
+ break;
+
+ case IPC_STAT:
+ case MSG_STAT:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_msgctl(first, second|IPC_64, (void *) &m64);
+ set_fs(old_fs);
+
+ if (version == IPC_64) {
+ if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(m64.msg_perm.key, &up64->msg_perm.key);
+ err2 |= __put_user(m64.msg_perm.uid, &up64->msg_perm.uid);
+ err2 |= __put_user(m64.msg_perm.gid, &up64->msg_perm.gid);
+ err2 |= __put_user(m64.msg_perm.cuid, &up64->msg_perm.cuid);
+ err2 |= __put_user(m64.msg_perm.cgid, &up64->msg_perm.cgid);
+ err2 |= __put_user(m64.msg_perm.mode, &up64->msg_perm.mode);
+ err2 |= __put_user(m64.msg_perm.seq, &up64->msg_perm.seq);
+ err2 |= __put_user(m64.msg_stime, &up64->msg_stime);
+ err2 |= __put_user(m64.msg_rtime, &up64->msg_rtime);
+ err2 |= __put_user(m64.msg_ctime, &up64->msg_ctime);
+ err2 |= __put_user(m64.msg_cbytes, &up64->msg_cbytes);
+ err2 |= __put_user(m64.msg_qnum, &up64->msg_qnum);
+ err2 |= __put_user(m64.msg_qbytes, &up64->msg_qbytes);
+ err2 |= __put_user(m64.msg_lspid, &up64->msg_lspid);
+ err2 |= __put_user(m64.msg_lrpid, &up64->msg_lrpid);
+ if (err2)
+ err = -EFAULT;
+ } else {
+ if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(m64.msg_perm.key, &up32->msg_perm.key);
+ err2 |= __put_user(m64.msg_perm.uid, &up32->msg_perm.uid);
+ err2 |= __put_user(m64.msg_perm.gid, &up32->msg_perm.gid);
+ err2 |= __put_user(m64.msg_perm.cuid, &up32->msg_perm.cuid);
+ err2 |= __put_user(m64.msg_perm.cgid, &up32->msg_perm.cgid);
+ err2 |= __put_user(m64.msg_perm.mode, &up32->msg_perm.mode);
+ err2 |= __put_user(m64.msg_perm.seq, &up32->msg_perm.seq);
+ err2 |= __put_user(m64.msg_stime, &up32->msg_stime);
+ err2 |= __put_user(m64.msg_rtime, &up32->msg_rtime);
+ err2 |= __put_user(m64.msg_ctime, &up32->msg_ctime);
+ err2 |= __put_user(m64.msg_cbytes, &up32->msg_cbytes);
+ err2 |= __put_user(m64.msg_qnum, &up32->msg_qnum);
+ err2 |= __put_user(m64.msg_qbytes, &up32->msg_qbytes);
+ err2 |= __put_user(m64.msg_lspid, &up32->msg_lspid);
+ err2 |= __put_user(m64.msg_lrpid, &up32->msg_lrpid);
+ if (err2)
+ err = -EFAULT;
+ }
+ break;
+ }
+ return err;
+}
+
+static int
+shmat32 (int first, int second, int third, int version, void *uptr)
+{
+ unsigned long raddr;
+ u32 *uaddr = (u32 *)A((u32)third);
+ int err;
+
+ if (version == 1)
+ return -EINVAL; /* iBCS2 emulator entry point: unsupported */
+ err = sys_shmat(first, uptr, second, &raddr);
+ if (err)
+ return err;
+ return put_user(raddr, uaddr);
+}
+
+static int put_shmid64(struct shmid64_ds *s64p, void *uptr, int version)
+{
+ int err2;
+#define s64 (*s64p)
+ if (version == IPC_64) {
+ struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
+
+ if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
+ return -EFAULT;
+
+ err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
+ err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
+ err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
+ err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
+ err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
+ err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
+ err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
+ err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
+ err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
+ err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
+ err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
+ err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
+ err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
+ err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
+ } else {
+ struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
+
+ if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32)))
+ return -EFAULT;
+
+ err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
+ err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
+ err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
+ err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
+ err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
+ err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
+ err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
+ err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
+ err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
+ err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
+ err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
+ err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
+ err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
+ err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
+ }
+#undef s64
+ return err2 ? -EFAULT : 0;
+}
+static int
+shmctl32 (int first, int second, void *uptr)
+{
+ int err = -EFAULT, err2;
+ struct shmid_ds s;
+ struct shmid64_ds s64;
+ mm_segment_t old_fs;
+ struct shm_info32 *uip = (struct shm_info32 *)uptr;
+ struct shm_info si;
+ int version = ipc_parse_version32(&second);
+ struct shminfo64 smi;
+ struct shminfo *usi32 = (struct shminfo *) uptr;
+ struct shminfo64_32 *usi64 = (struct shminfo64_32 *) uptr;
+
+ switch (second) {
+ case IPC_INFO:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_shmctl(first, second|IPC_64, (struct shmid_ds *)&smi);
+ set_fs(old_fs);
+
+ if (version == IPC_64) {
+ if (!access_ok(VERIFY_WRITE, usi64, sizeof(*usi64))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(smi.shmmax, &usi64->shmmax);
+ err2 |= __put_user(smi.shmmin, &usi64->shmmin);
+ err2 |= __put_user(smi.shmmni, &usi64->shmmni);
+ err2 |= __put_user(smi.shmseg, &usi64->shmseg);
+ err2 |= __put_user(smi.shmall, &usi64->shmall);
+ } else {
+ if (!access_ok(VERIFY_WRITE, usi32, sizeof(*usi32))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(smi.shmmax, &usi32->shmmax);
+ err2 |= __put_user(smi.shmmin, &usi32->shmmin);
+ err2 |= __put_user(smi.shmmni, &usi32->shmmni);
+ err2 |= __put_user(smi.shmseg, &usi32->shmseg);
+ err2 |= __put_user(smi.shmall, &usi32->shmall);
+ }
+ if (err2)
+ err = -EFAULT;
+ break;
+
+ case IPC_RMID:
+ case SHM_LOCK:
+ case SHM_UNLOCK:
+ err = sys_shmctl(first, second, (struct shmid_ds *)uptr);
+ break;
+
+ case IPC_SET:
+ if (version == IPC_64) {
+ struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
+ err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
+ err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
+ err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
+ } else {
+ struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
+ err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
+ err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
+ err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
+ }
+ if (err)
+ break;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_shmctl(first, second, &s);
+ set_fs(old_fs);
+ break;
+
+ case IPC_STAT:
+ case SHM_STAT:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_shmctl(first, second|IPC_64, (void *) &s64);
+ set_fs(old_fs);
+
+ if (err < 0)
+ break;
+ err2 = put_shmid64(&s64, uptr, version);
+ if (err2)
+ err = err2;
+ break;
+
+ case SHM_INFO:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_shmctl(first, second, (void *)&si);
+ set_fs(old_fs);
+ if (err < 0)
+ break;
+
+ if (!access_ok(VERIFY_WRITE, uip, sizeof(*uip))) {
+ err = -EFAULT;
+ break;
+ }
+ err2 = __put_user(si.used_ids, &uip->used_ids);
+ err2 |= __put_user(si.shm_tot, &uip->shm_tot);
+ err2 |= __put_user(si.shm_rss, &uip->shm_rss);
+ err2 |= __put_user(si.shm_swp, &uip->shm_swp);
+ err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
+ err2 |= __put_user(si.swap_successes, &uip->swap_successes);
+ if (err2)
+ err = -EFAULT;
+ break;
+
+ }
+ return err;
+}
+
+asmlinkage long
+sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
+{
+ int version;
+
+ version = call >> 16; /* hack for backward compatibility */
+ call &= 0xffff;
+
+ switch (call) {
+ case SEMOP:
+ /* struct sembuf is the same on 32 and 64bit :)) */
+ return sys_semop(first, (struct sembuf *)AA(ptr), second);
+ case SEMGET:
+ return sys_semget(first, second, third);
+ case SEMCTL:
+ return semctl32(first, second, third, (void *)AA(ptr));
+
+ case MSGSND:
+ return do_sys32_msgsnd(first, second, third, (void *)AA(ptr));
+ case MSGRCV:
+ return do_sys32_msgrcv(first, second, fifth, third, version, (void *)AA(ptr));
+ case MSGGET:
+ return sys_msgget((key_t) first, second);
+ case MSGCTL:
+ return msgctl32(first, second, (void *)AA(ptr));
+
+ case SHMAT:
+ return shmat32(first, second, third, version, (void *)AA(ptr));
+ break;
+ case SHMDT:
+ return sys_shmdt((char *)AA(ptr));
+ case SHMGET:
+ return sys_shmget(first, second, third);
+ case SHMCTL:
+ return shmctl32(first, second, (void *)AA(ptr));
+
+ default:
+ return -EINVAL;
+ }
+ return -EINVAL;
+}
+
diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
--- a/arch/x86_64/ia32/sys_ia32.c Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/ia32/sys_ia32.c Tue Jun 18 19:12:02 2002
@@ -1119,422 +1119,6 @@
}
/*
- * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
- *
- * This is really horribly ugly.
- */
-
-struct msgbuf32 { s32 mtype; char mtext[1]; };
-
-struct ipc_perm32
-{
- key_t key;
- __kernel_uid_t32 uid;
- __kernel_gid_t32 gid;
- __kernel_uid_t32 cuid;
- __kernel_gid_t32 cgid;
- __kernel_mode_t32 mode;
- unsigned short seq;
-};
-
-struct semid_ds32 {
- struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t32 sem_otime; /* last semop time */
- __kernel_time_t32 sem_ctime; /* last change time */
- u32 sem_base; /* ptr to first semaphore in array */
- u32 sem_pending; /* pending operations to be processed */
- u32 sem_pending_last; /* last pending operation */
- u32 undo; /* undo requests on this array */
- unsigned short sem_nsems; /* no. of semaphores in array */
-};
-
-struct msqid_ds32
-{
- struct ipc_perm32 msg_perm;
- u32 msg_first;
- u32 msg_last;
- __kernel_time_t32 msg_stime;
- __kernel_time_t32 msg_rtime;
- __kernel_time_t32 msg_ctime;
- u32 wwait;
- u32 rwait;
- unsigned short msg_cbytes;
- unsigned short msg_qnum;
- unsigned short msg_qbytes;
- __kernel_ipc_pid_t32 msg_lspid;
- __kernel_ipc_pid_t32 msg_lrpid;
-};
-
-struct shmid_ds32 {
- struct ipc_perm32 shm_perm;
- int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
- __kernel_ipc_pid_t32 shm_cpid;
- __kernel_ipc_pid_t32 shm_lpid;
- unsigned short shm_nattch;
-};
-
-#define IPCOP_MASK(__x) (1UL << (__x))
-
-static int
-do_sys32_semctl(int first, int second, int third, void *uptr)
-{
- union semun fourth;
- u32 pad;
- int err;
- struct semid64_ds s;
- struct semid_ds32 *usp;
- mm_segment_t old_fs;
-
- if (!uptr)
- return -EINVAL;
- err = -EFAULT;
- if (get_user (pad, (u32 *)uptr))
- return err;
- if(third == SETVAL)
- fourth.val = (int)pad;
- else
- fourth.__pad = (void *)A(pad);
-
- switch (third) {
-
- case IPC_INFO:
- case IPC_RMID:
- case IPC_SET:
- case SEM_INFO:
- case GETVAL:
- case GETPID:
- case GETNCNT:
- case GETZCNT:
- case GETALL:
- case SETVAL:
- case SETALL:
- err = sys_semctl (first, second, third, fourth);
- break;
-
- case IPC_STAT:
- case SEM_STAT:
- usp = (struct semid_ds32 *)A(pad);
- fourth.__pad = &s;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_semctl (first, second, third, fourth);
- set_fs (old_fs);
- if (verify_area(VERIFY_WRITE, usp, sizeof(struct semid_ds32)) ||
- __put_user(s.sem_perm.key, &usp->sem_perm.key) ||
- __put_user(s.sem_perm.uid, &usp->sem_perm.uid) ||
- __put_user(s.sem_perm.gid, &usp->sem_perm.gid) ||
- __put_user(s.sem_perm.cuid, &usp->sem_perm.cuid) ||
- __put_user (s.sem_perm.cgid, &usp->sem_perm.cgid) ||
- __put_user (s.sem_perm.mode, &usp->sem_perm.mode) ||
- __put_user (s.sem_perm.seq, &usp->sem_perm.seq) ||
- __put_user (s.sem_otime, &usp->sem_otime) ||
- __put_user (s.sem_ctime, &usp->sem_ctime) ||
- __put_user (s.sem_nsems, &usp->sem_nsems))
- return -EFAULT;
- break;
-
- }
-
- return err;
-}
-
-static int
-do_sys32_msgsnd (int first, int second, int third, void *uptr)
-{
- struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
- + 4, GFP_USER);
- struct msgbuf32 *up = (struct msgbuf32 *)uptr;
- mm_segment_t old_fs;
- int err;
-
- if (!p)
- return -ENOMEM;
- err = verify_area(VERIFY_READ, up, sizeof(struct msgbuf32));
- if (err)
- goto out;
- err = __get_user (p->mtype, &up->mtype);
- err |= __copy_from_user (p->mtext, &up->mtext, second);
- if (err)
- goto out;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_msgsnd (first, p, second, third);
- set_fs (old_fs);
-out:
- kfree (p);
- return err;
-}
-
-static int
-do_sys32_msgrcv (int first, int second, int msgtyp, int third,
- int version, void *uptr)
-{
- struct msgbuf32 *up;
- struct msgbuf *p;
- mm_segment_t old_fs;
- int err;
-
- if (!version) {
- struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
- struct ipc_kludge ipck;
-
- err = -EINVAL;
- if (!uptr)
- goto out;
- err = -EFAULT;
- if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
- goto out;
- uptr = (void *)A(ipck.msgp);
- msgtyp = ipck.msgtyp;
- }
- err = -ENOMEM;
- p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
- if (!p)
- goto out;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_msgrcv (first, p, second + 4, msgtyp, third);
- set_fs (old_fs);
- if (err < 0)
- goto free_then_out;
- up = (struct msgbuf32 *)uptr;
- if (verify_area(VERIFY_WRITE, up, sizeof(struct msgbuf32)) ||
- __put_user (p->mtype, &up->mtype) ||
- __copy_to_user (&up->mtext, p->mtext, err))
- err = -EFAULT;
-free_then_out:
- kfree (p);
-out:
- return err;
-}
-
-static int
-do_sys32_msgctl (int first, int second, void *uptr)
-{
- int err = -EINVAL;
- struct msqid_ds m;
- struct msqid64_ds m64;
- struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
- mm_segment_t old_fs;
-
- switch (second) {
-
- case IPC_INFO:
- case IPC_RMID:
- case MSG_INFO:
- err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
- break;
-
- case IPC_SET:
- err = verify_area(VERIFY_READ, up, sizeof(struct msqid_ds32));
- if (err)
- break;
- err = __get_user (m.msg_perm.uid, &up->msg_perm.uid);
- err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
- err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
- err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
- if (err)
- break;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_msgctl (first, second, &m);
- set_fs (old_fs);
- break;
-
- case IPC_STAT:
- case MSG_STAT:
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_msgctl (first, second, (void *) &m64);
- set_fs (old_fs);
- if (verify_area(VERIFY_WRITE, up, sizeof(struct msqid_ds32)) ||
- __put_user (m64.msg_perm.key, &up->msg_perm.key) ||
- __put_user(m64.msg_perm.uid, &up->msg_perm.uid) ||
- __put_user(m64.msg_perm.gid, &up->msg_perm.gid) ||
- __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid) ||
- __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid) ||
- __put_user(m64.msg_perm.mode, &up->msg_perm.mode) ||
- __put_user(m64.msg_perm.seq, &up->msg_perm.seq) ||
- __put_user(m64.msg_stime, &up->msg_stime) ||
- __put_user(m64.msg_rtime, &up->msg_rtime) ||
- __put_user(m64.msg_ctime, &up->msg_ctime) ||
- __put_user(m64.msg_cbytes, &up->msg_cbytes) ||
- __put_user(m64.msg_qnum, &up->msg_qnum) ||
- __put_user(m64.msg_qbytes, &up->msg_qbytes) ||
- __put_user(m64.msg_lspid, &up->msg_lspid) ||
- __put_user(m64.msg_lrpid, &up->msg_lrpid))
- return -EFAULT;
- break;
-
- }
-
- return err;
-}
-
-static int
-do_sys32_shmat (int first, int second, int third, int version, void *uptr)
-{
- unsigned long raddr;
- u32 *uaddr = (u32 *)A((u32)third);
- int err = -EINVAL;
-
- if (version == 1)
- return err;
- err = sys_shmat (first, uptr, second, &raddr);
- if (err)
- return err;
- err = put_user (raddr, uaddr);
- return err;
-}
-
-static int
-do_sys32_shmctl (int first, int second, void *uptr)
-{
- int err = -EFAULT;
- struct shmid_ds s;
- struct shmid64_ds s64;
- struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
- mm_segment_t old_fs;
- struct shm_info32 {
- int used_ids;
- u32 shm_tot, shm_rss, shm_swp;
- u32 swap_attempts, swap_successes;
- } *uip = (struct shm_info32 *)uptr;
- struct shm_info si;
-
- switch (second) {
-
- case IPC_INFO:
- case IPC_RMID:
- case SHM_LOCK:
- case SHM_UNLOCK:
- err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
- break;
- case IPC_SET:
- err = verify_area(VERIFY_READ, up, sizeof(struct shmid_ds32));
- if (err)
- break;
- err = __get_user (s.shm_perm.uid, &up->shm_perm.uid);
- err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
- err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
- if (err)
- break;
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, &s);
- set_fs (old_fs);
- break;
-
- case IPC_STAT:
- case SHM_STAT:
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, (void *) &s64);
- set_fs (old_fs);
- if (err < 0)
- break;
- if (verify_area(VERIFY_WRITE, up, sizeof(struct shmid_ds32)) ||
- __put_user (s64.shm_perm.key, &up->shm_perm.key) ||
- __put_user (s64.shm_perm.uid, &up->shm_perm.uid) ||
- __put_user (s64.shm_perm.gid, &up->shm_perm.gid) ||
- __put_user (s64.shm_perm.cuid, &up->shm_perm.cuid) ||
- __put_user (s64.shm_perm.cgid, &up->shm_perm.cgid) ||
- __put_user (s64.shm_perm.mode, &up->shm_perm.mode) ||
- __put_user (s64.shm_perm.seq, &up->shm_perm.seq) ||
- __put_user (s64.shm_atime, &up->shm_atime) ||
- __put_user (s64.shm_dtime, &up->shm_dtime) ||
- __put_user (s64.shm_ctime, &up->shm_ctime) ||
- __put_user (s64.shm_segsz, &up->shm_segsz) ||
- __put_user (s64.shm_nattch, &up->shm_nattch) ||
- __put_user (s64.shm_cpid, &up->shm_cpid) ||
- __put_user (s64.shm_lpid, &up->shm_lpid))
- return -EFAULT;
- break;
-
- case SHM_INFO:
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, (void *)&si);
- set_fs (old_fs);
- if (err < 0)
- break;
- if (verify_area(VERIFY_WRITE, uip, sizeof(struct shm_info32)) ||
- __put_user (si.used_ids, &uip->used_ids) ||
- __put_user (si.shm_tot, &uip->shm_tot) ||
- __put_user (si.shm_rss, &uip->shm_rss) ||
- __put_user (si.shm_swp, &uip->shm_swp) ||
- __put_user (si.swap_attempts, &uip->swap_attempts) ||
- __put_user (si.swap_successes, &uip->swap_successes))
- return -EFAULT;
- break;
-
- }
- return err;
-}
-
-asmlinkage long
-sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
-{
- int version, err;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
-
- case SEMOP:
- /* struct sembuf is the same on 32 and 64bit :)) */
- err = sys_semop (first, (struct sembuf *)AA(ptr),
- second);
- break;
- case SEMGET:
- err = sys_semget (first, second, third);
- break;
- case SEMCTL:
- err = do_sys32_semctl (first, second, third,
- (void *)AA(ptr));
- break;
-
- case MSGSND:
- err = do_sys32_msgsnd (first, second, third,
- (void *)AA(ptr));
- break;
- case MSGRCV:
- err = do_sys32_msgrcv (first, second, fifth, third,
- version, (void *)AA(ptr));
- break;
- case MSGGET:
- err = sys_msgget ((key_t) first, second);
- break;
- case MSGCTL:
- err = do_sys32_msgctl (first, second, (void *)AA(ptr));
- break;
-
- case SHMAT:
- err = do_sys32_shmat (first, second, third,
- version, (void *)AA(ptr));
- break;
- case SHMDT:
- err = sys_shmdt ((char *)AA(ptr));
- break;
- case SHMGET:
- err = sys_shmget (first, second, third);
- break;
- case SHMCTL:
- err = do_sys32_shmctl (first, second, (void *)AA(ptr));
- break;
- default:
- err = -EINVAL;
- break;
- }
-
- return err;
-}
-
-/*
* sys_time() can be implemented in user-level using
* sys_gettimeofday(). IA64 did this but i386 Linux did not
* so we have to implement this system call here.
diff -Nru a/arch/x86_64/kernel/asm-offsets.c b/arch/x86_64/kernel/asm-offsets.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/kernel/asm-offsets.c Tue Jun 18 19:12:03 2002
@@ -0,0 +1,46 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+#define ENTRY(entry) DEFINE(tsk_ ## entry, offsetof(struct task_struct, entry))
+ ENTRY(state);
+ ENTRY(flags);
+ ENTRY(thread);
+ BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(threadinfo__ ## entry, offsetof(struct thread_info, entry))
+ ENTRY(flags);
+ ENTRY(addr_limit);
+ ENTRY(preempt_count);
+ BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(pda__ ## entry, offsetof(struct x8664_pda, entry))
+ ENTRY(kernelstack);
+ ENTRY(oldrsp);
+ ENTRY(pcurrent);
+ ENTRY(irqrsp);
+ ENTRY(irqcount);
+ ENTRY(cpunumber);
+ ENTRY(irqstackptr);
+ BLANK();
+#undef ENTRY
+ return 0;
+}
diff -Nru a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c
--- a/arch/x86_64/kernel/ioport.c Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/kernel/ioport.c Tue Jun 18 19:12:02 2002
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
@@ -61,27 +62,19 @@
return -EINVAL;
if (turn_on && !capable(CAP_SYS_RAWIO))
return -EPERM;
- /*
- * If it's the first ioperm() call in this thread's lifetime, set the
- * IO bitmap up. ioperm() is much less timing critical than clone(),
- * this is why we delay this operation until now:
- */
- if (!t->ioperm) {
- /*
- * just in case ...
- */
- memset(t->io_bitmap,0xff,(IO_BITMAP_SIZE+1)*4);
- t->ioperm = 1;
- /*
- * this activates it in the TSS
- */
+
+ if (!t->io_bitmap_ptr) {
+ t->io_bitmap_ptr = kmalloc((IO_BITMAP_SIZE+1)*4, GFP_KERNEL);
+ if (!t->io_bitmap_ptr)
+ return -ENOMEM;
+ memset(t->io_bitmap_ptr,0xff,(IO_BITMAP_SIZE+1)*4);
tss->io_map_base = IO_BITMAP_OFFSET;
}
/*
* do it in the per-thread copy and in the TSS ...
*/
- set_bitmap((unsigned long *) t->io_bitmap, from, num, !turn_on);
+ set_bitmap((unsigned long *) t->io_bitmap_ptr, from, num, !turn_on);
set_bitmap((unsigned long *) tss->io_bitmap, from, num, !turn_on);
return 0;
diff -Nru a/arch/x86_64/kernel/mtrr.c b/arch/x86_64/kernel/mtrr.c
--- a/arch/x86_64/kernel/mtrr.c Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/kernel/mtrr.c Tue Jun 18 19:12:02 2002
@@ -19,10 +19,14 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
(For earlier history, see arch/i386/kernel/mtrr.c)
- September 2001 Dave Jones
+ v2.00 September 2001 Dave Jones
Initial rewrite for x86-64.
-
+ Removal of non-Intel style MTRR code.
+ v2.01 June 2002 Dave Jones
+ Removal of redundant abstraction layer.
+ 64-bit fixes.
*/
+
#include
#include
#include
@@ -60,35 +64,19 @@
#include
#include
-#define MTRR_VERSION "2.00 (20020207)"
+#define MTRR_VERSION "2.01 (20020605)"
#define TRUE 1
#define FALSE 0
-#define MTRRcap_MSR 0x0fe
-#define MTRRdefType_MSR 0x2ff
-
-#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
-#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+#define MSR_MTRRphysBase(reg) (0x200 + 2 * (reg))
+#define MSR_MTRRphysMask(reg) (0x200 + 2 * (reg) + 1)
#define NUM_FIXED_RANGES 88
-#define MTRRfix64K_00000_MSR 0x250
-#define MTRRfix16K_80000_MSR 0x258
-#define MTRRfix16K_A0000_MSR 0x259
-#define MTRRfix4K_C0000_MSR 0x268
-#define MTRRfix4K_C8000_MSR 0x269
-#define MTRRfix4K_D0000_MSR 0x26a
-#define MTRRfix4K_D8000_MSR 0x26b
-#define MTRRfix4K_E0000_MSR 0x26c
-#define MTRRfix4K_E8000_MSR 0x26d
-#define MTRRfix4K_F0000_MSR 0x26e
-#define MTRRfix4K_F8000_MSR 0x26f
-#ifdef CONFIG_SMP
#define MTRR_CHANGE_MASK_FIXED 0x01
#define MTRR_CHANGE_MASK_VARIABLE 0x02
#define MTRR_CHANGE_MASK_DEFTYPE 0x04
-#endif
typedef u8 mtrr_type;
@@ -97,49 +85,43 @@
#ifdef CONFIG_SMP
#define set_mtrr(reg,base,size,type) set_mtrr_smp (reg, base, size, type)
#else
-#define set_mtrr(reg,base,size,type) (*set_mtrr_up) (reg, base, size, type, \
- TRUE)
+#define set_mtrr(reg,base,size,type) set_mtrr_up (reg, base, size, type, TRUE)
#endif
#if defined(CONFIG_PROC_FS) || defined(CONFIG_DEVFS_FS)
#define USERSPACE_INTERFACE
#endif
-#ifndef USERSPACE_INTERFACE
-#define compute_ascii() while (0)
-#endif
-
#ifdef USERSPACE_INTERFACE
static char *ascii_buffer;
static unsigned int ascii_buf_bytes;
-#endif
-static unsigned int *usage_table;
-static DECLARE_MUTEX (main_lock);
-
-/* Private functions */
-#ifdef USERSPACE_INTERFACE
static void compute_ascii (void);
+#else
+#define compute_ascii() while (0)
#endif
+static unsigned int *usage_table;
+static DECLARE_MUTEX (mtrr_lock);
+
struct set_mtrr_context {
- unsigned long flags;
- unsigned long deftype_lo;
- unsigned long deftype_hi;
- unsigned long cr4val;
+ u32 deftype_lo;
+ u32 deftype_hi;
+ u64 flags;
+ u64 cr4val;
};
/* Put the processor into a state where MTRRs can be safely set */
static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
{
- unsigned long cr0;
+ u64 cr0;
/* Disable interrupts locally */
__save_flags(ctxt->flags);
__cli();
/* Save value of CR4 and clear Page Global Enable (bit 7) */
- if (cpu_has_ge) {
+ if (cpu_has_pge) {
ctxt->cr4val = read_cr4();
write_cr4(ctxt->cr4val & ~(1UL << 7));
}
@@ -152,8 +134,8 @@
wbinvd();
/* Disable MTRRs, and set the default type to uncached */
- rdmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
- wrmsr(MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
+ rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
+ wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
}
@@ -164,7 +146,7 @@
wbinvd();
/* Restore MTRRdefType */
- wrmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
+ wrmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
/* Enable caches */
write_cr0(read_cr0() & 0xbfffffff);
@@ -181,9 +163,9 @@
/* This function returns the number of variable MTRRs */
static unsigned int get_num_var_ranges (void)
{
- unsigned long config, dummy;
+ u32 config, dummy;
- rdmsr (MTRRcap_MSR, config, dummy);
+ rdmsr (MSR_MTRRcap, config, dummy);
return (config & 0xff);
}
@@ -191,21 +173,21 @@
/* Returns non-zero if we have the write-combining memory type */
static int have_wrcomb (void)
{
- unsigned long config, dummy;
+ u32 config, dummy;
- rdmsr (MTRRcap_MSR, config, dummy);
+ rdmsr (MSR_MTRRcap, config, dummy);
return (config & (1 << 10));
}
-static u32 size_or_mask, size_and_mask;
+static u64 size_or_mask, size_and_mask;
-static void get_mtrr (unsigned int reg, unsigned long *base,
- unsigned long *size, mtrr_type * type)
+static void get_mtrr (unsigned int reg, u64 *base, u32 *size, mtrr_type * type)
{
- unsigned long mask_lo, mask_hi, base_lo, base_hi;
+ u32 mask_lo, mask_hi, base_lo, base_hi;
+ u64 newsize;
- rdmsr (MTRRphysMask_MSR (reg), mask_lo, mask_hi);
+ rdmsr (MSR_MTRRphysMask(reg), mask_lo, mask_hi);
if ((mask_lo & 0x800) == 0) {
/* Invalid (i.e. free) range */
*base = 0;
@@ -214,32 +196,29 @@
return;
}
- rdmsr (MTRRphysBase_MSR (reg), base_lo, base_hi);
+ rdmsr (MSR_MTRRphysBase(reg), base_lo, base_hi);
/* Work out the shifted address mask. */
- mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT)
- | mask_lo >> PAGE_SHIFT;
-
- /* This works correctly if size is a power of two, i.e. a
- contiguous range. */
- *size = -mask_lo;
+ newsize = (u64) mask_hi << 32 | (mask_lo & ~0x800);
+ newsize = ~newsize+1;
+ *size = (u32) newsize >> PAGE_SHIFT;
*base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
*type = base_lo & 0xff;
}
-static void set_mtrr_up (unsigned int reg, unsigned long base,
- unsigned long size, mtrr_type type, int do_safe)
-/* [SUMMARY] Set variable MTRR register on the local CPU.
- The register to set.
- The base address of the region.
- The size of the region. If this is 0 the region is disabled.
- The type of the region.
- If TRUE, do the change safely. If FALSE, safety measures should
- be done externally.
- [RETURNS] Nothing.
-*/
+/*
+ * Set variable MTRR register on the local CPU.
+ * The register to set.
+ * The base address of the region.
+ * The size of the region. If this is 0 the region is disabled.
+ * The type of the region.
+ * If TRUE, do the change safely. If FALSE, safety measures should
+ * be done externally.
+ */
+static void set_mtrr_up (unsigned int reg, u64 base,
+ u32 size, mtrr_type type, int do_safe)
{
struct set_mtrr_context ctxt;
@@ -249,12 +228,12 @@
if (size == 0) {
/* The invalid bit is kept in the mask, so we simply clear the
relevant mask register to disable a range. */
- wrmsr (MTRRphysMask_MSR (reg), 0, 0);
+ wrmsr (MSR_MTRRphysMask(reg), 0, 0);
} else {
- wrmsr (MTRRphysBase_MSR (reg), base << PAGE_SHIFT | type,
+ wrmsr (MSR_MTRRphysBase(reg), base << PAGE_SHIFT | type,
(base & size_and_mask) >> (32 - PAGE_SHIFT));
- wrmsr (MTRRphysMask_MSR (reg), -size << PAGE_SHIFT | 0x800,
- (-size & size_and_mask) >> (32 - PAGE_SHIFT));
+ wrmsr (MSR_MTRRphysMask(reg), (-size-1) << PAGE_SHIFT | 0x800,
+ ((-size-1) & size_and_mask) >> (32 - PAGE_SHIFT));
}
if (do_safe)
set_mtrr_done (&ctxt);
@@ -264,41 +243,40 @@
#ifdef CONFIG_SMP
struct mtrr_var_range {
- unsigned long base_lo;
- unsigned long base_hi;
- unsigned long mask_lo;
- unsigned long mask_hi;
+ u32 base_lo;
+ u32 base_hi;
+ u32 mask_lo;
+ u32 mask_hi;
};
/* Get the MSR pair relating to a var range */
static void __init get_mtrr_var_range (unsigned int index,
struct mtrr_var_range *vr)
{
- rdmsr (MTRRphysBase_MSR (index), vr->base_lo, vr->base_hi);
- rdmsr (MTRRphysMask_MSR (index), vr->mask_lo, vr->mask_hi);
+ rdmsr (MSR_MTRRphysBase(index), vr->base_lo, vr->base_hi);
+ rdmsr (MSR_MTRRphysMask(index), vr->mask_lo, vr->mask_hi);
}
/* Set the MSR pair relating to a var range. Returns TRUE if
changes are made */
-static int __init
-set_mtrr_var_range_testing (unsigned int index, struct mtrr_var_range *vr)
+static int __init set_mtrr_var_range_testing (unsigned int index,
+ struct mtrr_var_range *vr)
{
- unsigned int lo, hi;
+ u32 lo, hi;
int changed = FALSE;
- rdmsr (MTRRphysBase_MSR (index), lo, hi);
- if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
- || (vr->base_hi & 0xfUL) != (hi & 0xfUL)) {
- wrmsr (MTRRphysBase_MSR (index), vr->base_lo, vr->base_hi);
+ rdmsr (MSR_MTRRphysBase(index), lo, hi);
+ if ((vr->base_lo & 0xfffff0ff) != (lo & 0xfffff0ff)
+ || (vr->base_hi & 0x000fffff) != (hi & 0x000fffff)) {
+ wrmsr (MSR_MTRRphysBase(index), vr->base_lo, vr->base_hi);
changed = TRUE;
}
- rdmsr (MTRRphysMask_MSR (index), lo, hi);
-
- if ((vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
- || (vr->mask_hi & 0xfUL) != (hi & 0xfUL)) {
- wrmsr (MTRRphysMask_MSR (index), vr->mask_lo, vr->mask_hi);
+ rdmsr (MSR_MTRRphysMask(index), lo, hi);
+ if ((vr->mask_lo & 0xfffff800) != (lo & 0xfffff800)
+ || (vr->mask_hi & 0x000fffff) != (hi & 0x000fffff)) {
+ wrmsr (MSR_MTRRphysMask(index), vr->mask_lo, vr->mask_hi);
changed = TRUE;
}
return changed;
@@ -307,45 +285,50 @@
static void __init get_fixed_ranges (mtrr_type * frs)
{
- unsigned long *p = (unsigned long *) frs;
+ u32 *p = (u32 *) frs;
int i;
- rdmsr (MTRRfix64K_00000_MSR, p[0], p[1]);
+ rdmsr (MSR_MTRRfix64K_00000, p[0], p[1]);
for (i = 0; i < 2; i++)
- rdmsr (MTRRfix16K_80000_MSR + i, p[2 + i * 2], p[3 + i * 2]);
+ rdmsr (MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]);
for (i = 0; i < 8; i++)
- rdmsr (MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]);
+ rdmsr (MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]);
}
static int __init set_fixed_ranges_testing (mtrr_type * frs)
{
- unsigned long *p = (unsigned long *) frs;
+ u32 *p = (u32 *) frs;
int changed = FALSE;
int i;
- unsigned long lo, hi;
+ u32 lo, hi;
- rdmsr (MTRRfix64K_00000_MSR, lo, hi);
+ printk (KERN_INFO "mtrr: rdmsr 64K_00000\n");
+ rdmsr (MSR_MTRRfix64K_00000, lo, hi);
if (p[0] != lo || p[1] != hi) {
- wrmsr (MTRRfix64K_00000_MSR, p[0], p[1]);
+ printk (KERN_INFO "mtrr: Writing %x:%x to 64K MSR. lohi were %x:%x\n", p[0], p[1], lo, hi);
+ wrmsr (MSR_MTRRfix64K_00000, p[0], p[1]);
changed = TRUE;
}
+ printk (KERN_INFO "mtrr: rdmsr 16K_80000\n");
for (i = 0; i < 2; i++) {
- rdmsr (MTRRfix16K_80000_MSR + i, lo, hi);
+ rdmsr (MSR_MTRRfix16K_80000 + i, lo, hi);
if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) {
- wrmsr (MTRRfix16K_80000_MSR + i, p[2 + i * 2],
- p[3 + i * 2]);
+ printk (KERN_INFO "mtrr: Writing %x:%x to 16K MSR%d. lohi were %x:%x\n", p[2 + i * 2], p[3 + i * 2], i, lo, hi );
+ wrmsr (MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]);
changed = TRUE;
}
}
+ printk (KERN_INFO "mtrr: rdmsr 4K_C0000\n");
for (i = 0; i < 8; i++) {
- rdmsr (MTRRfix4K_C0000_MSR + i, lo, hi);
+ rdmsr (MSR_MTRRfix4K_C0000 + i, lo, hi);
+ printk (KERN_INFO "mtrr: MTRRfix4K_C0000+%d = %x:%x\n", i, lo, hi);
if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) {
- wrmsr (MTRRfix4K_C0000_MSR + i, p[6 + i * 2],
- p[7 + i * 2]);
+ printk (KERN_INFO "mtrr: Writing %x:%x to 4K MSR%d. lohi were %x:%x\n", p[6 + i * 2], p[7 + i * 2], i, lo, hi);
+ wrmsr (MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]);
changed = TRUE;
}
}
@@ -357,8 +340,8 @@
unsigned int num_var_ranges;
struct mtrr_var_range *var_ranges;
mtrr_type fixed_ranges[NUM_FIXED_RANGES];
- unsigned char enabled;
mtrr_type def_type;
+ unsigned char enabled;
};
@@ -367,9 +350,9 @@
{
unsigned int nvrs, i;
struct mtrr_var_range *vrs;
- unsigned long lo, dummy;
+ u32 lo, dummy;
- nvrs = state->num_var_ranges = get_num_var_ranges ();
+ nvrs = state->num_var_ranges = get_num_var_ranges();
vrs = state->var_ranges
= kmalloc (nvrs * sizeof (struct mtrr_var_range), GFP_KERNEL);
if (vrs == NULL)
@@ -379,7 +362,7 @@
get_mtrr_var_range (i, &vrs[i]);
get_fixed_ranges (state->fixed_ranges);
- rdmsr (MTRRdefType_MSR, lo, dummy);
+ rdmsr (MSR_MTRRdefType, lo, dummy);
state->def_type = (lo & 0xff);
state->enabled = (lo & 0xc00) >> 10;
}
@@ -393,17 +376,18 @@
}
-static unsigned long __init set_mtrr_state (struct mtrr_state *state,
+/*
+ * Set the MTRR state for this CPU.
+ * The MTRR state information to read.
+ * Some relevant CPU context.
+ * [NOTE] The CPU must already be in a safe state for MTRR changes.
+ * [RETURNS] 0 if no changes made, else a mask indication what was changed.
+ */
+static u64 __init set_mtrr_state (struct mtrr_state *state,
struct set_mtrr_context *ctxt)
-/* [SUMMARY] Set the MTRR state for this CPU.
- The MTRR state information to read.
- Some relevant CPU context.
- [NOTE] The CPU must already be in a safe state for MTRR changes.
- [RETURNS] 0 if no changes made, else a mask indication what was changed.
-*/
{
unsigned int i;
- unsigned long change_mask = 0;
+ u64 change_mask = 0;
for (i = 0; i < state->num_var_ranges; i++)
if (set_mtrr_var_range_testing (i, &state->var_ranges[i]))
@@ -428,16 +412,16 @@
static volatile int wait_barrier_cache_enable = FALSE;
struct set_mtrr_data {
- unsigned long smp_base;
- unsigned long smp_size;
+ u64 smp_base;
+ u32 smp_size;
unsigned int smp_reg;
mtrr_type smp_type;
};
+/*
+ * Synchronisation handler. Executed by "other" CPUs.
+ */
static void ipi_handler (void *info)
-/* [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
- [RETURNS] Nothing.
-*/
{
struct set_mtrr_data *data = info;
struct set_mtrr_context ctxt;
@@ -449,7 +433,7 @@
barrier ();
/* The master has cleared me to execute */
- (*set_mtrr_up) (data->smp_reg, data->smp_base, data->smp_size,
+ set_mtrr_up (data->smp_reg, data->smp_base, data->smp_size,
data->smp_type, FALSE);
/* Notify master CPU that I've executed the function */
@@ -462,8 +446,7 @@
}
-static void set_mtrr_smp (unsigned int reg, unsigned long base,
- unsigned long size, mtrr_type type)
+static void set_mtrr_smp (unsigned int reg, u64 base, u32 size, mtrr_type type)
{
struct set_mtrr_data data;
struct set_mtrr_context ctxt;
@@ -490,7 +473,7 @@
/* Set up for completion wait and then release other CPUs to change MTRRs */
atomic_set (&undone_count, smp_num_cpus - 1);
wait_barrier_execute = FALSE;
- (*set_mtrr_up) (reg, base, size, type, FALSE);
+ set_mtrr_up (reg, base, size, type, FALSE);
/* Now wait for other CPUs to complete the function */
while (atomic_read (&undone_count) > 0)
@@ -505,7 +488,7 @@
/* Some BIOS's are fucked and don't set all MTRRs the same! */
-static void __init mtrr_state_warn (unsigned long mask)
+static void __init mtrr_state_warn (u32 mask)
{
if (!mask)
return;
@@ -521,7 +504,7 @@
#endif /* CONFIG_SMP */
-static char inline * attrib_to_str (int x)
+static inline char * attrib_to_str (int x)
{
return (x <= 6) ? mtrr_strings[x] : "?";
}
@@ -551,21 +534,20 @@
}
-static int generic_get_free_region (unsigned long base,
- unsigned long size)
-/* [SUMMARY] Get a free MTRR.
- The starting (base) address of the region.
- The size (in bytes) of the region.
- [RETURNS] The index of the region on success, else -1 on error.
+/*
+ * Get a free MTRR.
+ * returns the index of the region on success, else -1 on error.
*/
+static int get_free_region(void)
{
int i, max;
mtrr_type ltype;
- unsigned long lbase, lsize;
+ u64 lbase;
+ u32 lsize;
max = get_num_var_ranges ();
for (i = 0; i < max; ++i) {
- (*get_mtrr) (i, &lbase, &lsize, <ype);
+ get_mtrr (i, &lbase, &lsize, <ype);
if (lsize == 0)
return i;
}
@@ -573,22 +555,19 @@
}
-static int (*get_free_region) (unsigned long base,
- unsigned long size) = generic_get_free_region;
-
/**
* mtrr_add_page - Add a memory type region
* @base: Physical base address of region in pages (4 KB)
* @size: Physical size of region in pages (4 KB)
* @type: Type of MTRR desired
* @increment: If this is true do usage counting on the region
+ * Returns The MTRR register on success, else a negative number
+ * indicating the error code.
*
- * Memory type region registers control the caching on newer Intel and
- * non Intel processors. This function allows drivers to request an
- * MTRR is added. The details and hardware specifics of each processor's
- * implementation are hidden from the caller, but nevertheless the
- * caller should expect to need to provide a power of two size on an
- * equivalent power of two boundary.
+ * Memory type region registers control the caching on newer
+ * processors. This function allows drivers to request an MTRR is added.
+ * The caller should expect to need to provide a power of two size on
+ * an equivalent power of two boundary.
*
* If the region cannot be added either because all regions are in use
* or the CPU cannot support it a negative value is returned. On success
@@ -596,42 +575,28 @@
* as a cookie only.
*
* On a multiprocessor machine the changes are made to all processors.
- * This is required on x86 by the Intel processors.
*
* The available types are
*
* %MTRR_TYPE_UNCACHABLE - No caching
- *
* %MTRR_TYPE_WRBACK - Write data back in bursts whenever
- *
* %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
- *
* %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
*
* BUGS: Needs a quiet flag for the cases where drivers do not mind
* failures and do not wish system log messages to be sent.
*/
-int mtrr_add_page (unsigned long base, unsigned long size,
- unsigned int type, char increment)
+int mtrr_add_page (u64 base, u32 size, unsigned int type, char increment)
{
-/* [SUMMARY] Add an MTRR entry.
- The starting (base, in pages) address of the region.
- The size of the region. (in pages)
- The type of the new region.
- If true and the region already exists, the usage count will be
- incremented.
- [RETURNS] The MTRR register on success, else a negative number indicating
- the error code.
- [NOTE] This routine uses a spinlock.
-*/
int i, max;
mtrr_type ltype;
- unsigned long lbase, lsize, last;
+ u64 lbase, last;
+ u32 lsize;
if (base + size < 0x100) {
printk (KERN_WARNING
- "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n",
+ "mtrr: cannot set region below 1 MiB (0x%lx000,0x%x000)\n",
base, size);
return -EINVAL;
}
@@ -644,7 +609,7 @@
if (lbase != last) {
printk (KERN_WARNING
- "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n",
+ "mtrr: base(0x%lx000) is not aligned on a size(0x%x000) boundary\n",
base, size);
return -EINVAL;
}
@@ -655,7 +620,7 @@
}
/* If the type is WC, check that this processor supports it */
- if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb ()) {
+ if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
printk (KERN_WARNING
"mtrr: your processor doesn't support write-combining\n");
return -ENOSYS;
@@ -669,9 +634,9 @@
increment = increment ? 1 : 0;
max = get_num_var_ranges ();
/* Search for existing MTRR */
- down (&main_lock);
+ down (&mtrr_lock);
for (i = 0; i < max; ++i) {
- (*get_mtrr) (i, &lbase, &lsize, <ype);
+ get_mtrr (i, &lbase, &lsize, <ype);
if (base >= lbase + lsize)
continue;
if ((base < lbase) && (base + size <= lbase))
@@ -679,41 +644,41 @@
/* At this point we know there is some kind of overlap/enclosure */
if ((base < lbase) || (base + size > lbase + lsize)) {
- up (&main_lock);
+ up (&mtrr_lock);
printk (KERN_WARNING
- "mtrr: 0x%lx000,0x%lx000 overlaps existing"
- " 0x%lx000,0x%lx000\n", base, size, lbase,
- lsize);
+ "mtrr: 0x%lx000,0x%x000 overlaps existing"
+ " 0x%lx000,0x%x000\n", base, size, lbase, lsize);
return -EINVAL;
}
/* New region is enclosed by an existing region */
if (ltype != type) {
if (type == MTRR_TYPE_UNCACHABLE)
continue;
- up (&main_lock);
+ up (&mtrr_lock);
printk
- ("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
- base, size, attrib_to_str (ltype),
+ ("mtrr: type mismatch for %lx000,%x000 old: %s new: %s\n",
+ base, size,
+ attrib_to_str (ltype),
attrib_to_str (type));
return -EINVAL;
}
if (increment)
++usage_table[i];
compute_ascii ();
- up (&main_lock);
+ up (&mtrr_lock);
return i;
}
/* Search for an empty MTRR */
- i = (*get_free_region) (base, size);
+ i = get_free_region();
if (i < 0) {
- up (&main_lock);
+ up (&mtrr_lock);
printk ("mtrr: no more MTRRs available\n");
return i;
}
set_mtrr (i, base, size, type);
usage_table[i] = 1;
compute_ascii ();
- up (&main_lock);
+ up (&mtrr_lock);
return i;
}
@@ -724,13 +689,13 @@
* @size: Physical size of region
* @type: Type of MTRR desired
* @increment: If this is true do usage counting on the region
+ * Return the MTRR register on success, else a negative numbe
+ * indicating the error code.
*
- * Memory type region registers control the caching on newer Intel and
- * non Intel processors. This function allows drivers to request an
- * MTRR is added. The details and hardware specifics of each processor's
- * implementation are hidden from the caller, but nevertheless the
- * caller should expect to need to provide a power of two size on an
- * equivalent power of two boundary.
+ * Memory type region registers control the caching on newer processors.
+ * This function allows drivers to request an MTRR is added.
+ * The caller should expect to need to provide a power of two size on
+ * an equivalent power of two boundary.
*
* If the region cannot be added either because all regions are in use
* or the CPU cannot support it a negative value is returned. On success
@@ -743,33 +708,19 @@
* The available types are
*
* %MTRR_TYPE_UNCACHABLE - No caching
- *
* %MTRR_TYPE_WRBACK - Write data back in bursts whenever
- *
* %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
- *
* %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
*
* BUGS: Needs a quiet flag for the cases where drivers do not mind
* failures and do not wish system log messages to be sent.
*/
-int mtrr_add (unsigned long base, unsigned long size, unsigned int type,
- char increment)
+int mtrr_add (u64 base, u32 size, unsigned int type, char increment)
{
-/* [SUMMARY] Add an MTRR entry.
- The starting (base) address of the region.
- The size (in bytes) of the region.
- The type of the new region.
- If true and the region already exists, the usage count will be
- incremented.
- [RETURNS] The MTRR register on success, else a negative number indicating
- the error code.
-*/
-
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk ("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
return mtrr_add_page (base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
@@ -792,55 +743,46 @@
* code.
*/
-int mtrr_del_page (int reg, unsigned long base, unsigned long size)
-/* [SUMMARY] Delete MTRR/decrement usage count.
- The register. If this is less than 0 then <> and <> must
- be supplied.
- The base address of the region. This is ignored if <> is >= 0.
- The size of the region. This is ignored if <> is >= 0.
- [RETURNS] The register on success, else a negative number indicating
- the error code.
- [NOTE] This routine uses a spinlock.
-*/
+int mtrr_del_page (int reg, u64 base, u32 size)
{
int i, max;
mtrr_type ltype;
- unsigned long lbase, lsize;
+ u64 lbase;
+ u32 lsize;
max = get_num_var_ranges ();
- down (&main_lock);
+ down (&mtrr_lock);
if (reg < 0) {
/* Search for existing MTRR */
for (i = 0; i < max; ++i) {
- (*get_mtrr) (i, &lbase, &lsize, <ype);
+ get_mtrr (i, &lbase, &lsize, <ype);
if (lbase == base && lsize == size) {
reg = i;
break;
}
}
if (reg < 0) {
- up (&main_lock);
- printk ("mtrr: no MTRR for %lx000,%lx000 found\n", base,
- size);
+ up (&mtrr_lock);
+ printk ("mtrr: no MTRR for %lx000,%x000 found\n", base, size);
return -EINVAL;
}
}
if (reg >= max) {
- up (&main_lock);
+ up (&mtrr_lock);
printk ("mtrr: register: %d too big\n", reg);
return -EINVAL;
}
- (*get_mtrr) (reg, &lbase, &lsize, <ype);
+ get_mtrr (reg, &lbase, &lsize, <ype);
if (lsize < 1) {
- up (&main_lock);
+ up (&mtrr_lock);
printk ("mtrr: MTRR %d not used\n", reg);
return -EINVAL;
}
if (usage_table[reg] < 1) {
- up (&main_lock);
+ up (&mtrr_lock);
printk ("mtrr: reg: %d has count=0\n", reg);
return -EINVAL;
}
@@ -848,7 +790,7 @@
if (--usage_table[reg] < 1)
set_mtrr (reg, 0, 0, 0);
compute_ascii ();
- up (&main_lock);
+ up (&mtrr_lock);
return reg;
}
@@ -868,19 +810,11 @@
* code.
*/
-int mtrr_del (int reg, unsigned long base, unsigned long size)
-/* [SUMMARY] Delete MTRR/decrement usage count.
- The register. If this is less than 0 then <> and <> must
- be supplied.
- The base address of the region. This is ignored if <> is >= 0.
- The size of the region. This is ignored if <> is >= 0.
- [RETURNS] The register on success, else a negative number indicating
- the error code.
-*/
+int mtrr_del (int reg, u64 base, u32 size)
{
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk ("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
return mtrr_del_page (reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
@@ -889,8 +823,8 @@
#ifdef USERSPACE_INTERFACE
-static int mtrr_file_add (unsigned long base, unsigned long size,
- unsigned int type, char increment, struct file *file, int page)
+static int mtrr_file_add (u64 base, u32 size, unsigned int type,
+ struct file *file, int page)
{
int reg, max;
unsigned int *fcount = file->private_data;
@@ -910,7 +844,7 @@
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk
("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
base >>= PAGE_SHIFT;
@@ -925,7 +859,7 @@
}
-static int mtrr_file_del (unsigned long base, unsigned long size,
+static int mtrr_file_del (u64 base, u32 size,
struct file *file, int page)
{
int reg;
@@ -935,7 +869,7 @@
if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
printk
("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%lx base: 0x%lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
base >>= PAGE_SHIFT;
@@ -977,9 +911,9 @@
"disable=%d"
*/
{
- int i, err;
- unsigned long reg;
- unsigned long long base, size;
+ int i, err, reg;
+ u64 base;
+ u32 size;
char *ptr;
char line[LINE_SIZE];
@@ -1027,7 +961,7 @@
if ((base & 0xfff) || (size & 0xfff)) {
printk ("mtrr: size and base must be multiples of 4 kiB\n");
- printk ("mtrr: size: 0x%Lx base: 0x%Lx\n", size, base);
+ printk ("mtrr: size: 0x%x base: 0x%lx\n", size, base);
return -EINVAL;
}
@@ -1046,9 +980,7 @@
continue;
base >>= PAGE_SHIFT;
size >>= PAGE_SHIFT;
- err =
- mtrr_add_page ((unsigned long) base, (unsigned long) size,
- i, 1);
+ err = mtrr_add_page ((u64) base, size, i, 1);
if (err < 0)
return err;
return len;
@@ -1076,7 +1008,7 @@
if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
return -EFAULT;
err =
- mtrr_file_add (sentry.base, sentry.size, sentry.type, 1,
+ mtrr_file_add (sentry.base, sentry.size, sentry.type,
file, 0);
if (err < 0)
return err;
@@ -1117,7 +1049,7 @@
return -EFAULT;
if (gentry.regnum >= get_num_var_ranges ())
return -EINVAL;
- (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
+ get_mtrr (gentry.regnum, &gentry.base, &gentry.size, &type);
/* Hide entries that go above 4GB */
if (gentry.base + gentry.size > 0x100000
@@ -1139,7 +1071,7 @@
if (copy_from_user (&sentry, (void *) arg, sizeof sentry))
return -EFAULT;
err =
- mtrr_file_add (sentry.base, sentry.size, sentry.type, 1,
+ mtrr_file_add (sentry.base, sentry.size, sentry.type,
file, 1);
if (err < 0)
return err;
@@ -1180,7 +1112,7 @@
return -EFAULT;
if (gentry.regnum >= get_num_var_ranges ())
return -EINVAL;
- (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
+ get_mtrr (gentry.regnum, &gentry.base, &gentry.size, &type);
gentry.type = type;
if (copy_to_user ((void *) arg, &gentry, sizeof gentry))
@@ -1199,7 +1131,6 @@
if (fcount == NULL)
return 0;
- lock_kernel ();
max = get_num_var_ranges ();
for (i = 0; i < max; ++i) {
while (fcount[i] > 0) {
@@ -1208,7 +1139,6 @@
--fcount[i];
}
}
- unlock_kernel ();
kfree (fcount);
file->private_data = NULL;
return 0;
@@ -1234,12 +1164,13 @@
char factor;
int i, max;
mtrr_type type;
- unsigned long base, size;
+ u64 base;
+ u32 size;
ascii_buf_bytes = 0;
max = get_num_var_ranges ();
for (i = 0; i < max; i++) {
- (*get_mtrr) (i, &base, &size, &type);
+ get_mtrr (i, &base, &size, &type);
if (size == 0)
usage_table[i] = 0;
else {
@@ -1253,11 +1184,10 @@
}
sprintf
(ascii_buffer + ascii_buf_bytes,
- "reg%02i: base=0x%05lx000 (%4liMB), size=%4li%cB: %s, count=%d\n",
+ "reg%02i: base=0x%05lx000 (%4liMB), size=%4i%cB: %s, count=%d\n",
i, base, base >> (20 - PAGE_SHIFT), size, factor,
attrib_to_str (type), usage_table[i]);
- ascii_buf_bytes +=
- strlen (ascii_buffer + ascii_buf_bytes);
+ ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes);
}
}
devfs_set_file_size (devfs_handle, ascii_buf_bytes);
@@ -1283,22 +1213,16 @@
if ((cpuid_eax (0x80000000) >= 0x80000008)) {
u32 phys_addr;
phys_addr = cpuid_eax (0x80000008) & 0xff;
- size_or_mask =
- ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
- size_and_mask = ~size_or_mask & 0xfff00000;
- } else {
- /* FIXME: This is to make it work on Athlon during debugging. */
- size_or_mask = 0xff000000; /* 36 bits */
- size_and_mask = 0x00f00000;
+ size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
+ size_and_mask = ~size_or_mask & 0xfffffffffff00000;
}
-
printk ("mtrr: detected mtrr type: x86-64\n");
}
}
#ifdef CONFIG_SMP
-static volatile unsigned long smp_changes_mask __initdata = 0;
+static volatile u32 smp_changes_mask __initdata = 0;
static struct mtrr_state smp_mtrr_state __initdata = { 0, 0 };
void __init mtrr_init_boot_cpu (void)
@@ -1310,7 +1234,8 @@
void __init mtrr_init_secondary_cpu (void)
{
- unsigned long mask, count;
+ u64 mask;
+ int count;
struct set_mtrr_context ctxt;
/* Note that this is not ideal, since the cache is only flushed/disabled
@@ -1357,4 +1282,3 @@
init_table ();
return 0;
}
-
diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c Tue Jun 18 19:12:01 2002
+++ b/arch/x86_64/kernel/process.c Tue Jun 18 19:12:01 2002
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
@@ -320,9 +321,6 @@
printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
}
-#define __STR(x) #x
-#define __STR2(x) __STR(x)
-
extern void load_gs_index(unsigned);
/*
@@ -330,7 +328,13 @@
*/
void exit_thread(void)
{
- /* nothing to do ... */
+ struct task_struct *me = current;
+ if (me->thread.io_bitmap_ptr) {
+ kfree(me->thread.io_bitmap_ptr);
+ me->thread.io_bitmap_ptr = NULL;
+ (init_tss + smp_processor_id())->io_map_base =
+ INVALID_IO_BITMAP_OFFSET;
+ }
}
void flush_thread(void)
@@ -392,6 +396,14 @@
unlazy_fpu(current);
p->thread.i387 = current->thread.i387;
+ if (unlikely(me->thread.io_bitmap_ptr != NULL)) {
+ p->thread.io_bitmap_ptr = kmalloc((IO_BITMAP_SIZE+1)*4, GFP_KERNEL);
+ if (!p->thread.io_bitmap_ptr)
+ return -ENOMEM;
+ memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
+ (IO_BITMAP_SIZE+1)*4);
+ }
+
return 0;
}
@@ -491,21 +503,14 @@
/*
* Handle the IO bitmap
*/
- if (unlikely(prev->ioperm || next->ioperm)) {
- if (next->ioperm) {
+ if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) {
+ if (next->io_bitmap_ptr) {
/*
* 4 cachelines copy ... not good, but not that
* bad either. Anyone got something better?
* This only affects processes which use ioperm().
- * [Putting the TSSs into 4k-tlb mapped regions
- * and playing VM tricks to switch the IO bitmap
- * is not really acceptable.]
- * On x86-64 we could put multiple bitmaps into
- * the GDT and just switch offsets
- * This would require ugly special cases on overflow
- * though -AK
*/
- memcpy(tss->io_bitmap, next->io_bitmap,
+ memcpy(tss->io_bitmap, next->io_bitmap_ptr,
IO_BITMAP_SIZE*sizeof(u32));
tss->io_map_base = IO_BITMAP_OFFSET;
} else {
diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/kernel/setup64.c Tue Jun 18 19:12:02 2002
@@ -91,6 +91,9 @@
pda->me = pda;
pda->cpudata_offset = 0;
+ pda->active_mm = &init_mm;
+ pda->mmu_state = 0;
+
asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
}
diff -Nru a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
--- a/arch/x86_64/kernel/signal.c Tue Jun 18 19:12:01 2002
+++ b/arch/x86_64/kernel/signal.c Tue Jun 18 19:12:01 2002
@@ -84,7 +84,6 @@
char *pretcode;
struct ucontext uc;
struct siginfo info;
- struct _fpstate fpstate;
};
static int
@@ -186,8 +185,7 @@
*/
static int
-setup_sigcontext(struct sigcontext *sc, struct _fpstate *fpstate,
- struct pt_regs *regs, unsigned long mask)
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask)
{
int tmp, err = 0;
struct task_struct *me = current;
@@ -221,20 +219,17 @@
err |= __put_user(mask, &sc->oldmask);
err |= __put_user(me->thread.cr2, &sc->cr2);
- tmp = save_i387(fpstate);
- if (tmp < 0)
- err = 1;
- else
- err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
-
return err;
}
/*
* Determine which stack to use..
*/
-static inline struct rt_sigframe *
-get_sigframe(struct k_sigaction *ka, struct pt_regs * regs)
+
+#define round_down(p, r) ((void *) ((unsigned long)((p) - (r) + 1) & ~((r)-1)))
+
+static void *
+get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
{
unsigned long rsp;
@@ -247,22 +242,34 @@
rsp = current->sas_ss_sp + current->sas_ss_size;
}
- rsp = (rsp - sizeof(struct _fpstate)) & ~(15UL);
- rsp -= offsetof(struct rt_sigframe, fpstate);
-
- return (struct rt_sigframe *) rsp;
+ return round_down(rsp - size, 16);
}
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;
+ struct rt_sigframe *frame = NULL;
+ struct _fpstate *fp = NULL;
int err = 0;
- frame = get_sigframe(ka, regs);
+ if (current->used_math) {
+ fp = get_stack(ka, regs, sizeof(struct _fpstate));
+ frame = round_down((char *)fp - sizeof(struct rt_sigframe), 16) - 8;
- if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) {
goto give_sigsegv;
+ }
+
+ if (save_i387(fp) < 0)
+ err |= -1;
+ }
+
+ if (!frame)
+ frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
+ goto give_sigsegv;
+ }
if (ka->sa.sa_flags & SA_SIGINFO) {
err |= copy_siginfo_to_user(&frame->info, info);
@@ -278,14 +285,10 @@
err |= __put_user(sas_ss_flags(regs->rsp),
&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 |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+ err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
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. */
/* x86-64 should always use SA_RESTORER. */
@@ -297,7 +300,6 @@
}
if (err) {
- printk("fault 3\n");
goto give_sigsegv;
}
@@ -305,7 +307,6 @@
printk("%d old rip %lx old rsp %lx old rax %lx\n", current->pid,regs->rip,regs->rsp,regs->rax);
#endif
-
/* Set up registers for signal handler */
{
struct exec_domain *ed = current_thread_info()->exec_domain;
@@ -320,8 +321,9 @@
next argument after the signal number on the stack. */
regs->rsi = (unsigned long)&frame->info;
regs->rdx = (unsigned long)&frame->uc;
- regs->rsp = (unsigned long) frame;
regs->rip = (unsigned long) ka->sa.sa_handler;
+
+ regs->rsp = (unsigned long)frame;
set_fs(USER_DS);
regs->eflags &= ~TF_MASK;
diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/kernel/smp.c Tue Jun 18 19:12:02 2002
@@ -25,8 +25,6 @@
/* The 'big kernel lock' */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
-struct tlb_state cpu_tlbstate[NR_CPUS] = {[0 ... NR_CPUS-1] = { &init_mm, 0 }};
-
/*
* the following functions deal with sending IPIs between CPUs.
*
@@ -147,9 +145,9 @@
*/
static void inline leave_mm (unsigned long cpu)
{
- if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
+ if (read_pda(mmu_state) == TLBSTATE_OK)
BUG();
- clear_bit(cpu, &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
+ clear_bit(cpu, &read_pda(active_mm)->cpu_vm_mask);
__flush_tlb();
}
@@ -164,18 +162,18 @@
* the other cpus, but smp_invalidate_interrupt ignore flush ipis
* for the wrong mm, and in the worst case we perform a superflous
* tlb flush.
- * 1a2) set cpu_tlbstate to TLBSTATE_OK
+ * 1a2) set cpu mmu_state to TLBSTATE_OK
* Now the smp_invalidate_interrupt won't call leave_mm if cpu0
* was in lazy tlb mode.
- * 1a3) update cpu_tlbstate[].active_mm
+ * 1a3) update cpu active_mm
* Now cpu0 accepts tlb flushes for the new mm.
* 1a4) set_bit(cpu, &new_mm->cpu_vm_mask);
* Now the other cpus will send tlb flush ipis.
* 1a4) change cr3.
* 1b) thread switch without mm change
- * cpu_tlbstate[].active_mm is correct, cpu0 already handles
+ * cpu active_mm is correct, cpu0 already handles
* flush ipis.
- * 1b1) set cpu_tlbstate to TLBSTATE_OK
+ * 1b1) set cpu mmu_state to TLBSTATE_OK
* 1b2) test_and_set the cpu bit in cpu_vm_mask.
* Atomically set the bit [other cpus will start sending flush ipis],
* and test the bit.
@@ -188,7 +186,7 @@
* runs in kernel space, the cpu could load tlb entries for user space
* pages.
*
- * The good news is that cpu_tlbstate is local to each cpu, no
+ * The good news is that cpu mmu_state is local to each cpu, no
* write/read ordering problems.
*/
@@ -216,8 +214,8 @@
* BUG();
*/
- if (flush_mm == cpu_tlbstate[cpu].active_mm) {
- if (cpu_tlbstate[cpu].state == TLBSTATE_OK) {
+ if (flush_mm == read_pda(active_mm)) {
+ if (read_pda(mmu_state) == TLBSTATE_OK) {
if (flush_va == FLUSH_ALL)
local_flush_tlb();
else
@@ -335,7 +333,7 @@
unsigned long cpu = smp_processor_id();
__flush_tlb_all();
- if (cpu_tlbstate[cpu].state == TLBSTATE_LAZY)
+ if (read_pda(mmu_state) == TLBSTATE_LAZY)
leave_mm(cpu);
}
diff -Nru a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
--- a/arch/x86_64/kernel/vsyscall.c Tue Jun 18 19:12:03 2002
+++ b/arch/x86_64/kernel/vsyscall.c Tue Jun 18 19:12:03 2002
@@ -47,7 +47,7 @@
#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
-#define NO_VSYSCALL 1
+//#define NO_VSYSCALL 1
#ifdef NO_VSYSCALL
#include
diff -Nru a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
--- a/arch/x86_64/kernel/x8664_ksyms.c Tue Jun 18 19:12:01 2002
+++ b/arch/x86_64/kernel/x8664_ksyms.c Tue Jun 18 19:12:01 2002
@@ -189,3 +189,5 @@
void out_of_line_bug(void);
EXPORT_SYMBOL(out_of_line_bug);
+
+EXPORT_SYMBOL(init_level4_pgt);
diff -Nru a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
--- a/arch/x86_64/lib/Makefile Tue Jun 18 19:12:01 2002
+++ b/arch/x86_64/lib/Makefile Tue Jun 18 19:12:01 2002
@@ -12,7 +12,7 @@
thunk.o io.o clear_page.o copy_page.o
obj-y += memcpy.o
obj-y += memmove.o
-#obj-y += memset.o
+obj-y += memset.o
obj-y += copy_user.o
export-objs := io.o csum-wrappers.o csum-partial.o
diff -Nru a/arch/x86_64/lib/memset.S b/arch/x86_64/lib/memset.S
--- a/arch/x86_64/lib/memset.S Tue Jun 18 19:12:02 2002
+++ b/arch/x86_64/lib/memset.S Tue Jun 18 19:12:02 2002
@@ -1,6 +1,4 @@
-/* Copyright 2002 Andi Kleen, SuSE Labs */
-
- // #define FIX_ALIGNMENT 1
+/* Copyright 2002 Andi Kleen */
/*
* ISO C memset - set a memory block to a byte value.
@@ -11,51 +9,51 @@
*
* rax original destination
*/
- .globl ____memset
+ .globl __memset
+ .globl memset
.p2align
-____memset:
- movq %rdi,%r10 /* save destination for return address */
- movq %rdx,%r11 /* save count */
+memset:
+__memset:
+ movq %rdi,%r10
+ movq %rdx,%r11
/* expand byte value */
- movzbl %sil,%ecx /* zero extend char value */
- movabs $0x0101010101010101,%rax /* expansion pattern */
- mul %rcx /* expand with rax, clobbers rdx */
+ movzbl %sil,%ecx
+ movabs $0x0101010101010101,%rax
+ mul %rcx /* with rax, clobbers rdx */
-#ifdef FIX_ALIGNMENT
/* align dst */
movl %edi,%r9d
- andl $7,%r9d /* test unaligned bits */
+ andl $7,%r9d
jnz bad_alignment
after_bad_alignment:
-#endif
- movq %r11,%rcx /* restore count */
- shrq $6,%rcx /* divide by 64 */
- jz handle_tail /* block smaller than 64 bytes? */
- movl $64,%r8d /* CSE loop block size */
+ movq %r11,%rcx
+ movl $64,%r8d
+ shrq $6,%rcx
+ jz handle_tail
loop_64:
- movnti %rax,0*8(%rdi)
- movnti %rax,1*8(%rdi)
- movnti %rax,2*8(%rdi)
- movnti %rax,3*8(%rdi)
- movnti %rax,4*8(%rdi)
- movnti %rax,5*8(%rdi)
- movnti %rax,6*8(%rdi)
- movnti %rax,7*8(%rdi) /* clear 64 byte blocks */
- addq %r8,%rdi /* increase pointer by 64 bytes */
- loop loop_64 /* decrement rcx and if not zero loop */
+ movnti %rax,(%rdi)
+ movnti %rax,8(%rdi)
+ movnti %rax,16(%rdi)
+ movnti %rax,24(%rdi)
+ movnti %rax,32(%rdi)
+ movnti %rax,40(%rdi)
+ movnti %rax,48(%rdi)
+ movnti %rax,56(%rdi)
+ addq %r8,%rdi
+ loop loop_64
/* Handle tail in loops. The loops should be faster than hard
to predict jump tables. */
handle_tail:
movl %r11d,%ecx
- andl $63,%ecx
- shrl $3,%ecx
+ andl $63&(~7),%ecx
jz handle_7
+ shrl $3,%ecx
loop_8:
- movnti %rax,(%rdi) /* long words */
+ movnti %rax,(%rdi)
addq $8,%rdi
loop loop_8
@@ -64,22 +62,20 @@
andl $7,%ecx
jz ende
loop_1:
- movb %al,(%rdi) /* bytes */
- incq %rdi
+ movb %al,(%rdi)
+ addq $1,%rdi
loop loop_1
ende:
movq %r10,%rax
ret
-#ifdef FIX_ALIGNMENT
bad_alignment:
- andq $-8,%r11 /* shorter than 8 bytes */
- jz handle_7 /* if yes handle it in the tail code */
- movnti %rax,(%rdi) /* unaligned store of 8 bytes */
+ cmpq $7,%r11
+ jbe handle_7
+ movnti %rax,(%rdi) /* unaligned store */
movq $8,%r8
- subq %r9,%r8 /* compute alignment (8-misalignment) */
- addq %r8,%rdi /* fix destination */
- subq %r8,%r11 /* fix count */
+ subq %r9,%r8
+ addq %r8,%rdi
+ subq %r8,%r11
jmp after_bad_alignment
-#endif
diff -Nru a/arch/x86_64/tools/Makefile b/arch/x86_64/tools/Makefile
--- a/arch/x86_64/tools/Makefile Tue Jun 18 19:12:01 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,29 +0,0 @@
-
-TARGET = $(TOPDIR)/include/asm-x86_64/offset.h
-
-all:
-
-mrproper:
-
-fastdep: $(TARGET)
-
-.PHONY: all
-
-$(TARGET): offset.h
- cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET))
-
-.PHONY : offset.h all modules modules_install
-
-offset.h: offset.sed offset.c FORCE
- $(CC) $(CFLAGS) -S -o offset.tmp offset.c
- sed -n -f offset.sed < offset.tmp > offset.h
-
-clean:
- rm -f offset.[hs] $(TARGET).new offset.tmp
-
-mrproper:
- rm -f offset.[hs] $(TARGET)
- rm -f $(TARGET)
-
-include $(TOPDIR)/Rules.make
-
diff -Nru a/arch/x86_64/tools/offset.c b/arch/x86_64/tools/offset.c
--- a/arch/x86_64/tools/offset.c Tue Jun 18 19:12:02 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,49 +0,0 @@
-/* Written 2000 by Andi Kleen */
-/* This program is never executed, just its assembly is examined for offsets
- (this trick is needed to get cross compiling right) */
-/* $Id: offset.c,v 1.13 2002/01/08 15:19:57 ak Exp $ */
-#define ASM_OFFSET_H 1
-#ifndef __KERNEL__
-#define __KERNEL__
-#endif
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define output(x) asm volatile ("--- " x)
-#define outconst(x,y) asm volatile ("--- " x : : "i" (y))
-
-int main(void)
-{
- output("/* Auto generated by arch/../tools/offset.c at " __DATE__ ". Do not edit. */\n");
- output("#ifndef ASM_OFFSET_H\n");
- output("#define ASM_OFFSET_H 1\n");
-
-#define ENTRY(entry) outconst("#define tsk_" #entry " %0", offsetof(struct task_struct, entry))
- ENTRY(state);
- ENTRY(flags);
- ENTRY(thread);
-#undef ENTRY
-#define ENTRY(entry) outconst("#define threadinfo_" #entry " %0", offsetof(struct thread_info, entry))
- ENTRY(flags);
- ENTRY(addr_limit);
- ENTRY(preempt_count);
-#undef ENTRY
-#define ENTRY(entry) outconst("#define pda_" #entry " %0", offsetof(struct x8664_pda, entry))
- ENTRY(kernelstack);
- ENTRY(oldrsp);
- ENTRY(pcurrent);
- ENTRY(irqrsp);
- ENTRY(irqcount);
- ENTRY(cpunumber);
- ENTRY(irqstackptr);
-#undef ENTRY
- output("#endif\n");
-
- return(0);
-}
diff -Nru a/arch/x86_64/tools/offset.sed b/arch/x86_64/tools/offset.sed
--- a/arch/x86_64/tools/offset.sed Tue Jun 18 19:12:01 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,7 +0,0 @@
-/---/ {
- s/---//
- s/\$//
- s/^ //
- s/^ //
- p
-}
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c Tue Jun 18 19:12:03 2002
+++ b/drivers/acpi/osl.c Tue Jun 18 19:12:03 2002
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include "acpi.h"
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c Tue Jun 18 19:12:02 2002
+++ b/drivers/acpi/processor.c Tue Jun 18 19:12:02 2002
@@ -2060,8 +2060,9 @@
return_VALUE(-EINVAL);
#ifdef CONFIG_SMP
- if (smp_num_cpus > 1)
- errata.smp = smp_num_cpus;
+ /* FIXME: What should this be? -- RR */
+ if (num_online_cpus() > 1)
+ errata.smp = num_online_cpus();
#endif
acpi_processor_errata(pr);
diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c
--- a/drivers/block/DAC960.c Tue Jun 18 19:12:03 2002
+++ b/drivers/block/DAC960.c Tue Jun 18 19:12:03 2002
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c Tue Jun 18 19:12:03 2002
+++ b/drivers/block/cciss.c Tue Jun 18 19:12:03 2002
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c Tue Jun 18 19:12:01 2002
+++ b/drivers/block/cpqarray.c Tue Jun 18 19:12:01 2002
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c Tue Jun 18 19:12:03 2002
+++ b/drivers/block/elevator.c Tue Jun 18 19:12:03 2002
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -424,3 +425,5 @@
EXPORT_SYMBOL(__elv_add_request);
EXPORT_SYMBOL(__elv_next_request);
EXPORT_SYMBOL(elv_remove_request);
+EXPORT_SYMBOL(elevator_exit);
+EXPORT_SYMBOL(elevator_init);
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c Tue Jun 18 19:12:01 2002
+++ b/drivers/block/floppy.c Tue Jun 18 19:12:01 2002
@@ -165,6 +165,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c Tue Jun 18 19:12:01 2002
+++ b/drivers/block/ll_rw_blk.c Tue Jun 18 19:12:01 2002
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -160,6 +161,7 @@
blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
init_waitqueue_head(&q->queue_wait);
+ INIT_LIST_HEAD(&q->plug_list);
}
/**
@@ -2002,8 +2004,8 @@
queue_nr_requests = (total_ram >> 8) & ~15; /* One per quarter-megabyte */
if (queue_nr_requests < 32)
queue_nr_requests = 32;
- if (queue_nr_requests > 512)
- queue_nr_requests = 512;
+ if (queue_nr_requests > 256)
+ queue_nr_requests = 256;
/*
* Batch frees according to queue length
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c Tue Jun 18 19:12:01 2002
+++ b/drivers/block/loop.c Tue Jun 18 19:12:01 2002
@@ -60,6 +60,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -168,6 +169,15 @@
}
+static inline int lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf,
+ char *lbuf, int size, int rblock)
+{
+ if (!lo->transfer)
+ return 0;
+
+ return lo->transfer(lo, cmd, rbuf, lbuf, size, rblock);
+}
+
static int
do_lo_send(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos)
{
@@ -454,20 +464,43 @@
out_bh:
bio->bi_sector = rbh->bi_sector + (lo->lo_offset >> 9);
bio->bi_rw = rbh->bi_rw;
- spin_lock_irq(&lo->lo_lock);
bio->bi_bdev = lo->lo_device;
- spin_unlock_irq(&lo->lo_lock);
return bio;
}
-static int loop_make_request(request_queue_t *q, struct bio *rbh)
+static int
+bio_transfer(struct loop_device *lo, struct bio *to_bio,
+ struct bio *from_bio)
+{
+ unsigned long IV = loop_get_iv(lo, from_bio->bi_sector);
+ struct bio_vec *from_bvec, *to_bvec;
+ char *vto, *vfrom;
+ int ret = 0, i;
+
+ __bio_for_each_segment(from_bvec, from_bio, i, 0) {
+ to_bvec = &to_bio->bi_io_vec[i];
+
+ kmap(from_bvec->bv_page);
+ kmap(to_bvec->bv_page);
+ vfrom = page_address(from_bvec->bv_page) + from_bvec->bv_offset;
+ vto = page_address(to_bvec->bv_page) + to_bvec->bv_offset;
+ ret |= lo_do_transfer(lo, bio_data_dir(to_bio), vto, vfrom,
+ from_bvec->bv_len, IV);
+ kunmap(from_bvec->bv_page);
+ kunmap(to_bvec->bv_page);
+ }
+
+ return ret;
+}
+
+static int loop_make_request(request_queue_t *q, struct bio *old_bio)
{
- struct bio *bh = NULL;
+ struct bio *new_bio = NULL;
struct loop_device *lo;
unsigned long IV;
- int rw = bio_rw(rbh);
- int unit = minor(to_kdev_t(rbh->bi_bdev->bd_dev));
+ int rw = bio_rw(old_bio);
+ int unit = minor(to_kdev_t(old_bio->bi_bdev->bd_dev));
if (unit >= max_loop)
goto out;
@@ -489,60 +522,41 @@
goto err;
}
- blk_queue_bounce(q, &rbh);
+ blk_queue_bounce(q, &old_bio);
/*
* file backed, queue for loop_thread to handle
*/
if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
- loop_add_bio(lo, rbh);
+ loop_add_bio(lo, old_bio);
return 0;
}
/*
* piggy old buffer on original, and submit for I/O
*/
- bh = loop_get_buffer(lo, rbh);
- IV = loop_get_iv(lo, rbh->bi_sector);
+ new_bio = loop_get_buffer(lo, old_bio);
+ IV = loop_get_iv(lo, old_bio->bi_sector);
if (rw == WRITE) {
- if (lo_do_transfer(lo, WRITE, bio_data(bh), bio_data(rbh),
- bh->bi_size, IV))
+ if (bio_transfer(lo, new_bio, old_bio))
goto err;
}
- generic_make_request(bh);
+ generic_make_request(new_bio);
return 0;
err:
if (atomic_dec_and_test(&lo->lo_pending))
up(&lo->lo_bh_mutex);
- loop_put_buffer(bh);
+ loop_put_buffer(new_bio);
out:
- bio_io_error(rbh);
+ bio_io_error(old_bio);
return 0;
inactive:
spin_unlock_irq(&lo->lo_lock);
goto out;
}
-static int do_bio_blockbacked(struct loop_device *lo, struct bio *bio,
- struct bio *rbh)
-{
- unsigned long IV = loop_get_iv(lo, rbh->bi_sector);
- struct bio_vec *from;
- char *vto, *vfrom;
- int ret = 0, i;
-
- bio_for_each_segment(from, rbh, i) {
- vfrom = page_address(from->bv_page) + from->bv_offset;
- vto = page_address(bio->bi_io_vec[i].bv_page) + bio->bi_io_vec[i].bv_offset;
- ret |= lo_do_transfer(lo, bio_data_dir(bio), vto, vfrom,
- from->bv_len, IV);
- }
-
- return ret;
-}
-
static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio)
{
int ret;
@@ -556,7 +570,7 @@
} else {
struct bio *rbh = bio->bi_private;
- ret = do_bio_blockbacked(lo, bio, rbh);
+ ret = bio_transfer(lo, bio, rbh);
bio_endio(rbh, !ret);
loop_put_buffer(bio);
@@ -588,10 +602,8 @@
set_user_nice(current, -20);
- spin_lock_irq(&lo->lo_lock);
lo->lo_state = Lo_bound;
atomic_inc(&lo->lo_pending);
- spin_unlock_irq(&lo->lo_lock);
/*
* up sem, we are running
diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c
--- a/drivers/block/nbd.c Tue Jun 18 19:12:02 2002
+++ b/drivers/block/nbd.c Tue Jun 18 19:12:02 2002
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c
--- a/drivers/block/rd.c Tue Jun 18 19:12:02 2002
+++ b/drivers/block/rd.c Tue Jun 18 19:12:02 2002
@@ -45,6 +45,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
diff -Nru a/drivers/block/umem.c b/drivers/block/umem.c
--- a/drivers/block/umem.c Tue Jun 18 19:12:02 2002
+++ b/drivers/block/umem.c Tue Jun 18 19:12:02 2002
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -128,6 +129,8 @@
*/
struct bio *bio, *currentbio, **biotail;
+ request_queue_t queue;
+
struct mm_page {
dma_addr_t page_dma;
struct mm_dma_desc *desc;
@@ -141,8 +144,6 @@
struct tasklet_struct tasklet;
unsigned int dma_status;
- struct tq_struct plug_tq;
-
struct {
int good;
int warned;
@@ -292,7 +293,7 @@
* Whenever IO on the active page completes, the Ready page is activated
* and the ex-Active page is clean out and made Ready.
* Otherwise the Ready page is only activated when it becomes full, or
- * when mm_unplug_device is called via run_task_queue(&tq_disk).
+ * when mm_unplug_device is called via blk_run_queues().
*
* If a request arrives while both pages a full, it is queued, and b_rdev is
* overloaded to record whether it was a read or a write.
@@ -340,8 +341,9 @@
offset = ((char*)desc) - ((char*)page->desc);
writel(cpu_to_le32((page->page_dma+offset)&0xffffffff),
card->csr_remap + DMA_DESCRIPTOR_ADDR);
- /* if sizeof(dma_addr_t) == 32, this will generate a warning, sorry */
- writel(cpu_to_le32((page->page_dma)>>32),
+ /* Force the value to u64 before shifting otherwise >> 32 is undefined C
+ * and on some ports will do nothing ! */
+ writel(cpu_to_le32(((u64)page->page_dma)>>32),
card->csr_remap + DMA_DESCRIPTOR_ADDR + 4);
/* Go, go, go */
@@ -383,10 +385,12 @@
static void mm_unplug_device(void *data)
{
- struct cardinfo *card = data;
+ request_queue_t *q = data;
+ struct cardinfo *card = q->queuedata;
spin_lock_bh(&card->lock);
- activate(card);
+ if (blk_remove_plug(q))
+ activate(card);
spin_unlock_bh(&card->lock);
}
@@ -564,8 +568,7 @@
*/
static int mm_make_request(request_queue_t *q, struct bio *bio)
{
- struct cardinfo *card = &cards[DEVICE_NR(
- bio->bi_bdev->bd_dev)];
+ struct cardinfo *card = q->queuedata;
PRINTK("mm_make_request %ld %d\n", bh->b_rsector, bh->b_size);
/* set uptodate now, and clear it if there are any errors */
@@ -575,9 +578,9 @@
*card->biotail = bio;
bio->bi_next = NULL;
card->biotail = &bio->bi_next;
+ blk_plug_device(q);
spin_unlock_bh(&card->lock);
- queue_task(&card->plug_tq, &tq_disk);
return 0;
}
@@ -1064,11 +1067,12 @@
card->bio = NULL;
card->biotail = &card->bio;
+ blk_queue_make_request(&card->queue, mm_make_request);
+ card->queue.queuedata = card;
+ card->queue.unplug_fn = mm_unplug_device;
+
tasklet_init(&card->tasklet, process_page, (unsigned long)card);
- card->plug_tq.sync = 0;
- card->plug_tq.routine = &mm_unplug_device;
- card->plug_tq.data = card;
card->check_batteries = 0;
mem_present = readb(card->csr_remap + MEMCTRLSTATUS_MEMORY);
@@ -1236,6 +1240,17 @@
-- mm_init
-----------------------------------------------------------------------------------
*/
+
+static request_queue_t * mm_queue_proc(kdev_t dev)
+{
+ int c = DEVICE_NR(kdev_val(dev));
+
+ if (c < MM_MAXCARDS)
+ return &cards[c].queue;
+ else
+ return BLK_DEFAULT_QUEUE(MAJOR_NR);
+}
+
int __init mm_init(void)
{
int retval, i;
@@ -1275,10 +1290,8 @@
mm_gendisk.part = mm_partitions;
mm_gendisk.nr_real = num_cards;
+ blk_dev[MAJOR_NR].queue = mm_queue_proc;
add_gendisk(&mm_gendisk);
-
- blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR),
- mm_make_request);
blk_size[MAJOR_NR] = mm_gendisk.sizes;
for (i = 0; i < num_cards; i++) {
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h Tue Jun 18 19:12:02 2002
+++ b/drivers/char/agp/agp.h Tue Jun 18 19:12:02 2002
@@ -118,8 +118,8 @@
int (*remove_memory) (agp_memory *, off_t, int);
agp_memory *(*alloc_by_type) (size_t, int);
void (*free_by_type) (agp_memory *);
- unsigned long (*agp_alloc_page) (void);
- void (*agp_destroy_page) (unsigned long);
+ void *(*agp_alloc_page) (void);
+ void (*agp_destroy_page) (void *);
int (*suspend)(void);
void (*resume)(void);
diff -Nru a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
--- a/drivers/char/agp/agpgart_be.c Tue Jun 18 19:12:01 2002
+++ b/drivers/char/agp/agpgart_be.c Tue Jun 18 19:12:01 2002
@@ -22,6 +22,8 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
+ * TODO:
+ * - Allocate more than order 0 pages to avoid too much linear map splitting.
*/
#include
#include
@@ -43,6 +45,7 @@
#include
#include
#include
+#include
#include
#include "agp.h"
@@ -59,56 +62,28 @@
EXPORT_SYMBOL(agp_backend_acquire);
EXPORT_SYMBOL(agp_backend_release);
-static void flush_cache(void);
-
static struct agp_bridge_data agp_bridge;
static int agp_try_unsupported __initdata = 0;
-
-static inline void flush_cache(void)
-{
-#if defined(__i386__) || defined(__x86_64__)
- asm volatile ("wbinvd":::"memory");
-#elif defined(__alpha__) || defined(__ia64__) || defined(__sparc__)
- /* ??? I wonder if we'll really need to flush caches, or if the
- core logic can manage to keep the system coherent. The ARM
- speaks only of using `cflush' to get things in memory in
- preparation for power failure.
-
- If we do need to call `cflush', we'll need a target page,
- as we can only flush one page at a time.
-
- Ditto for IA-64. --davidm 00/08/07 */
- mb();
-#else
-#error "Please define flush_cache."
-#endif
-}
-
#ifdef CONFIG_SMP
-static atomic_t cpus_waiting;
-
static void ipi_handler(void *null)
{
- flush_cache();
- atomic_dec(&cpus_waiting);
- while (atomic_read(&cpus_waiting) > 0)
- barrier();
+ flush_agp_cache();
}
static void smp_flush_cache(void)
{
- atomic_set(&cpus_waiting, smp_num_cpus - 1);
- if (smp_call_function(ipi_handler, NULL, 1, 0) != 0)
+ if (smp_call_function(ipi_handler, NULL, 1, 1) != 0)
panic(PFX "timed out waiting for the other CPUs!\n");
- flush_cache();
- while (atomic_read(&cpus_waiting) > 0)
- barrier();
+ flush_agp_cache();
}
#define global_cache_flush smp_flush_cache
#else /* CONFIG_SMP */
-#define global_cache_flush flush_cache
-#endif /* CONFIG_SMP */
+static void global_cache_flush(void)
+{
+ flush_agp_cache();
+}
+#endif /* !CONFIG_SMP */
int agp_backend_acquire(void)
{
@@ -208,8 +183,7 @@
if (curr->page_count != 0) {
for (i = 0; i < curr->page_count; i++) {
curr->memory[i] &= ~(0x00000fff);
- agp_bridge.agp_destroy_page((unsigned long)
- phys_to_virt(curr->memory[i]));
+ agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[i]));
}
}
agp_free_key(curr->key);
@@ -252,21 +226,22 @@
MOD_DEC_USE_COUNT;
return NULL;
}
+
for (i = 0; i < page_count; i++) {
- new->memory[i] = agp_bridge.agp_alloc_page();
+ void *addr = agp_bridge.agp_alloc_page();
- if (new->memory[i] == 0) {
+ if (addr == NULL) {
/* Free this structure */
agp_free_memory(new);
return NULL;
}
new->memory[i] =
- agp_bridge.mask_memory(
- virt_to_phys((void *) new->memory[i]),
- type);
+ agp_bridge.mask_memory(virt_to_phys(addr), type);
new->page_count++;
}
+ flush_agp_mappings();
+
return new;
}
@@ -561,6 +536,7 @@
agp_bridge.current_size;
break;
}
+ temp = agp_bridge.current_size;
} else {
agp_bridge.aperture_size_idx = i;
}
@@ -761,7 +737,7 @@
* against a maximum value.
*/
-static unsigned long agp_generic_alloc_page(void)
+static void *agp_generic_alloc_page(void)
{
struct page * page;
@@ -769,24 +745,26 @@
if (page == NULL)
return 0;
+ map_page_into_agp(page);
+
get_page(page);
SetPageLocked(page);
atomic_inc(&agp_bridge.current_memory_agp);
- return (unsigned long)page_address(page);
+ return page_address(page);
}
-static void agp_generic_destroy_page(unsigned long addr)
+static void agp_generic_destroy_page(void *addr)
{
- void *pt = (void *) addr;
struct page *page;
- if (pt == NULL)
+ if (addr == NULL)
return;
- page = virt_to_page(pt);
+ page = virt_to_page(addr);
+ unmap_page_from_agp(page);
put_page(page);
unlock_page(page);
- free_page((unsigned long) pt);
+ free_page((unsigned long)addr);
atomic_dec(&agp_bridge.current_memory_agp);
}
@@ -993,6 +971,7 @@
return new;
}
if(type == AGP_PHYS_MEMORY) {
+ void *addr;
/* The I810 requires a physical address to program
* it's mouse pointer into hardware. However the
* Xserver still writes to it through the agp
@@ -1007,17 +986,14 @@
return NULL;
}
MOD_INC_USE_COUNT;
- new->memory[0] = agp_bridge.agp_alloc_page();
+ addr = agp_bridge.agp_alloc_page();
- if (new->memory[0] == 0) {
+ if (addr == NULL) {
/* Free this structure */
agp_free_memory(new);
return NULL;
}
- new->memory[0] =
- agp_bridge.mask_memory(
- virt_to_phys((void *) new->memory[0]),
- type);
+ new->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr), type);
new->page_count = 1;
new->num_scratch_pages = 1;
new->type = AGP_PHYS_MEMORY;
@@ -1032,7 +1008,7 @@
{
agp_free_key(curr->key);
if(curr->type == AGP_PHYS_MEMORY) {
- agp_bridge.agp_destroy_page((unsigned long)
+ agp_bridge.agp_destroy_page(
phys_to_virt(curr->memory[0]));
vfree(curr->memory);
}
@@ -1291,7 +1267,7 @@
if (type == AGP_DCACHE_MEMORY) return(NULL);
if (type == AGP_PHYS_MEMORY) {
- unsigned long physical;
+ void *addr;
/* The i830 requires a physical address to program
* it's mouse pointer into hardware. However the
@@ -1306,19 +1282,18 @@
if (nw == NULL) return(NULL);
MOD_INC_USE_COUNT;
- nw->memory[0] = agp_bridge.agp_alloc_page();
- physical = nw->memory[0];
- if (nw->memory[0] == 0) {
+ addr = agp_bridge.agp_alloc_page();
+ if (addr == NULL) {
/* free this structure */
agp_free_memory(nw);
return(NULL);
}
- nw->memory[0] = agp_bridge.mask_memory(virt_to_phys((void *) nw->memory[0]),type);
+ nw->memory[0] = agp_bridge.mask_memory(virt_to_phys(addr),type);
nw->page_count = 1;
nw->num_scratch_pages = 1;
nw->type = AGP_PHYS_MEMORY;
- nw->physical = virt_to_phys((void *) physical);
+ nw->physical = virt_to_phys(addr);
return(nw);
}
@@ -1849,16 +1824,17 @@
* Let's just hope nobody counts on the allocated AGP memory being there
* before bind time (I don't think current drivers do)...
*/
-static unsigned long intel_i460_alloc_page(void)
+static void * intel_i460_alloc_page(void)
{
if (intel_i460_cpk)
return agp_generic_alloc_page();
/* Returning NULL would cause problems */
- return ~0UL;
+ /* AK: really dubious code. */
+ return (void *)~0UL;
}
-static void intel_i460_destroy_page(unsigned long page)
+static void intel_i460_destroy_page(void *page)
{
if (intel_i460_cpk)
agp_generic_destroy_page(page);
@@ -3298,38 +3274,29 @@
}
}
-static unsigned long ali_alloc_page(void)
+static void *ali_alloc_page(void)
{
- struct page *page;
- u32 temp;
+ void *adr = agp_generic_alloc_page();
+ unsigned temp;
- page = alloc_page(GFP_KERNEL);
- if (page == NULL)
+ if (adr == 0)
return 0;
- get_page(page);
- SetPageLocked(page);
- atomic_inc(&agp_bridge.current_memory_agp);
-
- global_cache_flush();
-
if (agp_bridge.type == ALI_M1541) {
pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp);
pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL,
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
- virt_to_phys(page_address(page))) |
+ virt_to_phys(adr)) |
ALI_CACHE_FLUSH_EN ));
}
- return (unsigned long)page_address(page);
+ return adr;
}
-static void ali_destroy_page(unsigned long addr)
+static void ali_destroy_page(void * addr)
{
u32 temp;
- void *pt = (void *) addr;
- struct page *page;
- if (pt == NULL)
+ if (addr == NULL)
return;
global_cache_flush();
@@ -3338,15 +3305,11 @@
pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp);
pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL,
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
- virt_to_phys((void *)pt)) |
+ virt_to_phys(addr)) |
ALI_CACHE_FLUSH_EN));
}
- page = virt_to_page(pt);
- put_page(page);
- unlock_page(page);
- free_page((unsigned long) pt);
- atomic_dec(&agp_bridge.current_memory_agp);
+ agp_generic_destroy_page(addr);
}
/* Setup function */
@@ -5011,15 +4974,15 @@
}
if (agp_bridge.needs_scratch_page == TRUE) {
- agp_bridge.scratch_page = agp_bridge.agp_alloc_page();
+ void *addr;
+ addr = agp_bridge.agp_alloc_page();
- if (agp_bridge.scratch_page == 0) {
+ if (addr == NULL) {
printk(KERN_ERR PFX "unable to get memory for "
"scratch page.\n");
return -ENOMEM;
}
- agp_bridge.scratch_page =
- virt_to_phys((void *) agp_bridge.scratch_page);
+ agp_bridge.scratch_page = virt_to_phys(addr);
agp_bridge.scratch_page =
agp_bridge.mask_memory(agp_bridge.scratch_page, 0);
}
@@ -5064,8 +5027,7 @@
err_out:
if (agp_bridge.needs_scratch_page == TRUE) {
agp_bridge.scratch_page &= ~(0x00000fff);
- agp_bridge.agp_destroy_page((unsigned long)
- phys_to_virt(agp_bridge.scratch_page));
+ agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page));
}
if (got_gatt)
agp_bridge.free_gatt_table();
@@ -5084,8 +5046,7 @@
if (agp_bridge.needs_scratch_page == TRUE) {
agp_bridge.scratch_page &= ~(0x00000fff);
- agp_bridge.agp_destroy_page((unsigned long)
- phys_to_virt(agp_bridge.scratch_page));
+ agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page));
}
}
diff -Nru a/drivers/char/random.c b/drivers/char/random.c
--- a/drivers/char/random.c Tue Jun 18 19:12:01 2002
+++ b/drivers/char/random.c Tue Jun 18 19:12:01 2002
@@ -252,6 +252,7 @@
#include
#include
#include
+#include
#include
#include
diff -Nru a/drivers/char/rio/func.h b/drivers/char/rio/func.h
--- a/drivers/char/rio/func.h Tue Jun 18 19:12:02 2002
+++ b/drivers/char/rio/func.h Tue Jun 18 19:12:02 2002
@@ -33,6 +33,8 @@
#ifndef __func_h_def
#define __func_h_def
+#include
+
#ifdef SCCS_LABELS
#ifndef lint
static char *_func_h_sccs_ = "@(#)func.h 1.3";
diff -Nru a/drivers/ide/ioctl.c b/drivers/ide/ioctl.c
--- a/drivers/ide/ioctl.c Tue Jun 18 19:12:02 2002
+++ b/drivers/ide/ioctl.c Tue Jun 18 19:12:02 2002
@@ -345,8 +345,9 @@
if (!arg) {
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
- else
- return 0;
+ /* Do nothing, just unlock */
+ spin_unlock_irq(drive->channel->lock);
+ return 0;
}
return do_cmd_ioctl(drive, arg);
diff -Nru a/drivers/ide/tcq.c b/drivers/ide/tcq.c
--- a/drivers/ide/tcq.c Tue Jun 18 19:12:03 2002
+++ b/drivers/ide/tcq.c Tue Jun 18 19:12:03 2002
@@ -175,13 +175,8 @@
tcq_invalidate_queue(drive);
}
-static void set_irq(struct ata_device *drive, ata_handler_t *handler)
+static void __set_irq(struct ata_channel *ch, ata_handler_t *handler)
{
- struct ata_channel *ch = drive->channel;
- unsigned long flags;
-
- spin_lock_irqsave(ch->lock, flags);
-
/*
* always just bump the timer for now, the timeout handling will
* have to be changed to be per-command
@@ -194,7 +189,15 @@
ch->timer.data = (unsigned long) ch->drive;
mod_timer(&ch->timer, jiffies + 5 * HZ);
ch->handler = handler;
+}
+
+static void set_irq(struct ata_device *drive, ata_handler_t *handler)
+{
+ struct ata_channel *ch = drive->channel;
+ unsigned long flags;
+ spin_lock_irqsave(ch->lock, flags);
+ __set_irq(ch, handler);
spin_unlock_irqrestore(ch->lock, flags);
}
@@ -230,8 +233,10 @@
*/
static ide_startstop_t service(struct ata_device *drive, struct request *rq)
{
- u8 feat;
- u8 stat;
+ struct ata_channel *ch = drive->channel;
+ ide_startstop_t ret;
+ unsigned long flags;
+ u8 feat, stat;
int tag;
TCQ_PRINTK("%s: started service\n", drive->name);
@@ -291,9 +296,12 @@
TCQ_PRINTK("%s: stat %x, feat %x\n", __FUNCTION__, stat, feat);
+ spin_lock_irqsave(ch->lock, flags);
+
rq = blk_queue_find_tag(&drive->queue, tag);
if (!rq) {
printk(KERN_ERR"%s: missing request for tag %d\n", __FUNCTION__, tag);
+ spin_unlock_irqrestore(ch->lock, flags);
return ide_stopped;
}
@@ -304,7 +312,10 @@
* interrupt to indicate end of transfer, release is not allowed
*/
TCQ_PRINTK("%s: starting command %x\n", __FUNCTION__, stat);
- return udma_tcq_start(drive, rq);
+
+ ret = udma_tcq_start(drive, rq);
+ spin_unlock_irqrestore(ch->lock, flags);
+ return ret;
}
static ide_startstop_t check_service(struct ata_device *drive, struct request *rq)
@@ -538,7 +549,7 @@
if (ata_start_dma(drive, rq))
return ide_stopped;
- set_irq(drive, ide_dmaq_intr);
+ __set_irq(ch, ide_dmaq_intr);
udma_start(drive, rq);
return ide_started;
@@ -590,7 +601,7 @@
if ((feat = GET_FEAT()) & NSEC_REL) {
drive->immed_rel++;
drive->rq = NULL;
- set_irq(drive, ide_dmaq_intr);
+ __set_irq(drive->channel, ide_dmaq_intr);
TCQ_PRINTK("REL in queued_start\n");
diff -Nru a/drivers/md/linear.c b/drivers/md/linear.c
--- a/drivers/md/linear.c Tue Jun 18 19:12:02 2002
+++ b/drivers/md/linear.c Tue Jun 18 19:12:02 2002
@@ -1,6 +1,6 @@
/*
linear.c : Multiple Devices driver for Linux
- Copyright (C) 1994-96 Marc ZYNGIER
+ Copyright (C) 1994-96 Marc ZYNGIER
or
@@ -20,7 +20,7 @@
#include
#include
-
+#include
#include
#define MAJOR_NR MD_MAJOR
@@ -33,39 +33,45 @@
linear_conf_t *conf;
struct linear_hash *table;
mdk_rdev_t *rdev;
- int size, i, j, nb_zone;
+ int size, i, nb_zone, cnt;
unsigned int curr_offset;
+ struct list_head *tmp;
MOD_INC_USE_COUNT;
conf = kmalloc (sizeof (*conf), GFP_KERNEL);
if (!conf)
goto out;
+ memset(conf, 0, sizeof(*conf));
mddev->private = conf;
- if (md_check_ordering(mddev)) {
- printk("linear: disks are not ordered, aborting!\n");
- goto out;
- }
/*
* Find the smallest device.
*/
conf->smallest = NULL;
- curr_offset = 0;
- ITERATE_RDEV_ORDERED(mddev,rdev,j) {
+ cnt = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ int j = rdev->sb->this_disk.raid_disk;
dev_info_t *disk = conf->disks + j;
+ if (j < 0 || j > mddev->sb->raid_disks || disk->bdev) {
+ printk("linear: disk numbering problem. Aborting!\n");
+ goto out;
+ }
+
disk->dev = rdev->dev;
disk->bdev = rdev->bdev;
atomic_inc(&rdev->bdev->bd_count);
disk->size = rdev->size;
- disk->offset = curr_offset;
-
- curr_offset += disk->size;
if (!conf->smallest || (disk->size < conf->smallest->size))
conf->smallest = disk;
+ cnt++;
+ }
+ if (cnt != mddev->sb->raid_disks) {
+ printk("linear: not enough drives present. Aborting!\n");
+ goto out;
}
nb_zone = conf->nr_zones =
@@ -81,10 +87,13 @@
* Here we generate the linear hash table
*/
table = conf->hash_table;
- i = 0;
size = 0;
- for (j = 0; j < mddev->nb_dev; j++) {
- dev_info_t *disk = conf->disks + j;
+ curr_offset = 0;
+ for (i = 0; i < cnt; i++) {
+ dev_info_t *disk = conf->disks + i;
+
+ disk->offset = curr_offset;
+ curr_offset += disk->size;
if (size < 0) {
table[-1].dev1 = disk;
@@ -130,12 +139,13 @@
return 0;
}
-static int linear_make_request (mddev_t *mddev, int rw, struct bio *bio)
+static int linear_make_request (request_queue_t *q, struct bio *bio)
{
- linear_conf_t *conf = mddev_to_conf(mddev);
- struct linear_hash *hash;
- dev_info_t *tmp_dev;
- long block;
+ mddev_t *mddev = q->queuedata;
+ linear_conf_t *conf = mddev_to_conf(mddev);
+ struct linear_hash *hash;
+ dev_info_t *tmp_dev;
+ long block;
block = bio->bi_sector >> 1;
hash = conf->hash_table + (block / conf->smallest->size);
@@ -186,7 +196,7 @@
}
sz += sprintf(page+sz, "\n");
#endif
- sz += sprintf(page+sz, " %dk rounding", mddev->param.chunk_size/1024);
+ sz += sprintf(page+sz, " %dk rounding", mddev->sb->chunk_size/1024);
return sz;
}
diff -Nru a/drivers/md/lvm-snap.c b/drivers/md/lvm-snap.c
--- a/drivers/md/lvm-snap.c Tue Jun 18 19:12:03 2002
+++ b/drivers/md/lvm-snap.c Tue Jun 18 19:12:03 2002
@@ -224,7 +224,7 @@
for (i = 0; i < nr; i++)
{
- bh = get_hash_table(dev, start++, blksize);
+ bh = find_get_block(dev, start++, blksize);
if (bh)
bforget(bh);
}
diff -Nru a/drivers/md/lvm.c b/drivers/md/lvm.c
--- a/drivers/md/lvm.c Tue Jun 18 19:12:02 2002
+++ b/drivers/md/lvm.c Tue Jun 18 19:12:02 2002
@@ -209,6 +209,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c Tue Jun 18 19:12:02 2002
+++ b/drivers/md/md.c Tue Jun 18 19:12:02 2002
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
@@ -106,7 +107,7 @@
* subsystems want to have a pre-defined structure
*/
struct hd_struct md_hd_struct[MAX_MD_DEVS];
-static int md_maxreadahead[MAX_MD_DEVS];
+static void md_recover_arrays(void);
static mdk_thread_t *md_recovery_thread;
int md_size[MAX_MD_DEVS];
@@ -128,93 +129,111 @@
/*
* Enables to iterate over all existing md arrays
+ * all_mddevs_lock protects this list as well as mddev_map.
*/
static LIST_HEAD(all_mddevs);
+static spinlock_t all_mddevs_lock = SPIN_LOCK_UNLOCKED;
+
/*
- * The mapping between kdev and mddev is not necessary a simple
- * one! Eg. HSM uses several sub-devices to implement Logical
- * Volumes. All these sub-devices map to the same mddev.
+ * iterates through all used mddevs in the system.
+ * We take care to grab the all_mddevs_lock whenever navigating
+ * the list, and to always hold a refcount when unlocked.
+ * Any code which breaks out of this loop while own
+ * a reference to the current mddev and must mddev_put it.
*/
-dev_mapping_t mddev_map[MAX_MD_DEVS];
-
-void add_mddev_mapping(mddev_t * mddev, kdev_t dev, void *data)
-{
- unsigned int minor = minor(dev);
+#define ITERATE_MDDEV(mddev,tmp) \
+ \
+ for (spin_lock(&all_mddevs_lock), \
+ (tmp = all_mddevs.next), \
+ (mddev = NULL); \
+ (void)(tmp != &all_mddevs && \
+ mddev_get(list_entry(tmp, mddev_t, all_mddevs))),\
+ spin_unlock(&all_mddevs_lock), \
+ (mddev ? mddev_put(mddev):(void)NULL), \
+ (mddev = list_entry(tmp, mddev_t, all_mddevs)), \
+ (tmp != &all_mddevs); \
+ spin_lock(&all_mddevs_lock), \
+ (tmp = tmp->next) \
+ )
- if (major(dev) != MD_MAJOR) {
- MD_BUG();
- return;
- }
- if (mddev_map[minor].mddev) {
- MD_BUG();
- return;
- }
- mddev_map[minor].mddev = mddev;
- mddev_map[minor].data = data;
-}
+static mddev_t *mddev_map[MAX_MD_DEVS];
-void del_mddev_mapping(mddev_t * mddev, kdev_t dev)
+static int md_fail_request (request_queue_t *q, struct bio *bio)
{
- unsigned int minor = minor(dev);
-
- if (major(dev) != MD_MAJOR) {
- MD_BUG();
- return;
- }
- if (mddev_map[minor].mddev != mddev) {
- MD_BUG();
- return;
- }
- mddev_map[minor].mddev = NULL;
- mddev_map[minor].data = NULL;
+ bio_io_error(bio);
+ return 0;
}
-static int md_make_request (request_queue_t *q, struct bio *bio)
+static inline mddev_t *mddev_get(mddev_t *mddev)
{
- mddev_t *mddev = kdev_to_mddev(to_kdev_t(bio->bi_bdev->bd_dev));
-
- if (mddev && mddev->pers)
- return mddev->pers->make_request(mddev, bio_rw(bio), bio);
- else {
- bio_io_error(bio);
- return 0;
- }
+ atomic_inc(&mddev->active);
+ return mddev;
}
-static mddev_t * alloc_mddev(kdev_t dev)
+static void mddev_put(mddev_t *mddev)
{
- mddev_t *mddev;
-
- if (major(dev) != MD_MAJOR) {
- MD_BUG();
- return 0;
+ if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
+ return;
+ if (!mddev->sb && list_empty(&mddev->disks)) {
+ list_del(&mddev->all_mddevs);
+ mddev_map[mdidx(mddev)] = NULL;
+ kfree(mddev);
+ MOD_DEC_USE_COUNT;
+ }
+ spin_unlock(&all_mddevs_lock);
+}
+
+static mddev_t * mddev_find(int unit)
+{
+ mddev_t *mddev, *new = NULL;
+
+ retry:
+ spin_lock(&all_mddevs_lock);
+ if (mddev_map[unit]) {
+ mddev = mddev_get(mddev_map[unit]);
+ spin_unlock(&all_mddevs_lock);
+ if (new)
+ kfree(new);
+ return mddev;
+ }
+ if (new) {
+ mddev_map[unit] = new;
+ list_add(&new->all_mddevs, &all_mddevs);
+ spin_unlock(&all_mddevs_lock);
+ MOD_INC_USE_COUNT;
+ return new;
}
- mddev = (mddev_t *) kmalloc(sizeof(*mddev), GFP_KERNEL);
- if (!mddev)
+ spin_unlock(&all_mddevs_lock);
+
+ new = (mddev_t *) kmalloc(sizeof(*new), GFP_KERNEL);
+ if (!new)
return NULL;
- memset(mddev, 0, sizeof(*mddev));
+ memset(new, 0, sizeof(*new));
- mddev->__minor = minor(dev);
- init_MUTEX(&mddev->reconfig_sem);
- init_MUTEX(&mddev->recovery_sem);
- init_MUTEX(&mddev->resync_sem);
- INIT_LIST_HEAD(&mddev->disks);
- INIT_LIST_HEAD(&mddev->all_mddevs);
- atomic_set(&mddev->active, 0);
+ new->__minor = unit;
+ init_MUTEX(&new->reconfig_sem);
+ INIT_LIST_HEAD(&new->disks);
+ INIT_LIST_HEAD(&new->all_mddevs);
+ atomic_set(&new->active, 1);
- /*
- * The 'base' mddev is the one with data NULL.
- * personalities can create additional mddevs
- * if necessary.
- */
- add_mddev_mapping(mddev, dev, 0);
- list_add(&mddev->all_mddevs, &all_mddevs);
+ goto retry;
+}
- MOD_INC_USE_COUNT;
+static inline int mddev_lock(mddev_t * mddev)
+{
+ return down_interruptible(&mddev->reconfig_sem);
+}
- return mddev;
+static inline int mddev_trylock(mddev_t * mddev)
+{
+ return down_trylock(&mddev->reconfig_sem);
+}
+
+static inline void mddev_unlock(mddev_t * mddev)
+{
+ up(&mddev->reconfig_sem);
}
mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
@@ -248,13 +267,12 @@
struct gendisk *hd;
static char nomem [] = "