From 0d6efc7fce3e85ea5e539919707956050122359d Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Mon, 20 Mar 2006 11:27:05 +0000 Subject: [PATCH 001/108] debian/rules: Also clean files from gencontrol in maintainerclean. svn path=/dists/trunk/linux-2.6/; revision=6233 --- debian/rules | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/rules b/debian/rules index fdc9c2deb..6ec8830d9 100755 --- a/debian/rules +++ b/debian/rules @@ -49,6 +49,7 @@ orig: ../orig/linux-$(MAJOR)-$(VERSION) fi maintainerclean: + -rm debian/control debian/control.md5sum debian/rules.gen rm -rf $(filter-out debian .svn, $(wildcard * .[^.]*)) clean: debian/control From 004e355d751fb89ba4ebc74d91985a211b498d4d Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Mon, 20 Mar 2006 11:58:24 +0000 Subject: [PATCH 002/108] debian/changelog: Update. svn path=/dists/trunk/linux-2.6/; revision=6234 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 758a7a572..4ec3da431 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low + + * + + -- Bastian Blank Mon, 20 Mar 2006 12:33:49 +0100 + linux-2.6 (2.6.16-1) UNRELEASED; urgency=low [ Bastian Blank ] From 79427c100c598487497310a80bb73aa125bf987e Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Mon, 20 Mar 2006 15:35:34 +0000 Subject: [PATCH 003/108] sync changed from dists/sid svn path=/dists/trunk/linux-2.6/; revision=6239 --- debian/arch/arm/config.footbridge | 14 +- debian/arch/arm/config.ixp4xx | 14 +- debian/arch/arm/config.nslu2 | 5 + debian/arch/arm/config.rpc | 12 +- debian/arch/arm/config.s3c2410 | 16 +- debian/arch/armeb/config | 1 + debian/arch/armeb/config.nslu2 | 15 +- debian/arch/mips/config.r4k-ip22 | 2 +- debian/arch/mips/config.r5k-ip32 | 2 +- debian/arch/mips/config.sb1-bcm91250a | 2 +- debian/arch/mips/config.sb1a-bcm91480b | 2 +- debian/arch/mipsel/config.sb1-bcm91250a | 2 +- debian/arch/mipsel/config.sb1a-bcm91480b | 2 +- debian/changelog | 2 + debian/patches/mips-gettimeofday.patch | 345 +++-------------------- debian/patches/mips-io-bad-code.patch | 59 ---- debian/patches/mips-sb1-irq-hazard.patch | 273 ------------------ debian/patches/series/1 | 6 +- debian/patches/series/1-extra | 8 +- 19 files changed, 111 insertions(+), 671 deletions(-) delete mode 100644 debian/patches/mips-io-bad-code.patch delete mode 100644 debian/patches/mips-sb1-irq-hazard.patch diff --git a/debian/arch/arm/config.footbridge b/debian/arch/arm/config.footbridge index 46a53bb75..460de62d9 100644 --- a/debian/arch/arm/config.footbridge +++ b/debian/arch/arm/config.footbridge @@ -448,6 +448,7 @@ CONFIG_IDEDISK_MULTI_MODE=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPNP is not set # CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_IDEDMA_AUTO is not set @@ -961,6 +962,11 @@ CONFIG_SENSORS_MAX6875=m # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + # # Hardware Monitoring support # @@ -1355,11 +1361,14 @@ CONFIG_CRAMFS=y # Network File Systems # CONFIG_NFS_FS=y -CONFIG_LOCKD=m +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=y CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set @@ -1491,6 +1500,7 @@ CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # # Cryptographic options # +CONFIG_CRYPTO_DES=y # # Hardware crypto devices diff --git a/debian/arch/arm/config.ixp4xx b/debian/arch/arm/config.ixp4xx index 10df5668f..61d5e11ba 100644 --- a/debian/arch/arm/config.ixp4xx +++ b/debian/arch/arm/config.ixp4xx @@ -83,6 +83,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y # # IXP4xx Platforms # +CONFIG_MACH_NSLU2=y # CONFIG_ARCH_AVILA is not set CONFIG_ARCH_ADI_COYOTE=y CONFIG_ARCH_IXDP425=y @@ -952,6 +953,11 @@ CONFIG_SENSORS_MAX6875=m # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + # # Hardware Monitoring support # @@ -1126,12 +1132,15 @@ CONFIG_JFFS2_RTIME=y # Network File Systems # CONFIG_NFS_FS=y -CONFIG_LOCKD=m +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m CONFIG_NFS_ACL_SUPPORT=y CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set @@ -1253,6 +1262,7 @@ CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # # Cryptographic options # +CONFIG_CRYPTO_DES=y # # Hardware crypto devices diff --git a/debian/arch/arm/config.nslu2 b/debian/arch/arm/config.nslu2 index 92c4575be..747f9e5f2 100644 --- a/debian/arch/arm/config.nslu2 +++ b/debian/arch/arm/config.nslu2 @@ -917,6 +917,11 @@ CONFIG_RTC_X1205_I2C=m # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + # # Hardware Monitoring support # diff --git a/debian/arch/arm/config.rpc b/debian/arch/arm/config.rpc index cfb07d036..f0bb08ef7 100644 --- a/debian/arch/arm/config.rpc +++ b/debian/arch/arm/config.rpc @@ -604,6 +604,11 @@ CONFIG_SENSORS_MAX6875=m # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + # # Hardware Monitoring support # @@ -846,11 +851,13 @@ CONFIG_ADFS_FS=y # Network File Systems # CONFIG_NFS_FS=y -CONFIG_LOCKD=m +CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=y CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set @@ -978,6 +985,7 @@ CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # # Cryptographic options # +CONFIG_CRYPTO_DES=y # # Hardware crypto devices diff --git a/debian/arch/arm/config.s3c2410 b/debian/arch/arm/config.s3c2410 index 6ea91ab05..31a2ae85a 100644 --- a/debian/arch/arm/config.s3c2410 +++ b/debian/arch/arm/config.s3c2410 @@ -714,6 +714,11 @@ CONFIG_SENSORS_MAX6875=m # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + # # Hardware Monitoring support # @@ -912,11 +917,15 @@ CONFIG_CRAMFS=y # # Network File Systems # -CONFIG_LOCKD=m +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=m -CONFIG_SUNRPC=m -# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set @@ -1040,6 +1049,7 @@ CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # # Cryptographic options # +CONFIG_CRYPTO_DES=y # # Hardware crypto devices diff --git a/debian/arch/armeb/config b/debian/arch/armeb/config index f2823c736..6808490dd 100644 --- a/debian/arch/armeb/config +++ b/debian/arch/armeb/config @@ -23,3 +23,4 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MACLIST is not set +# CONFIG_AEABI is not set diff --git a/debian/arch/armeb/config.nslu2 b/debian/arch/armeb/config.nslu2 index 4591737d9..747f9e5f2 100644 --- a/debian/arch/armeb/config.nslu2 +++ b/debian/arch/armeb/config.nslu2 @@ -44,9 +44,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_SLAB is not set # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set +CONFIG_SLOB=y CONFIG_OBSOLETE_INTERMODULE=y # @@ -141,7 +142,7 @@ CONFIG_CPU_TLB_V4WBI=y # Processor Features # # CONFIG_ARM_THUMB is not set -CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set CONFIG_XSCALE_PMU=y CONFIG_DMABOUNCE=y @@ -916,6 +917,11 @@ CONFIG_RTC_X1205_I2C=m # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_I2C_DEBUG_CHIP is not set +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + # # Hardware Monitoring support # @@ -1396,6 +1402,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -1468,10 +1475,10 @@ CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=y +CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y -CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y diff --git a/debian/arch/mips/config.r4k-ip22 b/debian/arch/mips/config.r4k-ip22 index 41d2c3119..8935f7bba 100644 --- a/debian/arch/mips/config.r4k-ip22 +++ b/debian/arch/mips/config.r4k-ip22 @@ -176,7 +176,7 @@ CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 +CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set # diff --git a/debian/arch/mips/config.r5k-ip32 b/debian/arch/mips/config.r5k-ip32 index 07cc59332..4a0bd6309 100644 --- a/debian/arch/mips/config.r5k-ip32 +++ b/debian/arch/mips/config.r5k-ip32 @@ -177,7 +177,7 @@ CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 +CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set # diff --git a/debian/arch/mips/config.sb1-bcm91250a b/debian/arch/mips/config.sb1-bcm91250a index aaa1f7160..0b02e75ef 100644 --- a/debian/arch/mips/config.sb1-bcm91250a +++ b/debian/arch/mips/config.sb1-bcm91250a @@ -191,7 +191,7 @@ CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 +CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set # diff --git a/debian/arch/mips/config.sb1a-bcm91480b b/debian/arch/mips/config.sb1a-bcm91480b index a240ef629..9095a59da 100644 --- a/debian/arch/mips/config.sb1a-bcm91480b +++ b/debian/arch/mips/config.sb1a-bcm91480b @@ -190,7 +190,7 @@ CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 +CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set # diff --git a/debian/arch/mipsel/config.sb1-bcm91250a b/debian/arch/mipsel/config.sb1-bcm91250a index a58f754d1..92e4fe17a 100644 --- a/debian/arch/mipsel/config.sb1-bcm91250a +++ b/debian/arch/mipsel/config.sb1-bcm91250a @@ -191,7 +191,7 @@ CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 +CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set # diff --git a/debian/arch/mipsel/config.sb1a-bcm91480b b/debian/arch/mipsel/config.sb1a-bcm91480b index 8cb20cfad..8b23d4723 100644 --- a/debian/arch/mipsel/config.sb1a-bcm91480b +++ b/debian/arch/mipsel/config.sb1a-bcm91480b @@ -190,7 +190,7 @@ CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 +CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set # diff --git a/debian/changelog b/debian/changelog index 4ec3da431..934522c29 100644 --- a/debian/changelog +++ b/debian/changelog @@ -24,6 +24,8 @@ linux-2.6 (2.6.16-1) UNRELEASED; urgency=low * [mips] SB1: DUART support (Broadcom). * [mips] Work around bad code generation for (Ralf Baechle). * [mips] Fix VINO drivers when using a 64-bit kernel (Mikael Nousiainen). + * [arm/armeb] Update configs for 2.6.16. + * [mips/mipsel] Update configs for 2.6.16. [ dann frazier ] * [ia64] use yaird on ia64 until #341181 is fixed diff --git a/debian/patches/mips-gettimeofday.patch b/debian/patches/mips-gettimeofday.patch index 9ded1118b..f5a0cbf08 100644 --- a/debian/patches/mips-gettimeofday.patch +++ b/debian/patches/mips-gettimeofday.patch @@ -1,329 +1,50 @@ -# DP: Fix for gettimeofday jumping backwards, then forwards. -# DP: Patch author: Dave Johnson -# DP: Upstream status: merged into linux-mips as 4 separate patches; -# one small fix (defined(CONFIG_SIBYTE_SB1250) || -# defined(CONFIG_SIBYTE_BCM112X for sb1250_hpt_setup) is missing in git +# DP: Avoid linker error on 1480 because sb1250_hpt_setup() is not defined +# DP: Patch author: Martin Michlmayr +# DP: Upstream status: not the ideal solution, but will work for now. Ralf +# Baechle will hopefully write a better fix, but this is needed for 2.6.16 +# to link on 1480. -From: Dave Johnson -[MIPS] Fix for gettimeofday jumping backwards, then forwards. +Date: Thu, 16 Mar 2006 14:11:27 +0000 +From: Martin Michlmayr +To: linux-mips@linux-mips.org +Subject: Re: [MIPS] Sibyte: Fix race in sb1250_gettimeoffset(). -Below are 2 fixes to do with time jumping around as reported by -gettimeofday(). One is SB1250 specific and one appears generic. +* linux-mips@linux-mips.org [2006-03-16 12:57]: +> Commit: 186326fa1e0360450b927ee5b21fb8db028fe7ba +> +> +void __init swarm_time_init(void) +> +{ +> + /* Setup HPT */ +> + sb1250_hpt_setup(); +> +} -The symptom is revealed by running multile copies (1 per cpu) of a -simple test program that calls gettimeofday() as fast as possible -looking for time to go backwards. +This leads to compiler errors on 1480 because sb1250_hpt_setup() is +not defined. We need something like the patch below (or possibly a +proper fix?): -When a jump is detected the program outputs a few samples before and -after each jump: -value delta -1121781527.912525: 1 -1121781527.912525: 0 -1121781527.912526: 1 -1121781527.912526: 0 -1121781527.912527: 1 -1121781527.912527: 0 -1121781527.912527: 0 -1121781527.912527: 0 -1121781527.911528: -999 -1121781527.911529: 1 -1121781527.911530: 1 -1121781527.912532: 1002 -1121781527.912533: 1 -1121781527.912533: 0 -1121781527.912534: 1 -1121781527.912534: 0 -1121781527.912535: 1 -1121781527.912536: 1 +[MIPS] don't call sb1250_hpt_setup on 1480 -value delta -1121781545.635524: 1 -1121781545.635524: 0 -1121781545.635525: 1 -1121781545.635525: 0 -1121781545.635526: 1 -1121781545.635526: 0 -1121781545.635527: 1 -1121781545.635527: 0 -1121781545.634527: -1000 -1121781545.635527: 1000 -1121781545.635528: 1 -1121781545.635529: 1 -1121781545.635529: 0 -1121781545.635530: 1 -1121781545.635530: 0 -1121781545.635531: 1 -1121781545.635531: 0 -1121781545.635532: 1 -1121781545.635533: 1 +sb1250_hpt_setup() should not be called on the 1480 board since it's +note defined there, leading to a linking error. -Time jumps backwards 1msec then forwards 1msec a few usec -later. Usually lasts < 2us but I've seen it as long as 5us if the -system is under load. - -First problem I found is that sb1250_gettimeoffset() simply reads the -current cpu 0 timer remaining value, however once this counter reaches -0 and the interrupt is raised, it immediately resets and begins to -count down again. - -If sb1250_gettimeoffset() is called on cpu 1 via do_gettimeofday() -after the timer has reset but prior to cpu 0 processing the interrupt -and taking write_seqlock() in timer_interrupt() it will return a -full value (or close to it) causing time to jump backwards 1ms. Once -cpu 0 handles the interrupt and timer_interrupt() gets far enough -along it will jump forward 1ms. - -To fix this problem I implemented mips_hpt_*() on sb1250 using a spare -timer unrelated to the existing periodic interrupt timers. It runs at -1Mhz with a full 23bit counter. This eliminated the custom -do_gettimeoffset() for sb1250 and allowed use of the generic -fixed_rate_gettimeoffset() using mips_hpt_*() and timerhi/timerlo. - -The second problem is that more of timer_interrupt() needs to be -protected by xtime_lock: - -* do_timer() expects the arch-specific handler to take the lock as it - modifies jiffies[_64] and xtime. -* writing timerhi/lo in timer_interrupt() will mess up - fixed_rate_gettimeoffset() which reads timerhi/lo. - -With both changes do_gettimeofday() works correctly on both cpu 0 and -cpu 1. - -Other changes/cleanups: - -The existing sb1250 periodic timers were slow by 999ppm (given a -perfect 100mhz reference). The timers need to be loaded with 1 less -than the desired interval not the interval itself. - -M_SCD_TIMER_INIT and M_SCD_TIMER_CNT had the wrong field width (should -be 23 bits not 20 bits) - -Signed-off-by: Dave Johnson Signed-off-by: Martin Michlmayr ---- - arch/mips/kernel/time.c | 6 +- - arch/mips/sibyte/sb1250/time.c | 77 ++++++++++++++++++++++++++--------- - arch/mips/sibyte/swarm/setup.c | 7 +++ - include/asm-mips/sibyte/sb1250.h | 2 - include/asm-mips/sibyte/sb1250_scd.h | 5 +- - 5 files changed, 73 insertions(+), 24 deletions(-) - - ---- a/arch/mips/kernel/time.c -+++ b/arch/mips/kernel/time.c -@@ -424,6 +424,8 @@ irqreturn_t timer_interrupt(int irq, voi - unsigned long j; - unsigned int count; - -+ write_seqlock(&xtime_lock); -+ - count = mips_hpt_read(); - mips_timer_ack(); - -@@ -441,7 +443,6 @@ irqreturn_t timer_interrupt(int irq, voi - * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be - * called as close as possible to 500 ms before the new second starts. - */ -- write_seqlock(&xtime_lock); - if (ntp_synced() && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && -@@ -453,7 +454,6 @@ irqreturn_t timer_interrupt(int irq, voi - last_rtc_update = xtime.tv_sec - 600; - } - } -- write_sequnlock(&xtime_lock); - - /* - * If jiffies has overflown in this timer_interrupt, we must -@@ -496,6 +496,8 @@ irqreturn_t timer_interrupt(int irq, voi - } - } - -+ write_sequnlock(&xtime_lock); -+ - /* - * In UP mode, we call local_timer_interrupt() to do profiling - * and process accouting. ---- a/arch/mips/sibyte/sb1250/time.c -+++ b/arch/mips/sibyte/sb1250/time.c -@@ -47,23 +47,51 @@ - #define IMR_IP3_VAL K_INT_MAP_I1 - #define IMR_IP4_VAL K_INT_MAP_I2 - -+#define SB1250_HPT_NUM 3 -+#define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ -+#define SB1250_HPT_SHIFT ((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH) -+ -+ - extern int sb1250_steal_irq(int irq); - -+static unsigned int sb1250_hpt_read(void); -+static void sb1250_hpt_init(unsigned int); -+ -+static unsigned int hpt_offset; -+ -+void __init sb1250_hpt_setup(void) -+{ -+ int cpu = smp_processor_id(); -+ -+ if (!cpu) { -+ /* Setup hpt using timer #3 but do not enable irq for it */ -+ __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); -+ __raw_writeq(SB1250_HPT_VALUE, -+ IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_INIT))); -+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, -+ IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); -+ -+ /* -+ * we need to fill 32 bits, so just use the upper 23 bits and pretend -+ * the timer is going 512Mhz instead of 1Mhz -+ */ -+ mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT; -+ mips_hpt_init = sb1250_hpt_init; -+ mips_hpt_read = sb1250_hpt_read; -+ } -+} -+ -+ - void sb1250_time_init(void) - { - int cpu = smp_processor_id(); - int irq = K_INT_TIMER_0+cpu; - -- /* Only have 4 general purpose timers */ -- if (cpu > 3) { -+ /* Only have 4 general purpose timers, and we use last one as hpt */ -+ if (cpu > 2) { - BUG(); - } - -- if (!cpu) { -- /* Use our own gettimeoffset() routine */ -- do_gettimeoffset = sb1250_gettimeoffset; -- } -- - sb1250_mask_irq(cpu, irq); - - /* Map the timer interrupt to ip[4] of this cpu */ -@@ -75,10 +103,10 @@ void sb1250_time_init(void) - /* Disable the timer and set up the count */ - __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); - #ifdef CONFIG_SIMULATION -- __raw_writeq(50000 / HZ, -+ __raw_writeq((50000 / HZ) - 1, - IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); - #else -- __raw_writeq(1000000 / HZ, -+ __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, - IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); - #endif - -@@ -103,7 +131,7 @@ void sb1250_timer_interrupt(struct pt_re - int cpu = smp_processor_id(); - int irq = K_INT_TIMER_0 + cpu; - -- /* Reset the timer */ -+ /* ACK interrupt */ - ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, - IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); - -@@ -122,15 +150,26 @@ void sb1250_timer_interrupt(struct pt_re - } - - /* -- * We use our own do_gettimeoffset() instead of the generic one, -- * because the generic one does not work for SMP case. -- * In addition, since we use general timer 0 for system time, -- * we can get accurate intra-jiffy offset without calibration. -+ * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over -+ * again. There's no easy way to set to a specific value so store init value -+ * in hpt_offset and subtract each time. -+ * -+ * Note: Timer isn't full 32bits so shift it into the upper part making -+ * it appear to run at a higher frequency. - */ --unsigned long sb1250_gettimeoffset(void) -+static unsigned int sb1250_hpt_read(void) - { -- unsigned long count = -- __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); -+ unsigned int count; - -- return 1000000/HZ - count; -- } -+ count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); -+ -+ count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT; -+ -+ return count - hpt_offset; -+} -+ -+static void sb1250_hpt_init(unsigned int count) -+{ -+ hpt_offset = count; -+ return; -+} +diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c +index b661d24..4a93f1d 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c -@@ -70,6 +70,14 @@ const char *get_system_type(void) - return "SiByte " SIBYTE_BOARD_NAME; +@@ -72,8 +72,10 @@ const char *get_system_type(void) + + void __init swarm_time_init(void) + { ++#if defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) + /* Setup HPT */ + sb1250_hpt_setup(); ++#endif } -+void __init swarm_time_init(void) -+{ -+#if defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) -+ /* Setup HPT */ -+ sb1250_hpt_setup(); -+#endif -+} -+ void __init swarm_timer_setup(struct irqaction *irq) - { - /* -@@ -109,6 +117,7 @@ void __init plat_setup(void) - - panic_timeout = 5; /* For debug. */ - -+ board_time_init = swarm_time_init; - board_timer_setup = swarm_timer_setup; - board_be_handler = swarm_be_handler; - ---- a/include/asm-mips/sibyte/sb1250.h -+++ b/include/asm-mips/sibyte/sb1250.h -@@ -45,8 +45,8 @@ extern unsigned int soc_type; - extern unsigned int periph_rev; - extern unsigned int zbbus_mhz; - -+extern void sb1250_hpt_setup(void); - extern void sb1250_time_init(void); --extern unsigned long sb1250_gettimeoffset(void); - extern void sb1250_mask_irq(int cpu, int irq); - extern void sb1250_unmask_irq(int cpu, int irq); - extern void sb1250_smp_finish(void); ---- a/include/asm-mips/sibyte/sb1250_scd.h -+++ b/include/asm-mips/sibyte/sb1250_scd.h -@@ -359,14 +359,15 @@ - */ - - #define V_SCD_TIMER_FREQ 1000000 -+#define V_SCD_TIMER_WIDTH 23 - - #define S_SCD_TIMER_INIT 0 --#define M_SCD_TIMER_INIT _SB_MAKEMASK(20,S_SCD_TIMER_INIT) -+#define M_SCD_TIMER_INIT _SB_MAKEMASK(V_SCD_TIMER_WIDTH,S_SCD_TIMER_INIT) - #define V_SCD_TIMER_INIT(x) _SB_MAKEVALUE(x,S_SCD_TIMER_INIT) - #define G_SCD_TIMER_INIT(x) _SB_GETVALUE(x,S_SCD_TIMER_INIT,M_SCD_TIMER_INIT) - - #define S_SCD_TIMER_CNT 0 --#define M_SCD_TIMER_CNT _SB_MAKEMASK(20,S_SCD_TIMER_CNT) -+#define M_SCD_TIMER_CNT _SB_MAKEMASK(V_SCD_TIMER_WIDTH,S_SCD_TIMER_CNT) - #define V_SCD_TIMER_CNT(x) _SB_MAKEVALUE(x,S_SCD_TIMER_CNT) - #define G_SCD_TIMER_CNT(x) _SB_GETVALUE(x,S_SCD_TIMER_CNT,M_SCD_TIMER_CNT) - diff --git a/debian/patches/mips-io-bad-code.patch b/debian/patches/mips-io-bad-code.patch deleted file mode 100644 index 3e03bf079..000000000 --- a/debian/patches/mips-io-bad-code.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: linux-mips@linux-mips.org -Date: Wed, 15 Mar 2006 11:28:15 +0000 -To: git-commits@linux-mips.org -Subject: [MIPS] Work around bad code generation for . - -Author: Ralf Baechle Wed Mar 15 11:36:31 2006 +0000 -Commit: 6a186683e0a3d51836b6ef6b971508861c7002b5 -Gitweb: http://www.linux-mips.org/g/linux/6a186683 -Branch: master - -If a call to set_io_port_base() was being followed by usage of -mips_io_port_base in the same function gcc was possibly using the old -value due to some clever abuse of const. Adding a barrier will keep -the optimization and result in correct code with latest gcc. - -Signed-off-by: Ralf Baechle - ---- - - include/asm-mips/io.h | 18 +++++++++++++++--- - 1 files changed, 15 insertions(+), 3 deletions(-) - -diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h -index 5c6d6ab..02995ad 100644 ---- a/include/asm-mips/io.h -+++ b/include/asm-mips/io.h -@@ -4,7 +4,7 @@ - * for more details. - * - * Copyright (C) 1994, 1995 Waldorf GmbH -- * Copyright (C) 1994 - 2000 Ralf Baechle -+ * Copyright (C) 1994 - 2000, 06 Ralf Baechle - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved. - * Author: Maciej W. Rozycki -@@ -103,8 +103,20 @@ - */ - extern const unsigned long mips_io_port_base; - --#define set_io_port_base(base) \ -- do { * (unsigned long *) &mips_io_port_base = (base); } while (0) -+/* -+ * Gcc will generate code to load the value of mips_io_port_base after each -+ * function call which may be fairly wasteful in some cases. So we don't -+ * play quite by the book. We tell gcc mips_io_port_base is a long variable -+ * which solves the code generation issue. Now we need to violate the -+ * aliasing rules a little to make initialization possible and finally we -+ * will need the barrier() to fight side effects of the aliasing chat. -+ * This trickery will eventually collapse under gcc's optimizer. Oh well. -+ */ -+static inline void set_io_port_base(unsigned long base) -+{ -+ * (unsigned long *) &mips_io_port_base = base; -+ barrier(); -+} - - /* - * Thanks to James van Artsdalen for a better timing-fix than - diff --git a/debian/patches/mips-sb1-irq-hazard.patch b/debian/patches/mips-sb1-irq-hazard.patch deleted file mode 100644 index e2e4ae252..000000000 --- a/debian/patches/mips-sb1-irq-hazard.patch +++ /dev/null @@ -1,273 +0,0 @@ -From: linux-mips@linux-mips.org -Date: Mon, 13 Mar 2006 16:07:47 +0000 -To: git-commits@linux-mips.org -Subject: [MIPS] SB1: Fix interrupt disable hazard. - -Author: Ralf Baechle Mon Mar 13 16:16:29 2006 +0000 -Commit: fa9e2c8227a0a770fbc748d35d0ec1d906c34614 -Gitweb: http://www.linux-mips.org/g/linux/fa9e2c82 -Branch: master - -The SB1 core has a three cycle interrupt disable hazard but we were -wrongly treating it as fully interlocked. - -Signed-off-by: Ralf Baechle - ---- - - include/asm-mips/hazards.h | 180 +++++++++++++++++++++++++------------------- - 1 files changed, 103 insertions(+), 77 deletions(-) - -diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h -index 6111a0c..feb29a7 100644 ---- a/include/asm-mips/hazards.h -+++ b/include/asm-mips/hazards.h -@@ -3,7 +3,9 @@ - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * -- * Copyright (C) 2003, 2004 Ralf Baechle -+ * Copyright (C) 2003, 2004 Ralf Baechle -+ * Copyright (C) MIPS Technologies, Inc. -+ * written by Ralf Baechle - */ - #ifndef _ASM_HAZARDS_H - #define _ASM_HAZARDS_H -@@ -74,8 +76,7 @@ - #define irq_disable_hazard - _ehb - --#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \ -- defined(CONFIG_CPU_SB1) -+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) - - /* - * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. -@@ -99,13 +100,13 @@ - #else /* __ASSEMBLY__ */ - - __asm__( -- " .macro _ssnop \n\t" -- " sll $0, $0, 1 \n\t" -- " .endm \n\t" -- " \n\t" -- " .macro _ehb \n\t" -- " sll $0, $0, 3 \n\t" -- " .endm \n\t"); -+ " .macro _ssnop \n" -+ " sll $0, $0, 1 \n" -+ " .endm \n" -+ " \n" -+ " .macro _ehb \n" -+ " sll $0, $0, 3 \n" -+ " .endm \n"); - - #ifdef CONFIG_CPU_RM9000 - -@@ -117,17 +118,21 @@ __asm__( - - #define mtc0_tlbw_hazard() \ - __asm__ __volatile__( \ -- ".set\tmips32\n\t" \ -- "_ssnop; _ssnop; _ssnop; _ssnop\n\t" \ -- ".set\tmips0") -+ " .set mips32 \n" \ -+ " _ssnop \n" \ -+ " _ssnop \n" \ -+ " _ssnop \n" \ -+ " _ssnop \n" \ -+ " .set mips0 \n") - - #define tlbw_use_hazard() \ - __asm__ __volatile__( \ -- ".set\tmips32\n\t" \ -- "_ssnop; _ssnop; _ssnop; _ssnop\n\t" \ -- ".set\tmips0") -- --#define back_to_back_c0_hazard() do { } while (0) -+ " .set mips32 \n" \ -+ " _ssnop \n" \ -+ " _ssnop \n" \ -+ " _ssnop \n" \ -+ " _ssnop \n" \ -+ " .set mips0 \n") - - #else - -@@ -136,15 +141,25 @@ __asm__( - */ - #define mtc0_tlbw_hazard() \ - __asm__ __volatile__( \ -- ".set noreorder\n\t" \ -- "nop; nop; nop; nop; nop; nop;\n\t" \ -- ".set reorder\n\t") -+ " .set noreorder \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " .set reorder \n") - - #define tlbw_use_hazard() \ - __asm__ __volatile__( \ -- ".set noreorder\n\t" \ -- "nop; nop; nop; nop; nop; nop;\n\t" \ -- ".set reorder\n\t") -+ " .set noreorder \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " nop \n" \ -+ " .set reorder \n") - - #endif - -@@ -156,49 +171,26 @@ __asm__( - - #ifdef CONFIG_CPU_MIPSR2 - --__asm__( -- " .macro\tirq_enable_hazard \n\t" -- " _ehb \n\t" -- " .endm \n\t" -- " \n\t" -- " .macro\tirq_disable_hazard \n\t" -- " _ehb \n\t" -- " .endm \n\t" -- " \n\t" -- " .macro\tback_to_back_c0_hazard \n\t" -- " _ehb \n\t" -- " .endm"); -- --#define irq_enable_hazard() \ -- __asm__ __volatile__( \ -- "irq_enable_hazard") -+__asm__(" .macro irq_enable_hazard \n" -+ " _ehb \n" -+ " .endm \n" -+ " \n" -+ " .macro irq_disable_hazard \n" -+ " _ehb \n" -+ " .endm \n"); - --#define irq_disable_hazard() \ -- __asm__ __volatile__( \ -- "irq_disable_hazard") -- --#define back_to_back_c0_hazard() \ -- __asm__ __volatile__( \ -- "back_to_back_c0_hazard") -- --#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \ -- defined(CONFIG_CPU_SB1) -+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) - - /* - * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. - */ - - __asm__( -- " .macro\tirq_enable_hazard \n\t" -- " .endm \n\t" -- " \n\t" -- " .macro\tirq_disable_hazard \n\t" -- " .endm"); -- --#define irq_enable_hazard() do { } while (0) --#define irq_disable_hazard() do { } while (0) -- --#define back_to_back_c0_hazard() do { } while (0) -+ " .macro irq_enable_hazard \n" -+ " .endm \n" -+ " \n" -+ " .macro irq_disable_hazard \n" -+ " .endm \n"); - - #else - -@@ -209,29 +201,63 @@ __asm__( - */ - - __asm__( -- " # \n\t" -- " # There is a hazard but we do not care \n\t" -- " # \n\t" -- " .macro\tirq_enable_hazard \n\t" -- " .endm \n\t" -- " \n\t" -- " .macro\tirq_disable_hazard \n\t" -- " _ssnop; _ssnop; _ssnop \n\t" -- " .endm"); -+ " # \n" -+ " # There is a hazard but we do not care \n" -+ " # \n" -+ " .macro\tirq_enable_hazard \n" -+ " .endm \n" -+ " \n" -+ " .macro\tirq_disable_hazard \n" -+ " _ssnop \n" -+ " _ssnop \n" -+ " _ssnop \n" -+ " .endm \n"); - --#define irq_enable_hazard() do { } while (0) -+#endif -+ -+#define irq_enable_hazard() \ -+ __asm__ __volatile__("irq_enable_hazard") - #define irq_disable_hazard() \ -- __asm__ __volatile__( \ -- "irq_disable_hazard") -+ __asm__ __volatile__("irq_disable_hazard") - --#define back_to_back_c0_hazard() \ -- __asm__ __volatile__( \ -- " .set noreorder \n" \ -- " nop; nop; nop \n" \ -- " .set reorder \n") -+ -+/* -+ * Back-to-back hazards - -+ * -+ * What is needed to separate a move to cp0 from a subsequent read from the -+ * same cp0 register? -+ */ -+#ifdef CONFIG_CPU_MIPSR2 -+ -+__asm__(" .macro back_to_back_c0_hazard \n" -+ " _ehb \n" -+ " .endm \n"); -+ -+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \ -+ defined(CONFIG_CPU_SB1) -+ -+__asm__(" .macro back_to_back_c0_hazard \n" -+ " .endm \n"); -+ -+#else -+ -+__asm__(" .macro back_to_back_c0_hazard \n" -+ " .set noreorder \n" -+ " _ssnop \n" -+ " _ssnop \n" -+ " _ssnop \n" -+ " .set reorder \n" -+ " .endm"); - - #endif - -+#define back_to_back_c0_hazard() \ -+ __asm__ __volatile__("back_to_back_c0_hazard") -+ -+ -+/* -+ * Instruction execution hazard -+ */ - #ifdef CONFIG_CPU_MIPSR2 - /* - * gcc has a tradition of misscompiling the previous construct using the - diff --git a/debian/patches/series/1 b/debian/patches/series/1 index 4cd504030..d6dbcc434 100644 --- a/debian/patches/series/1 +++ b/debian/patches/series/1 @@ -16,14 +16,12 @@ + sparc64-atyfb-xl-gr.patch + mips-makefile.patch + mips-arch-makefile.patch -#FIXME + mips-gettimeofday.patch -#FIXME + mips-ide-scan.patch ++ mips-gettimeofday.patch ++ mips-ide-scan.patch + mips-sb1-probe-ide.patch -#FIXME + mips-sb1-irq-hazard.patch + mips-sb1-eth-1480.patch + mips-sb1-eth-napi.patch + mips-sb1-duart.patch -#FIXME + mips-io-bad-code.patch + video-vino-64-bit-fix-kernel.diff + s390-drivers-ccw-uevent-modalias.patch + s390-drivers-ccw-uevent-cleanup.patch diff --git a/debian/patches/series/1-extra b/debian/patches/series/1-extra index 4053ee380..ed6de817d 100644 --- a/debian/patches/series/1-extra +++ b/debian/patches/series/1-extra @@ -1,8 +1,8 @@ -#+ maclist.patch arm armeb -#+ arm-nslu2-maclist.patch arm armeb ++ maclist.patch arm armeb ++ arm-nslu2-maclist.patch arm armeb + vserver-version.patch *_vserver *_xen-vserver + vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver + vserver-xen-clash.patch *_xen-vserver + xen-tree-merge-21966.patch *_xen *_xen-vserver -#+ mips-tulip.patch mipsel -#+ mips-tulip_dc21143.patch mipsel ++ mips-tulip.patch mipsel ++ mips-tulip_dc21143.patch mipsel From 87dbbda490a75832606cb7bfeaaaa18970bb7fac Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Mon, 20 Mar 2006 15:42:21 +0000 Subject: [PATCH 004/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6240 --- debian/arch/powerpc/config.powerpc64 | 1 + debian/arch/powerpc/vserver/config.powerpc64 | 1 + debian/lib/python/debian_linux/gencontrol.py | 2 +- debian/patches/s390-drivers-subchannel-fix.patch | 14 -------------- debian/patches/s390-scripts-modpost-ccw.patch | 15 --------------- debian/patches/series/1 | 1 - 6 files changed, 3 insertions(+), 31 deletions(-) delete mode 100644 debian/patches/s390-drivers-subchannel-fix.patch delete mode 100644 debian/patches/s390-scripts-modpost-ccw.patch diff --git a/debian/arch/powerpc/config.powerpc64 b/debian/arch/powerpc/config.powerpc64 index 01287d0fa..c2b408e64 100644 --- a/debian/arch/powerpc/config.powerpc64 +++ b/debian/arch/powerpc/config.powerpc64 @@ -108,3 +108,4 @@ CONFIG_KERNEL_START=0xc000000000000000 # CONFIG_IBMEBUS is not set CONFIG_SPU_FS=m CONFIG_SPIDER_NET=m +# CONFIG_LPARCFG is not set diff --git a/debian/arch/powerpc/vserver/config.powerpc64 b/debian/arch/powerpc/vserver/config.powerpc64 index 01287d0fa..c2b408e64 100644 --- a/debian/arch/powerpc/vserver/config.powerpc64 +++ b/debian/arch/powerpc/vserver/config.powerpc64 @@ -108,3 +108,4 @@ CONFIG_KERNEL_START=0xc000000000000000 # CONFIG_IBMEBUS is not set CONFIG_SPU_FS=m CONFIG_SPIDER_NET=m +# CONFIG_LPARCFG is not set diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index cd146f282..c36af6eea 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -105,7 +105,7 @@ class gencontrol(object): extra = {} makeflags['ARCH'] = arch - vars['localversion'] = vars['abiname'] + vars['localversion'] = '' self.do_arch_setup(vars, makeflags, arch) self.do_arch_makefile(makefile, arch, makeflags) diff --git a/debian/patches/s390-drivers-subchannel-fix.patch b/debian/patches/s390-drivers-subchannel-fix.patch deleted file mode 100644 index 14c574076..000000000 --- a/debian/patches/s390-drivers-subchannel-fix.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c -index 1bbf231..3c77d65 100644 ---- a/drivers/s390/cio/css.c -+++ b/drivers/s390/cio/css.c -@@ -409,6 +409,9 @@ __init_channel_subsystem(struct subchann - /* -ENXIO: no more subchannels. */ - case -ENXIO: - return ret; -+ /* -EIO: this subchannel set not supported. */ -+ case -EIO: -+ return ret; - default: - return 0; - } diff --git a/debian/patches/s390-scripts-modpost-ccw.patch b/debian/patches/s390-scripts-modpost-ccw.patch deleted file mode 100644 index c0e12bd26..000000000 --- a/debian/patches/s390-scripts-modpost-ccw.patch +++ /dev/null @@ -1,15 +0,0 @@ -## Upstream status: Commited as de1d9c033f32ce39bf60e25be3b8624225fa9181 - -diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c -index be97caf..c164b23 100644 ---- a/scripts/mod/file2alias.c -+++ b/scripts/mod/file2alias.c -@@ -246,7 +246,7 @@ static int do_ccw_entry(const char *file - id->cu_model); - ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, - id->dev_type); -- ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, -+ ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, - id->dev_model); - return 1; - } diff --git a/debian/patches/series/1 b/debian/patches/series/1 index d6dbcc434..1d0bde7ee 100644 --- a/debian/patches/series/1 +++ b/debian/patches/series/1 @@ -25,4 +25,3 @@ + video-vino-64-bit-fix-kernel.diff + s390-drivers-ccw-uevent-modalias.patch + s390-drivers-ccw-uevent-cleanup.patch -#FIXME + s390-drivers-subchannel-fix.patch From 0dfef16d4fb2e216fe38c9698daf80300f744fe4 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Mon, 20 Mar 2006 15:55:13 +0000 Subject: [PATCH 005/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6242 --- debian/patches/scripts-newmake.patch | 30 ++++++++++++++++++++++++++++ debian/patches/series/1 | 1 + 2 files changed, 31 insertions(+) create mode 100644 debian/patches/scripts-newmake.patch diff --git a/debian/patches/scripts-newmake.patch b/debian/patches/scripts-newmake.patch new file mode 100644 index 000000000..309b802d7 --- /dev/null +++ b/debian/patches/scripts-newmake.patch @@ -0,0 +1,30 @@ +diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include +index 0168d6c..d774b0e 100644 +--- a/scripts/Kbuild.include ++++ b/scripts/Kbuild.include +@@ -79,7 +79,7 @@ echo-cmd = $(if $($(quiet)cmd_$(1)), \ + # >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file + # note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars + # +-if_changed = $(if $(strip $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ ++if_changed = $(if $(strip $(filter-out FORCE, $?) $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ + @set -e; \ + $(echo-cmd) \ + $(cmd_$(1)); \ +@@ -87,7 +87,7 @@ if_changed = $(if $(strip $? $(call arg- + + # execute the command and also postprocess generated .d dependencies + # file +-if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\ ++if_changed_dep = $(if $(strip $(filter-out FORCE, $?) $(filter-out FORCE $(wildcard $^),$^)\ + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ + @set -e; \ + $(echo-cmd) \ +@@ -99,6 +99,6 @@ if_changed_dep = $(if $(strip $? $(filte + # 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 $? $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ ++if_changed_rule = $(if $(strip $(filter-out FORCE, $?) $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ + @set -e; \ + $(rule_$(1))) diff --git a/debian/patches/series/1 b/debian/patches/series/1 index 1d0bde7ee..ef27d3df4 100644 --- a/debian/patches/series/1 +++ b/debian/patches/series/1 @@ -25,3 +25,4 @@ + video-vino-64-bit-fix-kernel.diff + s390-drivers-ccw-uevent-modalias.patch + s390-drivers-ccw-uevent-cleanup.patch ++ scripts-newmake.patch From 740cca25a86e94af27f727ed5a6c66a97a28c39c Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Tue, 21 Mar 2006 22:48:04 +0000 Subject: [PATCH 006/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6257 --- debian/README.build | 2 +- debian/arch/arm/config.nslu2 | 3 ++- debian/arch/armeb/config.nslu2 | 3 ++- debian/arch/hppa/config | 2 ++ debian/arch/ia64/config | 13 ++++++++++- debian/arch/mipsel/config.r5k-cobalt | 28 ++++++++++++++++++++++-- debian/arch/mipsel/config.sb1-bcm91250a | 11 +++++----- debian/arch/mipsel/config.sb1a-bcm91480b | 11 +++++----- debian/changelog | 19 +++++++++++++--- 9 files changed, 73 insertions(+), 19 deletions(-) diff --git a/debian/README.build b/debian/README.build index 968520ed6..df088537e 100644 --- a/debian/README.build +++ b/debian/README.build @@ -2,7 +2,7 @@ Building kernels from SVN (for official images): 1) Start by downloading a kernel tarball from kernel.org (ie, linux-2.6.12.tar.bz2). -2) Run trunk/scripts/prune-non-free . This will produce two +2) Run trunk/scripts/prune-non-free . This will produce two additional tarballs; linux-kernel-.orig.tar.gz and linux-kernel-nonfree-.orig.tar.gz. Ignore the nonfree tarball for now. diff --git a/debian/arch/arm/config.nslu2 b/debian/arch/arm/config.nslu2 index 747f9e5f2..e84f0b234 100644 --- a/debian/arch/arm/config.nslu2 +++ b/debian/arch/arm/config.nslu2 @@ -1377,7 +1377,8 @@ CONFIG_LOCKD_V4=y CONFIG_SUNRPC=m # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set diff --git a/debian/arch/armeb/config.nslu2 b/debian/arch/armeb/config.nslu2 index 747f9e5f2..e84f0b234 100644 --- a/debian/arch/armeb/config.nslu2 +++ b/debian/arch/armeb/config.nslu2 @@ -1377,7 +1377,8 @@ CONFIG_LOCKD_V4=y CONFIG_SUNRPC=m # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set diff --git a/debian/arch/hppa/config b/debian/arch/hppa/config index b602c8df3..9997c6ab7 100644 --- a/debian/arch/hppa/config +++ b/debian/arch/hppa/config @@ -502,6 +502,7 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y @@ -801,6 +802,7 @@ CONFIG_ZLIB_DEFLATE=m CONFIG_SND_HWDEP=m CONFIG_NFS_ACL_SUPPORT=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_F71805F is not set # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set diff --git a/debian/arch/ia64/config b/debian/arch/ia64/config index c50260186..71fdc9921 100644 --- a/debian/arch/ia64/config +++ b/debian/arch/ia64/config @@ -171,7 +171,9 @@ CONFIG_PARPORT_PC_PCMCIA=m CONFIG_PARPORT_NOT_PC=y # CONFIG_PARPORT_GSC is not set CONFIG_PARPORT_1284=y -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set +CONFIG_PNPACPI=y CONFIG_PARIDE=m CONFIG_PARIDE_PARPORT=m CONFIG_PARIDE_PD=m @@ -211,6 +213,7 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8 # CONFIG_CDROM_PKTCDVD_WCACHE is not set CONFIG_ATA_OVER_ETH=m CONFIG_IDE=m +CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=m # CONFIG_BLK_DEV_IDE_SATA is not set CONFIG_BLK_DEV_IDEDISK=m @@ -451,6 +454,7 @@ CONFIG_BT_HCIBLUECARD=m CONFIG_BT_HCIBTUART=m CONFIG_BT_HCIVHCI=m CONFIG_DUMMY=m +CONFIG_NET_SB1000=m CONFIG_ARCNET=m CONFIG_ARCNET_1201=m CONFIG_ARCNET_1051=m @@ -657,8 +661,10 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_SERIAL_NONSTANDARD=y +CONFIG_COMPUTONE=m CONFIG_ROCKETPORT=m # CONFIG_CYCLADES is not set +CONFIG_MOXA_INTELLIO=m # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set CONFIG_SYNCLINKMP=m @@ -675,6 +681,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m CONFIG_SERIAL_8250_ACPI=y CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set @@ -684,6 +691,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_SGI_L1_CONSOLE=y CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_SGI_IOC3=m CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 CONFIG_PRINTER=m @@ -754,6 +762,7 @@ CONFIG_SENSORS_ADM1026=m CONFIG_SENSORS_ADM1031=m CONFIG_SENSORS_ASB100=m CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_FSCHER=m CONFIG_SENSORS_FSCPOS=m CONFIG_SENSORS_GL518SM=m @@ -1113,6 +1122,7 @@ CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_AIRPRIME=m CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m CONFIG_USB_SERIAL_CP2101=m CONFIG_USB_SERIAL_CYPRESS_M8=m @@ -1158,6 +1168,7 @@ CONFIG_INFINIBAND_MTHCA=m # CONFIG_INFINIBAND_MTHCA_DEBUG is not set CONFIG_INFINIBAND_IPOIB=m # CONFIG_INFINIBAND_IPOIB_DEBUG is not set +CONFIG_SGI_IOC3=m CONFIG_JBD=m CONFIG_FS_MBCACHE=m CONFIG_TMPFS_XATTR=y diff --git a/debian/arch/mipsel/config.r5k-cobalt b/debian/arch/mipsel/config.r5k-cobalt index f48cefdb9..0524de7e0 100644 --- a/debian/arch/mipsel/config.r5k-cobalt +++ b/debian/arch/mipsel/config.r5k-cobalt @@ -479,7 +479,13 @@ CONFIG_FW_LOADER=m # # Parallel port support # -# CONFIG_PARPORT is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_SUPERIO=y +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y # # Plug and Play support @@ -488,6 +494,7 @@ CONFIG_FW_LOADER=m # # Block devices # +# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -645,6 +652,8 @@ CONFIG_SCSI_FUTURE_DOMAIN=m CONFIG_SCSI_IPS=m CONFIG_SCSI_INITIO=m CONFIG_SCSI_INIA100=m +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set CONFIG_SCSI_SYM53C8XX_2=m CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 @@ -775,6 +784,7 @@ CONFIG_SUNDANCE=m CONFIG_VIA_RHINE=m # CONFIG_VIA_RHINE_MMIO is not set # CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) @@ -848,6 +858,7 @@ CONFIG_NET_WIRELESS=y # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set +CONFIG_PLIP=m CONFIG_PPP=m CONFIG_PPP_MULTILINK=y CONFIG_PPP_FILTER=y @@ -921,6 +932,7 @@ CONFIG_INPUT_UINPUT=m CONFIG_SERIO=m CONFIG_SERIO_I8042=m CONFIG_SERIO_SERPORT=m +# CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set @@ -949,6 +961,9 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set # # IPMI @@ -992,6 +1007,7 @@ CONFIG_SPI_MASTER=y # SPI Master Controller Drivers # CONFIG_SPI_BITBANG=m +# CONFIG_SPI_BUTTERFLY is not set # # SPI Protocol Masters @@ -1029,6 +1045,9 @@ CONFIG_VIDEO_DEV=m # Video Adapters # # CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_STRADIS is not set # CONFIG_VIDEO_MXB is not set @@ -1284,6 +1303,7 @@ CONFIG_USB_MON=y # # USB port drivers # +# CONFIG_USB_USS720 is not set # # USB Serial Converter support @@ -1383,7 +1403,11 @@ CONFIG_REISERFS_FS=m CONFIG_REISERFS_FS_XATTR=y # CONFIG_REISERFS_FS_POSIX_ACL is not set # CONFIG_REISERFS_FS_SECURITY is not set -# CONFIG_JFS_FS is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m CONFIG_XFS_EXPORT=y diff --git a/debian/arch/mipsel/config.sb1-bcm91250a b/debian/arch/mipsel/config.sb1-bcm91250a index 92e4fe17a..07837fa9d 100644 --- a/debian/arch/mipsel/config.sb1-bcm91250a +++ b/debian/arch/mipsel/config.sb1-bcm91250a @@ -737,12 +737,12 @@ CONFIG_SCSI_DEBUG=m # Multi-device support (RAID and LVM) # CONFIG_MD=y -CONFIG_BLK_DEV_MD=y +CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=y -CONFIG_MD_RAID1=y +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m -CONFIG_MD_RAID5=y +CONFIG_MD_RAID5=m CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m @@ -751,7 +751,8 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m -# CONFIG_DM_MULTIPATH is not set +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_MULTIPATH_EMC is not set # # Fusion MPT device support diff --git a/debian/arch/mipsel/config.sb1a-bcm91480b b/debian/arch/mipsel/config.sb1a-bcm91480b index 8b23d4723..3a07413e0 100644 --- a/debian/arch/mipsel/config.sb1a-bcm91480b +++ b/debian/arch/mipsel/config.sb1a-bcm91480b @@ -738,12 +738,12 @@ CONFIG_SCSI_DEBUG=m # Multi-device support (RAID and LVM) # CONFIG_MD=y -CONFIG_BLK_DEV_MD=y +CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=y -CONFIG_MD_RAID1=y +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m -CONFIG_MD_RAID5=y +CONFIG_MD_RAID5=m CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m @@ -752,7 +752,8 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m -# CONFIG_DM_MULTIPATH is not set +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_MULTIPATH_EMC is not set # # Fusion MPT device support diff --git a/debian/changelog b/debian/changelog index 934522c29..ae114d56a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,7 +4,15 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- Bastian Blank Mon, 20 Mar 2006 12:33:49 +0100 -linux-2.6 (2.6.16-1) UNRELEASED; urgency=low +linux-2.6 (2.6.16-2) UNRELEASED; urgency=low + + * [ia64] Set unconfigured options: + CONFIG_PNP_DEBUG=n and CONFIG_NET_SB1000=m + * [hppa] Update config for 2.6.16 + + -- dann frazier Tue, 21 Mar 2006 15:31:07 -0700 + +linux-2.6 (2.6.16-1) unstable; urgency=low [ Bastian Blank ] * New upstream release. @@ -26,11 +34,16 @@ linux-2.6 (2.6.16-1) UNRELEASED; urgency=low * [mips] Fix VINO drivers when using a 64-bit kernel (Mikael Nousiainen). * [arm/armeb] Update configs for 2.6.16. * [mips/mipsel] Update configs for 2.6.16. + * [arm/armeb] Enable the SMB module on NSLU2. + * [mipsel] Enable parallel port modules for Cobalt since there are PCI + cards that can be used in a Qube. + * [mipsel] Enable the JFS module on Cobalt. [ dann frazier ] - * [ia64] use yaird on ia64 until #341181 is fixed + * [ia64] use yaird on ia64 until #357414 is fixed + * [ia64] Update configs for 2.6.16 - -- Bastian Blank Thu, 16 Mar 2006 19:24:30 +0100 + -- Bastian Blank Tue, 21 Mar 2006 16:12:16 +0100 linux-2.6 (2.6.15+2.6.16-rc5-0experimental.1) experimental; urgency=low From 03043880f69bbdeb0918b2c0c5685a5c8fa3806a Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Tue, 21 Mar 2006 22:58:38 +0000 Subject: [PATCH 007/108] * debian/arch/i386/defines: Enable xen-vserver subarch. * debian/arch/i386/xen-vserver: New directory. * debian/arch/i386/xen-vserver/config, debian/arch/i386/xen-vserver/config.686, debian/arch/i386/xen-vserver/defines: Add. svn path=/dists/trunk/linux-2.6/; revision=6258 --- debian/arch/i386/defines | 1 + debian/arch/i386/xen-vserver/config | 48 +++++++++++++++++ debian/arch/i386/xen-vserver/config.686 | 71 +++++++++++++++++++++++++ debian/arch/i386/xen-vserver/defines | 12 +++++ 4 files changed, 132 insertions(+) create mode 100644 debian/arch/i386/xen-vserver/config create mode 100644 debian/arch/i386/xen-vserver/config.686 create mode 100644 debian/arch/i386/xen-vserver/defines diff --git a/debian/arch/i386/defines b/debian/arch/i386/defines index cdfe6e3cf..169936b82 100644 --- a/debian/arch/i386/defines +++ b/debian/arch/i386/defines @@ -10,6 +10,7 @@ kernel-header-dirs: i386 subarches: vserver xen + xen-vserver [image] suggests: grub | lilo (>= 19.1) diff --git a/debian/arch/i386/xen-vserver/config b/debian/arch/i386/xen-vserver/config new file mode 100644 index 000000000..ec23b6431 --- /dev/null +++ b/debian/arch/i386/xen-vserver/config @@ -0,0 +1,48 @@ +# CONFIG_X86_PC is not set +CONFIG_X86_XEN=y +CONFIG_XEN_PCIDEV_FRONTEND=y +# CONFIG_XEN_PCIDEV_FE_DEBUG is not set +CONFIG_XEN_PRIVILEGED_GUEST=y +CONFIG_XEN_PCIDEV_BACKEND=y +CONFIG_XEN_PCIDEV_BACKEND_VPCI=y +# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set +# CONFIG_XEN_PCIDEV_BE_DEBUG is not set +CONFIG_XEN_BLKDEV_BACKEND=y +# CONFIG_XEN_BLKDEV_TAP_BE is not set +CONFIG_XEN_NETDEV_BACKEND=y +# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set +# CONFIG_XEN_TPMDEV_BACKEND is not set +CONFIG_XEN_BLKDEV_FRONTEND=y +CONFIG_XEN_NETDEV_FRONTEND=y +# CONFIG_XEN_BLKDEV_TAP is not set +CONFIG_XEN_NETDEV_LOOPBACK=y +# CONFIG_XEN_TPMDEV_FRONTEND is not set +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XEN_DISABLE_SERIAL=y +# CONFIG_SMP_ALTERNATIVES is not set +# CONFIG_PCI_GOXEN_FE is not set +CONFIG_VSERVER=y +CONFIG_VSERVER_SECURITY=y +CONFIG_VSERVER_LEGACYNET=y +CONFIG_VSERVER_LEGACY=y +# CONFIG_VSERVER_LEGACY_VERSION is not set +CONFIG_VSERVER_DYNAMIC_IDS=y +# CONFIG_VSERVER_NGNET is not set +CONFIG_VSERVER_COWBL=y +CONFIG_VSERVER_PROC_SECURE=y +# CONFIG_VSERVER_HARDCPU is not set +# CONFIG_INOXID_NONE is not set +# CONFIG_INOXID_UID16 is not set +# CONFIG_INOXID_GID16 is not set +CONFIG_INOXID_UGID24=y +# CONFIG_INOXID_INTERN is not set +# CONFIG_INOXID_RUNTIME is not set +# CONFIG_XID_TAG_NFSD is not set +# CONFIG_XID_PROPAGATE is not set +# CONFIG_VSERVER_DEBUG is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_25G is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_15G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_BLK_DEV_VROOT=y diff --git a/debian/arch/i386/xen-vserver/config.686 b/debian/arch/i386/xen-vserver/config.686 new file mode 100644 index 000000000..a24aa9bb1 --- /dev/null +++ b/debian/arch/i386/xen-vserver/config.686 @@ -0,0 +1,71 @@ +CONFIG_LOCK_KERNEL=y +# CONFIG_CPUSETS is not set +CONFIG_STOP_MACHINE=y +# CONFIG_M386 is not set +CONFIG_M686=y +# CONFIG_MK7 is not set +# CONFIG_X86_GENERIC is not set +CONFIG_X86_CMPXCHG=y +CONFIG_X86_XADD=y +CONFIG_X86_L1_CACHE_SHIFT=5 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_X86_PPRO_FENCE=y +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_INVLPG=y +CONFIG_X86_BSWAP=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_GOOD_APIC=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_SMP=y +CONFIG_NR_CPUS=8 +CONFIG_SCHED_SMT=y +CONFIG_X86_TSC=y +CONFIG_X86_MCE=y +CONFIG_X86_MCE_NONFATAL=m +CONFIG_X86_MCE_P4THERMAL=y +# CONFIG_NOHIGHMEM is not set +CONFIG_HIGHMEM4G=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_IRQBALANCE is not set +CONFIG_HAVE_DEC_LOCK=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_EISA is not set +# CONFIG_MCA is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_SBPCD is not set +# CONFIG_CM206 is not set +# CONFIG_CDU31A is not set +# CONFIG_DMASCC is not set +# CONFIG_IRPORT_SIR is not set +# CONFIG_NI5010 is not set +# CONFIG_PCMCIA_XIRTULIP is not set +# CONFIG_ISDN_DRV_LOOP is not set +# CONFIG_HYSDN is not set +# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set +# CONFIG_ISDN_DRV_AVMB1_B1PCI is not set +# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set +# CONFIG_ISDN_DRV_AVMB1_B1PCMCIA is not set +# CONFIG_ISDN_DRV_AVMB1_T1PCI is not set +# CONFIG_ISDN_DRV_AVMB1_C4 is not set +# CONFIG_COMPUTONE is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALLION is not set +# CONFIG_ISTALLION is not set +# CONFIG_FTAPE is not set +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_STUB=m +# CONFIG_USB_W9968CF is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +CONFIG_FS_MBCACHE=m +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_X86_SMP=y +CONFIG_X86_HT=y +CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_CMPXCHG64=y +# CONFIG_M486 is not set diff --git a/debian/arch/i386/xen-vserver/defines b/debian/arch/i386/xen-vserver/defines new file mode 100644 index 000000000..4418ac830 --- /dev/null +++ b/debian/arch/i386/xen-vserver/defines @@ -0,0 +1,12 @@ +[base] +flavours: + 686 + +[image] +type: plain-xen + +[686] +class: PPro/Celeron/PII/PIII/P4 +longclass: Pentium Pro/Celeron/Pentium II/Pentium III/Pentium 4 +recommends: libc6-i686 + From 7cf3027ca7715eaf3e2e466b187dde0e3137ee48 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 22 Mar 2006 16:57:50 +0000 Subject: [PATCH 008/108] debian/rules.real: Use correct abiname for xen images. svn path=/dists/trunk/linux-2.6/; revision=6264 --- debian/rules.real | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules.real b/debian/rules.real index 14c607074..8c88734d8 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -155,7 +155,7 @@ $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: $(BUILD_DIR)/config rm -rf '$(DIR)' cp -al '$(SOURCE_DIR)' '$(DIR)' cp '$<' '$(DIR)/.config' - echo '$(KPKG_ABINAME)$(LOCALVERSION)' > '$(DIR)/localversion' + echo '$(ABINAME)$(LOCALVERSION)' > '$(DIR)/localversion' cd '$(DIR)'; $(setup_env) make prepare ARCH=$(KERNEL_ARCH) $(JOBS_ARG) touch '$@' From e4bd48571bf4f95619709b875a3a89d7d1203b6b Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 22 Mar 2006 17:49:41 +0000 Subject: [PATCH 009/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6265 --- debian/arch/arm/config.ixp4xx | 1 + debian/arch/mips/config | 1 + debian/arch/mips/config.r4k-ip22 | 7 ------- debian/arch/mips/config.r5k-ip32 | 7 ------- debian/arch/mips/config.sb1-bcm91250a | 7 ------- debian/arch/mips/config.sb1a-bcm91480b | 7 ------- debian/arch/mipsel/config | 1 + debian/arch/mipsel/config.r5k-cobalt | 9 +-------- debian/arch/mipsel/config.sb1-bcm91250a | 7 ------- debian/arch/mipsel/config.sb1a-bcm91480b | 7 ------- debian/changelog | 14 ++++++++++++-- 11 files changed, 16 insertions(+), 52 deletions(-) diff --git a/debian/arch/arm/config.ixp4xx b/debian/arch/arm/config.ixp4xx index 61d5e11ba..e049e26ab 100644 --- a/debian/arch/arm/config.ixp4xx +++ b/debian/arch/arm/config.ixp4xx @@ -652,6 +652,7 @@ CONFIG_CICADA_PHY=m # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +CONFIG_MACLIST=y CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set diff --git a/debian/arch/mips/config b/debian/arch/mips/config index e69de29bb..a1b333ca5 100644 --- a/debian/arch/mips/config +++ b/debian/arch/mips/config @@ -0,0 +1 @@ +CONFIG_MIPS=y diff --git a/debian/arch/mips/config.r4k-ip22 b/debian/arch/mips/config.r4k-ip22 index 8935f7bba..d12fd04e4 100644 --- a/debian/arch/mips/config.r4k-ip22 +++ b/debian/arch/mips/config.r4k-ip22 @@ -1,10 +1,3 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc5 -# Thu Mar 2 14:53:47 2006 -# -CONFIG_MIPS=y - # # Machine selection # diff --git a/debian/arch/mips/config.r5k-ip32 b/debian/arch/mips/config.r5k-ip32 index 4a0bd6309..4bc55ed4a 100644 --- a/debian/arch/mips/config.r5k-ip32 +++ b/debian/arch/mips/config.r5k-ip32 @@ -1,10 +1,3 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc5 -# Thu Mar 2 14:54:35 2006 -# -CONFIG_MIPS=y - # # Machine selection # diff --git a/debian/arch/mips/config.sb1-bcm91250a b/debian/arch/mips/config.sb1-bcm91250a index 0b02e75ef..ea3567c88 100644 --- a/debian/arch/mips/config.sb1-bcm91250a +++ b/debian/arch/mips/config.sb1-bcm91250a @@ -1,10 +1,3 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc5 -# Thu Mar 2 14:54:52 2006 -# -CONFIG_MIPS=y - # # Machine selection # diff --git a/debian/arch/mips/config.sb1a-bcm91480b b/debian/arch/mips/config.sb1a-bcm91480b index 9095a59da..15badc17d 100644 --- a/debian/arch/mips/config.sb1a-bcm91480b +++ b/debian/arch/mips/config.sb1a-bcm91480b @@ -1,10 +1,3 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc5 -# Thu Mar 2 14:54:52 2006 -# -CONFIG_MIPS=y - # # Machine selection # diff --git a/debian/arch/mipsel/config b/debian/arch/mipsel/config index e69de29bb..a1b333ca5 100644 --- a/debian/arch/mipsel/config +++ b/debian/arch/mipsel/config @@ -0,0 +1 @@ +CONFIG_MIPS=y diff --git a/debian/arch/mipsel/config.r5k-cobalt b/debian/arch/mipsel/config.r5k-cobalt index 0524de7e0..b722a7654 100644 --- a/debian/arch/mipsel/config.r5k-cobalt +++ b/debian/arch/mipsel/config.r5k-cobalt @@ -1,10 +1,3 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc5 -# Thu Mar 2 14:58:35 2006 -# -CONFIG_MIPS=y - # # Machine selection # @@ -236,7 +229,7 @@ CONFIG_NET=y # Networking options # # CONFIG_NETDEBUG is not set -CONFIG_PACKET=m +CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y diff --git a/debian/arch/mipsel/config.sb1-bcm91250a b/debian/arch/mipsel/config.sb1-bcm91250a index 07837fa9d..18f182a74 100644 --- a/debian/arch/mipsel/config.sb1-bcm91250a +++ b/debian/arch/mipsel/config.sb1-bcm91250a @@ -1,10 +1,3 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc5 -# Thu Mar 2 14:55:46 2006 -# -CONFIG_MIPS=y - # # Machine selection # diff --git a/debian/arch/mipsel/config.sb1a-bcm91480b b/debian/arch/mipsel/config.sb1a-bcm91480b index 3a07413e0..ac228384c 100644 --- a/debian/arch/mipsel/config.sb1a-bcm91480b +++ b/debian/arch/mipsel/config.sb1a-bcm91480b @@ -1,10 +1,3 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc5 -# Thu Mar 2 14:55:46 2006 -# -CONFIG_MIPS=y - # # Machine selection # diff --git a/debian/changelog b/debian/changelog index ae114d56a..f24cf9594 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,13 +4,23 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- Bastian Blank Mon, 20 Mar 2006 12:33:49 +0100 -linux-2.6 (2.6.16-2) UNRELEASED; urgency=low +linux-2.6 (2.6.16-2) unstable; urgency=low + [ dann frazier ] * [ia64] Set unconfigured options: CONFIG_PNP_DEBUG=n and CONFIG_NET_SB1000=m * [hppa] Update config for 2.6.16 - -- dann frazier Tue, 21 Mar 2006 15:31:07 -0700 + [ Martin Michlmayr ] + * [mips/mipsel] Put something in the generic config file because diff + will otherwise remove the empty file, causing the build to fail. + * [mipsel/r5k-cobalt] Set CONFIG_PACKET=y. + * [arm] Set CONFIG_MACLIST=y for ixp4xx because nas100d needs it. + + [ Frederik Schüler ] + * Add Maximilian Attems to uploaders list. + + -- Martin Michlmayr Wed, 22 Mar 2006 15:15:14 +0000 linux-2.6 (2.6.16-1) unstable; urgency=low From 4623737a378380d09d9add4be87cd4ab880b3a40 Mon Sep 17 00:00:00 2001 From: Jonas Smedegaard Date: Thu, 23 Mar 2006 11:27:14 +0000 Subject: [PATCH 010/108] Tighten yaird dependency to at least 0.0.12-8 (expected to reach etch tonight). svn path=/dists/trunk/linux-2.6/; revision=6268 --- debian/arch/defines | 2 +- debian/changelog | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/debian/arch/defines b/debian/arch/defines index 789d92153..f59c6ff23 100644 --- a/debian/arch/defines +++ b/debian/arch/defines @@ -30,5 +30,5 @@ gcc: gcc (>= 4:4.0) gcc-3.3: gcc-3.3 initramfs-fallback: linux-initramfs-tool initramfs-tools: initramfs-tools (>= 0.53) -yaird: yaird +yaird: yaird (>= 0.0.12-8) diff --git a/debian/changelog b/debian/changelog index f24cf9594..e0a3710b9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,14 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low + [ Bastian Blank ] * - -- Bastian Blank Mon, 20 Mar 2006 12:33:49 +0100 + [ Jonas Smedegaard ] + * Tighten yaird dependency to at least 0.0.12-8 (supporting + Linux 2.6.16 uppercase hex in Kconfig and new IDE sysfs naming, and + VIA IDE on powerpc). + + -- Jonas Smedegaard Thu, 23 Mar 2006 12:23:22 +0100 linux-2.6 (2.6.16-2) unstable; urgency=low From c4d6fda5c330d405f5a4664a303d4f8fe47cab80 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Thu, 23 Mar 2006 20:29:02 +0000 Subject: [PATCH 011/108] * debian/patches/series/99experimental.1-extra: Add xen-tls.patch. * debian/patches/xen-tls.patch: Add. svn path=/dists/trunk/linux-2.6/; revision=6271 --- debian/patches/series/99experimental.1-extra | 1 + debian/patches/xen-tls.patch | 24 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 debian/patches/series/99experimental.1-extra create mode 100644 debian/patches/xen-tls.patch diff --git a/debian/patches/series/99experimental.1-extra b/debian/patches/series/99experimental.1-extra new file mode 100644 index 000000000..0bc1bcd37 --- /dev/null +++ b/debian/patches/series/99experimental.1-extra @@ -0,0 +1 @@ ++ xen-tls.patch *_xen *_xen-vserver diff --git a/debian/patches/xen-tls.patch b/debian/patches/xen-tls.patch new file mode 100644 index 000000000..978ba0bae --- /dev/null +++ b/debian/patches/xen-tls.patch @@ -0,0 +1,24 @@ +diff --git a/arch/i386/kernel/fixup.c b/arch/i386/kernel/fixup.c +index 5188b23..d506a65 100644 +--- a/arch/i386/kernel/fixup.c ++++ b/arch/i386/kernel/fixup.c +@@ -39,7 +39,7 @@ + + fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code) + { +- static unsigned long printed = 0; ++ static unsigned long printed = 1; + char info[100]; + int i; + +diff --git a/arch/i386/kernel/vsyscall-note-xen.S b/arch/i386/kernel/vsyscall-note-xen.S +index c2d6dbf..019d9af 100644 +--- a/arch/i386/kernel/vsyscall-note-xen.S ++++ b/arch/i386/kernel/vsyscall-note-xen.S +@@ -28,5 +28,5 @@ + #define NOTE_KERNELCAP_END ASM_ELF_NOTE_END + + NOTE_KERNELCAP_BEGIN(1, 1) +-NOTE_KERNELCAP(1, "nosegneg") /* Change 1 back to 0 when glibc is fixed! */ ++NOTE_KERNELCAP(0, "nosegneg") + NOTE_KERNELCAP_END From 5151ffc57c50df520b5c2c25297e76ecb22e4e56 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Thu, 23 Mar 2006 20:40:54 +0000 Subject: [PATCH 012/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6272 --- debian/arch/amd64/defines | 2 +- debian/changelog | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/debian/arch/amd64/defines b/debian/arch/amd64/defines index 0957b3287..1f3cea6f5 100644 --- a/debian/arch/amd64/defines +++ b/debian/arch/amd64/defines @@ -6,7 +6,7 @@ flavours: em64t-p4 em64t-p4-smp kernel-arch: x86_64 -kernel-header-dirs: x86_64 +kernel-header-dirs: x86_64 i386 subarches: vserver xen diff --git a/debian/changelog b/debian/changelog index e0a3710b9..04813f449 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,14 +1,20 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low - [ Bastian Blank ] * - [ Jonas Smedegaard ] - * Tighten yaird dependency to at least 0.0.12-8 (supporting - Linux 2.6.16 uppercase hex in Kconfig and new IDE sysfs naming, and - VIA IDE on powerpc). + -- Bastian Blank Thu, 23 Mar 2006 21:40:17 +0100 - -- Jonas Smedegaard Thu, 23 Mar 2006 12:23:22 +0100 +linux-2.6 (2.6.16-3) UNRELEASED; urgency=low + + [ Frederik Schüler ] + * [amd64] Add asm-i386 to the linux-headers packages. + + [ Jonas Smedegaard ] + * Tighten yaird dependency to at least 0.0.12-8 (supporting Linux + 2.6.16 uppercase hex in Kconfig and new IDE sysfs naming, and VIA + IDE on powerpc). + + -- Frederik Schüler Thu, 23 Mar 2006 18:47:46 +0100 linux-2.6 (2.6.16-2) unstable; urgency=low From 741ad3c4f6dfe57bb4ddd39d19cf61e9da22376a Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 26 Mar 2006 18:37:44 +0000 Subject: [PATCH 013/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6287 --- debian/arch/arm/config | 1 - debian/arch/arm/config.footbridge | 2 +- debian/arch/arm/config.nslu2 | 14 +++++- debian/arch/armeb/config | 1 - debian/arch/armeb/config.nslu2 | 16 +++++-- debian/changelog | 10 ++++- debian/lib/python/debian_linux/gencontrol.py | 1 + debian/patches/series/3-extra | 1 + .../patches/vserver-vs2.0.2-rc14-update.patch | 44 +++++++++++++++++++ debian/templates/control.main.in | 5 +-- 10 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 debian/patches/series/3-extra create mode 100644 debian/patches/vserver-vs2.0.2-rc14-update.patch diff --git a/debian/arch/arm/config b/debian/arch/arm/config index 6808490dd..983204118 100644 --- a/debian/arch/arm/config +++ b/debian/arch/arm/config @@ -2,7 +2,6 @@ CONFIG_ARM=y # CONFIG_CIFS_EXPERIMENTAL is not set CONFIG_SLIP_SMART=y CONFIG_SUNRPC_GSS=m -# CONFIG_NFSD_V4 is not set # CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CODA_FS_OLD_API is not set CONFIG_CIFS_STATS=y diff --git a/debian/arch/arm/config.footbridge b/debian/arch/arm/config.footbridge index 460de62d9..02a36f465 100644 --- a/debian/arch/arm/config.footbridge +++ b/debian/arch/arm/config.footbridge @@ -663,7 +663,7 @@ CONFIG_NET_PCI=y # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set -CONFIG_NE2K_PCI=y +CONFIG_NE2K_PCI=m # CONFIG_8139CP is not set # CONFIG_8139TOO is not set # CONFIG_SIS900 is not set diff --git a/debian/arch/arm/config.nslu2 b/debian/arch/arm/config.nslu2 index e84f0b234..d6992a6e9 100644 --- a/debian/arch/arm/config.nslu2 +++ b/debian/arch/arm/config.nslu2 @@ -1369,14 +1369,24 @@ CONFIG_CRAMFS=y # # Network File Systems # +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_LOCKD=m CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m CONFIG_SUNRPC=m -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set diff --git a/debian/arch/armeb/config b/debian/arch/armeb/config index 6808490dd..983204118 100644 --- a/debian/arch/armeb/config +++ b/debian/arch/armeb/config @@ -2,7 +2,6 @@ CONFIG_ARM=y # CONFIG_CIFS_EXPERIMENTAL is not set CONFIG_SLIP_SMART=y CONFIG_SUNRPC_GSS=m -# CONFIG_NFSD_V4 is not set # CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CODA_FS_OLD_API is not set CONFIG_CIFS_STATS=y diff --git a/debian/arch/armeb/config.nslu2 b/debian/arch/armeb/config.nslu2 index e84f0b234..73f5accde 100644 --- a/debian/arch/armeb/config.nslu2 +++ b/debian/arch/armeb/config.nslu2 @@ -142,7 +142,7 @@ CONFIG_CPU_TLB_V4WBI=y # Processor Features # # CONFIG_ARM_THUMB is not set -# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_BIG_ENDIAN=y CONFIG_XSCALE_PMU=y CONFIG_DMABOUNCE=y @@ -1369,14 +1369,24 @@ CONFIG_CRAMFS=y # # Network File Systems # +CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_LOCKD=m CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=m CONFIG_SUNRPC=m -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set diff --git a/debian/changelog b/debian/changelog index 04813f449..8999c43d9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -14,7 +14,15 @@ linux-2.6 (2.6.16-3) UNRELEASED; urgency=low 2.6.16 uppercase hex in Kconfig and new IDE sysfs naming, and VIA IDE on powerpc). - -- Frederik Schüler Thu, 23 Mar 2006 18:47:46 +0100 + [ Martin Michlmayr ] + * [arm/armeb] Enable CONFIG_NFSD on NSLU2 again. Closes: #358709. + * [arm/footbridge] CONFIG_NE2K_PCI should be a module, not built-in. + + [ Bastian Blank ] + * Update vserver patch to 2.0.2-rc14. + - Fix sendfile. (closes: #358391, #358752) + + -- Bastian Blank Fri, 24 Mar 2006 12:49:46 +0100 linux-2.6 (2.6.16-2) unstable; urgency=low diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index c36af6eea..b5fad289c 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -211,6 +211,7 @@ class gencontrol(object): ret[1] = vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] vars['upstreamversion'] = version['upstream'] vars['version'] = version['version'] + vars['source_upstream'] = version['source_upstream'] vars['major'] = version['major'] ret[2] = vars return ret diff --git a/debian/patches/series/3-extra b/debian/patches/series/3-extra new file mode 100644 index 000000000..ac7d9ed55 --- /dev/null +++ b/debian/patches/series/3-extra @@ -0,0 +1 @@ ++ vserver-vs2.0.2-rc14-update.patch *_vserver diff --git a/debian/patches/vserver-vs2.0.2-rc14-update.patch b/debian/patches/vserver-vs2.0.2-rc14-update.patch new file mode 100644 index 000000000..67996859b --- /dev/null +++ b/debian/patches/vserver-vs2.0.2-rc14-update.patch @@ -0,0 +1,44 @@ +--- linux-2.6.16-vs2.0.2-rc13/fs/ioprio.c 2006-03-20 17:34:49 +0100 ++++ linux-2.6.16-vs2.0.2-rc14/fs/ioprio.c 2006-03-23 19:35:17 +0100 +@@ -96,7 +96,7 @@ + if (!who) + user = current->user; + else +- user = find_user(who, vx_current_xid()); ++ user = find_user(vx_current_xid(), who); + + if (!user) + break; +@@ -150,7 +150,7 @@ + if (!who) + user = current->user; + else +- user = find_user(who, vx_current_xid()); ++ user = find_user(vx_current_xid(), who); + + if (!user) + break; +--- linux-2.6.16-vs2.0.2-rc13/fs/read_write.c 2006-03-20 17:34:49 +0100 ++++ linux-2.6.16/fs/read_write.c 2006-03-20 17:33:14 +0100 +@@ -667,8 +667,9 @@ + if (!(in_file->f_mode & FMODE_PREAD)) + goto fput_in; + retval = rw_verify_area(READ, in_file, ppos, count); ++ if (retval < 0) +- if (retval) + goto fput_in; ++ count = retval; + + retval = security_file_permission (in_file, MAY_READ); + if (retval) +@@ -688,8 +689,9 @@ + goto fput_out; + out_inode = out_file->f_dentry->d_inode; + retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); ++ if (retval < 0) +- if (retval) + goto fput_out; ++ count = retval; + + retval = security_file_permission (out_file, MAY_WRITE); + if (retval) diff --git a/debian/templates/control.main.in b/debian/templates/control.main.in index 9d1e396d5..94f02626e 100644 --- a/debian/templates/control.main.in +++ b/debian/templates/control.main.in @@ -64,7 +64,4 @@ Description: Debian patches to version @version@ of the Linux kernel linux-source-@version@ package, as well as architecture-specific patches. Note that these patches do NOT apply against a pristine Linux @version@ kernel but only against the kernel tarball - linux-source-@version@_@version@.orig.tar.gz from the Debian archive. - . - This packages is produced using an updated kernel packaging system - and replaces older kernel-patch-debian packages + linux-@major@_@source_upstream@.orig.tar.gz from the Debian archive. From e4d031ccccefe5aabe6b564792f33320b21de10a Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Mon, 27 Mar 2006 19:25:48 +0000 Subject: [PATCH 014/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6298 --- debian/arch/arm/config.footbridge | 2 +- debian/changelog | 8 ++++++-- debian/patches/mips-sb1-duart.patch | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/debian/arch/arm/config.footbridge b/debian/arch/arm/config.footbridge index 02a36f465..87a0f530b 100644 --- a/debian/arch/arm/config.footbridge +++ b/debian/arch/arm/config.footbridge @@ -439,7 +439,7 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDE_SATA is not set CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_BLK_DEV_IDECD is not set +CONFIG_BLK_DEV_IDECD=m # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set diff --git a/debian/changelog b/debian/changelog index 8999c43d9..73c7ddb2f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,7 +4,7 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- Bastian Blank Thu, 23 Mar 2006 21:40:17 +0100 -linux-2.6 (2.6.16-3) UNRELEASED; urgency=low +linux-2.6 (2.6.16-3) unstable; urgency=low [ Frederik Schüler ] * [amd64] Add asm-i386 to the linux-headers packages. @@ -17,12 +17,16 @@ linux-2.6 (2.6.16-3) UNRELEASED; urgency=low [ Martin Michlmayr ] * [arm/armeb] Enable CONFIG_NFSD on NSLU2 again. Closes: #358709. * [arm/footbridge] CONFIG_NE2K_PCI should be a module, not built-in. + * [arm/footbridge] Enable CONFIG_BLK_DEV_IDECD=m since the CATS can + have a CD-ROM drive. + * [mips/sb1*] Use ttyS rather than duart as the name for the serial + console since the latter causes problems with debian-installer. [ Bastian Blank ] * Update vserver patch to 2.0.2-rc14. - Fix sendfile. (closes: #358391, #358752) - -- Bastian Blank Fri, 24 Mar 2006 12:49:46 +0100 + -- Bastian Blank Mon, 27 Mar 2006 16:08:20 +0200 linux-2.6 (2.6.16-2) unstable; urgency=low diff --git a/debian/patches/mips-sb1-duart.patch b/debian/patches/mips-sb1-duart.patch index 00cba6f0e..20932678f 100644 --- a/debian/patches/mips-sb1-duart.patch +++ b/debian/patches/mips-sb1-duart.patch @@ -812,8 +812,8 @@ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig + return -ENOMEM; + + sb1250_duart_driver->owner = THIS_MODULE; -+ sb1250_duart_driver->name = "duart"; -+ sb1250_duart_driver->devfs_name = "duart/"; ++ sb1250_duart_driver->name = "ttyS"; ++ sb1250_duart_driver->devfs_name = "tts/"; + sb1250_duart_driver->major = TTY_MAJOR; + sb1250_duart_driver->minor_start = SB1250_DUART_MINOR_BASE; + sb1250_duart_driver->type = TTY_DRIVER_TYPE_SERIAL; From 202e4dc8f918ce6931cc0c29b75b72768f13253f Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Tue, 28 Mar 2006 21:40:01 +0000 Subject: [PATCH 015/108] * debian/rules.real: Symlink scripts dir from kbuild package. * debian/templates/control.headers.in: Depend on kbuild package. svn path=/dists/trunk/linux-2.6/; revision=6324 --- debian/rules.real | 13 ++++--------- debian/templates/control.headers.in | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/debian/rules.real b/debian/rules.real index 8c88734d8..43d621828 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -228,6 +228,7 @@ install-header-$(ARCH)-$(SUBARCH): $(STAMPS_DIR)/source-$(ARCH)-$(SUBARCH) install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): REAL_VERSION = $(UPSTREAMVERSION)$(ABINAME)$(LOCALVERSION) install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): PACKAGE_NAME = linux-headers-$(REAL_VERSION) install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): PACKAGE_NAME_HEADERS = linux-headers-$(UPSTREAMVERSION)$(ABINAME)$(LOCALVERSION_HEADERS) +install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): PACKAGE_NAME_KBUILD = linux-kbuild-$(VERSION) install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): DH_OPTIONS = -p$(PACKAGE_NAME) install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): BASE_DIR = /usr/src/$(PACKAGE_NAME) install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): SOURCE_DIR = $(BUILD_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR) @@ -291,15 +292,9 @@ install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): $(STAMPS_DIR)/build-$(ARCH)-$(SUBA mkdir -p "${PACKAGE_DIR}/lib/modules/${REAL_VERSION}" ln -s "/usr/src/${PACKAGE_NAME}" "${PACKAGE_DIR}/lib/modules/${REAL_VERSION}/build" - - # Populate the scripts directory. The strategy here is to specify what - # *not* to copy, to make things a little bit more robust. We first create - # a file with exclude patterns, then copy everything minus excluded files. - # - cd $(SOURCE_DIR); \ - tar $(foreach t, *.c *.cc *.h *.l *.o *.y *.cmd *.glade *.gperf *POTFILES.in .gitignore *lxdialog* *package* *_shipped, --exclude=$(t)) -chf - scripts | \ - (cd "${DIR}"; umask 000; tar -xvsf -) - + + ln -s "../${PACKAGE_NAME_KBUILD}/scripts" "${DIR}" + $(MAKE) -f debian/rules.real install-base install-headers-all: PACKAGE_NAME = linux-headers-$(VERSION) diff --git a/debian/templates/control.headers.in b/debian/templates/control.headers.in index 88a5c7b8b..4eec82ce8 100644 --- a/debian/templates/control.headers.in +++ b/debian/templates/control.headers.in @@ -1,7 +1,7 @@ Package: linux-headers-@upstreamversion@@abiname@@localversion@ Section: devel Priority: optional -Depends: linux-headers-@upstreamversion@@abiname@@localversion_headers@ (= ${Source-Version}) +Depends: linux-headers-@upstreamversion@@abiname@@localversion_headers@ (= ${Source-Version}), linux-kbuild-@version@ Provides: linux-headers, linux-headers-@major@ Description: Header files for Linux kernel @upstreamversion@ on @class@ machines This package provides the architecture-specific kernel header files From e206c372e71eb36cb8ea58613ed87bbfacc58d1c Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Tue, 28 Mar 2006 21:48:15 +0000 Subject: [PATCH 016/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6326 --- debian/arch/arm/config.nslu2 | 1 + debian/arch/armeb/config.nslu2 | 1 + debian/bin/gencontrol.py | 37 +- debian/changelog | 29 ++ debian/lib/python/debian_linux/gencontrol.py | 1 + debian/modules/gencontrol.py | 5 +- debian/patches/2.6.16.1 | 449 +++++++++++++++++++ debian/patches/mips-sb1-duart-tts.patch | 20 + debian/patches/mips-sb1-duart.patch | 4 +- debian/patches/series/4 | 2 + debian/patches/vserver-vs2.0.2-rc13.patch | 4 +- debian/rules.real | 14 +- debian/templates/control.headers.arch.in | 24 +- 13 files changed, 559 insertions(+), 32 deletions(-) create mode 100644 debian/patches/2.6.16.1 create mode 100644 debian/patches/mips-sb1-duart-tts.patch create mode 100644 debian/patches/series/4 diff --git a/debian/arch/arm/config.nslu2 b/debian/arch/arm/config.nslu2 index d6992a6e9..fdf5c0d1b 100644 --- a/debian/arch/arm/config.nslu2 +++ b/debian/arch/arm/config.nslu2 @@ -1387,6 +1387,7 @@ CONFIG_NFS_ACL_SUPPORT=m CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set diff --git a/debian/arch/armeb/config.nslu2 b/debian/arch/armeb/config.nslu2 index 73f5accde..7e84de814 100644 --- a/debian/arch/armeb/config.nslu2 +++ b/debian/arch/armeb/config.nslu2 @@ -1387,6 +1387,7 @@ CONFIG_NFS_ACL_SUPPORT=m CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 2e9691f28..94bcef51d 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -22,31 +22,28 @@ class gencontrol(debian_linux.gencontrol.gencontrol): def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra): headers_arch = self.templates["control.headers.arch"] - package_headers_arch = self.process_package(headers_arch[0], vars) - extra['headers_arch_depends'] = [] + packages_headers_arch = self.process_packages(headers_arch, vars) + extra['headers_arch_depends'] = packages_headers_arch[2]['Depends'] - name = package_headers_arch['Package'] - if packages.has_key(name): - package_headers_arch = packages.get(name) - package_headers_arch['Architecture'].append(arch) - else: - package_headers_arch['Architecture'] = [arch] - packages.append(package_headers_arch) + for package in packages_headers_arch: + name = package['Package'] + if packages.has_key(name): + package = packages.get(name) + package['Architecture'].append(arch) + else: + package['Architecture'] = [arch] + packages.append(package) makeflags_string = ' '.join(["%s='%s'" % i for i in makeflags.iteritems()]) - cmds_source = [] - cmds_source.append(("$(MAKE) -f debian/rules.real source-arch %s" % makeflags_string,)) - makefile.append(("build-%s-real:" % arch)) - makefile.append(("setup-%s-real:" % arch)) - makefile.append(("source-%s-real:" % arch, cmds_source)) - - def do_arch_packages_post(self, packages, makefile, arch, vars, makeflags, extra): - makeflags_string = ' '.join(["%s='%s'" % i for i in makeflags.iteritems()]) - cmds_binary_arch = [] - cmds_binary_arch.append(("$(MAKE) -f debian/rules.real install-headers-all GENCONTROL_ARGS='\"-Vkernel:Depends=%s\"' %s" % (', '.join(["%s (= %s)" % (i, self.version['source']) for i in extra['headers_arch_depends']]), makeflags_string),)) + cmds_binary_arch.append(("$(MAKE) -f debian/rules.real binary-arch-arch %s" % makeflags_string)) + cmds_source = [] + cmds_source.append(("$(MAKE) -f debian/rules.real source-arch %s" % makeflags_string,)) makefile.append(("binary-arch-%s-real:" % arch, cmds_binary_arch)) + makefile.append(("build-%s-real:" % arch)) + makefile.append(("setup-%s-real:" % arch)) + makefile.append(("source-%s-real:" % arch, cmds_source)) def do_subarch_setup(self, vars, makeflags, arch, subarch): vars.update(self.config.get(('image', arch, subarch), {})) @@ -139,7 +136,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): package['Architecture'] = [arch] packages.append(package) - extra['headers_arch_depends'].append(packages_own[1]['Package']) + extra['headers_arch_depends'].append('%s (= ${Source-Version})' % packages_own[1]['Package']) makeflags_string = ' '.join(["%s='%s'" % i for i in makeflags.iteritems()]) diff --git a/debian/changelog b/debian/changelog index 73c7ddb2f..6bc4c7fc1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,35 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- Bastian Blank Thu, 23 Mar 2006 21:40:17 +0100 +linux-2.6 (2.6.16-4) unstable; urgency=medium + + [ Martin Michlmayr ] + * [arm/armeb] Update nslu2 config. + * Add stable release 2.6.16.1: + - Fix speedstep-smi assembly bug in speedstep_smi_ownership + - DMI: fix DMI onboard device discovery + - cciss: fix use-after-free in cciss_init_one + - DM: Fix bug: BIO_RW_BARRIER requests to md/raid1 hang. + - fix scheduler deadlock + - proc: fix duplicate line in /proc/devices + - rtc.h broke strace(1) builds + - dm: bio split bvec fix + - v9fs: assign dentry ops to negative dentries + - i810fb_cursor(): use GFP_ATOMIC + - NET: Ensure device name passed to SO_BINDTODEVICE is NULL terminated. + - XFS writeout fix + - sysfs: fix a kobject leak in sysfs_add_link on the error path + - get_cpu_sysdev() signedness fix + - firmware: fix BUG: in fw_realloc_buffer + - sysfs: sysfs_remove_dir() needs to invalidate the dentry + - TCP: Do not use inet->id of global tcp_socket when sending RST (CVE-2006-1242) + - 2.6.xx: sata_mv: another critical fix + - Kconfig: VIDEO_DECODER must select FW_LOADER + - V4L/DVB (3324): Fix Samsung tuner frequency ranges + - sata_mv: fix irq port status usage + + -- Bastian Blank Tue, 28 Mar 2006 17:19:10 +0200 + linux-2.6 (2.6.16-3) unstable; urgency=low [ Frederik Schüler ] diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index b5fad289c..e75147b28 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -96,6 +96,7 @@ class gencontrol(object): def do_arch(self, packages, makefile, arch, vars, makeflags): config_entry = self.config['base', arch] vars.update(config_entry) + vars['arch'] = arch if not config_entry.get('available', True): for i in self.makefile_targets: diff --git a/debian/modules/gencontrol.py b/debian/modules/gencontrol.py index 341280b6c..c9f7abfe3 100755 --- a/debian/modules/gencontrol.py +++ b/debian/modules/gencontrol.py @@ -12,9 +12,8 @@ class gencontrol(debian_linux.gencontrol.gencontrol): packages.extend(self.process_packages(main, vars)) def do_main_packages(self, packages): - l = package_relation_group() - l.extend([package_relation('linux-headers-%s%s-%s [%s]' % (self.version['upstream'], self.abiname, arch, arch)) for arch in self.config['base',]['arches']]) - packages['source']['Build-Depends'].append(l) + l = ['linux-headers-%s%s-all-%s [%s]' % (self.version['upstream'], self.abiname, arch, arch) for arch in self.config['base',]['arches']] + packages['source']['Build-Depends'].extend(l) def do_flavour_packages(self, packages, makefile, arch, subarch, flavour, vars, makeflags, extra): modules = self.templates["control.modules"] diff --git a/debian/patches/2.6.16.1 b/debian/patches/2.6.16.1 new file mode 100644 index 000000000..fc61da876 --- /dev/null +++ b/debian/patches/2.6.16.1 @@ -0,0 +1,449 @@ +diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +index 28cc5d5..cfc4276 100644 +--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c ++++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +@@ -75,7 +75,9 @@ static int speedstep_smi_ownership (void + __asm__ __volatile__( + "out %%al, (%%dx)\n" + : "=D" (result) +- : "a" (command), "b" (function), "c" (0), "d" (smi_port), "D" (0), "S" (magic) ++ : "a" (command), "b" (function), "c" (0), "d" (smi_port), ++ "D" (0), "S" (magic) ++ : "memory" + ); + + dprintk("result is %x\n", result); +diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c +index 6a93d75..ca2a0cb 100644 +--- a/arch/i386/kernel/dmi_scan.c ++++ b/arch/i386/kernel/dmi_scan.c +@@ -106,7 +106,7 @@ static void __init dmi_save_devices(stru + struct dmi_device *dev; + + for (i = 0; i < count; i++) { +- char *d = ((char *) dm) + (i * 2); ++ char *d = (char *)(dm + 1) + (i * 2); + + /* Skip disabled device */ + if ((*d & 0x80) == 0) +diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c +index 07a7f97..29f3d75 100644 +--- a/drivers/base/cpu.c ++++ b/drivers/base/cpu.c +@@ -141,7 +141,7 @@ int __devinit register_cpu(struct cpu *c + return error; + } + +-struct sys_device *get_cpu_sysdev(int cpu) ++struct sys_device *get_cpu_sysdev(unsigned cpu) + { + if (cpu < NR_CPUS) + return cpu_sys_devices[cpu]; +diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c +index e97e911..4723182 100644 +--- a/drivers/base/firmware_class.c ++++ b/drivers/base/firmware_class.c +@@ -211,18 +211,20 @@ static int + fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) + { + u8 *new_data; ++ int new_size = fw_priv->alloc_size; + + if (min_size <= fw_priv->alloc_size) + return 0; + +- new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE); ++ new_size = ALIGN(min_size, PAGE_SIZE); ++ new_data = vmalloc(new_size); + if (!new_data) { + printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__); + /* Make sure that we don't keep incomplete data */ + fw_load_abort(fw_priv); + return -ENOMEM; + } +- fw_priv->alloc_size += PAGE_SIZE; ++ fw_priv->alloc_size = new_size; + if (fw_priv->fw->data) { + memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size); + vfree(fw_priv->fw->data); +diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c +index 0d65394..c149d57 100644 +--- a/drivers/block/cciss.c ++++ b/drivers/block/cciss.c +@@ -3269,8 +3269,8 @@ clean2: + unregister_blkdev(hba[i]->major, hba[i]->devname); + clean1: + release_io_mem(hba[i]); +- free_hba(i); + hba[i]->busy_initializing = 0; ++ free_hba(i); + return(-1); + } + +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 745ca1f..d559569 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -533,30 +533,35 @@ static void __clone_and_map(struct clone + + } else { + /* +- * Create two copy bios to deal with io that has +- * been split across a target. ++ * Handle a bvec that must be split between two or more targets. + */ + struct bio_vec *bv = bio->bi_io_vec + ci->idx; ++ sector_t remaining = to_sector(bv->bv_len); ++ unsigned int offset = 0; + +- clone = split_bvec(bio, ci->sector, ci->idx, +- bv->bv_offset, max); +- __map_bio(ti, clone, tio); +- +- ci->sector += max; +- ci->sector_count -= max; +- ti = dm_table_find_target(ci->map, ci->sector); +- +- len = to_sector(bv->bv_len) - max; +- clone = split_bvec(bio, ci->sector, ci->idx, +- bv->bv_offset + to_bytes(max), len); +- tio = alloc_tio(ci->md); +- tio->io = ci->io; +- tio->ti = ti; +- memset(&tio->info, 0, sizeof(tio->info)); +- __map_bio(ti, clone, tio); ++ do { ++ if (offset) { ++ ti = dm_table_find_target(ci->map, ci->sector); ++ max = max_io_len(ci->md, ci->sector, ti); ++ ++ tio = alloc_tio(ci->md); ++ tio->io = ci->io; ++ tio->ti = ti; ++ memset(&tio->info, 0, sizeof(tio->info)); ++ } ++ ++ len = min(remaining, max); ++ ++ clone = split_bvec(bio, ci->sector, ci->idx, ++ bv->bv_offset + offset, len); ++ ++ __map_bio(ti, clone, tio); ++ ++ ci->sector += len; ++ ci->sector_count -= len; ++ offset += to_bytes(len); ++ } while (remaining -= len); + +- ci->sector += len; +- ci->sector_count -= len; + ci->idx++; + } + } +diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig +index d82c8a3..ef42a26 100644 +--- a/drivers/media/video/Kconfig ++++ b/drivers/media/video/Kconfig +@@ -349,6 +349,7 @@ config VIDEO_AUDIO_DECODER + config VIDEO_DECODER + tristate "Add support for additional video chipsets" + depends on VIDEO_DEV && I2C && EXPERIMENTAL ++ select FW_LOADER + ---help--- + Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 + video decoders. +diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c +index 6fe7817..5f3d46d 100644 +--- a/drivers/media/video/tuner-types.c ++++ b/drivers/media/video/tuner-types.c +@@ -1087,8 +1087,8 @@ static struct tuner_params tuner_tnf_533 + /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */ + + static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = { +- { 16 * 175.75 /*MHz*/, 0x01, }, +- { 16 * 410.25 /*MHz*/, 0x02, }, ++ { 16 * 130.00 /*MHz*/, 0x01, }, ++ { 16 * 364.50 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, + }; + +diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c +index 2770005..b00af08 100644 +--- a/drivers/scsi/sata_mv.c ++++ b/drivers/scsi/sata_mv.c +@@ -1102,6 +1102,7 @@ static u8 mv_get_crpb_status(struct ata_ + void __iomem *port_mmio = mv_ap_base(ap); + struct mv_port_priv *pp = ap->private_data; + u32 out_ptr; ++ u8 ata_status; + + out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); + +@@ -1109,6 +1110,8 @@ static u8 mv_get_crpb_status(struct ata_ + assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + pp->rsp_consumer); + ++ ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT; ++ + /* increment our consumer index... */ + pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); + +@@ -1123,7 +1126,7 @@ static u8 mv_get_crpb_status(struct ata_ + writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); + + /* Return ATA status register for completed CRPB */ +- return (pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT); ++ return ata_status; + } + + /** +@@ -1192,7 +1195,6 @@ static void mv_host_intr(struct ata_host + u32 hc_irq_cause; + int shift, port, port0, hard_port, handled; + unsigned int err_mask; +- u8 ata_status = 0; + + if (hc == 0) { + port0 = 0; +@@ -1210,6 +1212,7 @@ static void mv_host_intr(struct ata_host + hc,relevant,hc_irq_cause); + + for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { ++ u8 ata_status = 0; + ap = host_set->ports[port]; + hard_port = port & MV_PORT_MASK; /* range 0-3 */ + handled = 0; /* ensure ata_status is set if handled++ */ +diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c +index d8467c0..788297e 100644 +--- a/drivers/video/i810/i810_main.c ++++ b/drivers/video/i810/i810_main.c +@@ -1508,7 +1508,7 @@ static int i810fb_cursor(struct fb_info + int size = ((cursor->image.width + 7) >> 3) * + cursor->image.height; + int i; +- u8 *data = kmalloc(64 * 8, GFP_KERNEL); ++ u8 *data = kmalloc(64 * 8, GFP_ATOMIC); + + if (data == NULL) + return -ENOMEM; +diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c +index 3ad8455..651a9e1 100644 +--- a/fs/9p/vfs_inode.c ++++ b/fs/9p/vfs_inode.c +@@ -614,6 +614,7 @@ static struct dentry *v9fs_vfs_lookup(st + + sb = dir->i_sb; + v9ses = v9fs_inode2v9ses(dir); ++ dentry->d_op = &v9fs_dentry_operations; + dirfid = v9fs_fid_lookup(dentry->d_parent); + + if (!dirfid) { +@@ -681,8 +682,6 @@ static struct dentry *v9fs_vfs_lookup(st + goto FreeFcall; + + fid->qid = fcall->params.rstat.stat.qid; +- +- dentry->d_op = &v9fs_dentry_operations; + v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); + + d_add(dentry, inode); +diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c +index 1d24fea..826c131 100644 +--- a/fs/proc/proc_misc.c ++++ b/fs/proc/proc_misc.c +@@ -312,7 +312,7 @@ static void *devinfo_next(struct seq_fil + case BLK_HDR: + info->state = BLK_LIST; + (*pos)++; +- break; ++ /*fallthrough*/ + case BLK_LIST: + if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) { + /* +diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c +index 49bd219..cfd290d 100644 +--- a/fs/sysfs/dir.c ++++ b/fs/sysfs/dir.c +@@ -302,6 +302,7 @@ void sysfs_remove_dir(struct kobject * k + * Drop reference from dget() on entrance. + */ + dput(dentry); ++ kobj->dentry = NULL; + } + + int sysfs_rename_dir(struct kobject * kobj, const char *new_name) +diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c +index 689f7bc..6beee6f 100644 +--- a/fs/sysfs/inode.c ++++ b/fs/sysfs/inode.c +@@ -227,12 +227,16 @@ void sysfs_drop_dentry(struct sysfs_dire + void sysfs_hash_and_remove(struct dentry * dir, const char * name) + { + struct sysfs_dirent * sd; +- struct sysfs_dirent * parent_sd = dir->d_fsdata; ++ struct sysfs_dirent * parent_sd; ++ ++ if (!dir) ++ return; + + if (dir->d_inode == NULL) + /* no inode means this hasn't been made visible yet */ + return; + ++ parent_sd = dir->d_fsdata; + mutex_lock(&dir->d_inode->i_mutex); + list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { + if (!sd->s_element) +diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c +index e38d633..e5ce6e7 100644 +--- a/fs/sysfs/symlink.c ++++ b/fs/sysfs/symlink.c +@@ -66,6 +66,7 @@ static int sysfs_add_link(struct dentry + if (!error) + return 0; + ++ kobject_put(target); + kfree(sl->link_name); + exit2: + kfree(sl); +diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c +index 74d8be8..a980736 100644 +--- a/fs/xfs/linux-2.6/xfs_aops.c ++++ b/fs/xfs/linux-2.6/xfs_aops.c +@@ -616,7 +616,7 @@ xfs_is_delayed_page( + acceptable = (type == IOMAP_UNWRITTEN); + else if (buffer_delay(bh)) + acceptable = (type == IOMAP_DELAY); +- else if (buffer_mapped(bh)) ++ else if (buffer_dirty(bh) && buffer_mapped(bh)) + acceptable = (type == 0); + else + break; +diff --git a/include/linux/cpu.h b/include/linux/cpu.h +index 0ed1d48..d612b89 100644 +--- a/include/linux/cpu.h ++++ b/include/linux/cpu.h +@@ -32,7 +32,7 @@ struct cpu { + }; + + extern int register_cpu(struct cpu *, int, struct node *); +-extern struct sys_device *get_cpu_sysdev(int cpu); ++extern struct sys_device *get_cpu_sysdev(unsigned cpu); + #ifdef CONFIG_HOTPLUG_CPU + extern void unregister_cpu(struct cpu *, struct node *); + #endif +diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h +index 9d5494a..3009c81 100644 +--- a/include/linux/raid/raid1.h ++++ b/include/linux/raid/raid1.h +@@ -130,6 +130,6 @@ struct r1bio_s { + * with failure when last write completes (and all failed). + * Record that bi_end_io was called with this flag... + */ +-#define R1BIO_Returned 4 ++#define R1BIO_Returned 6 + + #endif +diff --git a/include/linux/rtc.h b/include/linux/rtc.h +index 0b2ba67..b739ac1 100644 +--- a/include/linux/rtc.h ++++ b/include/linux/rtc.h +@@ -11,8 +11,6 @@ + #ifndef _LINUX_RTC_H_ + #define _LINUX_RTC_H_ + +-#include +- + /* + * The struct used to pass data via the following ioctl. Similar to the + * struct tm in , but it needs to be here so that the kernel +@@ -95,6 +93,8 @@ struct rtc_pll_info { + + #ifdef __KERNEL__ + ++#include ++ + typedef struct rtc_task { + void (*func)(void *private_data); + void *private_data; +diff --git a/kernel/sched.c b/kernel/sched.c +index 4d46e90..4e7efac 100644 +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -237,6 +237,7 @@ struct runqueue { + + task_t *migration_thread; + struct list_head migration_queue; ++ int cpu; + #endif + + #ifdef CONFIG_SCHEDSTATS +@@ -1660,6 +1661,9 @@ unsigned long nr_iowait(void) + /* + * double_rq_lock - safely lock two runqueues + * ++ * We must take them in cpu order to match code in ++ * dependent_sleeper and wake_dependent_sleeper. ++ * + * Note this does not disable interrupts like task_rq_lock, + * you need to do so manually before calling. + */ +@@ -1671,7 +1675,7 @@ static void double_rq_lock(runqueue_t *r + spin_lock(&rq1->lock); + __acquire(rq2->lock); /* Fake it out ;) */ + } else { +- if (rq1 < rq2) { ++ if (rq1->cpu < rq2->cpu) { + spin_lock(&rq1->lock); + spin_lock(&rq2->lock); + } else { +@@ -1707,7 +1711,7 @@ static void double_lock_balance(runqueue + __acquires(this_rq->lock) + { + if (unlikely(!spin_trylock(&busiest->lock))) { +- if (busiest < this_rq) { ++ if (busiest->cpu < this_rq->cpu) { + spin_unlock(&this_rq->lock); + spin_lock(&busiest->lock); + spin_lock(&this_rq->lock); +@@ -6035,6 +6039,7 @@ void __init sched_init(void) + rq->push_cpu = 0; + rq->migration_thread = NULL; + INIT_LIST_HEAD(&rq->migration_queue); ++ rq->cpu = i; + #endif + atomic_set(&rq->nr_iowait, 0); + +diff --git a/net/core/sock.c b/net/core/sock.c +index 6e00811..5621198 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -404,8 +404,9 @@ set_rcvbuf: + if (!valbool) { + sk->sk_bound_dev_if = 0; + } else { +- if (optlen > IFNAMSIZ) +- optlen = IFNAMSIZ; ++ if (optlen > IFNAMSIZ - 1) ++ optlen = IFNAMSIZ - 1; ++ memset(devname, 0, sizeof(devname)); + if (copy_from_user(devname, optval, optlen)) { + ret = -EFAULT; + break; +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index 8ee4d01..f75ff1d 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -1249,11 +1249,7 @@ int ip_push_pending_frames(struct sock * + iph->tos = inet->tos; + iph->tot_len = htons(skb->len); + iph->frag_off = df; +- if (!df) { +- __ip_select_ident(iph, &rt->u.dst, 0); +- } else { +- iph->id = htons(inet->id++); +- } ++ ip_select_ident(iph, &rt->u.dst, sk); + iph->ttl = ttl; + iph->protocol = sk->sk_protocol; + iph->saddr = rt->rt_src; diff --git a/debian/patches/mips-sb1-duart-tts.patch b/debian/patches/mips-sb1-duart-tts.patch new file mode 100644 index 000000000..a724d50e8 --- /dev/null +++ b/debian/patches/mips-sb1-duart-tts.patch @@ -0,0 +1,20 @@ +Patch: change the name of the sb1250 DUART from duart to ttyS +Needed for debian-installer +Status: the sb1250_duart.c driver needs a completely re-write... + +diff --git a/drivers/char/sb1250_duart.c b/drivers/char/sb1250_duart.c +index 7819acc..57a227c 100644 +--- a/drivers/char/sb1250_duart.c ++++ b/drivers/char/sb1250_duart.c +@@ -762,8 +762,8 @@ static int __init sb1250_duart_init(void + return -ENOMEM; + + sb1250_duart_driver->owner = THIS_MODULE; +- sb1250_duart_driver->name = "duart"; +- sb1250_duart_driver->devfs_name = "duart/"; ++ sb1250_duart_driver->name = "ttyS"; ++ sb1250_duart_driver->devfs_name = "tts/"; + sb1250_duart_driver->major = TTY_MAJOR; + sb1250_duart_driver->minor_start = SB1250_DUART_MINOR_BASE; + sb1250_duart_driver->type = TTY_DRIVER_TYPE_SERIAL; + diff --git a/debian/patches/mips-sb1-duart.patch b/debian/patches/mips-sb1-duart.patch index 20932678f..00cba6f0e 100644 --- a/debian/patches/mips-sb1-duart.patch +++ b/debian/patches/mips-sb1-duart.patch @@ -812,8 +812,8 @@ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig + return -ENOMEM; + + sb1250_duart_driver->owner = THIS_MODULE; -+ sb1250_duart_driver->name = "ttyS"; -+ sb1250_duart_driver->devfs_name = "tts/"; ++ sb1250_duart_driver->name = "duart"; ++ sb1250_duart_driver->devfs_name = "duart/"; + sb1250_duart_driver->major = TTY_MAJOR; + sb1250_duart_driver->minor_start = SB1250_DUART_MINOR_BASE; + sb1250_duart_driver->type = TTY_DRIVER_TYPE_SERIAL; diff --git a/debian/patches/series/4 b/debian/patches/series/4 new file mode 100644 index 000000000..dc52e44c7 --- /dev/null +++ b/debian/patches/series/4 @@ -0,0 +1,2 @@ ++ 2.6.16.1 ++ mips-sb1-duart-tts.patch diff --git a/debian/patches/vserver-vs2.0.2-rc13.patch b/debian/patches/vserver-vs2.0.2-rc13.patch index 464766587..bcfa24ae4 100644 --- a/debian/patches/vserver-vs2.0.2-rc13.patch +++ b/debian/patches/vserver-vs2.0.2-rc13.patch @@ -13019,9 +13019,9 @@ index 4d46e90..545c80b 100644 /* * Convert user-nice values [ -20 ... 0 ... 19 ] -@@ -238,6 +241,10 @@ struct runqueue { - task_t *migration_thread; +@@ -238,6 +241,10 @@ struct list_head migration_queue; + int cpu; #endif +#ifdef CONFIG_VSERVER_HARDCPU + struct list_head hold_queue; diff --git a/debian/rules.real b/debian/rules.real index 43d621828..3da553de2 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -66,6 +66,7 @@ endif # # Targets # +binary-arch-arch: install-headers-all install-headers-$(ARCH) binary-arch-subarch: install-header-$(ARCH)-$(SUBARCH) binary-arch-flavour: install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR) @@ -196,6 +197,13 @@ install-dummy: dh_clean -d -k $(MAKE) -f debian/rules.real install-base +install-headers-$(ARCH): PACKAGE_NAMES = linux-headers-$(UPSTREAMVERSION)$(ABINAME)-all linux-headers-$(UPSTREAMVERSION)$(ABINAME)-all-$(ARCH) +install-headers-$(ARCH): DH_OPTIONS = $(foreach p, $(PACKAGE_NAMES), -p$(p)) +install-headers-$(ARCH): + dh_testdir + dh_testroot + $(MAKE) -f debian/rules.real install-base GENCONTROL_ARGS='-Vkernel:Arch=$(ARCH)' + install-header-$(ARCH)-$(SUBARCH): PACKAGE_NAME = linux-headers-$(UPSTREAMVERSION)$(ABINAME)$(LOCALVERSION_HEADERS) install-header-$(ARCH)-$(SUBARCH): DH_OPTIONS = -p$(PACKAGE_NAME) install-header-$(ARCH)-$(SUBARCH): BASE_DIR = /usr/src/$(PACKAGE_NAME) @@ -303,9 +311,9 @@ install-headers-all: dh_testdir dh_testroot chmod a+x debian/modules/gencontrol.py - dh_install $(DH_OPTIONS) debian/arch debian/lib debian/modules '/usr/src/linux-headers-$(VERSION)' - dh_python $(DH_OPTIONS) -V 2.4 /usr/src/linux-headers-$(VERSION)/lib/python - $(MAKE) -f debian/rules.real install-base DH_OPTIONS='$(DH_OPTIONS)' GENCONTROL_ARGS='$(GENCONTROL_ARGS) -Vkernel:Provides=linux-headers-$(UPSTREAMVERSION)$(ABINAME)-$(ARCH)' + dh_install debian/arch debian/lib debian/modules '/usr/src/linux-headers-$(VERSION)' + dh_python -V 2.4 /usr/src/linux-headers-$(VERSION)/lib/python + $(MAKE) -f debian/rules.real install-base install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): REAL_VERSION = $(UPSTREAMVERSION)$(ABINAME)$(LOCALVERSION) install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): PACKAGE_NAME = linux-image-$(REAL_VERSION) diff --git a/debian/templates/control.headers.arch.in b/debian/templates/control.headers.arch.in index a9061fca9..b2ccee9d4 100644 --- a/debian/templates/control.headers.arch.in +++ b/debian/templates/control.headers.arch.in @@ -1,9 +1,29 @@ Package: linux-headers-@version@ Section: devel Priority: optional -Provides: linux-headers-@upstreamversion@@abiname@-all, linux-headers-@major@-all, ${kernel:Provides} -Depends: ${kernel:Depends} +Depends: python2.4-minimal Description: All header files for Linux kernel @version@ This package depends against all architecture-specific kernel header files for Linux kernel version @upstreamversion@, generally used for building out-of-tree kernel modules. + +Package: linux-headers-@upstreamversion@@abiname@-all +Section: devel +Priority: optional +Provides: linux-headers-@major@-all, linux-headers-@version@-all +Depends: linux-headers-@upstreamversion@@abiname@-all-${kernel:Arch} (= ${Source-Version}) +Description: All header files for Linux kernel @version@ + This package depends against all architecture-specific kernel header files + for Linux kernel version @upstreamversion@, generally used for building out-of-tree + kernel modules. + +Package: linux-headers-@upstreamversion@@abiname@-all-@arch@ +Section: devel +Priority: optional +Provides: linux-headers-@major@-all-@arch@, linux-headers-@version@-all-@arch@ +Depends: linux-headers-@version@ (= ${Source-Version}) +Description: All header files for Linux kernel @version@ + This package depends against all architecture-specific kernel header files + for Linux kernel version @upstreamversion@, generally used for building out-of-tree + kernel modules. + From 94f5bb0cbb028dae809885adcf6a8c1dd0beea81 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 11:12:36 +0000 Subject: [PATCH 017/108] debian/rules.real: Reorder rules. svn path=/dists/trunk/linux-2.6/; revision=6328 --- debian/rules.real | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/debian/rules.real b/debian/rules.real index 3da553de2..f037107b7 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -127,20 +127,6 @@ $(STAMPS_DIR)/source-$(ARCH)-$(SUBARCH): $(STAMPS_DIR)/source touch '$(DIR)/debian/official' $(patch_cmd) -a $(ARCH) -s $(SUBARCH) touch '$@' -# -# This target performs a build for a particular flavour. Note -# that in this file it should be always placed *before* the -# build-$(subarch)-% target, which creates the build directory. -# -$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): DIR=$(BUILD_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR) - -$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) - cd '$(DIR)'; $(setup_env) $(setup_env_kpkg_jobs) PATH='$(CURDIR)/build:$(CURDIR)/bin:$(PATH)' $(kpkg_image) build - touch '$@' - -$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) - cd '$(DIR)'; $(setup_env) make ARCH=$(KERNEL_ARCH) $(JOBS_ARG) - touch '$@' $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): SOURCE_DIR=$(BUILD_DIR)/source-$(ARCH)-$(SUBARCH) $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): DIR=$(BUILD_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR) @@ -160,6 +146,16 @@ $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: $(BUILD_DIR)/config cd '$(DIR)'; $(setup_env) make prepare ARCH=$(KERNEL_ARCH) $(JOBS_ARG) touch '$@' +$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): DIR=$(BUILD_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR) + +$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) + cd '$(DIR)'; $(setup_env) $(setup_env_kpkg_jobs) PATH='$(CURDIR)/build:$(CURDIR)/bin:$(PATH)' $(kpkg_image) build + touch '$@' + +$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) + cd '$(DIR)'; $(setup_env) make ARCH=$(KERNEL_ARCH) $(JOBS_ARG) + touch '$@' + install-base: dh_installchangelogs dh_installdocs From 4d20e20a729cc47cd9766a553d93caf3fbbeac26 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 11:18:32 +0000 Subject: [PATCH 018/108] debian/rules.real: Make logic easier in setup targets. svn path=/dists/trunk/linux-2.6/; revision=6329 --- debian/rules.real | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/debian/rules.real b/debian/rules.real index f037107b7..9397e6998 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -128,20 +128,23 @@ $(STAMPS_DIR)/source-$(ARCH)-$(SUBARCH): $(STAMPS_DIR)/source $(patch_cmd) -a $(ARCH) -s $(SUBARCH) touch '$@' +$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): CONFIG=$(BUILD_DIR)/config.$(ARCH)-$(SUBARCH)-$(FLAVOUR) $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): SOURCE_DIR=$(BUILD_DIR)/source-$(ARCH)-$(SUBARCH) $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): DIR=$(BUILD_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR) +$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): $(BUILD_DIR)/config.$(ARCH)-$(SUBARCH)-$(FLAVOUR) $(STAMPS_DIR)/source-$(ARCH)-$(SUBARCH) -$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: $(BUILD_DIR)/config.$(ARCH)-$(SUBARCH)-$(FLAVOUR) $(STAMPS_DIR)/source-$(ARCH)-$(SUBARCH) +$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: rm -rf '$(DIR)' cp -al '$(SOURCE_DIR)' '$(DIR)' - cp '$<' '$(DIR)/.config' + cp '$(CONFIG)' '$(DIR)/.config' cd '$(DIR)'; $(setup_env) $(kpkg_image) configure touch '$@' -$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: $(BUILD_DIR)/config.$(ARCH)-$(SUBARCH)-$(FLAVOUR) $(STAMPS_DIR)/source-$(ARCH)-$(SUBARCH) +$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-s390-tape \ +$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: rm -rf '$(DIR)' cp -al '$(SOURCE_DIR)' '$(DIR)' - cp '$<' '$(DIR)/.config' + cp '$(CONFIG)' '$(DIR)/.config' echo '$(ABINAME)$(LOCALVERSION)' > '$(DIR)/localversion' cd '$(DIR)'; $(setup_env) make prepare ARCH=$(KERNEL_ARCH) $(JOBS_ARG) touch '$@' From 97d1862558122d2fd6f6fb566d24f509e9066181 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 11:41:51 +0000 Subject: [PATCH 019/108] debian/bin/gencontrol.py: Make it possible to disable headers packages. svn path=/dists/trunk/linux-2.6/; revision=6330 --- debian/bin/gencontrol.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 94bcef51d..c5d200490 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -123,9 +123,12 @@ class gencontrol(debian_linux.gencontrol.gencontrol): packages_own.append(p) packages_own.append(self.process_real_image(image[0], image_depends, vars)) - packages_own.append(self.process_package(headers[0], vars)) packages_dummy.extend(self.process_packages(image_latest, vars)) - packages_dummy.append(self.process_package(headers_latest[0], vars)) + + if self.config.merge('headers', arch, subarch, flavour).get('enable', True): + packages_own.append(self.process_package(headers[0], vars)) + packages_dummy.append(self.process_package(headers_latest[0], vars)) + extra['headers_arch_depends'].append('%s (= ${Source-Version})' % packages_own[-1]['Package']) for package in packages_own + packages_dummy: name = package['Package'] @@ -136,8 +139,6 @@ class gencontrol(debian_linux.gencontrol.gencontrol): package['Architecture'] = [arch] packages.append(package) - extra['headers_arch_depends'].append('%s (= ${Source-Version})' % packages_own[1]['Package']) - makeflags_string = ' '.join(["%s='%s'" % i for i in makeflags.iteritems()]) cmds_binary_arch = [] From 9708faa9c9ade5b94dd622613a9a6acb02a6c170 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 11:44:51 +0000 Subject: [PATCH 020/108] * debian/bin/gencontrol.py: Disabled modules support disabled headers as well. * debian/lib/python/debian_linux/config.py: Add new entries. svn path=/dists/trunk/linux-2.6/; revision=6331 --- debian/bin/gencontrol.py | 2 +- debian/lib/python/debian_linux/config.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index c5d200490..472e1e0fc 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -125,7 +125,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): packages_own.append(self.process_real_image(image[0], image_depends, vars)) packages_dummy.extend(self.process_packages(image_latest, vars)) - if self.config.merge('headers', arch, subarch, flavour).get('enable', True): + if vars.get('modules', True): packages_own.append(self.process_package(headers[0], vars)) packages_dummy.append(self.process_package(headers_latest[0], vars)) extra['headers_arch_depends'].append('%s (= ${Source-Version})' % packages_own[-1]['Package']) diff --git a/debian/lib/python/debian_linux/config.py b/debian/lib/python/debian_linux/config.py index b6b02f291..55ed5ff85 100644 --- a/debian/lib/python/debian_linux/config.py +++ b/debian/lib/python/debian_linux/config.py @@ -33,6 +33,7 @@ class config_reader(dict): 'available': schema_item_boolean(), 'flavours': schema_item_list(), 'initramfs': schema_item_boolean(), + 'modules': schema_item_boolean(), 'initramfs-generators': schema_item_list(), 'subarches': schema_item_list(), } From 80c42f552a4371b935b7cb32aab275b04b22dfea Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 11:56:51 +0000 Subject: [PATCH 021/108] debian/bin/gencontrol.py - Export modules setting. - Add makeflags for dummy package building. svn path=/dists/trunk/linux-2.6/; revision=6332 --- debian/bin/gencontrol.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 472e1e0fc..994769f0e 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -89,6 +89,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): ('kpkg-arch', 'KPKG_ARCH'), ('kpkg-subarch', 'KPKG_SUBARCH'), ('localversion', 'LOCALVERSION'), + ('modules', 'MODULES',), ('type', 'TYPE'), ): if vars.has_key(i[0]): @@ -143,7 +144,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): cmds_binary_arch = [] cmds_binary_arch.append(("$(MAKE) -f debian/rules.real binary-arch-flavour %s" % makeflags_string,)) - cmds_binary_arch.append(("$(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='%s'" % ' '.join(["-p%s" % i['Package'] for i in packages_dummy]),)) + cmds_binary_arch.append(("$(MAKE) -f debian/rules.real install-dummy DH_OPTIONS='%s' %s" % (' '.join(["-p%s" % i['Package'] for i in packages_dummy]), makeflags_string),)) cmds_build = [] cmds_build.append(("$(MAKE) -f debian/rules.real build %s" % makeflags_string,)) cmds_setup = [] From 4e118544b607a6605f07a57c6fff962bedf53e11 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 11:57:39 +0000 Subject: [PATCH 022/108] debian/rules.real - Only build headers if modules are enabled. - Support s390-tape images. svn path=/dists/trunk/linux-2.6/; revision=6333 --- debian/rules.real | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/debian/rules.real b/debian/rules.real index 9397e6998..20a7d9afc 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -68,7 +68,10 @@ endif # binary-arch-arch: install-headers-all install-headers-$(ARCH) binary-arch-subarch: install-header-$(ARCH)-$(SUBARCH) -binary-arch-flavour: install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR) +binary-arch-flavour: install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) +ifneq ($(MODULES),False) + binary-arch-flavour: install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR) +endif binary-indep: install-doc install-patch install-source install-tree @@ -140,7 +143,14 @@ $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: cd '$(DIR)'; $(setup_env) $(kpkg_image) configure touch '$@' -$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-s390-tape \ +$(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-s390-tape: + rm -rf '$(DIR)' + cp -al '$(SOURCE_DIR)' '$(DIR)' + cp '$(CONFIG)' '$(DIR)/.config' + echo '$(ABINAME)$(subst -tape,,$(LOCALVERSION))' > '$(DIR)/localversion' + cd '$(DIR)'; $(setup_env) make prepare ARCH=$(KERNEL_ARCH) $(JOBS_ARG) + touch '$@' + $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: rm -rf '$(DIR)' cp -al '$(SOURCE_DIR)' '$(DIR)' @@ -150,12 +160,17 @@ $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: touch '$@' $(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): DIR=$(BUILD_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR) +$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) -$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) +$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: cd '$(DIR)'; $(setup_env) $(setup_env_kpkg_jobs) PATH='$(CURDIR)/build:$(CURDIR)/bin:$(PATH)' $(kpkg_image) build touch '$@' -$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: $(STAMPS_DIR)/setup-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) +$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-s390-tape: + cd '$(DIR)'; $(setup_env) make ARCH=$(KERNEL_ARCH) $(JOBS_ARG) image + touch '$@' + +$(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: cd '$(DIR)'; $(setup_env) make ARCH=$(KERNEL_ARCH) $(JOBS_ARG) touch '$@' @@ -318,8 +333,9 @@ install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): REAL_VERSION = $(UPSTREAMVE install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): PACKAGE_NAME = linux-image-$(REAL_VERSION) install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): PACKAGE_DIR = $(CURDIR)/debian/$(PACKAGE_NAME) install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): DIR=$(BUILD_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR) +install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): $(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) -install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: $(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) +install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-kernel-package: ifdef IMAGE_POSTPROC # Install the postproc script into the hook directory install -d '$(DIR)/debian/image.d' @@ -332,10 +348,19 @@ endif mv "$(BUILD_DIR)/$$i" ..; \ done +install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-s390-tape: DH_OPTIONS = -p$(PACKAGE_NAME) +install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-s390-tape: + dh_testdir + dh_testroot + dh_clean -d -k + dh_installdirs 'boot' + cp '$(DIR)/arch/s390/boot/image' $(PACKAGE_DIR)/boot/vmlinuz-$(REAL_VERSION) + $(MAKE) -f debian/rules.real install-base + install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: MODULES_PACKAGE_NAME = linux-modules-$(REAL_VERSION) install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: MODULES_PACKAGE_DIR = $(CURDIR)/debian/$(MODULES_PACKAGE_NAME) install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: DH_OPTIONS = -p$(PACKAGE_NAME) -p$(MODULES_PACKAGE_NAME) -install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: $(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) +install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-plain-xen: dh_testdir dh_testroot dh_clean -d -k From 28740c47268e54492f8f3699801200b6a3db2f30 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 22:18:18 +0000 Subject: [PATCH 023/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6338 --- debian/changelog | 9 +++++++++ debian/rules.real | 4 +--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6bc4c7fc1..afbd7fb0f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,15 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- Bastian Blank Thu, 23 Mar 2006 21:40:17 +0100 +linux-2.6 (2.6.16-5) UNRELEASED; urgency=low + + [ Bastian Blank ] + * Provide real dependency packages for module building. + * Fix module package output. + * Include .kernelrelease in headers packages. (closes: #359813) + + -- Bastian Blank Thu, 30 Mar 2006 00:08:39 +0200 + linux-2.6 (2.6.16-4) unstable; urgency=medium [ Martin Michlmayr ] diff --git a/debian/rules.real b/debian/rules.real index 20a7d9afc..055aa7cd1 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -264,9 +264,7 @@ install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): $(STAMPS_DIR)/build-$(ARCH)-$(SUBA mkdir -p "${DIR}/arch/${KERNEL_ARCH}/kernel" mkdir -p "${DIR}/include" - cp -a ${SOURCE_DIR}/{.config,Module.symvers} "${DIR}" - # TODO - echo $(ABINAME)$(LOCALVERSION) > "${DIR}/localversion" + cp -a ${SOURCE_DIR}/{.config,.kernelrelease,Module.symvers} "${DIR}" cd ${SOURCE_DIR}; \ find . -mindepth 1 -maxdepth 1 \ From 87420cf16694ed3ff205a64df96a6ee56da6789a Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 22:51:23 +0000 Subject: [PATCH 024/108] * debian/bin/gencontrol.py: Use different templates depending on type. * debian/rules.real: Fix detection of headers build. * debian/templates/control.image.type-modulesextra.in, debian/templates/control.image.type-modulesinline.in, debian/templates/control.image.type-standalone.in: Add. * debian/templates/control.image.in, debian/templates/control.modules.in: Remove. svn path=/dists/trunk/linux-2.6/; revision=6339 --- debian/bin/gencontrol.py | 21 +++++++++++-------- debian/rules.real | 2 +- .../control.image.type-modulesextra.in | 20 ++++++++++++++++++ ...in => control.image.type-modulesinline.in} | 0 .../control.image.type-standalone.in | 11 ++++++++++ debian/templates/control.modules.in | 8 ------- 6 files changed, 44 insertions(+), 18 deletions(-) create mode 100644 debian/templates/control.image.type-modulesextra.in rename debian/templates/{control.image.in => control.image.type-modulesinline.in} (100%) create mode 100644 debian/templates/control.image.type-standalone.in delete mode 100644 debian/templates/control.modules.in diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 994769f0e..910a19fb0 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -89,16 +89,16 @@ class gencontrol(debian_linux.gencontrol.gencontrol): ('kpkg-arch', 'KPKG_ARCH'), ('kpkg-subarch', 'KPKG_SUBARCH'), ('localversion', 'LOCALVERSION'), - ('modules', 'MODULES',), ('type', 'TYPE'), ): if vars.has_key(i[0]): makeflags[i[1]] = vars[i[0]] def do_flavour_packages(self, packages, makefile, arch, subarch, flavour, vars, makeflags, extra): - image = self.templates["control.image"] + image_type_modulesextra = self.templates["control.image.type-modulesextra"] + image_type_modulesinline = self.templates["control.image.type-modulesinline"] + image_type_standalone = self.templates["control.image.type-standalone"] headers = self.templates["control.headers"] - modules = self.templates["control.modules"] image_latest = self.templates["control.image.latest"] headers_latest = self.templates["control.headers.latest"] @@ -117,16 +117,19 @@ class gencontrol(debian_linux.gencontrol.gencontrol): packages_own = [] packages_dummy = [] - if vars['type'] == 'plain-xen': - p = self.process_package(modules[0], vars) - image_depends.extend(p['Reverse-Depends']) - del p['Reverse-Depends'] - packages_own.append(p) + if vars['type'] == 'plain-s390-tape': + image = image_type_standalone + elif vars['type'] == 'plain-xen': + image = image_type_modulesextra + else: + image = image_type_modulesinline packages_own.append(self.process_real_image(image[0], image_depends, vars)) + packages_own.extend(self.process_packages(image[1:], vars)) packages_dummy.extend(self.process_packages(image_latest, vars)) - if vars.get('modules', True): + if image in (image_type_modulesextra, image_type_modulesinline): + makeflags['MODULES'] = True packages_own.append(self.process_package(headers[0], vars)) packages_dummy.append(self.process_package(headers_latest[0], vars)) extra['headers_arch_depends'].append('%s (= ${Source-Version})' % packages_own[-1]['Package']) diff --git a/debian/rules.real b/debian/rules.real index 055aa7cd1..087dc4242 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -69,7 +69,7 @@ endif binary-arch-arch: install-headers-all install-headers-$(ARCH) binary-arch-subarch: install-header-$(ARCH)-$(SUBARCH) binary-arch-flavour: install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) -ifneq ($(MODULES),False) +ifeq ($(MODULES),True) binary-arch-flavour: install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR) endif diff --git a/debian/templates/control.image.type-modulesextra.in b/debian/templates/control.image.type-modulesextra.in new file mode 100644 index 000000000..a9910b789 --- /dev/null +++ b/debian/templates/control.image.type-modulesextra.in @@ -0,0 +1,20 @@ +Package: linux-image-@upstreamversion@@abiname@@localversion@ +Section: base +Priority: optional +Provides: linux-image, linux-image-@major@ +Depends: linux-modules-@upstreamversion@@abiname@@localversion@ (= ${Source-Version}) +Suggests: linux-doc-@version@ | linux-source-@version@ +Description: Linux kernel @upstreamversion@ image on @class@ machines + This package provides the binary image for + Linux kernel @upstreamversion@ on @longclass@ machines. + . + This packages is produced using an updated kernel packaging system + and replaces older kernel-image packages + +Package: linux-modules-@upstreamversion@@abiname@@localversion@ +Section: base +Priority: optional +Depends: module-init-tools (>= 0.9.13) +Description: Linux kernel modules @upstreamversion@ image on @class@ machines + This package provides pre-built loadable modules for + Linux kernel @version@ on @longclass@ machines. diff --git a/debian/templates/control.image.in b/debian/templates/control.image.type-modulesinline.in similarity index 100% rename from debian/templates/control.image.in rename to debian/templates/control.image.type-modulesinline.in diff --git a/debian/templates/control.image.type-standalone.in b/debian/templates/control.image.type-standalone.in new file mode 100644 index 000000000..3b8671b32 --- /dev/null +++ b/debian/templates/control.image.type-standalone.in @@ -0,0 +1,11 @@ +Package: linux-image-@upstreamversion@@abiname@@localversion@ +Section: base +Priority: optional +Provides: linux-image, linux-image-@major@ +Suggests: linux-doc-@version@ | linux-source-@version@ +Description: Linux kernel @upstreamversion@ image on @class@ machines + This package provides the binary image for + Linux kernel @upstreamversion@ on @longclass@ machines. + . + This packages is produced using an updated kernel packaging system + and replaces older kernel-image packages diff --git a/debian/templates/control.modules.in b/debian/templates/control.modules.in deleted file mode 100644 index a764bf0a5..000000000 --- a/debian/templates/control.modules.in +++ /dev/null @@ -1,8 +0,0 @@ -Package: linux-modules-@upstreamversion@@abiname@@localversion@ -Section: base -Priority: optional -Depends: module-init-tools (>= 0.9.13) -Reverse-Depends: linux-modules-@upstreamversion@@abiname@@localversion@ (= ${Source-Version}) -Description: Linux kernel modules @upstreamversion@ image on @class@ machines - This package provides pre-built loadable modules for - Linux kernel @version@ on @longclass@ machines. From df35583dd20a7ab793f43de3300745e66122e1b1 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 22:54:55 +0000 Subject: [PATCH 025/108] debian/lib/python/debian_linux/config.py, debian/lib/python/debian_linux/debian.py: Remove unused entries. svn path=/dists/trunk/linux-2.6/; revision=6340 --- debian/lib/python/debian_linux/config.py | 1 - debian/lib/python/debian_linux/debian.py | 1 - 2 files changed, 2 deletions(-) diff --git a/debian/lib/python/debian_linux/config.py b/debian/lib/python/debian_linux/config.py index 55ed5ff85..b6b02f291 100644 --- a/debian/lib/python/debian_linux/config.py +++ b/debian/lib/python/debian_linux/config.py @@ -33,7 +33,6 @@ class config_reader(dict): 'available': schema_item_boolean(), 'flavours': schema_item_list(), 'initramfs': schema_item_boolean(), - 'modules': schema_item_boolean(), 'initramfs-generators': schema_item_list(), 'subarches': schema_item_list(), } diff --git a/debian/lib/python/debian_linux/debian.py b/debian/lib/python/debian_linux/debian.py index 2b83362c7..9e41e0c83 100644 --- a/debian/lib/python/debian_linux/debian.py +++ b/debian/lib/python/debian_linux/debian.py @@ -202,7 +202,6 @@ class package(dict): ('Suggests', package_relation_list), ('Replaces', package_relation_list), ('Conflicts', package_relation_list), - ('Reverse-Depends', package_relation_list), # Some sort of hack ('Description', package_description), )) From b55427f44acdaf060697477c82083c1c83b2c406 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Wed, 29 Mar 2006 22:59:52 +0000 Subject: [PATCH 026/108] debian/arch/s390/defines: Add s390-tape flavour. svn path=/dists/trunk/linux-2.6/; revision=6341 --- debian/arch/s390/defines | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/debian/arch/s390/defines b/debian/arch/s390/defines index 7e0823625..160c97393 100644 --- a/debian/arch/s390/defines +++ b/debian/arch/s390/defines @@ -1,5 +1,8 @@ [base] -flavours: s390 s390x +flavours: + s390 + s390-tape + s390x kernel-arch: s390 kernel-header-dirs: s390 @@ -13,6 +16,14 @@ initramfs-tools: initramfs-tools (>= 0.55) [s390] class: IBM S/390 +[s390-tape] +class: IBM S/390 tape + +[s390-tape_image] +desc: This kernel has support to IPL (boot) from a tape. +initramfs: false +type: plain-s390-tape + [s390x] class: IBM zSeries From a27da8be623f74a6d6862877b0af8f2424197efd Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 31 Mar 2006 17:13:35 +0000 Subject: [PATCH 027/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6356 --- debian/arch/alpha/config | 2 +- debian/arch/amd64/config | 2 +- debian/arch/arm/config.s3c2410 | 2 +- debian/arch/i386/config | 2 +- debian/arch/ia64/config | 2 +- debian/arch/ia64/defines | 1 - debian/bin/check-patches.sh | 13 + debian/changelog | 6 +- debian/lib/python/debian_linux/gencontrol.py | 1 + debian/modules/gencontrol.py | 1 - debian/modules/rules.include | 8 +- debian/modules/rules.real.include | 16 + debian/patches/TODO | 115 - debian/patches/hppa-incompatible.patch | 9775 ----------------- ...powerpc-mv643xx-spinlock-fix-support.patch | 66 - debian/patches/series/1 | 3 - debian/patches/vserver-powerpc-fix01.patch | 10 - 17 files changed, 44 insertions(+), 9981 deletions(-) create mode 100755 debian/bin/check-patches.sh create mode 100644 debian/modules/rules.real.include delete mode 100644 debian/patches/TODO delete mode 100644 debian/patches/hppa-incompatible.patch delete mode 100644 debian/patches/powerpc-mv643xx-spinlock-fix-support.patch delete mode 100644 debian/patches/vserver-powerpc-fix01.patch diff --git a/debian/arch/alpha/config b/debian/arch/alpha/config index 55014dc47..80755c15a 100644 --- a/debian/arch/alpha/config +++ b/debian/arch/alpha/config @@ -1552,7 +1552,7 @@ CONFIG_CODA_FS=m CONFIG_AFS_FS=m CONFIG_RXRPC=m CONFIG_ACORN_PARTITION=y -CONFIG_ACORN_PARTITION_CUMANA=y +# CONFIG_ACORN_PARTITION_CUMANA is not set # CONFIG_ACORN_PARTITION_EESOX is not set CONFIG_ACORN_PARTITION_ICS=y # CONFIG_ACORN_PARTITION_ADFS is not set diff --git a/debian/arch/amd64/config b/debian/arch/amd64/config index 991570c5e..dac97d81d 100644 --- a/debian/arch/amd64/config +++ b/debian/arch/amd64/config @@ -1459,7 +1459,7 @@ CONFIG_CODA_FS=m CONFIG_AFS_FS=m CONFIG_RXRPC=m CONFIG_ACORN_PARTITION=y -CONFIG_ACORN_PARTITION_CUMANA=y +# CONFIG_ACORN_PARTITION_CUMANA is not set # CONFIG_ACORN_PARTITION_EESOX is not set CONFIG_ACORN_PARTITION_ICS=y # CONFIG_ACORN_PARTITION_ADFS is not set diff --git a/debian/arch/arm/config.s3c2410 b/debian/arch/arm/config.s3c2410 index 31a2ae85a..8101bb9ac 100644 --- a/debian/arch/arm/config.s3c2410 +++ b/debian/arch/arm/config.s3c2410 @@ -1131,7 +1131,7 @@ CONFIG_PPP_MULTILINK=y # CONFIG_USB_GADGET_NET2280 is not set CONFIG_USB_SERIAL_MCT_U232=m CONFIG_PARPORT_NOT_PC=y -CONFIG_ACORN_PARTITION_CUMANA=y +# CONFIG_ACORN_PARTITION_CUMANA is not set CONFIG_USB_SERIAL_TI=m CONFIG_USB_STORAGE_JUMPSHOT=y CONFIG_USB_AIPTEK=m diff --git a/debian/arch/i386/config b/debian/arch/i386/config index 4e4a9cd6f..fd8014e31 100644 --- a/debian/arch/i386/config +++ b/debian/arch/i386/config @@ -1709,7 +1709,7 @@ CONFIG_CODA_FS=m CONFIG_AFS_FS=m CONFIG_RXRPC=m CONFIG_ACORN_PARTITION=y -CONFIG_ACORN_PARTITION_CUMANA=y +# CONFIG_ACORN_PARTITION_CUMANA is not set # CONFIG_ACORN_PARTITION_EESOX is not set CONFIG_ACORN_PARTITION_ICS=y # CONFIG_ACORN_PARTITION_ADFS is not set diff --git a/debian/arch/ia64/config b/debian/arch/ia64/config index 71fdc9921..0ceeec104 100644 --- a/debian/arch/ia64/config +++ b/debian/arch/ia64/config @@ -1228,7 +1228,7 @@ CONFIG_CODA_FS_OLD_API=y CONFIG_AFS_FS=m CONFIG_RXRPC=m CONFIG_ACORN_PARTITION=y -CONFIG_ACORN_PARTITION_CUMANA=y +# CONFIG_ACORN_PARTITION_CUMANA is not set CONFIG_ACORN_PARTITION_EESOX=y CONFIG_ACORN_PARTITION_ICS=y CONFIG_ACORN_PARTITION_ADFS=y diff --git a/debian/arch/ia64/defines b/debian/arch/ia64/defines index 5bafb5e50..d1ec57da6 100644 --- a/debian/arch/ia64/defines +++ b/debian/arch/ia64/defines @@ -8,7 +8,6 @@ kernel-arch: ia64 kernel-header-dirs: ia64 [image] -initramfs-generators: yaird suggests: elilo, fdutils [itanium] diff --git a/debian/bin/check-patches.sh b/debian/bin/check-patches.sh new file mode 100755 index 000000000..22e36d482 --- /dev/null +++ b/debian/bin/check-patches.sh @@ -0,0 +1,13 @@ +#!/bin/sh -e + +TMPDIR=$(mktemp -d) +trap "rm -rf $TMPDIR" EXIT +awk '{if (NF >= 2) print $2}' debian/patches/series/* | sort -u > $TMPDIR/used +find debian/patches -maxdepth 1 -type f -printf "%f\n" | sort > $TMPDIR/avail +echo "Used patches" +echo "==============" +cat $TMPDIR/used +echo +echo "Unused patches" +echo "==============" +fgrep -v -f $TMPDIR/used $TMPDIR/avail diff --git a/debian/changelog b/debian/changelog index afbd7fb0f..fde3b38a2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,8 +10,12 @@ linux-2.6 (2.6.16-5) UNRELEASED; urgency=low * Provide real dependency packages for module building. * Fix module package output. * Include .kernelrelease in headers packages. (closes: #359813) + * Disable Cumana partition support completely. (closes: #359207) - -- Bastian Blank Thu, 30 Mar 2006 00:08:39 +0200 + [ dann frazier ] + * [ia64] initramfs-tools works now, no longer restrict initramfs-generators + + -- dann frazier Thu, 30 Mar 2006 15:45:35 -0700 linux-2.6 (2.6.16-4) unstable; urgency=medium diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index e75147b28..5d6ebecd8 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -37,6 +37,7 @@ class gencontrol(object): def do_main(self, packages, makefile): makeflags = { + 'MAJOR': self.version['major'], 'VERSION': self.version['version'], 'SOURCE_UPSTREAM': self.version['source_upstream'], 'SOURCEVERSION': self.version['source'], diff --git a/debian/modules/gencontrol.py b/debian/modules/gencontrol.py index c9f7abfe3..8cc05d71e 100755 --- a/debian/modules/gencontrol.py +++ b/debian/modules/gencontrol.py @@ -11,7 +11,6 @@ class gencontrol(debian_linux.gencontrol.gencontrol): main = self.templates["control.main"] packages.extend(self.process_packages(main, vars)) - def do_main_packages(self, packages): l = ['linux-headers-%s%s-all-%s [%s]' % (self.version['upstream'], self.abiname, arch, arch) for arch in self.config['base',]['arches']] packages['source']['Build-Depends'].extend(l) diff --git a/debian/modules/rules.include b/debian/modules/rules.include index 7d5ca8961..0720da490 100644 --- a/debian/modules/rules.include +++ b/debian/modules/rules.include @@ -30,8 +30,8 @@ binary-arch: binary: binary-indep binary-arch CONTROL_FILES = debian/changelog $(wildcard debian/templates/control.*) -CONTROL_FILES += debian/arch/defines $(wildcard debian/arch/*/defines) $(wildcard debian/arch/*/*/defines) -debian/control debian/rules.gen: $(__MODULES_DIR)gencontrol.py $(CONTROL_FILES) +CONTROL_FILES += $(wildcard debian/arch/defines) $(wildcard debian/arch/*/defines) $(wildcard debian/arch/*/*/defines) +debian/control debian/rules.gen: $(CONTROL_FILES) if [ -f debian/control.md5sum ]; then \ if md5sum $^ | diff - debian/control.md5sum > /dev/null; then true; else \ $(MAKE) -f debian/rules debian/control-real; \ @@ -40,8 +40,8 @@ debian/control debian/rules.gen: $(__MODULES_DIR)gencontrol.py $(CONTROL_FILES) $(MAKE) -f debian/rules debian/control-real; \ fi -debian/control-real: $(__MODULES_DIR)gencontrol.py $(CONTROL_FILES) - $< +debian/control-real: $(CONTROL_FILES) + $(__MODULES_DIR)gencontrol.py md5sum $^ > debian/control.md5sum @echo @echo This target is made to fail intentionally, to make sure diff --git a/debian/modules/rules.real.include b/debian/modules/rules.real.include new file mode 100644 index 000000000..04a44592c --- /dev/null +++ b/debian/modules/rules.real.include @@ -0,0 +1,16 @@ +__MODULES_DIR := $(dir $(lastword $(MAKEFILE_LIST))) + +DEB_HOST_ARCH := $(shell dpkg-architecture -a$(ARCH) -qDEB_HOST_ARCH) +DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -a$(ARCH) -qDEB_HOST_GNU_TYPE) +DEB_BUILD_ARCH := $(shell dpkg-architecture -a$(ARCH) -qDEB_BUILD_ARCH) + +export DH_OPTIONS + +HEADERS_DIR = /usr/src/linux-headers-$(UPSTREAMVERSION)$(ABINAME)$(LOCALVERSION) + +include $(__MODULES_DIR)rules.defs + +ifdef DEBIAN_KERNEL_JOBS + JOBS_ARG = -j$(DEBIAN_KERNEL_JOBS) +endif + diff --git a/debian/patches/TODO b/debian/patches/TODO deleted file mode 100644 index a899821f0..000000000 --- a/debian/patches/TODO +++ /dev/null @@ -1,115 +0,0 @@ -Disabled because not applying cleanly, need investigating : - -drivers-scsi-megaraid_splitup.patch - FAILS: 1 hunk (drivers/scsi/megaraid/Kconfig.megaraid) - -remove-references-to-removed-drivers.patch - FAILS 1 hunk (drivers/usb/misc/Makefile) - -powerpc-g4-l2-flush-errata.patch - FAILS 1 hunk (arch/ppc/kernel/l2cr.S) - - - -Complete list of Mark Hymers (not all of those where still in use). - -Applied upstream -================ - -amd64-tlb-flush-sigsegv-fix.patch - Git commit: bc5e8fdfc622b03acf5ac974a1b8b26da6511c99 - -kernel-api-documentation-generation-fix.diff - Git commit: 9d01a82e46a8dd18233121a6bc140e5576649583 - -m68k-sonic.patch - Git commit: efcce839360fb3a7b6dedeacaec80f68b0f2d052 - -mempolicy-check-mode.patch - Git commit: ba17101b41977f124948e0a7797fdcbb59e19f3e - -powerpc-pmac-sound-check.patch - Git commit: 4e6a06eec46067df3c30fe1fbc2e1a7cc37b9678 - -powerpc-ppc64-biarch-override.patch - Git commit: 723e2b35e43dcbcfd737c40453caa7d198092d23 - - -Not applied upstream -==================== - -amd64-int3-fix.patch - APPLIES Offset - -drivers-scsi-megaraid_splitup.patch - FAILS: 1 hunk (drivers/scsi/megaraid/Kconfig.megaraid) - -fbdev-radeon-noaccel.patch - APPLIES Offset - -fs-asfs-2.patch - APPLIES Offset - -ia64-irq-affinity-upfix.patch - APPLIES Offset - -m68k-42_dma.patch - APPLIES Offset - -modular-ide.patch - APPLIES Offset - -modular-ide-pnp.patch - APPLIES Offset - -powerpc-apus.patch - APPLIES Offset - -powerpc-apus-todo.patch - FAILS 1 hunk (include/video/vga.h) - -powerpc-calibrate-tau.patch - APPLIES Offset + fuzz - -powerpc-fix-power3-ftbfs.patch - APPLIES - -powerpc-g3-750cxe.patch - Claims to already be applied - Looks like patch is confused as a different but similar model was added - -powerpc-g4-l2-flush-errata.patch - FAILS 1 hunk (arch/ppc/kernel/l2cr.S) - -powerpc-mkvmlinuz-support.patch - APPLIES - -powerpc-mv643xx-hotplug-support.patch - APPLIES - -powerpc-pmac-cache-power34-fix.patch - APPLIES - -powerpc-serial-of.patch - FAILS 1 hunk ignored (arch/ppc64/kernel/setup.c) - This hunk claims to already be applied - -powerpc-serial.patch - APPLIES Offset - -qla2xxx-removed.patch - APPLIES Offset - -remove-references-to-removed-drivers.patch - FAILS 1 hunk (drivers/usb/misc/Makefile) - -sparc64-hme-lockup.patch - APPLIES - -tty-locking-fixes9.patch - APPLIES - -version.patch - APPLIES OFFSET - -============== diff --git a/debian/patches/hppa-incompatible.patch b/debian/patches/hppa-incompatible.patch deleted file mode 100644 index e133abe90..000000000 --- a/debian/patches/hppa-incompatible.patch +++ /dev/null @@ -1,9775 +0,0 @@ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/Documentation/parisc/todo CVS2_6_15_RC7_PA0/Documentation/parisc/todo ---- LINUS_2_6_15_RC7/Documentation/parisc/todo 1969-12-31 17:00:00.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/Documentation/parisc/todo 2005-10-28 19:28:34.000000000 -0600 -@@ -0,0 +1,82 @@ -+Status 2005-10-28 : -+------------------- -+ - Merged to 2.6.15 -+ -+Todo: -+----- -+ -+ - Review and eliminate all warnings for io accesses with an eye to -+ turning on ioremap -+ - 2005-02-04 (Carlos) Review the gettimeofday -+ implementation, possibly use a light-weight-syscall and -+ rely on cr16 and cpu speed for more accurate timing? -+ This requires adding some backwards compatibility code in -+ userspace since the LWS might not be available on the -+ booted kernel. Detecting LWS is a problem. -+ - PREEMPT support -+ - CPU hotplug: we cannot bring up cpus after init, and we don't know if we can -+ shutdown cpus -+ - task_struct/thread_info split -- task_struct should not be visible in -+ entry.S, we need to move some items into thread_info -- this includes -+ pt_regs and maybe some of the flags (ptrace, etc) -+ - flush_tlb_kernel_range is horribly inefficient. this has been merged -+ with the userspace tlb flush, but it has a magic constant that needs -+ tuning -+ - Superdome support -+ - our PDC early debug console hacks need to be cleaned up somehow -+ - CPU IRQ affinity (willy) -+ - Allow more than BITS_PER_LONG cpu interrupts to be allocated (willy) -+ - 64-bit userspace (Leandro) -+ - syscall signal return path needs work, we don't loop on signal -+ delivery like other archs. -+ = 2005-02-04 (Carlos) This entry should be more specific, -+ we recently fixed do_signal such that it always -+ loops forcing the signal. If this was the bug then it was -+ fixed. -+ -+ -+Drivers -+------- -+ -+ - write Lasi floppy driver -+ - write Suckyio floppy driver -+ - write spifi driver (rbrad) -+ - modify ncr53c8xx driver for Outfield (735 & 755) -+ - write GSC FDDI driver -+ - write Timi ASIC (74x) support -+ - EISA DMA support -+ -+ -+Started and in progress: -+------------------------ -+ - 2004-08-16 (Carlos) -+ 64-bit binutils needs to be fixed to get multiple stub -+ section support. -+ - port hil_kbd.c to new input layer -+ - port hil_ptr.c to new input layer -+ -+ -+CONFIG options without help: -+----------------------------- -+ - REVIEW THESE ENTRIES! -+ -+ _USB_OHCI_HCD (add parisc info?) -+ _HP_SDC_RTC -+ _HIL_MLC -+ _HIL_KBD (to improve) -+ _HIL_PTR (to improve) -+ -+ -+Review all the todo entries below! -+---------------------------------- -+ -+ - the fix for do_fork needs checking -+ - ns87415 dma doesn't work reliably on suckyio-systems -+ - (ab)use kmap/kunmap on 64-bit to eliminate flush_dcache calls. -+ - cp_new_stat32 for sys_parisc32.c is inefficient; maybe it's better -+ to fill in a tmp stat32 and just do copy_to_user in one go at the end? -+ - investigate not putting in extable entries for put_kernel_asm; will -+ probably reduce kernel size -+ - fix HIL problem: ksoftirqd/0 eats 56% cpu (kernel 2.4 & kernel 2.6) -+ - NPTL kernel support (CLONE_*TID flags need to be correctly handled by -+ sys_clone() and friends) -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/ia64/ia32/ia32_signal.c CVS2_6_15_RC7_PA0/arch/ia64/ia32/ia32_signal.c ---- LINUS_2_6_15_RC7/arch/ia64/ia32/ia32_signal.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/ia64/ia32/ia32_signal.c 2005-09-14 06:54:22.000000000 -0600 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/ia64/ia32/ia32priv.h CVS2_6_15_RC7_PA0/arch/ia64/ia32/ia32priv.h ---- LINUS_2_6_15_RC7/arch/ia64/ia32/ia32priv.h 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/ia64/ia32/ia32priv.h 2005-12-19 05:42:13.000000000 -0700 -@@ -225,58 +225,6 @@ - unsigned int st_ino_hi; - }; - --typedef struct compat_siginfo { -- int si_signo; -- int si_errno; -- int si_code; -- -- union { -- int _pad[((128/sizeof(int)) - 3)]; -- -- /* kill() */ -- struct { -- unsigned int _pid; /* sender's pid */ -- unsigned int _uid; /* sender's uid */ -- } _kill; -- -- /* POSIX.1b timers */ -- struct { -- compat_timer_t _tid; /* timer id */ -- int _overrun; /* overrun count */ -- char _pad[sizeof(unsigned int) - sizeof(int)]; -- compat_sigval_t _sigval; /* same as below */ -- int _sys_private; /* not to be passed to user */ -- } _timer; -- -- /* POSIX.1b signals */ -- struct { -- unsigned int _pid; /* sender's pid */ -- unsigned int _uid; /* sender's uid */ -- compat_sigval_t _sigval; -- } _rt; -- -- /* SIGCHLD */ -- struct { -- unsigned int _pid; /* which child */ -- unsigned int _uid; /* sender's uid */ -- int _status; /* exit code */ -- compat_clock_t _utime; -- compat_clock_t _stime; -- } _sigchld; -- -- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ -- struct { -- unsigned int _addr; /* faulting insn/memory ref. */ -- } _sigfault; -- -- /* SIGPOLL */ -- struct { -- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ -- int _fd; -- } _sigpoll; -- } _sifields; --} compat_siginfo_t; -- - struct old_linux32_dirent { - u32 d_ino; - u32 d_offset; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/cache.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/cache.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/cache.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/cache.c 2005-12-17 10:21:16.000000000 -0700 -@@ -29,9 +29,9 @@ - #include - #include - --int split_tlb; --int dcache_stride; --int icache_stride; -+int split_tlb __read_mostly; -+int dcache_stride __read_mostly; -+int icache_stride __read_mostly; - EXPORT_SYMBOL(dcache_stride); - - -@@ -45,29 +45,29 @@ - EXPORT_SYMBOL(pa_tlb_lock); - #endif - --struct pdc_cache_info cache_info; -+struct pdc_cache_info cache_info __read_mostly; - #ifndef CONFIG_PA20 --static struct pdc_btlb_info btlb_info; -+static struct pdc_btlb_info btlb_info __read_mostly; - #endif - - #ifdef CONFIG_SMP - void - flush_data_cache(void) - { -- on_each_cpu((void (*)(void *))flush_data_cache_local, NULL, 1, 1); -+ on_each_cpu(flush_data_cache_local, NULL, 1, 1); - } - void - flush_instruction_cache(void) - { -- on_each_cpu((void (*)(void *))flush_instruction_cache_local, NULL, 1, 1); -+ on_each_cpu(flush_instruction_cache_local, NULL, 1, 1); - } - #endif - - void - flush_cache_all_local(void) - { -- flush_instruction_cache_local(); -- flush_data_cache_local(); -+ flush_instruction_cache_local(NULL); -+ flush_data_cache_local(NULL); - } - EXPORT_SYMBOL(flush_cache_all_local); - -@@ -332,7 +332,7 @@ - } - - #define FLUSH_THRESHOLD 0x80000 /* 0.5MB */ --int parisc_cache_flush_threshold = FLUSH_THRESHOLD; -+int parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD; - - void parisc_setup_cache_timing(void) - { -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/drivers.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/drivers.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/drivers.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/drivers.c 2005-12-17 11:18:59.000000000 -0700 -@@ -39,7 +39,7 @@ - #include - - /* See comments in include/asm-parisc/pci.h */ --struct hppa_dma_ops *hppa_dma_ops; -+struct hppa_dma_ops *hppa_dma_ops __read_mostly; - EXPORT_SYMBOL(hppa_dma_ops); - - static struct device root = { -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/firmware.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/firmware.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/firmware.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/firmware.c 2005-12-17 10:21:16.000000000 -0700 -@@ -80,7 +80,7 @@ - - /* Firmware needs to be initially set to narrow to determine the - * actual firmware width. */ --int parisc_narrow_firmware = 1; -+int parisc_narrow_firmware __read_mostly = 1; - #endif - - /* On most currently-supported platforms, IODC I/O calls are 32-bit calls -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/inventory.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/inventory.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/inventory.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/inventory.c 2005-12-17 10:54:41.000000000 -0700 -@@ -38,7 +38,7 @@ - */ - #undef DEBUG_PAT - --int pdc_type = PDC_TYPE_ILLEGAL; -+int pdc_type __read_mostly = PDC_TYPE_ILLEGAL; - - void __init setup_pdc(void) - { -@@ -120,8 +120,8 @@ - * pdc info is bad in this case). - */ - -- if ( ((start & (PAGE_SIZE - 1)) != 0) -- || ((pages4k & ((1UL << PDC_PAGE_ADJ_SHIFT) - 1)) != 0) ) { -+ if (unlikely( ((start & (PAGE_SIZE - 1)) != 0) -+ || ((pages4k & ((1UL << PDC_PAGE_ADJ_SHIFT) - 1)) != 0) )) { - - panic("Memory range doesn't align with page size!\n"); - } -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/pci-dma.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/pci-dma.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/pci-dma.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/pci-dma.c 2005-12-17 10:54:41.000000000 -0700 -@@ -33,10 +33,10 @@ - #include - #include /* for purge_tlb_*() macros */ - --static struct proc_dir_entry * proc_gsc_root = NULL; -+static struct proc_dir_entry * proc_gsc_root __read_mostly = NULL; - static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length); --static unsigned long pcxl_used_bytes = 0; --static unsigned long pcxl_used_pages = 0; -+static unsigned long pcxl_used_bytes __read_mostly = 0; -+static unsigned long pcxl_used_pages __read_mostly = 0; - - extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */ - static spinlock_t pcxl_res_lock; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/pdc_chassis.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/pdc_chassis.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/pdc_chassis.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/pdc_chassis.c 2005-12-17 11:18:59.000000000 -0700 -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -38,8 +39,8 @@ - - - #ifdef CONFIG_PDC_CHASSIS --static int pdc_chassis_old = 0; --static unsigned int pdc_chassis_enabled = 1; -+static int pdc_chassis_old __read_mostly = 0; -+static unsigned int pdc_chassis_enabled __read_mostly = 1; - - - /** -@@ -132,7 +133,7 @@ - { - #ifdef CONFIG_PDC_CHASSIS - int handle = 0; -- if (pdc_chassis_enabled) { -+ if (likely(pdc_chassis_enabled)) { - DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); - - /* Let see if we have something to handle... */ -@@ -142,7 +143,7 @@ - printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); - handle = 1; - } -- else if (pdc_chassis_old) { -+ else if (unlikely(pdc_chassis_old)) { - printk(KERN_INFO "Enabling old style chassis LED panel support.\n"); - handle = 1; - } -@@ -178,7 +179,7 @@ - /* Maybe we should do that in an other way ? */ - int retval = 0; - #ifdef CONFIG_PDC_CHASSIS -- if (pdc_chassis_enabled) { -+ if (likely(pdc_chassis_enabled)) { - - DPRINTK(KERN_DEBUG "%s: pdc_chassis_send_status(%d)\n", __FILE__, message); - -@@ -214,7 +215,7 @@ - } - } else retval = -1; - #else -- if (pdc_chassis_old) { -+ if (unlikely(pdc_chassis_old)) { - switch (message) { - case PDC_CHASSIS_DIRECT_BSTART: - case PDC_CHASSIS_DIRECT_BCOMPLETE: -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/perf.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/perf.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/perf.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/perf.c 2005-12-17 10:54:41.000000000 -0700 -@@ -66,10 +66,10 @@ - uint8_t write_control; - }; - --static int perf_processor_interface = UNKNOWN_INTF; --static int perf_enabled = 0; -+static int perf_processor_interface __read_mostly = UNKNOWN_INTF; -+static int perf_enabled __read_mostly = 0; - static spinlock_t perf_lock; --struct parisc_device *cpu_device = NULL; -+struct parisc_device *cpu_device __read_mostly = NULL; - - /* RDRs to write for PCX-W */ - static int perf_rdrs_W[] = -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/process.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/process.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/process.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/process.c 2005-12-17 10:54:41.000000000 -0700 -@@ -54,7 +54,7 @@ - #include - #include - --static int hlt_counter; -+static int hlt_counter __read_mostly; - - /* - * Power off function, if any -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/processor.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/processor.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/processor.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/processor.c 2005-12-17 10:21:16.000000000 -0700 -@@ -44,10 +44,10 @@ - #include /* for struct irq_region */ - #include - --struct system_cpuinfo_parisc boot_cpu_data; -+struct system_cpuinfo_parisc boot_cpu_data __read_mostly; - EXPORT_SYMBOL(boot_cpu_data); - --struct cpuinfo_parisc cpu_data[NR_CPUS]; -+struct cpuinfo_parisc cpu_data[NR_CPUS] __read_mostly; - - /* - ** PARISC CPU driver - claim "device" and initialize CPU data structures. -@@ -378,12 +378,12 @@ - return 0; - } - --static struct parisc_device_id processor_tbl[] = { -+static struct parisc_device_id processor_tbl[] __read_mostly = { - { HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID }, - { 0, } - }; - --static struct parisc_driver cpu_driver = { -+static struct parisc_driver cpu_driver __read_mostly = { - .name = "CPU", - .id_table = processor_tbl, - .probe = processor_probe -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/setup.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/setup.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/setup.c 2005-12-27 13:25:34.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/setup.c 2005-12-17 10:54:41.000000000 -0700 -@@ -46,15 +46,15 @@ - #include - #include - --char command_line[COMMAND_LINE_SIZE]; -+char command_line[COMMAND_LINE_SIZE] __read_mostly; - - /* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */ --struct proc_dir_entry * proc_runway_root = NULL; --struct proc_dir_entry * proc_gsc_root = NULL; --struct proc_dir_entry * proc_mckinley_root = NULL; -+struct proc_dir_entry * proc_runway_root __read_mostly = NULL; -+struct proc_dir_entry * proc_gsc_root __read_mostly = NULL; -+struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL; - - #if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA)) --int parisc_bus_is_phys = 1; /* Assume no IOMMU is present */ -+int parisc_bus_is_phys __read_mostly = 1; /* Assume no IOMMU is present */ - EXPORT_SYMBOL(parisc_bus_is_phys); - #endif - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/smp.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/smp.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/smp.c 2005-12-27 13:25:35.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/smp.c 2005-12-17 10:54:41.000000000 -0700 -@@ -39,7 +39,7 @@ - #include - #include - #include --#include /* for flush_tlb_all() proto/macro */ -+#include - - #include - #include /* for CPU_IRQ_REGION and friends */ -@@ -58,9 +58,9 @@ - - volatile struct task_struct *smp_init_current_idle_task; - --static volatile int cpu_now_booting = 0; /* track which CPU is booting */ -+static volatile int cpu_now_booting __read_mostly = 0; /* track which CPU is booting */ - --static int parisc_max_cpus = 1; -+static int parisc_max_cpus __read_mostly = 1; - - /* online cpus are ones that we've managed to bring up completely - * possible cpus are all valid cpu -@@ -71,8 +71,8 @@ - * empty in the beginning. - */ - --cpumask_t cpu_online_map = CPU_MASK_NONE; /* Bitmap of online CPUs */ --cpumask_t cpu_possible_map = CPU_MASK_ALL; /* Bitmap of Present CPUs */ -+cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; /* Bitmap of online CPUs */ -+cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL; /* Bitmap of Present CPUs */ - - EXPORT_SYMBOL(cpu_online_map); - EXPORT_SYMBOL(cpu_possible_map); -@@ -406,12 +406,10 @@ - * as we want to ensure all TLB's flushed before proceeding. - */ - --extern void flush_tlb_all_local(void); -- - void - smp_flush_tlb_all(void) - { -- on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1); -+ on_each_cpu(flush_tlb_all_local, NULL, 1, 1); - } - - -@@ -487,7 +485,7 @@ - #endif - - flush_cache_all_local(); /* start with known state */ -- flush_tlb_all_local(); -+ flush_tlb_all_local(NULL); - - local_irq_enable(); /* Interrupts have been off until now */ - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/time.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/time.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/time.c 2005-12-27 13:25:35.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/time.c 2005-12-17 10:21:16.000000000 -0700 -@@ -36,8 +36,8 @@ - /* xtime and wall_jiffies keep wall-clock time */ - extern unsigned long wall_jiffies; - --static long clocktick; /* timer cycles per tick */ --static long halftick; -+static long clocktick __read_mostly; /* timer cycles per tick */ -+static long halftick __read_mostly; - - #ifdef CONFIG_SMP - extern void smp_do_timer(struct pt_regs *regs); -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/topology.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/topology.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/topology.c 2005-12-27 13:25:35.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/topology.c 2005-12-17 11:18:59.000000000 -0700 -@@ -20,8 +20,9 @@ - #include - #include - #include -+#include - --static struct cpu cpu_devices[NR_CPUS]; -+static struct cpu cpu_devices[NR_CPUS] __read_mostly; - - static int __init topology_init(void) - { -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/unaligned.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/unaligned.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/unaligned.c 2005-12-27 13:25:35.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/unaligned.c 2005-12-17 10:21:16.000000000 -0700 -@@ -122,7 +122,7 @@ - #define ERR_NOTHANDLED -1 - #define ERR_PAGEFAULT -2 - --int unaligned_enabled = 1; -+int unaligned_enabled __read_mostly = 1; - - void die_if_kernel (char *str, struct pt_regs *regs, long err); - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/unwind.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/unwind.c ---- LINUS_2_6_15_RC7/arch/parisc/kernel/unwind.c 2005-12-27 13:25:35.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/unwind.c 2005-12-17 10:54:41.000000000 -0700 -@@ -35,7 +35,7 @@ - * we can call unwind_init as early in the bootup process as - * possible (before the slab allocator is initialized) - */ --static struct unwind_table kernel_unwind_table; -+static struct unwind_table kernel_unwind_table __read_mostly; - static LIST_HEAD(unwind_tables); - - static inline const struct unwind_table_entry * -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/vmlinux.lds.S CVS2_6_15_RC7_PA0/arch/parisc/kernel/vmlinux.lds.S ---- LINUS_2_6_15_RC7/arch/parisc/kernel/vmlinux.lds.S 2005-12-27 13:25:35.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/vmlinux.lds.S 2005-12-19 08:10:07.000000000 -0700 -@@ -68,7 +68,7 @@ - RODATA - - /* writeable */ -- . = ALIGN(4096); /* Make sure this is paged aligned so -+ . = ALIGN(4096); /* Make sure this is page aligned so - that we can properly leave these - as writable */ - data_start = .; -@@ -105,6 +105,10 @@ - . = ALIGN(16); - .data.lock_aligned : { *(.data.lock_aligned) } - -+ /* rarely changed data like cpu maps */ -+ . = ALIGN(16); -+ .data.read_mostly : { *(.data.read_mostly) } -+ - _edata = .; /* End of data section */ - - . = ALIGN(16384); /* init_task */ -@@ -194,14 +198,7 @@ - #endif - } - -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -+ STABS_DEBUG - .note 0 : { *(.note) } - - } -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/mm/init.c CVS2_6_15_RC7_PA0/arch/parisc/mm/init.c ---- LINUS_2_6_15_RC7/arch/parisc/mm/init.c 2005-12-27 13:25:35.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/mm/init.c 2005-12-17 11:04:12.000000000 -0700 -@@ -36,9 +36,9 @@ - extern char __init_begin, __init_end; - - #ifdef CONFIG_DISCONTIGMEM --struct node_map_data node_data[MAX_NUMNODES]; --bootmem_data_t bmem_data[MAX_NUMNODES]; --unsigned char pfnnid_map[PFNNID_MAP_MAX]; -+struct node_map_data node_data[MAX_NUMNODES] __read_mostly; -+bootmem_data_t bmem_data[MAX_NUMNODES] __read_mostly; -+unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly; - #endif - - static struct resource data_resource = { -@@ -58,14 +58,14 @@ - .flags = IORESOURCE_BUSY | IORESOURCE_MEM, - }; - --static struct resource sysram_resources[MAX_PHYSMEM_RANGES]; -+static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly; - - /* The following array is initialized from the firmware specific - * information retrieved in kernel/inventory.c. - */ - --physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES]; --int npmem_ranges; -+physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly; -+int npmem_ranges __read_mostly; - - #ifdef __LP64__ - #define MAX_MEM (~0UL) -@@ -73,7 +73,7 @@ - #define MAX_MEM (3584U*1024U*1024U) - #endif /* !__LP64__ */ - --static unsigned long mem_limit = MAX_MEM; -+static unsigned long mem_limit __read_mostly = MAX_MEM; - - static void __init mem_limit_func(void) - { -@@ -300,6 +300,13 @@ - max_pfn = start_pfn + npages; - } - -+ /* IOMMU is always used to access "high mem" on those boxes -+ * that can support enough mem that a PCI device couldn't -+ * directly DMA to any physical addresses. -+ * ISA DMA support will need to revisit this. -+ */ -+ max_low_pfn = max_pfn; -+ - if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) { - printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n"); - BUG(); -@@ -431,11 +438,11 @@ - #define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \ - & ~(VM_MAP_OFFSET-1))) - --void *vmalloc_start; -+void *vmalloc_start __read_mostly; - EXPORT_SYMBOL(vmalloc_start); - - #ifdef CONFIG_PA11 --unsigned long pcxl_dma_start; -+unsigned long pcxl_dma_start __read_mostly; - #endif - - void __init mem_init(void) -@@ -475,7 +482,7 @@ - return 0; - } - --unsigned long *empty_zero_page; -+unsigned long *empty_zero_page __read_mostly; - - void show_mem(void) - { -@@ -785,8 +792,6 @@ - EXPORT_SYMBOL(map_hpux_gateway_page); - #endif - --extern void flush_tlb_all_local(void); -- - void __init paging_init(void) - { - int i; -@@ -795,7 +800,7 @@ - pagetable_init(); - gateway_init(); - flush_cache_all_local(); /* start with known state */ -- flush_tlb_all_local(); -+ flush_tlb_all_local(NULL); - - for (i = 0; i < npmem_ranges; i++) { - unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 }; -@@ -986,7 +991,7 @@ - do_recycle++; - } - spin_unlock(&sid_lock); -- on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1); -+ on_each_cpu(flush_tlb_all_local, NULL, 1, 1); - if (do_recycle) { - spin_lock(&sid_lock); - recycle_sids(recycle_ndirty,recycle_dirty_array); -@@ -998,7 +1003,7 @@ - void flush_tlb_all(void) - { - spin_lock(&sid_lock); -- flush_tlb_all_local(); -+ flush_tlb_all_local(NULL); - recycle_sids(); - spin_unlock(&sid_lock); - } -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/mm/ioremap.c CVS2_6_15_RC7_PA0/arch/parisc/mm/ioremap.c ---- LINUS_2_6_15_RC7/arch/parisc/mm/ioremap.c 2005-12-27 13:25:35.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/parisc/mm/ioremap.c 2005-12-23 18:30:19.000000000 -0700 -@@ -1,12 +1,9 @@ - /* - * arch/parisc/mm/ioremap.c - * -- * Re-map IO memory to kernel address space so that we can access it. -- * This is needed for high PCI addresses that aren't mapped in the -- * 640k-1MB IO memory area on PC's -- * - * (C) Copyright 1995 1996 Linus Torvalds - * (C) Copyright 2001 Helge Deller -+ * (C) Copyright 2005 Kyle McMartin - */ - - #include -@@ -14,81 +11,107 @@ - #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) --{ -- unsigned long end; -+static inline void -+remap_area_pte(pte_t *pte, unsigned long address, unsigned long size, -+ unsigned long phys_addr, unsigned long flags) -+{ -+ unsigned long end, pfn; -+ pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | -+ _PAGE_ACCESSED | flags); - - address &= ~PMD_MASK; -+ - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; -- if (address >= end) -- BUG(); -+ -+ BUG_ON(address >= end); -+ -+ pfn = phys_addr >> PAGE_SHIFT; - do { -- if (!pte_none(*pte)) { -- printk(KERN_ERR "remap_area_pte: page already exists\n"); -- BUG(); -- } -- set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | _PAGE_RW | -- _PAGE_DIRTY | _PAGE_ACCESSED | flags))); -+ BUG_ON(!pte_none(*pte)); -+ -+ set_pte(pte, pfn_pte(pfn, pgprot)); -+ - address += PAGE_SIZE; -- phys_addr += PAGE_SIZE; -+ pfn++; - pte++; - } while (address && (address < end)); - } - --static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, -- unsigned long phys_addr, unsigned long flags) -+static inline int -+remap_area_pmd(pmd_t *pmd, unsigned long address, unsigned long size, -+ unsigned long phys_addr, unsigned long flags) - { - unsigned long end; - - address &= ~PGDIR_MASK; -+ - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; -+ -+ BUG_ON(address >= end); -+ - phys_addr -= address; -- if (address >= end) -- BUG(); - do { -- pte_t * pte = pte_alloc_kernel(pmd, address); -+ pte_t *pte = pte_alloc_kernel(pmd, address); - if (!pte) - return -ENOMEM; -- remap_area_pte(pte, address, end - address, address + phys_addr, flags); -+ -+ remap_area_pte(pte, address, end - address, -+ address + phys_addr, flags); -+ - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); -+ - return 0; - } - --#if (USE_HPPA_IOREMAP) --static int remap_area_pages(unsigned long address, unsigned long phys_addr, -- unsigned long size, unsigned long flags) -+#if USE_HPPA_IOREMAP -+static int -+remap_area_pages(unsigned long address, unsigned long phys_addr, -+ unsigned long size, unsigned long flags) - { -- int error; -- pgd_t * dir; -+ pgd_t *dir; -+ int error = 0; - unsigned long end = address + size; - -+ BUG_ON(address >= end); -+ - phys_addr -= address; -- dir = pgd_offset(&init_mm, address); -+ dir = pgd_offset_k(address); -+ - flush_cache_all(); -- if (address >= end) -- BUG(); -+ - do { -+ pud_t *pud; - pmd_t *pmd; -- pmd = pmd_alloc(&init_mm, dir, address); -+ - error = -ENOMEM; -+ pud = pud_alloc(&init_mm, dir, address); -+ if (!pud) -+ break; -+ -+ pmd = pmd_alloc(&init_mm, pud, address); - if (!pmd) - break; -+ - if (remap_area_pmd(pmd, address, end - address, -- phys_addr + address, flags)) -+ phys_addr + address, flags)) - break; -+ - error = 0; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); -+ - flush_tlb_all(); -+ - return error; - } - #endif /* USE_HPPA_IOREMAP */ -@@ -123,8 +146,7 @@ - - /* - * Remap an arbitrary physical address space into the kernel virtual -- * address space. Needed when the kernel wants to access high addresses -- * directly. -+ * address space. - * - * NOTE! We need to allow non-page-aligned mappings too: we will obviously - * have to convert them into an offset in a page-aligned mapping, but the -@@ -148,8 +170,8 @@ - #endif - - #else -- void * addr; -- struct vm_struct * area; -+ void *addr; -+ struct vm_struct *area; - unsigned long offset, last_addr; - - /* Don't allow wraparound or zero size */ -@@ -167,9 +189,11 @@ - t_addr = __va(phys_addr); - t_end = t_addr + (size - 1); - -- for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) -+ for (page = virt_to_page(t_addr); -+ page <= virt_to_page(t_end); page++) { - if(!PageReserved(page)) - return NULL; -+ } - } - - /* -@@ -185,11 +209,13 @@ - area = get_vm_area(size, VM_IOREMAP); - if (!area) - return NULL; -+ - addr = area->addr; - if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { - vfree(addr); - return NULL; - } -+ - return (void __iomem *) (offset + (char *)addr); - #endif - } -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/x86_64/ia32/ia32_signal.c CVS2_6_15_RC7_PA0/arch/x86_64/ia32/ia32_signal.c ---- LINUS_2_6_15_RC7/arch/x86_64/ia32/ia32_signal.c 2005-12-27 13:25:38.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/arch/x86_64/ia32/ia32_signal.c 2005-11-12 20:29:21.000000000 -0700 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/net/tulip/media.c CVS2_6_15_RC7_PA0/drivers/net/tulip/media.c ---- LINUS_2_6_15_RC7/drivers/net/tulip/media.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/net/tulip/media.c 2005-09-14 06:56:25.000000000 -0600 -@@ -44,8 +44,10 @@ - - /* MII transceiver control section. - Read and write the MII registers using software-generated serial -- MDIO protocol. See the MII specifications or DP83840A data sheet -- for details. */ -+ MDIO protocol. -+ See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions") -+ or DP83840A data sheet for more details. -+ */ - - int tulip_mdio_read(struct net_device *dev, int phy_id, int location) - { -@@ -261,24 +263,56 @@ - u16 *reset_sequence = &((u16*)(p+3))[init_length]; - int reset_length = p[2 + init_length*2]; - misc_info = reset_sequence + reset_length; -- if (startup) -+ if (startup) { -+ int timeout = 10; /* max 1 ms */ - for (i = 0; i < reset_length; i++) - iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); -+ -+ /* flush posted writes */ -+ ioread32(ioaddr + CSR15); -+ -+ /* Sect 3.10.3 in DP83840A.pdf (p39) */ -+ udelay(500); -+ -+ /* Section 4.2 in DP83840A.pdf (p43) */ -+ /* and IEEE 802.3 "22.2.4.1.1 Reset" */ -+ while (timeout-- && -+ (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) -+ udelay(100); -+ } - for (i = 0; i < init_length; i++) - iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); -+ -+ ioread32(ioaddr + CSR15); /* flush posted writes */ - } else { - u8 *init_sequence = p + 2; - u8 *reset_sequence = p + 3 + init_length; - int reset_length = p[2 + init_length]; - misc_info = (u16*)(reset_sequence + reset_length); - if (startup) { -+ int timeout = 10; /* max 1 ms */ - iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12); - for (i = 0; i < reset_length; i++) - iowrite32(reset_sequence[i], ioaddr + CSR12); -+ -+ /* flush posted writes */ -+ ioread32(ioaddr + CSR12); -+ -+ /* Sect 3.10.3 in DP83840A.pdf (p39) */ -+ udelay(500); -+ -+ /* Section 4.2 in DP83840A.pdf (p43) */ -+ /* and IEEE 802.3 "22.2.4.1.1 Reset" */ -+ while (timeout-- && -+ (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) -+ udelay(100); - } - for (i = 0; i < init_length; i++) - iowrite32(init_sequence[i], ioaddr + CSR12); -+ -+ ioread32(ioaddr + CSR12); /* flush posted writes */ - } -+ - tmp_info = get_u16(&misc_info[1]); - if (tmp_info) - tp->advertising[phy_num] = tmp_info | 1; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/net/tulip/tulip.h CVS2_6_15_RC7_PA0/drivers/net/tulip/tulip.h ---- LINUS_2_6_15_RC7/drivers/net/tulip/tulip.h 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/net/tulip/tulip.h 2005-09-14 06:56:25.000000000 -0600 -@@ -474,8 +474,11 @@ - udelay(10); - - if (!i) -- printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n", -- pci_name(tp->pdev)); -+ printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed" -+ " (CSR5 0x%x CSR6 0x%x)\n", -+ pci_name(tp->pdev), -+ ioread32(ioaddr + CSR5), -+ ioread32(ioaddr + CSR6)); - } - } - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/net/tulip/tulip_core.c CVS2_6_15_RC7_PA0/drivers/net/tulip/tulip_core.c ---- LINUS_2_6_15_RC7/drivers/net/tulip/tulip_core.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/net/tulip/tulip_core.c 2005-11-11 21:07:59.000000000 -0700 -@@ -22,7 +22,7 @@ - #else - #define DRV_VERSION "1.1.13" - #endif --#define DRV_RELDATE "May 11, 2002" -+#define DRV_RELDATE "December 15, 2004" - - - #include -@@ -148,7 +148,7 @@ - HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer }, - - /* DC21142, DC21143 */ -- { "Digital DS21143 Tulip", 128, 0x0801fbff, -+ { "Digital DS21142/DS21143 Tulip", 128, 0x0801fbff, - HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY - | HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer }, - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/dino.c CVS2_6_15_RC7_PA0/drivers/parisc/dino.c ---- LINUS_2_6_15_RC7/drivers/parisc/dino.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parisc/dino.c 2005-12-14 00:49:15.000000000 -0700 -@@ -124,6 +124,7 @@ - - #define DINO_IRQS 11 /* bits 0-10 are architected */ - #define DINO_IRR_MASK 0x5ff /* only 10 bits are implemented */ -+#define DINO_LOCAL_IRQS (DINO_IRQS+1) - - #define DINO_MASK_IRQ(x) (1<<(x)) - -@@ -146,7 +147,7 @@ - unsigned long txn_addr; /* EIR addr to generate interrupt */ - u32 txn_data; /* EIR data assign to each dino */ - u32 imr; /* IRQ's which are enabled */ -- int global_irq[12]; /* map IMR bit to global irq */ -+ int global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */ - #ifdef DINO_DEBUG - unsigned int dino_irr0; /* save most recent IRQ line stat */ - #endif -@@ -297,7 +298,7 @@ - static void dino_disable_irq(unsigned int irq) - { - struct dino_device *dino_dev = irq_desc[irq].handler_data; -- int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq); -+ int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); - - DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); - -@@ -309,7 +310,7 @@ - static void dino_enable_irq(unsigned int irq) - { - struct dino_device *dino_dev = irq_desc[irq].handler_data; -- int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq); -+ int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); - u32 tmp; - - DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); -@@ -435,6 +436,21 @@ - dino_assign_irq(dino, irq, &dev->irq); - } - -+ -+/* -+ * Cirrus 6832 Cardbus reports wrong irq on RDI Tadpole PARISC Laptop (deller@gmx.de) -+ * (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem...) -+ */ -+static void __devinit quirk_cirrus_cardbus(struct pci_dev *dev) -+{ -+ u8 new_irq = dev->irq - 1; -+ printk(KERN_INFO "PCI: Cirrus Cardbus IRQ fixup for %s, from %d to %d\n", -+ pci_name(dev), dev->irq, new_irq); -+ dev->irq = new_irq; -+} -+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus ); -+ -+ - static void __init - dino_bios_init(void) - { -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/eisa.c CVS2_6_15_RC7_PA0/drivers/parisc/eisa.c ---- LINUS_2_6_15_RC7/drivers/parisc/eisa.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parisc/eisa.c 2005-12-19 06:48:41.000000000 -0700 -@@ -57,7 +57,7 @@ - - static DEFINE_SPINLOCK(eisa_irq_lock); - --void __iomem *eisa_eeprom_addr; -+void __iomem *eisa_eeprom_addr __read_mostly; - - /* We can only have one EISA adapter in the system because neither - * implementation can be flexed. -@@ -141,7 +141,7 @@ - * in the furure. - */ - /* irq 13,8,2,1,0 must be edge */ --static unsigned int eisa_irq_level; /* default to edge triggered */ -+static unsigned int eisa_irq_level __read_mostly; /* default to edge triggered */ - - - /* called by free irq */ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/eisa_eeprom.c CVS2_6_15_RC7_PA0/drivers/parisc/eisa_eeprom.c ---- LINUS_2_6_15_RC7/drivers/parisc/eisa_eeprom.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parisc/eisa_eeprom.c 2005-12-23 19:04:41.000000000 -0700 -@@ -48,7 +48,7 @@ - } - - static ssize_t eisa_eeprom_read(struct file * file, -- char *buf, size_t count, loff_t *ppos ) -+ char __user *buf, size_t count, loff_t *ppos ) - { - unsigned char *tmp; - ssize_t ret; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/lasi.c CVS2_6_15_RC7_PA0/drivers/parisc/lasi.c ---- LINUS_2_6_15_RC7/drivers/parisc/lasi.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parisc/lasi.c 2005-12-19 06:48:41.000000000 -0700 -@@ -150,7 +150,7 @@ - * - */ - --static unsigned long lasi_power_off_hpa; -+static unsigned long lasi_power_off_hpa __read_mostly; - - static void lasi_power_off(void) - { -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/lba_pci.c CVS2_6_15_RC7_PA0/drivers/parisc/lba_pci.c ---- LINUS_2_6_15_RC7/drivers/parisc/lba_pci.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parisc/lba_pci.c 2005-12-19 06:48:41.000000000 -0700 -@@ -167,7 +167,7 @@ - - /* non-postable I/O port space, densely packed */ - #define LBA_PORT_BASE (PCI_F_EXTEND | 0xfee00000UL) --static void __iomem *astro_iop_base; -+static void __iomem *astro_iop_base __read_mostly; - - #define ELROY_HVERS 0x782 - #define MERCURY_HVERS 0x783 -@@ -695,11 +695,71 @@ - } - } - } -+ -+ -+/* -+ * truncate_pat_collision: Deal with overlaps or outright collisions -+ * between PAT PDC reported ranges. -+ * -+ * Broken PA8800 firmware will report lmmio range that -+ * overlaps with CPU HPA. Just truncate the lmmio range. -+ * -+ * BEWARE: conflicts with this lmmio range may be an -+ * elmmio range which is pointing down another rope. -+ * -+ * FIXME: only deals with one collision per range...theoretically we -+ * could have several. Supporting more than one collision will get messy. -+ */ -+static unsigned long -+truncate_pat_collision(struct resource *root, struct resource *new) -+{ -+ unsigned long start = new->start; -+ unsigned long end = new->end; -+ struct resource *tmp = root->child; -+ -+ if (end <= start || start < root->start || !tmp) -+ return 0; -+ -+ /* find first overlap */ -+ while (tmp && tmp->end < start) -+ tmp = tmp->sibling; -+ -+ /* no entries overlap */ -+ if (!tmp) return 0; -+ -+ /* found one that starts behind the new one -+ ** Don't need to do anything. -+ */ -+ if (tmp->start >= end) return 0; -+ -+ if (tmp->start <= start) { -+ /* "front" of new one overlaps */ -+ new->start = tmp->end + 1; -+ -+ if (tmp->end >= end) { -+ /* AACCKK! totally overlaps! drop this range. */ -+ return 1; -+ } -+ } -+ -+ if (tmp->end < end ) { -+ /* "end" of new one overlaps */ -+ new->end = tmp->start - 1; -+ } -+ -+ printk(KERN_WARNING "LBA: Truncating lmmio_space [%lx/%lx] " -+ "to [%lx,%lx]\n", -+ start, end, -+ new->start, new->end ); -+ -+ return 0; /* truncation successful */ -+} -+ - #else --#define lba_claim_dev_resources(dev) -+#define lba_claim_dev_resources(dev) do { } while (0) -+#define truncate_pat_collision(r,n) (0) - #endif - -- - /* - ** The algorithm is generic code. - ** But it needs to access local data structures to get the IRQ base. -@@ -747,6 +807,9 @@ - lba_dump_res(&ioport_resource, 2); - BUG(); - } -+ /* advertize Host bridge resources to PCI bus */ -+ bus->resource[0] = &(ldev->hba.io_space); -+ i = 1; - - if (ldev->hba.elmmio_space.start) { - err = request_resource(&iomem_resource, -@@ -760,23 +823,35 @@ - - /* lba_dump_res(&iomem_resource, 2); */ - /* BUG(); */ -- } -+ } else -+ bus->resource[i++] = &(ldev->hba.elmmio_space); - } - -- err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space)); -- if (err < 0) { -- /* FIXME overlaps with elmmio will fail here. -- * Need to prune (or disable) the distributed range. -- * -- * BEWARE: conflicts with this lmmio range may be -- * elmmio range which is pointing down another rope. -- */ - -- printk("FAILED: lba_fixup_bus() request for " -+ /* Overlaps with elmmio can (and should) fail here. -+ * We will prune (or ignore) the distributed range. -+ * -+ * FIXME: SBA code should register all elmmio ranges first. -+ * that would take care of elmmio ranges routed -+ * to a different rope (already discovered) from -+ * getting registered *after* LBA code has already -+ * registered it's distributed lmmio range. -+ */ -+ if (truncate_pat_collision(&iomem_resource, -+ &(ldev->hba.lmmio_space))) { -+ -+ printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n", -+ ldev->hba.lmmio_space.start, -+ ldev->hba.lmmio_space.end); -+ } else { -+ err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space)); -+ if (err < 0) { -+ printk(KERN_ERR "FAILED: lba_fixup_bus() request for " - "lmmio_space [%lx/%lx]\n", - ldev->hba.lmmio_space.start, - ldev->hba.lmmio_space.end); -- /* lba_dump_res(&iomem_resource, 2); */ -+ } else -+ bus->resource[i++] = &(ldev->hba.lmmio_space); - } - - #ifdef CONFIG_64BIT -@@ -791,18 +866,10 @@ - lba_dump_res(&iomem_resource, 2); - BUG(); - } -+ bus->resource[i++] = &(ldev->hba.gmmio_space); - } - #endif - -- /* advertize Host bridge resources to PCI bus */ -- bus->resource[0] = &(ldev->hba.io_space); -- bus->resource[1] = &(ldev->hba.lmmio_space); -- i=2; -- if (ldev->hba.elmmio_space.start) -- bus->resource[i++] = &(ldev->hba.elmmio_space); -- if (ldev->hba.gmmio_space.start) -- bus->resource[i++] = &(ldev->hba.gmmio_space); -- - } - - list_for_each(ln, &bus->devices) { -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/led.c CVS2_6_15_RC7_PA0/drivers/parisc/led.c ---- LINUS_2_6_15_RC7/drivers/parisc/led.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parisc/led.c 2005-12-19 06:48:41.000000000 -0700 -@@ -3,7 +3,7 @@ - * - * (c) Copyright 2000 Red Hat Software - * (c) Copyright 2000 Helge Deller -- * (c) Copyright 2001-2004 Helge Deller -+ * (c) Copyright 2001-2005 Helge Deller - * (c) Copyright 2001 Randolph Chung - * - * This program is free software; you can redistribute it and/or modify -@@ -56,13 +56,13 @@ - relatively large amount of CPU time, some of the calculations can be - turned off with the following variables (controlled via procfs) */ - --static int led_type = -1; -+static int led_type __read_mostly = -1; - static unsigned char lastleds; /* LED state from most recent update */ --static unsigned int led_heartbeat = 1; --static unsigned int led_diskio = 1; --static unsigned int led_lanrxtx = 1; --static char lcd_text[32]; --static char lcd_text_default[32]; -+static unsigned int led_heartbeat __read_mostly = 1; -+static unsigned int led_diskio __read_mostly = 1; -+static unsigned int led_lanrxtx __read_mostly = 1; -+static char lcd_text[32] __read_mostly; -+static char lcd_text_default[32] __read_mostly; - - - static struct workqueue_struct *led_wq; -@@ -108,7 +108,7 @@ - /* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's - * HP seems to have used Sharp/Hitachi HD44780 LCDs most of the time. */ - static struct pdc_chassis_lcd_info_ret_block --lcd_info __attribute__((aligned(8))) = -+lcd_info __attribute__((aligned(8))) __read_mostly = - { - .model = DISPLAY_MODEL_LCD, - .lcd_width = 16, -@@ -144,7 +144,7 @@ - device_initcall(start_task); - - /* ptr to LCD/LED-specific function */ --static void (*led_func_ptr) (unsigned char); -+static void (*led_func_ptr) (unsigned char) __read_mostly; - - #ifdef CONFIG_PROC_FS - static int led_proc_read(char *page, char **start, off_t off, int count, -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/pdc_stable.c CVS2_6_15_RC7_PA0/drivers/parisc/pdc_stable.c ---- LINUS_2_6_15_RC7/drivers/parisc/pdc_stable.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parisc/pdc_stable.c 2005-12-19 06:48:41.000000000 -0700 -@@ -56,7 +56,7 @@ - #include - #include - --#define PDCS_VERSION "0.09" -+#define PDCS_VERSION "0.10" - - #define PDCS_ADDR_PPRI 0x00 - #define PDCS_ADDR_OSID 0x40 -@@ -70,7 +70,7 @@ - MODULE_LICENSE("GPL"); - MODULE_VERSION(PDCS_VERSION); - --static unsigned long pdcs_size = 0; -+static unsigned long pdcs_size __read_mostly; - - /* This struct defines what we need to deal with a parisc pdc path entry */ - struct pdcspath_entry { -@@ -194,7 +194,8 @@ - return -EIO; - } - -- entry->ready = 1; -+ /* kobject is already registered */ -+ entry->ready = 2; - - DPRINTK("%s: device: 0x%p\n", __func__, entry->dev); - -@@ -653,15 +654,21 @@ - { - unsigned short i; - struct pdcspath_entry *entry; -+ int err; - - for (i = 0; (entry = pdcspath_entries[i]); i++) { - if (pdcspath_fetch(entry) < 0) - continue; - -- kobject_set_name(&entry->kobj, "%s", entry->name); -+ if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) -+ return err; - kobj_set_kset_s(entry, paths_subsys); -- kobject_register(&entry->kobj); -- -+ if ((err = kobject_register(&entry->kobj))) -+ return err; -+ -+ /* kobject is now registered */ -+ entry->ready = 2; -+ - if (!entry->dev) - continue; - -@@ -675,14 +682,14 @@ - /** - * pdcs_unregister_pathentries - Routine called when unregistering the module. - */ --static inline void __exit -+static inline void - pdcs_unregister_pathentries(void) - { - unsigned short i; - struct pdcspath_entry *entry; - - for (i = 0; (entry = pdcspath_entries[i]); i++) -- if (entry->ready) -+ if (entry->ready >= 2) - kobject_unregister(&entry->kobj); - } - -@@ -704,7 +711,7 @@ - - /* For now we'll register the pdc subsys within this driver */ - if ((rc = firmware_register(&pdc_subsys))) -- return rc; -+ goto fail_firmreg; - - /* Don't forget the info entry */ - for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) -@@ -713,12 +720,25 @@ - - /* register the paths subsys as a subsystem of pdc subsys */ - kset_set_kset_s(&paths_subsys, pdc_subsys); -- subsystem_register(&paths_subsys); -+ if ((rc= subsystem_register(&paths_subsys))) -+ goto fail_subsysreg; - - /* now we create all "files" for the paths subsys */ -- pdcs_register_pathentries(); -+ if ((rc = pdcs_register_pathentries())) -+ goto fail_pdcsreg; -+ -+ return rc; - -- return 0; -+fail_pdcsreg: -+ pdcs_unregister_pathentries(); -+ subsystem_unregister(&paths_subsys); -+ -+fail_subsysreg: -+ firmware_unregister(&pdc_subsys); -+ -+fail_firmreg: -+ printk(KERN_INFO "PDC Stable Storage bailing out\n"); -+ return rc; - } - - static void __exit -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/power.c CVS2_6_15_RC7_PA0/drivers/parisc/power.c ---- LINUS_2_6_15_RC7/drivers/parisc/power.c 2005-12-27 13:25:46.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parisc/power.c 2005-12-19 06:48:41.000000000 -0700 -@@ -2,7 +2,7 @@ - * linux/arch/parisc/kernel/power.c - * HP PARISC soft power switch support driver - * -- * Copyright (c) 2001-2002 Helge Deller -+ * Copyright (c) 2001-2005 Helge Deller - * All rights reserved. - * - * -@@ -102,7 +102,7 @@ - - static void poweroff(void) - { -- static int powering_off; -+ static int powering_off __read_mostly; - - if (powering_off) - return; -@@ -113,7 +113,7 @@ - - - /* local time-counter for shutdown */ --static int shutdown_timer; -+static int shutdown_timer __read_mostly; - - /* check, give feedback and start shutdown after one second */ - static void process_shutdown(void) -@@ -139,7 +139,7 @@ - DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0); - - /* soft power switch enabled/disabled */ --int pwrsw_enabled = 1; -+int pwrsw_enabled __read_mostly = 1; - - /* - * On gecko style machines (e.g. 712/xx and 715/xx) -@@ -149,7 +149,7 @@ - */ - static void gecko_tasklet_func(unsigned long unused) - { -- if (!pwrsw_enabled) -+ if (unlikely(!pwrsw_enabled)) - return; - - if (__getDIAG(25) & 0x80000000) { -@@ -173,7 +173,7 @@ - { - unsigned long current_status; - -- if (!pwrsw_enabled) -+ if (unlikely(!pwrsw_enabled)) - return; - - current_status = gsc_readl(soft_power_reg); -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parport/Kconfig CVS2_6_15_RC7_PA0/drivers/parport/Kconfig ---- LINUS_2_6_15_RC7/drivers/parport/Kconfig 2005-12-27 13:25:47.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/parport/Kconfig 2005-12-07 14:28:17.000000000 -0700 -@@ -121,6 +121,7 @@ - tristate - default GSC - depends on PARPORT -+ select PARPORT_NOT_PC - - config PARPORT_SUNBPP - tristate "Sparc hardware (EXPERIMENTAL)" -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/pcmcia/Kconfig CVS2_6_15_RC7_PA0/drivers/pcmcia/Kconfig ---- LINUS_2_6_15_RC7/drivers/pcmcia/Kconfig 2005-12-27 13:25:47.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/pcmcia/Kconfig 2005-12-11 10:56:12.000000000 -0700 -@@ -200,7 +200,7 @@ - - config PCMCIA_PROBE - bool -- default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X -+ default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711XS && !PARISC - - config M32R_PCC - bool "M32R PCMCIA I/F" -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/53c700.c CVS2_6_15_RC7_PA0/drivers/scsi/53c700.c ---- LINUS_2_6_15_RC7/drivers/scsi/53c700.c 2005-12-27 13:25:48.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/53c700.c 2005-11-11 21:08:09.000000000 -0700 -@@ -302,6 +302,7 @@ - __u8 *memory; - __u32 *script; - struct Scsi_Host *host; -+ const char *chipname; - static int banner = 0; - int j; - -@@ -402,11 +403,11 @@ - printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n"); - banner = 1; - } -+ chipname = hostdata->chip710 ? "53c710" : \ -+ (hostdata->fast ? "53c700-66" : "53c700"); - printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no, -- hostdata->chip710 ? "53c710" : -- (hostdata->fast ? "53c700-66" : "53c700"), -- hostdata->rev, hostdata->differential ? -- "(Differential)" : ""); -+ chipname, hostdata->rev, -+ hostdata->differential ? "(Differential)" : ""); - /* reset the chip */ - NCR_700_chip_reset(host); - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/Kconfig CVS2_6_15_RC7_PA0/drivers/scsi/Kconfig ---- LINUS_2_6_15_RC7/drivers/scsi/Kconfig 2005-12-27 13:25:48.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/Kconfig 2005-12-12 09:35:31.000000000 -0700 -@@ -1066,7 +1066,7 @@ - memory using PCI DAC cycles. - - config SCSI_SYM53C8XX_DEFAULT_TAGS -- int "default tagged command queue depth" -+ int "Default tagged command queue depth" - depends on SCSI_SYM53C8XX_2 - default "16" - help -@@ -1077,7 +1077,7 @@ - exceed CONFIG_SCSI_SYM53C8XX_MAX_TAGS. - - config SCSI_SYM53C8XX_MAX_TAGS -- int "maximum number of queued commands" -+ int "Maximum number of queued commands" - depends on SCSI_SYM53C8XX_2 - default "64" - help -@@ -1086,13 +1086,14 @@ - possible. The driver supports up to 256 queued commands per device. - This value is used as a compiled-in hard limit. - --config SCSI_SYM53C8XX_IOMAPPED -- bool "use port IO" -+config SCSI_SYM53C8XX_MMIO -+ bool "Use memory mapped IO" - depends on SCSI_SYM53C8XX_2 -+ default y - help -- If you say Y here, the driver will use port IO to access -- the card. This is significantly slower then using memory -- mapped IO. Most people should answer N. -+ Memory mapped IO is faster than Port IO. Most people should -+ answer Y here, but some machines may have problems. If you have -+ to answer N here, please report the problem to the maintainer. - - config SCSI_IPR - tristate "IBM Power Linux RAID adapter support" -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/constants.c CVS2_6_15_RC7_PA0/drivers/scsi/constants.c ---- LINUS_2_6_15_RC7/drivers/scsi/constants.c 2005-12-27 13:25:48.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/constants.c 2005-12-12 17:01:16.000000000 -0700 -@@ -114,8 +114,7 @@ - {0xd, "Report supported task management functions"}, - {0xe, "Report priority"}, - }; --#define MAINT_IN_SZ \ -- (int)(sizeof(maint_in_arr) / sizeof(maint_in_arr[0])) -+#define MAINT_IN_SZ (int)ARRAY_SIZE(maint_in_arr) - - static const struct value_name_pair maint_out_arr[] = { - {0x6, "Set device identifier"}, -@@ -123,34 +122,29 @@ - {0xb, "Change aliases"}, - {0xe, "Set priority"}, - }; --#define MAINT_OUT_SZ \ -- (int)(sizeof(maint_out_arr) / sizeof(maint_out_arr[0])) -+#define MAINT_OUT_SZ (int)ARRAY_SIZE(maint_out_arr) - - static const struct value_name_pair serv_in12_arr[] = { - {0x1, "Read media serial number"}, - }; --#define SERV_IN12_SZ \ -- (int)(sizeof(serv_in12_arr) / sizeof(serv_in12_arr[0])) -+#define SERV_IN12_SZ (int)ARRAY_SIZE(serv_in12_arr) - - static const struct value_name_pair serv_out12_arr[] = { - {-1, "dummy entry"}, - }; --#define SERV_OUT12_SZ \ -- (int)(sizeof(serv_out12_arr) / sizeof(serv_in12_arr[0])) -+#define SERV_OUT12_SZ (int)ARRAY_SIZE(serv_out12_arr) - - static const struct value_name_pair serv_in16_arr[] = { - {0x10, "Read capacity(16)"}, - {0x11, "Read long(16)"}, - }; --#define SERV_IN16_SZ \ -- (int)(sizeof(serv_in16_arr) / sizeof(serv_in16_arr[0])) -+#define SERV_IN16_SZ (int)ARRAY_SIZE(serv_in16_arr) - - static const struct value_name_pair serv_out16_arr[] = { - {0x11, "Write long(16)"}, - {0x1f, "Notify data transfer device(16)"}, - }; --#define SERV_OUT16_SZ \ -- (int)(sizeof(serv_out16_arr) / sizeof(serv_in16_arr[0])) -+#define SERV_OUT16_SZ (int)ARRAY_SIZE(serv_out16_arr) - - static const struct value_name_pair variable_length_arr[] = { - {0x1, "Rebuild(32)"}, -@@ -190,8 +184,7 @@ - {0x8f7e, "Perform SCSI command (osd)"}, - {0x8f7f, "Perform task management function (osd)"}, - }; --#define VARIABLE_LENGTH_SZ \ -- (int)(sizeof(variable_length_arr) / sizeof(variable_length_arr[0])) -+#define VARIABLE_LENGTH_SZ (int)ARRAY_SIZE(variable_length_arr) - - static const char * get_sa_name(const struct value_name_pair * arr, - int arr_sz, int service_action) -@@ -1287,19 +1280,20 @@ - /* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", - /* 0x0f */ "Initiate Recovery", "Release Recovery" - }; --#define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs) / sizeof (const char *)) -+#define NO_ONE_BYTE_MSGS ARRAY_SIZE(one_byte_msgs) - - static const char *two_byte_msgs[] = { --/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag" -+/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag", - /* 0x23 */ "Ignore Wide Residue" - }; --#define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs) / sizeof (const char *)) -+#define NO_TWO_BYTE_MSGS ARRAY_SIZE(two_byte_msgs) - - static const char *extended_msgs[] = { - /* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request", --/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request" -+/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request", -+/* 0x04 */ "Parallel Protocol Request" - }; --#define NO_EXTENDED_MSGS (sizeof(two_byte_msgs) / sizeof (const char *)) -+#define NO_EXTENDED_MSGS ARRAY_SIZE(extended_msgs) - - - int scsi_print_msg (const unsigned char *msg) -@@ -1324,6 +1318,10 @@ - case EXTENDED_WDTR: - printk("width = 2^%d bytes", msg[3]); - break; -+ case EXTENDED_PPR: -+ printk("period = %d ns, offset = %d, width = %d", -+ (int) msg[3] * 4, (int) msg[5], 1 << msg[6]); -+ break; - default: - for (i = 2; i < len; ++i) - printk("%02x ", msg[i]); -@@ -1401,7 +1399,7 @@ - "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", - "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", - "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"}; --#define NUM_HOSTBYTE_STRS (sizeof(hostbyte_table) / sizeof(const char *)) -+#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) - - void scsi_print_hostbyte(int scsiresult) - { -@@ -1425,12 +1423,12 @@ - static const char * driverbyte_table[]={ - "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", - "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; --#define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *)) -+#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table) - - static const char * driversuggest_table[]={"SUGGEST_OK", - "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", - "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"}; --#define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *)) -+#define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table) - - void scsi_print_driverbyte(int scsiresult) - { -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/ncr53c8xx.c CVS2_6_15_RC7_PA0/drivers/scsi/ncr53c8xx.c ---- LINUS_2_6_15_RC7/drivers/scsi/ncr53c8xx.c 2005-12-27 13:25:48.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/ncr53c8xx.c 2005-12-12 12:01:54.000000000 -0700 -@@ -69,6 +69,10 @@ - ** Low PCI traffic for command handling when on-chip RAM is present. - ** Aggressive SCSI SCRIPTS optimizations. - ** -+** 2005 by Matthew Wilcox and James Bottomley -+** PCI-ectomy. This driver now supports only the 720 chip (see the -+** NCR_Q720 and zalon drivers for the bus probe logic). -+** - ******************************************************************************* - */ - -@@ -90,13 +94,6 @@ - - #define SCSI_NCR_DEBUG_FLAGS (0) - --/*========================================================== --** --** Include files --** --**========================================================== --*/ -- - #include - #include - #include -@@ -121,6 +118,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -128,10 +126,740 @@ - - #include "ncr53c8xx.h" - --#define NAME53C "ncr53c" - #define NAME53C8XX "ncr53c8xx" - --#include "sym53c8xx_comm.h" -+/*========================================================== -+** -+** Debugging tags -+** -+**========================================================== -+*/ -+ -+#define DEBUG_ALLOC (0x0001) -+#define DEBUG_PHASE (0x0002) -+#define DEBUG_QUEUE (0x0008) -+#define DEBUG_RESULT (0x0010) -+#define DEBUG_POINTER (0x0020) -+#define DEBUG_SCRIPT (0x0040) -+#define DEBUG_TINY (0x0080) -+#define DEBUG_TIMING (0x0100) -+#define DEBUG_NEGO (0x0200) -+#define DEBUG_TAGS (0x0400) -+#define DEBUG_SCATTER (0x0800) -+#define DEBUG_IC (0x1000) -+ -+/* -+** Enable/Disable debug messages. -+** Can be changed at runtime too. -+*/ -+ -+#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT -+static int ncr_debug = SCSI_NCR_DEBUG_FLAGS; -+ #define DEBUG_FLAGS ncr_debug -+#else -+ #define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS -+#endif -+ -+static inline struct list_head *ncr_list_pop(struct list_head *head) -+{ -+ if (!list_empty(head)) { -+ struct list_head *elem = head->next; -+ -+ list_del(elem); -+ return elem; -+ } -+ -+ return NULL; -+} -+ -+/*========================================================== -+** -+** Simple power of two buddy-like allocator. -+** -+** This simple code is not intended to be fast, but to -+** provide power of 2 aligned memory allocations. -+** Since the SCRIPTS processor only supplies 8 bit -+** arithmetic, this allocator allows simple and fast -+** address calculations from the SCRIPTS code. -+** In addition, cache line alignment is guaranteed for -+** power of 2 cache line size. -+** Enhanced in linux-2.3.44 to provide a memory pool -+** per pcidev to support dynamic dma mapping. (I would -+** have preferred a real bus astraction, btw). -+** -+**========================================================== -+*/ -+ -+#define MEMO_SHIFT 4 /* 16 bytes minimum memory chunk */ -+#if PAGE_SIZE >= 8192 -+#define MEMO_PAGE_ORDER 0 /* 1 PAGE maximum */ -+#else -+#define MEMO_PAGE_ORDER 1 /* 2 PAGES maximum */ -+#endif -+#define MEMO_FREE_UNUSED /* Free unused pages immediately */ -+#define MEMO_WARN 1 -+#define MEMO_GFP_FLAGS GFP_ATOMIC -+#define MEMO_CLUSTER_SHIFT (PAGE_SHIFT+MEMO_PAGE_ORDER) -+#define MEMO_CLUSTER_SIZE (1UL << MEMO_CLUSTER_SHIFT) -+#define MEMO_CLUSTER_MASK (MEMO_CLUSTER_SIZE-1) -+ -+typedef u_long m_addr_t; /* Enough bits to bit-hack addresses */ -+typedef struct device *m_bush_t; /* Something that addresses DMAable */ -+ -+typedef struct m_link { /* Link between free memory chunks */ -+ struct m_link *next; -+} m_link_s; -+ -+typedef struct m_vtob { /* Virtual to Bus address translation */ -+ struct m_vtob *next; -+ m_addr_t vaddr; -+ m_addr_t baddr; -+} m_vtob_s; -+#define VTOB_HASH_SHIFT 5 -+#define VTOB_HASH_SIZE (1UL << VTOB_HASH_SHIFT) -+#define VTOB_HASH_MASK (VTOB_HASH_SIZE-1) -+#define VTOB_HASH_CODE(m) \ -+ ((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK) -+ -+typedef struct m_pool { /* Memory pool of a given kind */ -+ m_bush_t bush; -+ m_addr_t (*getp)(struct m_pool *); -+ void (*freep)(struct m_pool *, m_addr_t); -+ int nump; -+ m_vtob_s *(vtob[VTOB_HASH_SIZE]); -+ struct m_pool *next; -+ struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1]; -+} m_pool_s; -+ -+static void *___m_alloc(m_pool_s *mp, int size) -+{ -+ int i = 0; -+ int s = (1 << MEMO_SHIFT); -+ int j; -+ m_addr_t a; -+ m_link_s *h = mp->h; -+ -+ if (size > (PAGE_SIZE << MEMO_PAGE_ORDER)) -+ return NULL; -+ -+ while (size > s) { -+ s <<= 1; -+ ++i; -+ } -+ -+ j = i; -+ while (!h[j].next) { -+ if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { -+ h[j].next = (m_link_s *)mp->getp(mp); -+ if (h[j].next) -+ h[j].next->next = NULL; -+ break; -+ } -+ ++j; -+ s <<= 1; -+ } -+ a = (m_addr_t) h[j].next; -+ if (a) { -+ h[j].next = h[j].next->next; -+ while (j > i) { -+ j -= 1; -+ s >>= 1; -+ h[j].next = (m_link_s *) (a+s); -+ h[j].next->next = NULL; -+ } -+ } -+#ifdef DEBUG -+ printk("___m_alloc(%d) = %p\n", size, (void *) a); -+#endif -+ return (void *) a; -+} -+ -+static void ___m_free(m_pool_s *mp, void *ptr, int size) -+{ -+ int i = 0; -+ int s = (1 << MEMO_SHIFT); -+ m_link_s *q; -+ m_addr_t a, b; -+ m_link_s *h = mp->h; -+ -+#ifdef DEBUG -+ printk("___m_free(%p, %d)\n", ptr, size); -+#endif -+ -+ if (size > (PAGE_SIZE << MEMO_PAGE_ORDER)) -+ return; -+ -+ while (size > s) { -+ s <<= 1; -+ ++i; -+ } -+ -+ a = (m_addr_t) ptr; -+ -+ while (1) { -+#ifdef MEMO_FREE_UNUSED -+ if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { -+ mp->freep(mp, a); -+ break; -+ } -+#endif -+ b = a ^ s; -+ q = &h[i]; -+ while (q->next && q->next != (m_link_s *) b) { -+ q = q->next; -+ } -+ if (!q->next) { -+ ((m_link_s *) a)->next = h[i].next; -+ h[i].next = (m_link_s *) a; -+ break; -+ } -+ q->next = q->next->next; -+ a = a & b; -+ s <<= 1; -+ ++i; -+ } -+} -+ -+static DEFINE_SPINLOCK(ncr53c8xx_lock); -+ -+static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags) -+{ -+ void *p; -+ -+ p = ___m_alloc(mp, size); -+ -+ if (DEBUG_FLAGS & DEBUG_ALLOC) -+ printk ("new %-10s[%4d] @%p.\n", name, size, p); -+ -+ if (p) -+ memset(p, 0, size); -+ else if (uflags & MEMO_WARN) -+ printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size); -+ -+ return p; -+} -+ -+#define __m_calloc(mp, s, n) __m_calloc2(mp, s, n, MEMO_WARN) -+ -+static void __m_free(m_pool_s *mp, void *ptr, int size, char *name) -+{ -+ if (DEBUG_FLAGS & DEBUG_ALLOC) -+ printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr); -+ -+ ___m_free(mp, ptr, size); -+ -+} -+ -+/* -+ * With pci bus iommu support, we use a default pool of unmapped memory -+ * for memory we donnot need to DMA from/to and one pool per pcidev for -+ * memory accessed by the PCI chip. `mp0' is the default not DMAable pool. -+ */ -+ -+static m_addr_t ___mp0_getp(m_pool_s *mp) -+{ -+ m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER); -+ if (m) -+ ++mp->nump; -+ return m; -+} -+ -+static void ___mp0_freep(m_pool_s *mp, m_addr_t m) -+{ -+ free_pages(m, MEMO_PAGE_ORDER); -+ --mp->nump; -+} -+ -+static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep}; -+ -+/* -+ * DMAable pools. -+ */ -+ -+/* -+ * With pci bus iommu support, we maintain one pool per pcidev and a -+ * hashed reverse table for virtual to bus physical address translations. -+ */ -+static m_addr_t ___dma_getp(m_pool_s *mp) -+{ -+ m_addr_t vp; -+ m_vtob_s *vbp; -+ -+ vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB"); -+ if (vbp) { -+ dma_addr_t daddr; -+ vp = (m_addr_t) dma_alloc_coherent(mp->bush, -+ PAGE_SIZE<vaddr = vp; -+ vbp->baddr = daddr; -+ vbp->next = mp->vtob[hc]; -+ mp->vtob[hc] = vbp; -+ ++mp->nump; -+ return vp; -+ } -+ } -+ if (vbp) -+ __m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); -+ return 0; -+} -+ -+static void ___dma_freep(m_pool_s *mp, m_addr_t m) -+{ -+ m_vtob_s **vbpp, *vbp; -+ int hc = VTOB_HASH_CODE(m); -+ -+ vbpp = &mp->vtob[hc]; -+ while (*vbpp && (*vbpp)->vaddr != m) -+ vbpp = &(*vbpp)->next; -+ if (*vbpp) { -+ vbp = *vbpp; -+ *vbpp = (*vbpp)->next; -+ dma_free_coherent(mp->bush, PAGE_SIZE<vaddr, (dma_addr_t)vbp->baddr); -+ __m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); -+ --mp->nump; -+ } -+} -+ -+static inline m_pool_s *___get_dma_pool(m_bush_t bush) -+{ -+ m_pool_s *mp; -+ for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next); -+ return mp; -+} -+ -+static m_pool_s *___cre_dma_pool(m_bush_t bush) -+{ -+ m_pool_s *mp; -+ mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL"); -+ if (mp) { -+ memset(mp, 0, sizeof(*mp)); -+ mp->bush = bush; -+ mp->getp = ___dma_getp; -+ mp->freep = ___dma_freep; -+ mp->next = mp0.next; -+ mp0.next = mp; -+ } -+ return mp; -+} -+ -+static void ___del_dma_pool(m_pool_s *p) -+{ -+ struct m_pool **pp = &mp0.next; -+ -+ while (*pp && *pp != p) -+ pp = &(*pp)->next; -+ if (*pp) { -+ *pp = (*pp)->next; -+ __m_free(&mp0, p, sizeof(*p), "MPOOL"); -+ } -+} -+ -+static void *__m_calloc_dma(m_bush_t bush, int size, char *name) -+{ -+ u_long flags; -+ struct m_pool *mp; -+ void *m = NULL; -+ -+ spin_lock_irqsave(&ncr53c8xx_lock, flags); -+ mp = ___get_dma_pool(bush); -+ if (!mp) -+ mp = ___cre_dma_pool(bush); -+ if (mp) -+ m = __m_calloc(mp, size, name); -+ if (mp && !mp->nump) -+ ___del_dma_pool(mp); -+ spin_unlock_irqrestore(&ncr53c8xx_lock, flags); -+ -+ return m; -+} -+ -+static void __m_free_dma(m_bush_t bush, void *m, int size, char *name) -+{ -+ u_long flags; -+ struct m_pool *mp; -+ -+ spin_lock_irqsave(&ncr53c8xx_lock, flags); -+ mp = ___get_dma_pool(bush); -+ if (mp) -+ __m_free(mp, m, size, name); -+ if (mp && !mp->nump) -+ ___del_dma_pool(mp); -+ spin_unlock_irqrestore(&ncr53c8xx_lock, flags); -+} -+ -+static m_addr_t __vtobus(m_bush_t bush, void *m) -+{ -+ u_long flags; -+ m_pool_s *mp; -+ int hc = VTOB_HASH_CODE(m); -+ m_vtob_s *vp = NULL; -+ m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK; -+ -+ spin_lock_irqsave(&ncr53c8xx_lock, flags); -+ mp = ___get_dma_pool(bush); -+ if (mp) { -+ vp = mp->vtob[hc]; -+ while (vp && (m_addr_t) vp->vaddr != a) -+ vp = vp->next; -+ } -+ spin_unlock_irqrestore(&ncr53c8xx_lock, flags); -+ return vp ? vp->baddr + (((m_addr_t) m) - a) : 0; -+} -+ -+#define _m_calloc_dma(np, s, n) __m_calloc_dma(np->dev, s, n) -+#define _m_free_dma(np, p, s, n) __m_free_dma(np->dev, p, s, n) -+#define m_calloc_dma(s, n) _m_calloc_dma(np, s, n) -+#define m_free_dma(p, s, n) _m_free_dma(np, p, s, n) -+#define _vtobus(np, p) __vtobus(np->dev, p) -+#define vtobus(p) _vtobus(np, p) -+ -+/* -+ * Deal with DMA mapping/unmapping. -+ */ -+ -+/* To keep track of the dma mapping (sg/single) that has been set */ -+#define __data_mapped SCp.phase -+#define __data_mapping SCp.have_data_in -+ -+static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd) -+{ -+ switch(cmd->__data_mapped) { -+ case 2: -+ dma_unmap_sg(dev, cmd->buffer, cmd->use_sg, -+ cmd->sc_data_direction); -+ break; -+ case 1: -+ dma_unmap_single(dev, cmd->__data_mapping, -+ cmd->request_bufflen, -+ cmd->sc_data_direction); -+ break; -+ } -+ cmd->__data_mapped = 0; -+} -+ -+static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd) -+{ -+ dma_addr_t mapping; -+ -+ if (cmd->request_bufflen == 0) -+ return 0; -+ -+ mapping = dma_map_single(dev, cmd->request_buffer, -+ cmd->request_bufflen, -+ cmd->sc_data_direction); -+ cmd->__data_mapped = 1; -+ cmd->__data_mapping = mapping; -+ -+ return mapping; -+} -+ -+static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) -+{ -+ int use_sg; -+ -+ if (cmd->use_sg == 0) -+ return 0; -+ -+ use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg, -+ cmd->sc_data_direction); -+ cmd->__data_mapped = 2; -+ cmd->__data_mapping = use_sg; -+ -+ return use_sg; -+} -+ -+#define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd) -+#define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->dev, cmd) -+#define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd) -+ -+/*========================================================== -+** -+** Driver setup. -+** -+** This structure is initialized from linux config -+** options. It can be overridden at boot-up by the boot -+** command line. -+** -+**========================================================== -+*/ -+static struct ncr_driver_setup -+ driver_setup = SCSI_NCR_DRIVER_SETUP; -+ -+#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT -+static struct ncr_driver_setup -+ driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; -+#endif -+ -+#define initverbose (driver_setup.verbose) -+#define bootverbose (np->verbose) -+ -+ -+/*=================================================================== -+** -+** Driver setup from the boot command line -+** -+**=================================================================== -+*/ -+ -+#ifdef MODULE -+#define ARG_SEP ' ' -+#else -+#define ARG_SEP ',' -+#endif -+ -+#define OPT_TAGS 1 -+#define OPT_MASTER_PARITY 2 -+#define OPT_SCSI_PARITY 3 -+#define OPT_DISCONNECTION 4 -+#define OPT_SPECIAL_FEATURES 5 -+#define OPT_UNUSED_1 6 -+#define OPT_FORCE_SYNC_NEGO 7 -+#define OPT_REVERSE_PROBE 8 -+#define OPT_DEFAULT_SYNC 9 -+#define OPT_VERBOSE 10 -+#define OPT_DEBUG 11 -+#define OPT_BURST_MAX 12 -+#define OPT_LED_PIN 13 -+#define OPT_MAX_WIDE 14 -+#define OPT_SETTLE_DELAY 15 -+#define OPT_DIFF_SUPPORT 16 -+#define OPT_IRQM 17 -+#define OPT_PCI_FIX_UP 18 -+#define OPT_BUS_CHECK 19 -+#define OPT_OPTIMIZE 20 -+#define OPT_RECOVERY 21 -+#define OPT_SAFE_SETUP 22 -+#define OPT_USE_NVRAM 23 -+#define OPT_EXCLUDE 24 -+#define OPT_HOST_ID 25 -+ -+#ifdef SCSI_NCR_IARB_SUPPORT -+#define OPT_IARB 26 -+#endif -+ -+static char setup_token[] __initdata = -+ "tags:" "mpar:" -+ "spar:" "disc:" -+ "specf:" "ultra:" -+ "fsn:" "revprob:" -+ "sync:" "verb:" -+ "debug:" "burst:" -+ "led:" "wide:" -+ "settle:" "diff:" -+ "irqm:" "pcifix:" -+ "buschk:" "optim:" -+ "recovery:" -+ "safe:" "nvram:" -+ "excl:" "hostid:" -+#ifdef SCSI_NCR_IARB_SUPPORT -+ "iarb:" -+#endif -+ ; /* DONNOT REMOVE THIS ';' */ -+ -+#ifdef MODULE -+#define ARG_SEP ' ' -+#else -+#define ARG_SEP ',' -+#endif -+ -+static int __init get_setup_token(char *p) -+{ -+ char *cur = setup_token; -+ char *pc; -+ int i = 0; -+ -+ while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { -+ ++pc; -+ ++i; -+ if (!strncmp(p, cur, pc - cur)) -+ return i; -+ cur = pc; -+ } -+ return 0; -+} -+ -+ -+static int __init sym53c8xx__setup(char *str) -+{ -+#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT -+ char *cur = str; -+ char *pc, *pv; -+ int i, val, c; -+ int xi = 0; -+ -+ while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { -+ char *pe; -+ -+ val = 0; -+ pv = pc; -+ c = *++pv; -+ -+ if (c == 'n') -+ val = 0; -+ else if (c == 'y') -+ val = 1; -+ else -+ val = (int) simple_strtoul(pv, &pe, 0); -+ -+ switch (get_setup_token(cur)) { -+ case OPT_TAGS: -+ driver_setup.default_tags = val; -+ if (pe && *pe == '/') { -+ i = 0; -+ while (*pe && *pe != ARG_SEP && -+ i < sizeof(driver_setup.tag_ctrl)-1) { -+ driver_setup.tag_ctrl[i++] = *pe++; -+ } -+ driver_setup.tag_ctrl[i] = '\0'; -+ } -+ break; -+ case OPT_MASTER_PARITY: -+ driver_setup.master_parity = val; -+ break; -+ case OPT_SCSI_PARITY: -+ driver_setup.scsi_parity = val; -+ break; -+ case OPT_DISCONNECTION: -+ driver_setup.disconnection = val; -+ break; -+ case OPT_SPECIAL_FEATURES: -+ driver_setup.special_features = val; -+ break; -+ case OPT_FORCE_SYNC_NEGO: -+ driver_setup.force_sync_nego = val; -+ break; -+ case OPT_REVERSE_PROBE: -+ driver_setup.reverse_probe = val; -+ break; -+ case OPT_DEFAULT_SYNC: -+ driver_setup.default_sync = val; -+ break; -+ case OPT_VERBOSE: -+ driver_setup.verbose = val; -+ break; -+ case OPT_DEBUG: -+ driver_setup.debug = val; -+ break; -+ case OPT_BURST_MAX: -+ driver_setup.burst_max = val; -+ break; -+ case OPT_LED_PIN: -+ driver_setup.led_pin = val; -+ break; -+ case OPT_MAX_WIDE: -+ driver_setup.max_wide = val? 1:0; -+ break; -+ case OPT_SETTLE_DELAY: -+ driver_setup.settle_delay = val; -+ break; -+ case OPT_DIFF_SUPPORT: -+ driver_setup.diff_support = val; -+ break; -+ case OPT_IRQM: -+ driver_setup.irqm = val; -+ break; -+ case OPT_PCI_FIX_UP: -+ driver_setup.pci_fix_up = val; -+ break; -+ case OPT_BUS_CHECK: -+ driver_setup.bus_check = val; -+ break; -+ case OPT_OPTIMIZE: -+ driver_setup.optimize = val; -+ break; -+ case OPT_RECOVERY: -+ driver_setup.recovery = val; -+ break; -+ case OPT_USE_NVRAM: -+ driver_setup.use_nvram = val; -+ break; -+ case OPT_SAFE_SETUP: -+ memcpy(&driver_setup, &driver_safe_setup, -+ sizeof(driver_setup)); -+ break; -+ case OPT_EXCLUDE: -+ if (xi < SCSI_NCR_MAX_EXCLUDES) -+ driver_setup.excludes[xi++] = val; -+ break; -+ case OPT_HOST_ID: -+ driver_setup.host_id = val; -+ break; -+#ifdef SCSI_NCR_IARB_SUPPORT -+ case OPT_IARB: -+ driver_setup.iarb = val; -+ break; -+#endif -+ default: -+ printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); -+ break; -+ } -+ -+ if ((cur = strchr(cur, ARG_SEP)) != NULL) -+ ++cur; -+ } -+#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ -+ return 1; -+} -+ -+/*=================================================================== -+** -+** Get device queue depth from boot command line. -+** -+**=================================================================== -+*/ -+#define DEF_DEPTH (driver_setup.default_tags) -+#define ALL_TARGETS -2 -+#define NO_TARGET -1 -+#define ALL_LUNS -2 -+#define NO_LUN -1 -+ -+static int device_queue_depth(int unit, int target, int lun) -+{ -+ int c, h, t, u, v; -+ char *p = driver_setup.tag_ctrl; -+ char *ep; -+ -+ h = -1; -+ t = NO_TARGET; -+ u = NO_LUN; -+ while ((c = *p++) != 0) { -+ v = simple_strtoul(p, &ep, 0); -+ switch(c) { -+ case '/': -+ ++h; -+ t = ALL_TARGETS; -+ u = ALL_LUNS; -+ break; -+ case 't': -+ if (t != target) -+ t = (target == v) ? v : NO_TARGET; -+ u = ALL_LUNS; -+ break; -+ case 'u': -+ if (u != lun) -+ u = (lun == v) ? v : NO_LUN; -+ break; -+ case 'q': -+ if (h == unit && -+ (t == ALL_TARGETS || t == target) && -+ (u == ALL_LUNS || u == lun)) -+ return v; -+ break; -+ case '-': -+ t = ALL_TARGETS; -+ u = ALL_LUNS; -+ break; -+ default: -+ break; -+ } -+ p = ep; -+ } -+ return DEF_DEPTH; -+} - - - /*========================================================== -@@ -1379,7 +2107,7 @@ - */ - - /* -- ** The M_REJECT problem seems to be due to a selection -+ ** The MESSAGE_REJECT problem seems to be due to a selection - ** timing problem. - ** Wait immediately for the selection to complete. - ** (2.5x behaves so) -@@ -1430,7 +2158,7 @@ - /* - ** Selection complete. - ** Send the IDENTIFY and SIMPLE_TAG messages -- ** (and the M_X_SYNC_REQ message) -+ ** (and the EXTENDED_SDTR message) - */ - SCR_MOVE_TBL ^ SCR_MSG_OUT, - offsetof (struct dsb, smsg), -@@ -1459,7 +2187,7 @@ - /* - ** Initialize the msgout buffer with a NOOP message. - */ -- SCR_LOAD_REG (scratcha, M_NOOP), -+ SCR_LOAD_REG (scratcha, NOP), - 0, - SCR_COPY (1), - RADDR (scratcha), -@@ -1611,21 +2339,21 @@ - /* - ** Handle this message. - */ -- SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)), -+ SCR_JUMP ^ IFTRUE (DATA (COMMAND_COMPLETE)), - PADDR (complete), -- SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)), -+ SCR_JUMP ^ IFTRUE (DATA (DISCONNECT)), - PADDR (disconnect), -- SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)), -+ SCR_JUMP ^ IFTRUE (DATA (SAVE_POINTERS)), - PADDR (save_dp), -- SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)), -+ SCR_JUMP ^ IFTRUE (DATA (RESTORE_POINTERS)), - PADDR (restore_dp), -- SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), -+ SCR_JUMP ^ IFTRUE (DATA (EXTENDED_MESSAGE)), - PADDRH (msg_extended), -- SCR_JUMP ^ IFTRUE (DATA (M_NOOP)), -+ SCR_JUMP ^ IFTRUE (DATA (NOP)), - PADDR (clrack), -- SCR_JUMP ^ IFTRUE (DATA (M_REJECT)), -+ SCR_JUMP ^ IFTRUE (DATA (MESSAGE_REJECT)), - PADDRH (msg_reject), -- SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)), -+ SCR_JUMP ^ IFTRUE (DATA (IGNORE_WIDE_RESIDUE)), - PADDRH (msg_ign_residue), - /* - ** Rest of the messages left as -@@ -1640,7 +2368,7 @@ - */ - SCR_INT, - SIR_REJECT_SENT, -- SCR_LOAD_REG (scratcha, M_REJECT), -+ SCR_LOAD_REG (scratcha, MESSAGE_REJECT), - 0, - }/*-------------------------< SETMSG >----------------------*/,{ - SCR_COPY (1), -@@ -1832,7 +2560,7 @@ - /* - ** If it was no ABORT message ... - */ -- SCR_JUMP ^ IFTRUE (DATA (M_ABORT)), -+ SCR_JUMP ^ IFTRUE (DATA (ABORT_TASK_SET)), - PADDRH (msg_out_abort), - /* - ** ... wait for the next phase -@@ -1844,7 +2572,7 @@ - /* - ** ... else clear the message ... - */ -- SCR_LOAD_REG (scratcha, M_NOOP), -+ SCR_LOAD_REG (scratcha, NOP), - 0, - SCR_COPY (4), - RADDR (scratcha), -@@ -2303,7 +3031,7 @@ - */ - SCR_MOVE_ABS (1) ^ SCR_MSG_IN, - NADDR (msgin[2]), -- SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)), -+ SCR_JUMP ^ IFTRUE (DATA (EXTENDED_WDTR)), - PADDRH (msg_wdtr), - /* - ** unknown extended message -@@ -2337,7 +3065,7 @@ - - }/*-------------------------< SEND_WDTR >----------------*/,{ - /* -- ** Send the M_X_WIDE_REQ -+ ** Send the EXTENDED_WDTR - */ - SCR_MOVE_ABS (4) ^ SCR_MSG_OUT, - NADDR (msgout), -@@ -2357,7 +3085,7 @@ - */ - SCR_MOVE_ABS (1) ^ SCR_MSG_IN, - NADDR (msgin[2]), -- SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)), -+ SCR_JUMP ^ IFTRUE (DATA (EXTENDED_SDTR)), - PADDRH (msg_sdtr), - /* - ** unknown extended message -@@ -2392,7 +3120,7 @@ - - }/*-------------------------< SEND_SDTR >-------------*/,{ - /* -- ** Send the M_X_SYNC_REQ -+ ** Send the EXTENDED_SDTR - */ - SCR_MOVE_ABS (5) ^ SCR_MSG_OUT, - NADDR (msgout), -@@ -2470,10 +3198,10 @@ - - }/*-------------------------< RESET >----------------------*/,{ - /* -- ** Send a M_RESET message if bad IDENTIFY -+ ** Send a TARGET_RESET message if bad IDENTIFY - ** received on reselection. - */ -- SCR_LOAD_REG (scratcha, M_ABORT_TAG), -+ SCR_LOAD_REG (scratcha, ABORT_TASK), - 0, - SCR_JUMP, - PADDRH (abort_resel), -@@ -2481,7 +3209,7 @@ - /* - ** Abort a wrong tag received on reselection. - */ -- SCR_LOAD_REG (scratcha, M_ABORT_TAG), -+ SCR_LOAD_REG (scratcha, ABORT_TASK), - 0, - SCR_JUMP, - PADDRH (abort_resel), -@@ -2489,7 +3217,7 @@ - /* - ** Abort a reselection when no active CCB. - */ -- SCR_LOAD_REG (scratcha, M_ABORT), -+ SCR_LOAD_REG (scratcha, ABORT_TASK_SET), - 0, - }/*-------------------------< ABORT_RESEL >----------------*/,{ - SCR_COPY (1), -@@ -2601,7 +3329,7 @@ - ** Read the message, since we got it directly - ** from the SCSI BUS data lines. - ** Signal problem to C code for logging the event. -- ** Send a M_ABORT to clear all pending tasks. -+ ** Send an ABORT_TASK_SET to clear all pending tasks. - */ - SCR_INT, - SIR_RESEL_BAD_LUN, -@@ -2613,7 +3341,7 @@ - /* - ** We donnot have a task for that I_T_L. - ** Signal problem to C code for logging the event. -- ** Send a M_ABORT message. -+ ** Send an ABORT_TASK_SET message. - */ - SCR_INT, - SIR_RESEL_BAD_I_T_L, -@@ -2623,7 +3351,7 @@ - /* - ** We donnot have a task that matches the tag. - ** Signal problem to C code for logging the event. -- ** Send a M_ABORTTAG message. -+ ** Send an ABORT_TASK message. - */ - SCR_INT, - SIR_RESEL_BAD_I_T_L_Q, -@@ -2634,7 +3362,7 @@ - ** We donnot know the target that reselected us. - ** Grab the first message if any (IDENTIFY). - ** Signal problem to C code for logging the event. -- ** M_RESET message. -+ ** TARGET_RESET message. - */ - SCR_INT, - SIR_RESEL_BAD_TARGET, -@@ -2971,21 +3699,10 @@ - - static void ncr_print_msg(struct ccb *cp, char *label, u_char *msg) - { -- int i; - PRINT_ADDR(cp->cmd, "%s: ", label); - -- printk ("%x",*msg); -- if (*msg == M_EXTENDED) { -- for (i = 1; i < 8; i++) { -- if (i - 1 > msg[1]) -- break; -- printk ("-%x",msg[i]); -- } -- } else if ((*msg & 0xf0) == 0x20) { -- printk ("-%x",msg[1]); -- } -- -- printk(".\n"); -+ scsi_print_msg(msg); -+ printk("\n"); - } - - /*========================================================== -@@ -3388,16 +4105,16 @@ - - switch (nego) { - case NS_SYNC: -- msgptr[msglen++] = M_EXTENDED; -+ msgptr[msglen++] = EXTENDED_MESSAGE; - msgptr[msglen++] = 3; -- msgptr[msglen++] = M_X_SYNC_REQ; -+ msgptr[msglen++] = EXTENDED_SDTR; - msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0; - msgptr[msglen++] = tp->maxoffs; - break; - case NS_WIDE: -- msgptr[msglen++] = M_EXTENDED; -+ msgptr[msglen++] = EXTENDED_MESSAGE; - msgptr[msglen++] = 2; -- msgptr[msglen++] = M_X_WIDE_REQ; -+ msgptr[msglen++] = EXTENDED_WDTR; - msgptr[msglen++] = tp->usrwide; - break; - } -@@ -3499,7 +4216,7 @@ - **---------------------------------------------------- - */ - -- idmsg = M_IDENTIFY | sdev->lun; -+ idmsg = IDENTIFY(0, sdev->lun); - - if (cp ->tag != NO_TAG || - (cp != np->ccb && np->disc && !(tp->usrflag & UF_NODISC))) -@@ -3518,7 +4235,7 @@ - */ - if (lp && time_after(jiffies, lp->tags_stime)) { - if (lp->tags_smap) { -- order = M_ORDERED_TAG; -+ order = ORDERED_QUEUE_TAG; - if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){ - PRINT_ADDR(cmd, - "ordered tag forced.\n"); -@@ -3536,10 +4253,10 @@ - case 0x08: /* READ_SMALL (6) */ - case 0x28: /* READ_BIG (10) */ - case 0xa8: /* READ_HUGE (12) */ -- order = M_SIMPLE_TAG; -+ order = SIMPLE_QUEUE_TAG; - break; - default: -- order = M_ORDERED_TAG; -+ order = ORDERED_QUEUE_TAG; - } - } - msgptr[msglen++] = order; -@@ -5508,9 +6225,9 @@ - if (!(dbc & 0xc0000000)) - phase = (dbc >> 24) & 7; - if (phase == 7) -- msg = M_PARITY; -+ msg = MSG_PARITY_ERROR; - else -- msg = M_ID_ERROR; -+ msg = INITIATOR_ERROR; - - - /* -@@ -6074,6 +6791,8 @@ - /*----------------------------------------------------------------------------- - ** - ** Was Sie schon immer ueber transfermode negotiation wissen wollten ... -+** ("Everything you've always wanted to know about transfer mode -+** negotiation") - ** - ** We try to negotiate sync and wide transfer only after - ** a successful inquire command. We look at byte 7 of the -@@ -6175,8 +6894,8 @@ - break; - - } -- np->msgin [0] = M_NOOP; -- np->msgout[0] = M_NOOP; -+ np->msgin [0] = NOP; -+ np->msgout[0] = NOP; - cp->nego_status = 0; - break; - -@@ -6270,9 +6989,9 @@ - spi_offset(starget) = ofs; - ncr_setsync(np, cp, scntl3, (fak<<5)|ofs); - -- np->msgout[0] = M_EXTENDED; -+ np->msgout[0] = EXTENDED_MESSAGE; - np->msgout[1] = 3; -- np->msgout[2] = M_X_SYNC_REQ; -+ np->msgout[2] = EXTENDED_SDTR; - np->msgout[3] = per; - np->msgout[4] = ofs; - -@@ -6286,7 +7005,7 @@ - OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad)); - return; - } -- np->msgin [0] = M_NOOP; -+ np->msgin [0] = NOP; - - break; - -@@ -6362,12 +7081,12 @@ - spi_width(starget) = wide; - ncr_setwide(np, cp, wide, 1); - -- np->msgout[0] = M_EXTENDED; -+ np->msgout[0] = EXTENDED_MESSAGE; - np->msgout[1] = 2; -- np->msgout[2] = M_X_WIDE_REQ; -+ np->msgout[2] = EXTENDED_WDTR; - np->msgout[3] = wide; - -- np->msgin [0] = M_NOOP; -+ np->msgin [0] = NOP; - - cp->nego_status = NS_WIDE; - -@@ -6386,12 +7105,12 @@ - case SIR_REJECT_RECEIVED: - /*----------------------------------------------- - ** -- ** We received a M_REJECT message. -+ ** We received a MESSAGE_REJECT. - ** - **----------------------------------------------- - */ - -- PRINT_ADDR(cp->cmd, "M_REJECT received (%x:%x).\n", -+ PRINT_ADDR(cp->cmd, "MESSAGE_REJECT received (%x:%x).\n", - (unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]); - break; - -@@ -6403,7 +7122,7 @@ - **----------------------------------------------- - */ - -- ncr_print_msg(cp, "M_REJECT sent for", np->msgin); -+ ncr_print_msg(cp, "MESSAGE_REJECT sent for", np->msgin); - break; - - /*-------------------------------------------------------------------- -@@ -6422,7 +7141,7 @@ - **----------------------------------------------- - */ - -- PRINT_ADDR(cp->cmd, "M_IGN_RESIDUE received, but not yet " -+ PRINT_ADDR(cp->cmd, "IGNORE_WIDE_RESIDUE received, but not yet " - "implemented.\n"); - break; - #if 0 -@@ -6435,7 +7154,7 @@ - **----------------------------------------------- - */ - -- PRINT_ADDR(cp->cmd, "M_DISCONNECT received, but datapointer " -+ PRINT_ADDR(cp->cmd, "DISCONNECT received, but datapointer " - "not saved: data=%x save=%x goal=%x.\n", - (unsigned) INL (nc_temp), - (unsigned) scr_to_cpu(np->header.savep), -@@ -7141,7 +7860,7 @@ - **========================================================== - ** - ** Note: we have to return the correct value. --** THERE IS NO SAVE DEFAULT VALUE. -+** THERE IS NO SAFE DEFAULT VALUE. - ** - ** Most NCR/SYMBIOS boards are delivered with a 40 Mhz clock. - ** 53C860 and 53C875 rev. 1 support fast20 transfers but -@@ -7841,7 +8560,7 @@ - - /* use SIMPLE TAG messages by default */ - #ifdef SCSI_NCR_ALWAYS_SIMPLE_TAG -- np->order = M_SIMPLE_TAG; -+ np->order = SIMPLE_QUEUE_TAG; - #endif - - spin_unlock_irqrestore(&np->smp_lock, flags); -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/ncr53c8xx.h CVS2_6_15_RC7_PA0/drivers/scsi/ncr53c8xx.h ---- LINUS_2_6_15_RC7/drivers/scsi/ncr53c8xx.h 2005-12-27 13:25:48.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/ncr53c8xx.h 2005-12-12 12:01:54.000000000 -0700 -@@ -36,6 +36,13 @@ - ** And has been ported to NetBSD by - ** Charles M. Hannum - ** -+** Added support for MIPS big endian systems. -+** Carsten Langgaard, carstenl@mips.com -+** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -+** -+** Added support for HP PARISC big endian systems. -+** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -+** - ******************************************************************************* - */ - -@@ -44,7 +51,1225 @@ - - #include - --#include "sym53c8xx_defs.h" -+#include -+ -+/* -+** If you want a driver as small as possible, donnot define the -+** following options. -+*/ -+#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT -+#define SCSI_NCR_DEBUG_INFO_SUPPORT -+ -+/* -+** To disable integrity checking, do not define the -+** following option. -+*/ -+#ifdef CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK -+# define SCSI_NCR_ENABLE_INTEGRITY_CHECK -+#endif -+ -+/* --------------------------------------------------------------------- -+** Take into account kernel configured parameters. -+** Most of these options can be overridden at startup by a command line. -+** --------------------------------------------------------------------- -+*/ -+ -+/* -+ * For Ultra2 and Ultra3 SCSI support option, use special features. -+ * -+ * Value (default) means: -+ * bit 0 : all features enabled, except: -+ * bit 1 : PCI Write And Invalidate. -+ * bit 2 : Data Phase Mismatch handling from SCRIPTS. -+ * -+ * Use boot options ncr53c8xx=specf:1 if you want all chip features to be -+ * enabled by the driver. -+ */ -+#define SCSI_NCR_SETUP_SPECIAL_FEATURES (3) -+ -+#define SCSI_NCR_MAX_SYNC (80) -+ -+/* -+ * Allow tags from 2 to 256, default 8 -+ */ -+#ifdef CONFIG_SCSI_NCR53C8XX_MAX_TAGS -+#if CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2 -+#define SCSI_NCR_MAX_TAGS (2) -+#elif CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256 -+#define SCSI_NCR_MAX_TAGS (256) -+#else -+#define SCSI_NCR_MAX_TAGS CONFIG_SCSI_NCR53C8XX_MAX_TAGS -+#endif -+#else -+#define SCSI_NCR_MAX_TAGS (8) -+#endif -+ -+/* -+ * Allow tagged command queuing support if configured with default number -+ * of tags set to max (see above). -+ */ -+#ifdef CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS -+#define SCSI_NCR_SETUP_DEFAULT_TAGS CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS -+#elif defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE -+#define SCSI_NCR_SETUP_DEFAULT_TAGS SCSI_NCR_MAX_TAGS -+#else -+#define SCSI_NCR_SETUP_DEFAULT_TAGS (0) -+#endif -+ -+/* -+ * Immediate arbitration -+ */ -+#if defined(CONFIG_SCSI_NCR53C8XX_IARB) -+#define SCSI_NCR_IARB_SUPPORT -+#endif -+ -+/* -+ * Sync transfer frequency at startup. -+ * Allow from 5Mhz to 80Mhz default 20 Mhz. -+ */ -+#ifndef CONFIG_SCSI_NCR53C8XX_SYNC -+#define CONFIG_SCSI_NCR53C8XX_SYNC (20) -+#elif CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC -+#undef CONFIG_SCSI_NCR53C8XX_SYNC -+#define CONFIG_SCSI_NCR53C8XX_SYNC SCSI_NCR_MAX_SYNC -+#endif -+ -+#if CONFIG_SCSI_NCR53C8XX_SYNC == 0 -+#define SCSI_NCR_SETUP_DEFAULT_SYNC (255) -+#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 5 -+#define SCSI_NCR_SETUP_DEFAULT_SYNC (50) -+#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 20 -+#define SCSI_NCR_SETUP_DEFAULT_SYNC (250/(CONFIG_SCSI_NCR53C8XX_SYNC)) -+#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 33 -+#define SCSI_NCR_SETUP_DEFAULT_SYNC (11) -+#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 40 -+#define SCSI_NCR_SETUP_DEFAULT_SYNC (10) -+#else -+#define SCSI_NCR_SETUP_DEFAULT_SYNC (9) -+#endif -+ -+/* -+ * Disallow disconnections at boot-up -+ */ -+#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT -+#define SCSI_NCR_SETUP_DISCONNECTION (0) -+#else -+#define SCSI_NCR_SETUP_DISCONNECTION (1) -+#endif -+ -+/* -+ * Force synchronous negotiation for all targets -+ */ -+#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO -+#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (1) -+#else -+#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (0) -+#endif -+ -+/* -+ * Disable master parity checking (flawed hardwares need that) -+ */ -+#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK -+#define SCSI_NCR_SETUP_MASTER_PARITY (0) -+#else -+#define SCSI_NCR_SETUP_MASTER_PARITY (1) -+#endif -+ -+/* -+ * Disable scsi parity checking (flawed devices may need that) -+ */ -+#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK -+#define SCSI_NCR_SETUP_SCSI_PARITY (0) -+#else -+#define SCSI_NCR_SETUP_SCSI_PARITY (1) -+#endif -+ -+/* -+ * Settle time after reset at boot-up -+ */ -+#define SCSI_NCR_SETUP_SETTLE_TIME (2) -+ -+/* -+** Bridge quirks work-around option defaulted to 1. -+*/ -+#ifndef SCSI_NCR_PCIQ_WORK_AROUND_OPT -+#define SCSI_NCR_PCIQ_WORK_AROUND_OPT 1 -+#endif -+ -+/* -+** Work-around common bridge misbehaviour. -+** -+** - Do not flush posted writes in the opposite -+** direction on read. -+** - May reorder DMA writes to memory. -+** -+** This option should not affect performances -+** significantly, so it is the default. -+*/ -+#if SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1 -+#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM -+#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES -+#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS -+ -+/* -+** Same as option 1, but also deal with -+** misconfigured interrupts. -+** -+** - Edge triggerred instead of level sensitive. -+** - No interrupt line connected. -+** - IRQ number misconfigured. -+** -+** If no interrupt is delivered, the driver will -+** catch the interrupt conditions 10 times per -+** second. No need to say that this option is -+** not recommended. -+*/ -+#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2 -+#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM -+#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES -+#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS -+#define SCSI_NCR_PCIQ_BROKEN_INTR -+ -+/* -+** Some bridge designers decided to flush -+** everything prior to deliver the interrupt. -+** This option tries to deal with such a -+** behaviour. -+*/ -+#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3 -+#define SCSI_NCR_PCIQ_SYNC_ON_INTR -+#endif -+ -+/* -+** Other parameters not configurable with "make config" -+** Avoid to change these constants, unless you know what you are doing. -+*/ -+ -+#define SCSI_NCR_ALWAYS_SIMPLE_TAG -+#define SCSI_NCR_MAX_SCATTER (127) -+#define SCSI_NCR_MAX_TARGET (16) -+ -+/* -+** Compute some desirable value for CAN_QUEUE -+** and CMD_PER_LUN. -+** The driver will use lower values if these -+** ones appear to be too large. -+*/ -+#define SCSI_NCR_CAN_QUEUE (8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET) -+#define SCSI_NCR_CMD_PER_LUN (SCSI_NCR_MAX_TAGS) -+ -+#define SCSI_NCR_SG_TABLESIZE (SCSI_NCR_MAX_SCATTER) -+#define SCSI_NCR_TIMER_INTERVAL (HZ) -+ -+#if 1 /* defined CONFIG_SCSI_MULTI_LUN */ -+#define SCSI_NCR_MAX_LUN (16) -+#else -+#define SCSI_NCR_MAX_LUN (1) -+#endif -+ -+/* -+ * IO functions definition for big/little endian CPU support. -+ * For now, the NCR is only supported in little endian addressing mode, -+ */ -+ -+#ifdef __BIG_ENDIAN -+ -+#define inw_l2b inw -+#define inl_l2b inl -+#define outw_b2l outw -+#define outl_b2l outl -+ -+#define readb_raw readb -+#define writeb_raw writeb -+ -+#if defined(SCSI_NCR_BIG_ENDIAN) -+#define readw_l2b __raw_readw -+#define readl_l2b __raw_readl -+#define writew_b2l __raw_writew -+#define writel_b2l __raw_writel -+#define readw_raw __raw_readw -+#define readl_raw __raw_readl -+#define writew_raw __raw_writew -+#define writel_raw __raw_writel -+#else /* Other big-endian */ -+#define readw_l2b readw -+#define readl_l2b readl -+#define writew_b2l writew -+#define writel_b2l writel -+#define readw_raw readw -+#define readl_raw readl -+#define writew_raw writew -+#define writel_raw writel -+#endif -+ -+#else /* little endian */ -+ -+#define inw_raw inw -+#define inl_raw inl -+#define outw_raw outw -+#define outl_raw outl -+ -+#define readb_raw readb -+#define readw_raw readw -+#define readl_raw readl -+#define writeb_raw writeb -+#define writew_raw writew -+#define writel_raw writel -+ -+#endif -+ -+#if !defined(__hppa__) && !defined(__mips__) -+#ifdef SCSI_NCR_BIG_ENDIAN -+#error "The NCR in BIG ENDIAN addressing mode is not (yet) supported" -+#endif -+#endif -+ -+#define MEMORY_BARRIER() mb() -+ -+ -+/* -+ * If the NCR uses big endian addressing mode over the -+ * PCI, actual io register addresses for byte and word -+ * accesses must be changed according to lane routing. -+ * Btw, ncr_offb() and ncr_offw() macros only apply to -+ * constants and so donnot generate bloated code. -+ */ -+ -+#if defined(SCSI_NCR_BIG_ENDIAN) -+ -+#define ncr_offb(o) (((o)&~3)+((~((o)&3))&3)) -+#define ncr_offw(o) (((o)&~3)+((~((o)&3))&2)) -+ -+#else -+ -+#define ncr_offb(o) (o) -+#define ncr_offw(o) (o) -+ -+#endif -+ -+/* -+ * If the CPU and the NCR use same endian-ness addressing, -+ * no byte reordering is needed for script patching. -+ * Macro cpu_to_scr() is to be used for script patching. -+ * Macro scr_to_cpu() is to be used for getting a DWORD -+ * from the script. -+ */ -+ -+#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN) -+ -+#define cpu_to_scr(dw) cpu_to_le32(dw) -+#define scr_to_cpu(dw) le32_to_cpu(dw) -+ -+#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN) -+ -+#define cpu_to_scr(dw) cpu_to_be32(dw) -+#define scr_to_cpu(dw) be32_to_cpu(dw) -+ -+#else -+ -+#define cpu_to_scr(dw) (dw) -+#define scr_to_cpu(dw) (dw) -+ -+#endif -+ -+/* -+ * Access to the controller chip. -+ * -+ * If the CPU and the NCR use same endian-ness addressing, -+ * no byte reordering is needed for accessing chip io -+ * registers. Functions suffixed by '_raw' are assumed -+ * to access the chip over the PCI without doing byte -+ * reordering. Functions suffixed by '_l2b' are -+ * assumed to perform little-endian to big-endian byte -+ * reordering, those suffixed by '_b2l' blah, blah, -+ * blah, ... -+ */ -+ -+/* -+ * MEMORY mapped IO input / output -+ */ -+ -+#define INB_OFF(o) readb_raw((char __iomem *)np->reg + ncr_offb(o)) -+#define OUTB_OFF(o, val) writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o)) -+ -+#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN) -+ -+#define INW_OFF(o) readw_l2b((char __iomem *)np->reg + ncr_offw(o)) -+#define INL_OFF(o) readl_l2b((char __iomem *)np->reg + (o)) -+ -+#define OUTW_OFF(o, val) writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o)) -+#define OUTL_OFF(o, val) writel_b2l((val), (char __iomem *)np->reg + (o)) -+ -+#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN) -+ -+#define INW_OFF(o) readw_b2l((char __iomem *)np->reg + ncr_offw(o)) -+#define INL_OFF(o) readl_b2l((char __iomem *)np->reg + (o)) -+ -+#define OUTW_OFF(o, val) writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o)) -+#define OUTL_OFF(o, val) writel_l2b((val), (char __iomem *)np->reg + (o)) -+ -+#else -+ -+#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS -+/* Only 8 or 32 bit transfers allowed */ -+#define INW_OFF(o) (readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1)) -+#else -+#define INW_OFF(o) readw_raw((char __iomem *)np->reg + ncr_offw(o)) -+#endif -+#define INL_OFF(o) readl_raw((char __iomem *)np->reg + (o)) -+ -+#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS -+/* Only 8 or 32 bit transfers allowed */ -+#define OUTW_OFF(o, val) do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0) -+#else -+#define OUTW_OFF(o, val) writew_raw((val), (char __iomem *)np->reg + ncr_offw(o)) -+#endif -+#define OUTL_OFF(o, val) writel_raw((val), (char __iomem *)np->reg + (o)) -+ -+#endif -+ -+#define INB(r) INB_OFF (offsetof(struct ncr_reg,r)) -+#define INW(r) INW_OFF (offsetof(struct ncr_reg,r)) -+#define INL(r) INL_OFF (offsetof(struct ncr_reg,r)) -+ -+#define OUTB(r, val) OUTB_OFF (offsetof(struct ncr_reg,r), (val)) -+#define OUTW(r, val) OUTW_OFF (offsetof(struct ncr_reg,r), (val)) -+#define OUTL(r, val) OUTL_OFF (offsetof(struct ncr_reg,r), (val)) -+ -+/* -+ * Set bit field ON, OFF -+ */ -+ -+#define OUTONB(r, m) OUTB(r, INB(r) | (m)) -+#define OUTOFFB(r, m) OUTB(r, INB(r) & ~(m)) -+#define OUTONW(r, m) OUTW(r, INW(r) | (m)) -+#define OUTOFFW(r, m) OUTW(r, INW(r) & ~(m)) -+#define OUTONL(r, m) OUTL(r, INL(r) | (m)) -+#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m)) -+ -+/* -+ * We normally want the chip to have a consistent view -+ * of driver internal data structures when we restart it. -+ * Thus these macros. -+ */ -+#define OUTL_DSP(v) \ -+ do { \ -+ MEMORY_BARRIER(); \ -+ OUTL (nc_dsp, (v)); \ -+ } while (0) -+ -+#define OUTONB_STD() \ -+ do { \ -+ MEMORY_BARRIER(); \ -+ OUTONB (nc_dcntl, (STD|NOCOM)); \ -+ } while (0) -+ -+ -+/* -+** NCR53C8XX devices features table. -+*/ -+struct ncr_chip { -+ unsigned short revision_id; -+ unsigned char burst_max; /* log-base-2 of max burst */ -+ unsigned char offset_max; -+ unsigned char nr_divisor; -+ unsigned int features; -+#define FE_LED0 (1<<0) -+#define FE_WIDE (1<<1) /* Wide data transfers */ -+#define FE_ULTRA (1<<2) /* Ultra speed 20Mtrans/sec */ -+#define FE_DBLR (1<<4) /* Clock doubler present */ -+#define FE_QUAD (1<<5) /* Clock quadrupler present */ -+#define FE_ERL (1<<6) /* Enable read line */ -+#define FE_CLSE (1<<7) /* Cache line size enable */ -+#define FE_WRIE (1<<8) /* Write & Invalidate enable */ -+#define FE_ERMP (1<<9) /* Enable read multiple */ -+#define FE_BOF (1<<10) /* Burst opcode fetch */ -+#define FE_DFS (1<<11) /* DMA fifo size */ -+#define FE_PFEN (1<<12) /* Prefetch enable */ -+#define FE_LDSTR (1<<13) /* Load/Store supported */ -+#define FE_RAM (1<<14) /* On chip RAM present */ -+#define FE_VARCLK (1<<15) /* SCSI clock may vary */ -+#define FE_RAM8K (1<<16) /* On chip RAM sized 8Kb */ -+#define FE_64BIT (1<<17) /* Have a 64-bit PCI interface */ -+#define FE_IO256 (1<<18) /* Requires full 256 bytes in PCI space */ -+#define FE_NOPM (1<<19) /* Scripts handles phase mismatch */ -+#define FE_LEDC (1<<20) /* Hardware control of LED */ -+#define FE_DIFF (1<<21) /* Support Differential SCSI */ -+#define FE_66MHZ (1<<23) /* 66MHz PCI Support */ -+#define FE_DAC (1<<24) /* Support DAC cycles (64 bit addressing) */ -+#define FE_ISTAT1 (1<<25) /* Have ISTAT1, MBOX0, MBOX1 registers */ -+#define FE_DAC_IN_USE (1<<26) /* Platform does DAC cycles */ -+#define FE_EHP (1<<27) /* 720: Even host parity */ -+#define FE_MUX (1<<28) /* 720: Multiplexed bus */ -+#define FE_EA (1<<29) /* 720: Enable Ack */ -+ -+#define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP) -+#define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80) -+#define FE_SPECIAL_SET (FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM) -+}; -+ -+ -+/* -+** Driver setup structure. -+** -+** This structure is initialized from linux config options. -+** It can be overridden at boot-up by the boot command line. -+*/ -+#define SCSI_NCR_MAX_EXCLUDES 8 -+struct ncr_driver_setup { -+ u8 master_parity; -+ u8 scsi_parity; -+ u8 disconnection; -+ u8 special_features; -+ u8 force_sync_nego; -+ u8 reverse_probe; -+ u8 pci_fix_up; -+ u8 use_nvram; -+ u8 verbose; -+ u8 default_tags; -+ u16 default_sync; -+ u16 debug; -+ u8 burst_max; -+ u8 led_pin; -+ u8 max_wide; -+ u8 settle_delay; -+ u8 diff_support; -+ u8 irqm; -+ u8 bus_check; -+ u8 optimize; -+ u8 recovery; -+ u8 host_id; -+ u16 iarb; -+ u32 excludes[SCSI_NCR_MAX_EXCLUDES]; -+ char tag_ctrl[100]; -+}; -+ -+/* -+** Initial setup. -+** Can be overriden at startup by a command line. -+*/ -+#define SCSI_NCR_DRIVER_SETUP \ -+{ \ -+ SCSI_NCR_SETUP_MASTER_PARITY, \ -+ SCSI_NCR_SETUP_SCSI_PARITY, \ -+ SCSI_NCR_SETUP_DISCONNECTION, \ -+ SCSI_NCR_SETUP_SPECIAL_FEATURES, \ -+ SCSI_NCR_SETUP_FORCE_SYNC_NEGO, \ -+ 0, \ -+ 0, \ -+ 1, \ -+ 0, \ -+ SCSI_NCR_SETUP_DEFAULT_TAGS, \ -+ SCSI_NCR_SETUP_DEFAULT_SYNC, \ -+ 0x00, \ -+ 7, \ -+ 0, \ -+ 1, \ -+ SCSI_NCR_SETUP_SETTLE_TIME, \ -+ 0, \ -+ 0, \ -+ 1, \ -+ 0, \ -+ 0, \ -+ 255, \ -+ 0x00 \ -+} -+ -+/* -+** Boot fail safe setup. -+** Override initial setup from boot command line: -+** ncr53c8xx=safe:y -+*/ -+#define SCSI_NCR_DRIVER_SAFE_SETUP \ -+{ \ -+ 0, \ -+ 1, \ -+ 0, \ -+ 0, \ -+ 0, \ -+ 0, \ -+ 0, \ -+ 1, \ -+ 2, \ -+ 0, \ -+ 255, \ -+ 0x00, \ -+ 255, \ -+ 0, \ -+ 0, \ -+ 10, \ -+ 1, \ -+ 1, \ -+ 1, \ -+ 0, \ -+ 0, \ -+ 255 \ -+} -+ -+/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/ -+ -+/*----------------------------------------------------------------- -+** -+** The ncr 53c810 register structure. -+** -+**----------------------------------------------------------------- -+*/ -+ -+struct ncr_reg { -+/*00*/ u8 nc_scntl0; /* full arb., ena parity, par->ATN */ -+ -+/*01*/ u8 nc_scntl1; /* no reset */ -+ #define ISCON 0x10 /* connected to scsi */ -+ #define CRST 0x08 /* force reset */ -+ #define IARB 0x02 /* immediate arbitration */ -+ -+/*02*/ u8 nc_scntl2; /* no disconnect expected */ -+ #define SDU 0x80 /* cmd: disconnect will raise error */ -+ #define CHM 0x40 /* sta: chained mode */ -+ #define WSS 0x08 /* sta: wide scsi send [W]*/ -+ #define WSR 0x01 /* sta: wide scsi received [W]*/ -+ -+/*03*/ u8 nc_scntl3; /* cnf system clock dependent */ -+ #define EWS 0x08 /* cmd: enable wide scsi [W]*/ -+ #define ULTRA 0x80 /* cmd: ULTRA enable */ -+ /* bits 0-2, 7 rsvd for C1010 */ -+ -+/*04*/ u8 nc_scid; /* cnf host adapter scsi address */ -+ #define RRE 0x40 /* r/w:e enable response to resel. */ -+ #define SRE 0x20 /* r/w:e enable response to select */ -+ -+/*05*/ u8 nc_sxfer; /* ### Sync speed and count */ -+ /* bits 6-7 rsvd for C1010 */ -+ -+/*06*/ u8 nc_sdid; /* ### Destination-ID */ -+ -+/*07*/ u8 nc_gpreg; /* ??? IO-Pins */ -+ -+/*08*/ u8 nc_sfbr; /* ### First byte in phase */ -+ -+/*09*/ u8 nc_socl; -+ #define CREQ 0x80 /* r/w: SCSI-REQ */ -+ #define CACK 0x40 /* r/w: SCSI-ACK */ -+ #define CBSY 0x20 /* r/w: SCSI-BSY */ -+ #define CSEL 0x10 /* r/w: SCSI-SEL */ -+ #define CATN 0x08 /* r/w: SCSI-ATN */ -+ #define CMSG 0x04 /* r/w: SCSI-MSG */ -+ #define CC_D 0x02 /* r/w: SCSI-C_D */ -+ #define CI_O 0x01 /* r/w: SCSI-I_O */ -+ -+/*0a*/ u8 nc_ssid; -+ -+/*0b*/ u8 nc_sbcl; -+ -+/*0c*/ u8 nc_dstat; -+ #define DFE 0x80 /* sta: dma fifo empty */ -+ #define MDPE 0x40 /* int: master data parity error */ -+ #define BF 0x20 /* int: script: bus fault */ -+ #define ABRT 0x10 /* int: script: command aborted */ -+ #define SSI 0x08 /* int: script: single step */ -+ #define SIR 0x04 /* int: script: interrupt instruct. */ -+ #define IID 0x01 /* int: script: illegal instruct. */ -+ -+/*0d*/ u8 nc_sstat0; -+ #define ILF 0x80 /* sta: data in SIDL register lsb */ -+ #define ORF 0x40 /* sta: data in SODR register lsb */ -+ #define OLF 0x20 /* sta: data in SODL register lsb */ -+ #define AIP 0x10 /* sta: arbitration in progress */ -+ #define LOA 0x08 /* sta: arbitration lost */ -+ #define WOA 0x04 /* sta: arbitration won */ -+ #define IRST 0x02 /* sta: scsi reset signal */ -+ #define SDP 0x01 /* sta: scsi parity signal */ -+ -+/*0e*/ u8 nc_sstat1; -+ #define FF3210 0xf0 /* sta: bytes in the scsi fifo */ -+ -+/*0f*/ u8 nc_sstat2; -+ #define ILF1 0x80 /* sta: data in SIDL register msb[W]*/ -+ #define ORF1 0x40 /* sta: data in SODR register msb[W]*/ -+ #define OLF1 0x20 /* sta: data in SODL register msb[W]*/ -+ #define DM 0x04 /* sta: DIFFSENS mismatch (895/6 only) */ -+ #define LDSC 0x02 /* sta: disconnect & reconnect */ -+ -+/*10*/ u8 nc_dsa; /* --> Base page */ -+/*11*/ u8 nc_dsa1; -+/*12*/ u8 nc_dsa2; -+/*13*/ u8 nc_dsa3; -+ -+/*14*/ u8 nc_istat; /* --> Main Command and status */ -+ #define CABRT 0x80 /* cmd: abort current operation */ -+ #define SRST 0x40 /* mod: reset chip */ -+ #define SIGP 0x20 /* r/w: message from host to ncr */ -+ #define SEM 0x10 /* r/w: message between host + ncr */ -+ #define CON 0x08 /* sta: connected to scsi */ -+ #define INTF 0x04 /* sta: int on the fly (reset by wr)*/ -+ #define SIP 0x02 /* sta: scsi-interrupt */ -+ #define DIP 0x01 /* sta: host/script interrupt */ -+ -+/*15*/ u8 nc_istat1; /* 896 and later cores only */ -+ #define FLSH 0x04 /* sta: chip is flushing */ -+ #define SRUN 0x02 /* sta: scripts are running */ -+ #define SIRQD 0x01 /* r/w: disable INT pin */ -+ -+/*16*/ u8 nc_mbox0; /* 896 and later cores only */ -+/*17*/ u8 nc_mbox1; /* 896 and later cores only */ -+ -+/*18*/ u8 nc_ctest0; -+ #define EHP 0x04 /* 720 even host parity */ -+/*19*/ u8 nc_ctest1; -+ -+/*1a*/ u8 nc_ctest2; -+ #define CSIGP 0x40 -+ /* bits 0-2,7 rsvd for C1010 */ -+ -+/*1b*/ u8 nc_ctest3; -+ #define FLF 0x08 /* cmd: flush dma fifo */ -+ #define CLF 0x04 /* cmd: clear dma fifo */ -+ #define FM 0x02 /* mod: fetch pin mode */ -+ #define WRIE 0x01 /* mod: write and invalidate enable */ -+ /* bits 4-7 rsvd for C1010 */ -+ -+/*1c*/ u32 nc_temp; /* ### Temporary stack */ -+ -+/*20*/ u8 nc_dfifo; -+/*21*/ u8 nc_ctest4; -+ #define MUX 0x80 /* 720 host bus multiplex mode */ -+ #define BDIS 0x80 /* mod: burst disable */ -+ #define MPEE 0x08 /* mod: master parity error enable */ -+ -+/*22*/ u8 nc_ctest5; -+ #define DFS 0x20 /* mod: dma fifo size */ -+ /* bits 0-1, 3-7 rsvd for C1010 */ -+/*23*/ u8 nc_ctest6; -+ -+/*24*/ u32 nc_dbc; /* ### Byte count and command */ -+/*28*/ u32 nc_dnad; /* ### Next command register */ -+/*2c*/ u32 nc_dsp; /* --> Script Pointer */ -+/*30*/ u32 nc_dsps; /* --> Script pointer save/opcode#2 */ -+ -+/*34*/ u8 nc_scratcha; /* Temporary register a */ -+/*35*/ u8 nc_scratcha1; -+/*36*/ u8 nc_scratcha2; -+/*37*/ u8 nc_scratcha3; -+ -+/*38*/ u8 nc_dmode; -+ #define BL_2 0x80 /* mod: burst length shift value +2 */ -+ #define BL_1 0x40 /* mod: burst length shift value +1 */ -+ #define ERL 0x08 /* mod: enable read line */ -+ #define ERMP 0x04 /* mod: enable read multiple */ -+ #define BOF 0x02 /* mod: burst op code fetch */ -+ -+/*39*/ u8 nc_dien; -+/*3a*/ u8 nc_sbr; -+ -+/*3b*/ u8 nc_dcntl; /* --> Script execution control */ -+ #define CLSE 0x80 /* mod: cache line size enable */ -+ #define PFF 0x40 /* cmd: pre-fetch flush */ -+ #define PFEN 0x20 /* mod: pre-fetch enable */ -+ #define EA 0x20 /* mod: 720 enable-ack */ -+ #define SSM 0x10 /* mod: single step mode */ -+ #define IRQM 0x08 /* mod: irq mode (1 = totem pole !) */ -+ #define STD 0x04 /* cmd: start dma mode */ -+ #define IRQD 0x02 /* mod: irq disable */ -+ #define NOCOM 0x01 /* cmd: protect sfbr while reselect */ -+ /* bits 0-1 rsvd for C1010 */ -+ -+/*3c*/ u32 nc_adder; -+ -+/*40*/ u16 nc_sien; /* -->: interrupt enable */ -+/*42*/ u16 nc_sist; /* <--: interrupt status */ -+ #define SBMC 0x1000/* sta: SCSI Bus Mode Change (895/6 only) */ -+ #define STO 0x0400/* sta: timeout (select) */ -+ #define GEN 0x0200/* sta: timeout (general) */ -+ #define HTH 0x0100/* sta: timeout (handshake) */ -+ #define MA 0x80 /* sta: phase mismatch */ -+ #define CMP 0x40 /* sta: arbitration complete */ -+ #define SEL 0x20 /* sta: selected by another device */ -+ #define RSL 0x10 /* sta: reselected by another device*/ -+ #define SGE 0x08 /* sta: gross error (over/underflow)*/ -+ #define UDC 0x04 /* sta: unexpected disconnect */ -+ #define RST 0x02 /* sta: scsi bus reset detected */ -+ #define PAR 0x01 /* sta: scsi parity error */ -+ -+/*44*/ u8 nc_slpar; -+/*45*/ u8 nc_swide; -+/*46*/ u8 nc_macntl; -+/*47*/ u8 nc_gpcntl; -+/*48*/ u8 nc_stime0; /* cmd: timeout for select&handshake*/ -+/*49*/ u8 nc_stime1; /* cmd: timeout user defined */ -+/*4a*/ u16 nc_respid; /* sta: Reselect-IDs */ -+ -+/*4c*/ u8 nc_stest0; -+ -+/*4d*/ u8 nc_stest1; -+ #define SCLK 0x80 /* Use the PCI clock as SCSI clock */ -+ #define DBLEN 0x08 /* clock doubler running */ -+ #define DBLSEL 0x04 /* clock doubler selected */ -+ -+ -+/*4e*/ u8 nc_stest2; -+ #define ROF 0x40 /* reset scsi offset (after gross error!) */ -+ #define DIF 0x20 /* 720 SCSI differential mode */ -+ #define EXT 0x02 /* extended filtering */ -+ -+/*4f*/ u8 nc_stest3; -+ #define TE 0x80 /* c: tolerAnt enable */ -+ #define HSC 0x20 /* c: Halt SCSI Clock */ -+ #define CSF 0x02 /* c: clear scsi fifo */ -+ -+/*50*/ u16 nc_sidl; /* Lowlevel: latched from scsi data */ -+/*52*/ u8 nc_stest4; -+ #define SMODE 0xc0 /* SCSI bus mode (895/6 only) */ -+ #define SMODE_HVD 0x40 /* High Voltage Differential */ -+ #define SMODE_SE 0x80 /* Single Ended */ -+ #define SMODE_LVD 0xc0 /* Low Voltage Differential */ -+ #define LCKFRQ 0x20 /* Frequency Lock (895/6 only) */ -+ /* bits 0-5 rsvd for C1010 */ -+ -+/*53*/ u8 nc_53_; -+/*54*/ u16 nc_sodl; /* Lowlevel: data out to scsi data */ -+/*56*/ u8 nc_ccntl0; /* Chip Control 0 (896) */ -+ #define ENPMJ 0x80 /* Enable Phase Mismatch Jump */ -+ #define PMJCTL 0x40 /* Phase Mismatch Jump Control */ -+ #define ENNDJ 0x20 /* Enable Non Data PM Jump */ -+ #define DISFC 0x10 /* Disable Auto FIFO Clear */ -+ #define DILS 0x02 /* Disable Internal Load/Store */ -+ #define DPR 0x01 /* Disable Pipe Req */ -+ -+/*57*/ u8 nc_ccntl1; /* Chip Control 1 (896) */ -+ #define ZMOD 0x80 /* High Impedance Mode */ -+ #define DIC 0x10 /* Disable Internal Cycles */ -+ #define DDAC 0x08 /* Disable Dual Address Cycle */ -+ #define XTIMOD 0x04 /* 64-bit Table Ind. Indexing Mode */ -+ #define EXTIBMV 0x02 /* Enable 64-bit Table Ind. BMOV */ -+ #define EXDBMV 0x01 /* Enable 64-bit Direct BMOV */ -+ -+/*58*/ u16 nc_sbdl; /* Lowlevel: data from scsi data */ -+/*5a*/ u16 nc_5a_; -+ -+/*5c*/ u8 nc_scr0; /* Working register B */ -+/*5d*/ u8 nc_scr1; /* */ -+/*5e*/ u8 nc_scr2; /* */ -+/*5f*/ u8 nc_scr3; /* */ -+ -+/*60*/ u8 nc_scrx[64]; /* Working register C-R */ -+/*a0*/ u32 nc_mmrs; /* Memory Move Read Selector */ -+/*a4*/ u32 nc_mmws; /* Memory Move Write Selector */ -+/*a8*/ u32 nc_sfs; /* Script Fetch Selector */ -+/*ac*/ u32 nc_drs; /* DSA Relative Selector */ -+/*b0*/ u32 nc_sbms; /* Static Block Move Selector */ -+/*b4*/ u32 nc_dbms; /* Dynamic Block Move Selector */ -+/*b8*/ u32 nc_dnad64; /* DMA Next Address 64 */ -+/*bc*/ u16 nc_scntl4; /* C1010 only */ -+ #define U3EN 0x80 /* Enable Ultra 3 */ -+ #define AIPEN 0x40 /* Allow check upper byte lanes */ -+ #define XCLKH_DT 0x08 /* Extra clock of data hold on DT -+ transfer edge */ -+ #define XCLKH_ST 0x04 /* Extra clock of data hold on ST -+ transfer edge */ -+ -+/*be*/ u8 nc_aipcntl0; /* Epat Control 1 C1010 only */ -+/*bf*/ u8 nc_aipcntl1; /* AIP Control C1010_66 Only */ -+ -+/*c0*/ u32 nc_pmjad1; /* Phase Mismatch Jump Address 1 */ -+/*c4*/ u32 nc_pmjad2; /* Phase Mismatch Jump Address 2 */ -+/*c8*/ u8 nc_rbc; /* Remaining Byte Count */ -+/*c9*/ u8 nc_rbc1; /* */ -+/*ca*/ u8 nc_rbc2; /* */ -+/*cb*/ u8 nc_rbc3; /* */ -+ -+/*cc*/ u8 nc_ua; /* Updated Address */ -+/*cd*/ u8 nc_ua1; /* */ -+/*ce*/ u8 nc_ua2; /* */ -+/*cf*/ u8 nc_ua3; /* */ -+/*d0*/ u32 nc_esa; /* Entry Storage Address */ -+/*d4*/ u8 nc_ia; /* Instruction Address */ -+/*d5*/ u8 nc_ia1; -+/*d6*/ u8 nc_ia2; -+/*d7*/ u8 nc_ia3; -+/*d8*/ u32 nc_sbc; /* SCSI Byte Count (3 bytes only) */ -+/*dc*/ u32 nc_csbc; /* Cumulative SCSI Byte Count */ -+ -+ /* Following for C1010 only */ -+/*e0*/ u16 nc_crcpad; /* CRC Value */ -+/*e2*/ u8 nc_crccntl0; /* CRC control register */ -+ #define SNDCRC 0x10 /* Send CRC Request */ -+/*e3*/ u8 nc_crccntl1; /* CRC control register */ -+/*e4*/ u32 nc_crcdata; /* CRC data register */ -+/*e8*/ u32 nc_e8_; /* rsvd */ -+/*ec*/ u32 nc_ec_; /* rsvd */ -+/*f0*/ u16 nc_dfbc; /* DMA FIFO byte count */ -+ -+}; -+ -+/*----------------------------------------------------------- -+** -+** Utility macros for the script. -+** -+**----------------------------------------------------------- -+*/ -+ -+#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r)) -+#define REG(r) REGJ (nc_, r) -+ -+typedef u32 ncrcmd; -+ -+/*----------------------------------------------------------- -+** -+** SCSI phases -+** -+** DT phases illegal for ncr driver. -+** -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_DATA_OUT 0x00000000 -+#define SCR_DATA_IN 0x01000000 -+#define SCR_COMMAND 0x02000000 -+#define SCR_STATUS 0x03000000 -+#define SCR_DT_DATA_OUT 0x04000000 -+#define SCR_DT_DATA_IN 0x05000000 -+#define SCR_MSG_OUT 0x06000000 -+#define SCR_MSG_IN 0x07000000 -+ -+#define SCR_ILG_OUT 0x04000000 -+#define SCR_ILG_IN 0x05000000 -+ -+/*----------------------------------------------------------- -+** -+** Data transfer via SCSI. -+** -+**----------------------------------------------------------- -+** -+** MOVE_ABS (LEN) -+** <> -+** -+** MOVE_IND (LEN) -+** <> -+** -+** MOVE_TBL -+** <> -+** -+**----------------------------------------------------------- -+*/ -+ -+#define OPC_MOVE 0x08000000 -+ -+#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l)) -+#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l)) -+#define SCR_MOVE_TBL (0x10000000 | OPC_MOVE) -+ -+#define SCR_CHMOV_ABS(l) ((0x00000000) | (l)) -+#define SCR_CHMOV_IND(l) ((0x20000000) | (l)) -+#define SCR_CHMOV_TBL (0x10000000) -+ -+struct scr_tblmove { -+ u32 size; -+ u32 addr; -+}; -+ -+/*----------------------------------------------------------- -+** -+** Selection -+** -+**----------------------------------------------------------- -+** -+** SEL_ABS | SCR_ID (0..15) [ | REL_JMP] -+** <> -+** -+** SEL_TBL | << dnad_offset>> [ | REL_JMP] -+** <> -+** -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_SEL_ABS 0x40000000 -+#define SCR_SEL_ABS_ATN 0x41000000 -+#define SCR_SEL_TBL 0x42000000 -+#define SCR_SEL_TBL_ATN 0x43000000 -+ -+ -+#ifdef SCSI_NCR_BIG_ENDIAN -+struct scr_tblsel { -+ u8 sel_scntl3; -+ u8 sel_id; -+ u8 sel_sxfer; -+ u8 sel_scntl4; -+}; -+#else -+struct scr_tblsel { -+ u8 sel_scntl4; -+ u8 sel_sxfer; -+ u8 sel_id; -+ u8 sel_scntl3; -+}; -+#endif -+ -+#define SCR_JMP_REL 0x04000000 -+#define SCR_ID(id) (((u32)(id)) << 16) -+ -+/*----------------------------------------------------------- -+** -+** Waiting for Disconnect or Reselect -+** -+**----------------------------------------------------------- -+** -+** WAIT_DISC -+** dummy: <> -+** -+** WAIT_RESEL -+** <> -+** -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_WAIT_DISC 0x48000000 -+#define SCR_WAIT_RESEL 0x50000000 -+ -+/*----------------------------------------------------------- -+** -+** Bit Set / Reset -+** -+**----------------------------------------------------------- -+** -+** SET (flags {|.. }) -+** -+** CLR (flags {|.. }) -+** -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_SET(f) (0x58000000 | (f)) -+#define SCR_CLR(f) (0x60000000 | (f)) -+ -+#define SCR_CARRY 0x00000400 -+#define SCR_TRG 0x00000200 -+#define SCR_ACK 0x00000040 -+#define SCR_ATN 0x00000008 -+ -+ -+ -+ -+/*----------------------------------------------------------- -+** -+** Memory to memory move -+** -+**----------------------------------------------------------- -+** -+** COPY (bytecount) -+** << source_address >> -+** << destination_address >> -+** -+** SCR_COPY sets the NO FLUSH option by default. -+** SCR_COPY_F does not set this option. -+** -+** For chips which do not support this option, -+** ncr_copy_and_bind() will remove this bit. -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_NO_FLUSH 0x01000000 -+ -+#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n)) -+#define SCR_COPY_F(n) (0xc0000000 | (n)) -+ -+/*----------------------------------------------------------- -+** -+** Register move and binary operations -+** -+**----------------------------------------------------------- -+** -+** SFBR_REG (reg, op, data) reg = SFBR op data -+** << 0 >> -+** -+** REG_SFBR (reg, op, data) SFBR = reg op data -+** << 0 >> -+** -+** REG_REG (reg, op, data) reg = reg op data -+** << 0 >> -+** -+**----------------------------------------------------------- -+** On 810A, 860, 825A, 875, 895 and 896 chips the content -+** of SFBR register can be used as data (SCR_SFBR_DATA). -+** The 896 has additionnal IO registers starting at -+** offset 0x80. Bit 7 of register offset is stored in -+** bit 7 of the SCRIPTS instruction first DWORD. -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) -+ -+#define SCR_SFBR_REG(reg,op,data) \ -+ (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) -+ -+#define SCR_REG_SFBR(reg,op,data) \ -+ (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) -+ -+#define SCR_REG_REG(reg,op,data) \ -+ (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) -+ -+ -+#define SCR_LOAD 0x00000000 -+#define SCR_SHL 0x01000000 -+#define SCR_OR 0x02000000 -+#define SCR_XOR 0x03000000 -+#define SCR_AND 0x04000000 -+#define SCR_SHR 0x05000000 -+#define SCR_ADD 0x06000000 -+#define SCR_ADDC 0x07000000 -+ -+#define SCR_SFBR_DATA (0x00800000>>8ul) /* Use SFBR as data */ -+ -+/*----------------------------------------------------------- -+** -+** FROM_REG (reg) SFBR = reg -+** << 0 >> -+** -+** TO_REG (reg) reg = SFBR -+** << 0 >> -+** -+** LOAD_REG (reg, data) reg = -+** << 0 >> -+** -+** LOAD_SFBR(data) SFBR = -+** << 0 >> -+** -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_FROM_REG(reg) \ -+ SCR_REG_SFBR(reg,SCR_OR,0) -+ -+#define SCR_TO_REG(reg) \ -+ SCR_SFBR_REG(reg,SCR_OR,0) -+ -+#define SCR_LOAD_REG(reg,data) \ -+ SCR_REG_REG(reg,SCR_LOAD,data) -+ -+#define SCR_LOAD_SFBR(data) \ -+ (SCR_REG_SFBR (gpreg, SCR_LOAD, data)) -+ -+/*----------------------------------------------------------- -+** -+** LOAD from memory to register. -+** STORE from register to memory. -+** -+** Only supported by 810A, 860, 825A, 875, 895 and 896. -+** -+**----------------------------------------------------------- -+** -+** LOAD_ABS (LEN) -+** <> -+** -+** LOAD_REL (LEN) (DSA relative) -+** <> -+** -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul) -+#define SCR_NO_FLUSH2 0x02000000 -+#define SCR_DSA_REL2 0x10000000 -+ -+#define SCR_LOAD_R(reg, how, n) \ -+ (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n)) -+ -+#define SCR_STORE_R(reg, how, n) \ -+ (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n)) -+ -+#define SCR_LOAD_ABS(reg, n) SCR_LOAD_R(reg, SCR_NO_FLUSH2, n) -+#define SCR_LOAD_REL(reg, n) SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n) -+#define SCR_LOAD_ABS_F(reg, n) SCR_LOAD_R(reg, 0, n) -+#define SCR_LOAD_REL_F(reg, n) SCR_LOAD_R(reg, SCR_DSA_REL2, n) -+ -+#define SCR_STORE_ABS(reg, n) SCR_STORE_R(reg, SCR_NO_FLUSH2, n) -+#define SCR_STORE_REL(reg, n) SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n) -+#define SCR_STORE_ABS_F(reg, n) SCR_STORE_R(reg, 0, n) -+#define SCR_STORE_REL_F(reg, n) SCR_STORE_R(reg, SCR_DSA_REL2, n) -+ -+ -+/*----------------------------------------------------------- -+** -+** Waiting for Disconnect or Reselect -+** -+**----------------------------------------------------------- -+** -+** JUMP [ | IFTRUE/IFFALSE ( ... ) ] -+** <
> -+** -+** JUMPR [ | IFTRUE/IFFALSE ( ... ) ] -+** <> -+** -+** CALL [ | IFTRUE/IFFALSE ( ... ) ] -+** <
> -+** -+** CALLR [ | IFTRUE/IFFALSE ( ... ) ] -+** <> -+** -+** RETURN [ | IFTRUE/IFFALSE ( ... ) ] -+** <> -+** -+** INT [ | IFTRUE/IFFALSE ( ... ) ] -+** <> -+** -+** INT_FLY [ | IFTRUE/IFFALSE ( ... ) ] -+** <> -+** -+** Conditions: -+** WHEN (phase) -+** IF (phase) -+** CARRYSET -+** DATA (data, mask) -+** -+**----------------------------------------------------------- -+*/ -+ -+#define SCR_NO_OP 0x80000000 -+#define SCR_JUMP 0x80080000 -+#define SCR_JUMP64 0x80480000 -+#define SCR_JUMPR 0x80880000 -+#define SCR_CALL 0x88080000 -+#define SCR_CALLR 0x88880000 -+#define SCR_RETURN 0x90080000 -+#define SCR_INT 0x98080000 -+#define SCR_INT_FLY 0x98180000 -+ -+#define IFFALSE(arg) (0x00080000 | (arg)) -+#define IFTRUE(arg) (0x00000000 | (arg)) -+ -+#define WHEN(phase) (0x00030000 | (phase)) -+#define IF(phase) (0x00020000 | (phase)) -+ -+#define DATA(D) (0x00040000 | ((D) & 0xff)) -+#define MASK(D,M) (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff)) -+ -+#define CARRYSET (0x00200000) -+ -+/*----------------------------------------------------------- -+** -+** SCSI constants. -+** -+**----------------------------------------------------------- -+*/ -+ -+/* -+** Status -+*/ -+ -+#define S_GOOD (0x00) -+#define S_CHECK_COND (0x02) -+#define S_COND_MET (0x04) -+#define S_BUSY (0x08) -+#define S_INT (0x10) -+#define S_INT_COND_MET (0x14) -+#define S_CONFLICT (0x18) -+#define S_TERMINATED (0x20) -+#define S_QUEUE_FULL (0x28) -+#define S_ILLEGAL (0xff) -+#define S_SENSE (0x80) -+ -+/* -+ * End of ncrreg from FreeBSD -+ */ - - /* - Build a scatter/gather entry. -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_defs.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_defs.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_defs.h 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_defs.h 2005-12-12 09:00:09.000000000 -0700 -@@ -40,7 +40,7 @@ - #ifndef SYM_DEFS_H - #define SYM_DEFS_H - --#define SYM_VERSION "2.2.1" -+#define SYM_VERSION "2.2.2" - #define SYM_DRIVER_NAME "sym-" SYM_VERSION - - /* -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw.c ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw.c 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw.c 2005-09-27 08:18:02.000000000 -0600 -@@ -37,11 +37,7 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - --#ifdef __FreeBSD__ --#include --#else - #include "sym_glue.h" --#endif - - /* - * Macros used for all firmwares. -@@ -60,19 +56,12 @@ - #define SYM_FWA_SCR sym_fw1a_scr - #define SYM_FWB_SCR sym_fw1b_scr - #define SYM_FWZ_SCR sym_fw1z_scr --#ifdef __FreeBSD__ --#include --#else - #include "sym_fw1.h" --#endif - static struct sym_fwa_ofs sym_fw1a_ofs = { - SYM_GEN_FW_A(struct SYM_FWA_SCR) - }; - static struct sym_fwb_ofs sym_fw1b_ofs = { - SYM_GEN_FW_B(struct SYM_FWB_SCR) --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- SYM_GEN_B(struct SYM_FWB_SCR, data_io) --#endif - }; - static struct sym_fwz_ofs sym_fw1z_ofs = { - SYM_GEN_FW_Z(struct SYM_FWZ_SCR) -@@ -88,19 +77,12 @@ - #define SYM_FWA_SCR sym_fw2a_scr - #define SYM_FWB_SCR sym_fw2b_scr - #define SYM_FWZ_SCR sym_fw2z_scr --#ifdef __FreeBSD__ --#include --#else - #include "sym_fw2.h" --#endif - static struct sym_fwa_ofs sym_fw2a_ofs = { - SYM_GEN_FW_A(struct SYM_FWA_SCR) - }; - static struct sym_fwb_ofs sym_fw2b_ofs = { - SYM_GEN_FW_B(struct SYM_FWB_SCR) --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- SYM_GEN_B(struct SYM_FWB_SCR, data_io) --#endif - SYM_GEN_B(struct SYM_FWB_SCR, start64) - SYM_GEN_B(struct SYM_FWB_SCR, pm_handle) - }; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw.h 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw.h 2005-09-27 08:18:02.000000000 -0600 -@@ -92,9 +92,6 @@ - }; - struct sym_fwb_ofs { - SYM_GEN_FW_B(u_short) --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- SYM_GEN_B(u_short, data_io) --#endif - SYM_GEN_B(u_short, start64) - SYM_GEN_B(u_short, pm_handle) - }; -@@ -111,9 +108,6 @@ - }; - struct sym_fwb_ba { - SYM_GEN_FW_B(u32) --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- SYM_GEN_B(u32, data_io) --#endif - SYM_GEN_B(u32, start64); - SYM_GEN_B(u32, pm_handle); - }; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw1.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw1.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw1.h 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw1.h 2005-09-27 08:18:02.000000000 -0600 -@@ -197,12 +197,6 @@ - u32 bad_status [ 7]; - u32 wsr_ma_helper [ 4]; - --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- /* Unknown direction handling */ -- u32 data_io [ 2]; -- u32 data_io_com [ 8]; -- u32 data_io_out [ 7]; --#endif - /* Data area */ - u32 zero [ 1]; - u32 scratch [ 1]; -@@ -1747,48 +1741,6 @@ - SCR_JUMP, - PADDR_A (dispatch), - --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN --}/*-------------------------< DATA_IO >--------------------------*/,{ -- /* -- * We jump here if the data direction was unknown at the -- * time we had to queue the command to the scripts processor. -- * Pointers had been set as follow in this situation: -- * savep --> DATA_IO -- * lastp --> start pointer when DATA_IN -- * wlastp --> start pointer when DATA_OUT -- * This script sets savep and lastp according to the -- * direction chosen by the target. -- */ -- SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)), -- PADDR_B (data_io_out), --}/*-------------------------< DATA_IO_COM >----------------------*/,{ -- /* -- * Direction is DATA IN. -- */ -- SCR_COPY (4), -- HADDR_1 (ccb_head.lastp), -- HADDR_1 (ccb_head.savep), -- /* -- * Jump to the SCRIPTS according to actual direction. -- */ -- SCR_COPY (4), -- HADDR_1 (ccb_head.savep), -- RADDR_1 (temp), -- SCR_RETURN, -- 0, --}/*-------------------------< DATA_IO_OUT >----------------------*/,{ -- /* -- * Direction is DATA OUT. -- */ -- SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)), -- 0, -- SCR_COPY (4), -- HADDR_1 (ccb_head.wlastp), -- HADDR_1 (ccb_head.lastp), -- SCR_JUMP, -- PADDR_B(data_io_com), --#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */ -- - }/*-------------------------< ZERO >-----------------------------*/,{ - SCR_DATA_ZERO, - }/*-------------------------< SCRATCH >--------------------------*/,{ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw2.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw2.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw2.h 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw2.h 2005-09-27 08:18:02.000000000 -0600 -@@ -191,13 +191,6 @@ - u32 pm_wsr_handle [ 38]; - u32 wsr_ma_helper [ 4]; - --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- /* Unknown direction handling */ -- u32 data_io [ 2]; -- u32 data_io_in [ 2]; -- u32 data_io_com [ 6]; -- u32 data_io_out [ 8]; --#endif - /* Data area */ - u32 zero [ 1]; - u32 scratch [ 1]; -@@ -1838,51 +1831,6 @@ - SCR_JUMP, - PADDR_A (dispatch), - --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN --}/*-------------------------< DATA_IO >--------------------------*/,{ -- /* -- * We jump here if the data direction was unknown at the -- * time we had to queue the command to the scripts processor. -- * Pointers had been set as follow in this situation: -- * savep --> DATA_IO -- * lastp --> start pointer when DATA_IN -- * wlastp --> start pointer when DATA_OUT -- * This script sets savep and lastp according to the -- * direction chosen by the target. -- */ -- SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)), -- PADDR_B (data_io_out), --}/*-------------------------< DATA_IO_IN >-----------------------*/,{ -- /* -- * Direction is DATA IN. -- */ -- SCR_LOAD_REL (scratcha, 4), -- offsetof (struct sym_ccb, phys.head.lastp), --}/*-------------------------< DATA_IO_COM >----------------------*/,{ -- SCR_STORE_REL (scratcha, 4), -- offsetof (struct sym_ccb, phys.head.savep), -- -- /* -- * Jump to the SCRIPTS according to actual direction. -- */ -- SCR_LOAD_REL (temp, 4), -- offsetof (struct sym_ccb, phys.head.savep), -- SCR_RETURN, -- 0, --}/*-------------------------< DATA_IO_OUT >----------------------*/,{ -- /* -- * Direction is DATA OUT. -- */ -- SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)), -- 0, -- SCR_LOAD_REL (scratcha, 4), -- offsetof (struct sym_ccb, phys.head.wlastp), -- SCR_STORE_REL (scratcha, 4), -- offsetof (struct sym_ccb, phys.head.lastp), -- SCR_JUMP, -- PADDR_B(data_io_com), --#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */ -- - }/*-------------------------< ZERO >-----------------------------*/,{ - SCR_DATA_ZERO, - }/*-------------------------< SCRATCH >--------------------------*/,{ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_glue.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_glue.c ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_glue.c 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_glue.c 2005-12-18 08:29:09.000000000 -0700 -@@ -134,45 +134,6 @@ - } - } - --/* -- * We used to try to deal with 64-bit BARs here, but don't any more. -- * There are many parts of this driver which would need to be modified -- * to handle a 64-bit base address, including scripts. I'm uncomfortable -- * with making those changes when I have no way of testing it, so I'm -- * just going to disable it. -- * -- * Note that some machines (eg HP rx8620 and Superdome) have bus addresses -- * below 4GB and physical addresses above 4GB. These will continue to work. -- */ --static int __devinit --pci_get_base_address(struct pci_dev *pdev, int index, unsigned long *basep) --{ -- u32 tmp; -- unsigned long base; --#define PCI_BAR_OFFSET(index) (PCI_BASE_ADDRESS_0 + (index<<2)) -- -- pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp); -- base = tmp; -- if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) { -- pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp); -- if (tmp > 0) { -- dev_err(&pdev->dev, -- "BAR %d is 64-bit, disabling\n", index - 1); -- base = 0; -- } -- } -- -- if ((base & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { -- base &= PCI_BASE_ADDRESS_IO_MASK; -- } else { -- base &= PCI_BASE_ADDRESS_MEM_MASK; -- } -- -- *basep = base; -- return index; --#undef PCI_BAR_OFFSET --} -- - static struct scsi_transport_template *sym2_transport_template = NULL; - - /* -@@ -514,9 +475,8 @@ - */ - int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) - { -+ u32 lastp, goalp; - int dir; -- struct sym_tcb *tp = &np->target[cp->target]; -- struct sym_lcb *lp = sym_lp(tp, cp->lun); - - /* - * Build the CDB. -@@ -534,15 +494,47 @@ - sym_set_cam_status(cmd, DID_ERROR); - goto out_abort; - } -+ -+ /* -+ * No segments means no data. -+ */ -+ if (!cp->segments) -+ dir = DMA_NONE; - } else { - cp->data_len = 0; - cp->segments = 0; - } - - /* -- * Set data pointers. -+ * Set the data pointer. -+ */ -+ switch (dir) { -+ case DMA_BIDIRECTIONAL: -+ printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np)); -+ sym_set_cam_status(cmd, DID_ERROR); -+ goto out_abort; -+ case DMA_TO_DEVICE: -+ goalp = SCRIPTA_BA(np, data_out2) + 8; -+ lastp = goalp - 8 - (cp->segments * (2*4)); -+ break; -+ case DMA_FROM_DEVICE: -+ cp->host_flags |= HF_DATA_IN; -+ goalp = SCRIPTA_BA(np, data_in2) + 8; -+ lastp = goalp - 8 - (cp->segments * (2*4)); -+ break; -+ case DMA_NONE: -+ default: -+ lastp = goalp = SCRIPTB_BA(np, no_data); -+ break; -+ } -+ -+ /* -+ * Set all pointers values needed by SCRIPTS. - */ -- sym_setup_data_pointers(np, cp, dir); -+ cp->phys.head.lastp = cpu_to_scr(lastp); -+ cp->phys.head.savep = cpu_to_scr(lastp); -+ cp->startp = cp->phys.head.savep; -+ cp->goalp = cpu_to_scr(goalp); - - /* - * When `#ifed 1', the code below makes the driver -@@ -563,10 +555,7 @@ - /* - * activate this job. - */ -- if (lp) -- sym_start_next_ccbs(np, lp, 2); -- else -- sym_put_start_queue(np, cp); -+ sym_put_start_queue(np, cp); - return 0; - - out_abort: -@@ -721,7 +710,6 @@ - * What we will do regarding the involved SCSI command. - */ - #define SYM_EH_DO_IGNORE 0 --#define SYM_EH_DO_COMPLETE 1 - #define SYM_EH_DO_WAIT 2 - - /* -@@ -773,25 +761,18 @@ - - dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname); - -+ spin_lock_irq(cmd->device->host->host_lock); - /* This one is queued in some place -> to wait for completion */ - FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { - struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); - if (cp->cmd == cmd) { - to_do = SYM_EH_DO_WAIT; -- goto prepare; -+ break; - } - } - --prepare: -- /* Prepare stuff to either ignore, complete or wait for completion */ -- switch(to_do) { -- default: -- case SYM_EH_DO_IGNORE: -- break; -- case SYM_EH_DO_WAIT: -+ if (to_do == SYM_EH_DO_WAIT) { - init_completion(&ep->done); -- /* fall through */ -- case SYM_EH_DO_COMPLETE: - ep->old_done = cmd->scsi_done; - cmd->scsi_done = sym_eh_done; - SYM_UCMD_PTR(cmd)->eh_wait = ep; -@@ -827,9 +808,6 @@ - } - - ep->to_do = to_do; -- /* Complete the command with locks held as required by the driver */ -- if (to_do == SYM_EH_DO_COMPLETE) -- sym_xpt_done2(np, cmd, DID_ABORT); - - /* Wait for completion with locks released, as required by kernel */ - if (to_do == SYM_EH_DO_WAIT) { -@@ -845,6 +823,7 @@ - if (ep->timed_out) - sts = -2; - } -+ spin_unlock_irq(cmd->device->host->host_lock); - dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname, - sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed"); - return sts ? SCSI_FAILED : SCSI_SUCCESS; -@@ -856,46 +835,22 @@ - */ - static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd) - { -- int rc; -- -- spin_lock_irq(cmd->device->host->host_lock); -- rc = sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd); -- spin_unlock_irq(cmd->device->host->host_lock); -- -- return rc; -+ return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd); - } - - static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd) - { -- int rc; -- -- spin_lock_irq(cmd->device->host->host_lock); -- rc = sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd); -- spin_unlock_irq(cmd->device->host->host_lock); -- -- return rc; -+ return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd); - } - - static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd) - { -- int rc; -- -- spin_lock_irq(cmd->device->host->host_lock); -- rc = sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd); -- spin_unlock_irq(cmd->device->host->host_lock); -- -- return rc; -+ return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd); - } - - static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd) - { -- int rc; -- -- spin_lock_irq(cmd->device->host->host_lock); -- rc = sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); -- spin_unlock_irq(cmd->device->host->host_lock); -- -- return rc; -+ return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); - } - - /* -@@ -914,15 +869,12 @@ - if (reqtags > lp->s.scdev_depth) - reqtags = lp->s.scdev_depth; - -- lp->started_limit = reqtags ? reqtags : 2; -- lp->started_max = 1; - lp->s.reqtags = reqtags; - - if (reqtags != oldtags) { - dev_info(&tp->starget->dev, - "tagged command queuing %s, command queue depth %d.\n", -- lp->s.reqtags ? "enabled" : "disabled", -- lp->started_limit); -+ lp->s.reqtags ? "enabled" : "disabled", reqtags); - } - } - -@@ -981,15 +933,14 @@ - - static int sym53c8xx_slave_alloc(struct scsi_device *sdev) - { -- struct sym_hcb *np; -- struct sym_tcb *tp; -+ struct sym_hcb *np = sym_get_hcb(sdev->host); -+ struct sym_tcb *tp = &np->target[sdev->id]; -+ struct sym_lcb *lp; - - if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN) - return -ENXIO; - -- np = sym_get_hcb(sdev->host); -- tp = &np->target[sdev->id]; -- -+ tp->starget = sdev->sdev_target; - /* - * Fail the device init if the device is flagged NOSCAN at BOOT in - * the NVRAM. This may speed up boot and maintain coherency with -@@ -999,35 +950,41 @@ - * lun devices behave badly when asked for a non zero LUN. - */ - -- if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) || -- ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) { -+ if (tp->usrflags & SYM_SCAN_BOOT_DISABLED) { - tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED; -+ starget_printk(KERN_INFO, tp->starget, -+ "Scan at boot disabled in NVRAM\n"); - return -ENXIO; - } - -- tp->starget = sdev->sdev_target; -+ if (tp->usrflags & SYM_SCAN_LUNS_DISABLED) { -+ if (sdev->lun != 0) -+ return -ENXIO; -+ starget_printk(KERN_INFO, tp->starget, -+ "Multiple LUNs disabled in NVRAM\n"); -+ } -+ -+ lp = sym_alloc_lcb(np, sdev->id, sdev->lun); -+ if (!lp) -+ return -ENOMEM; -+ -+ spi_min_period(tp->starget) = tp->usr_period; -+ spi_max_width(tp->starget) = tp->usr_width; -+ - return 0; - } - - /* - * Linux entry point for device queue sizing. - */ --static int sym53c8xx_slave_configure(struct scsi_device *device) -+static int sym53c8xx_slave_configure(struct scsi_device *sdev) - { -- struct sym_hcb *np = sym_get_hcb(device->host); -- struct sym_tcb *tp = &np->target[device->id]; -- struct sym_lcb *lp; -+ struct sym_hcb *np = sym_get_hcb(sdev->host); -+ struct sym_tcb *tp = &np->target[sdev->id]; -+ struct sym_lcb *lp = sym_lp(tp, sdev->lun); - int reqtags, depth_to_use; - - /* -- * Allocate the LCB if not yet. -- * If it fail, we may well be in the sh*t. :) -- */ -- lp = sym_alloc_lcb(np, device->id, device->lun); -- if (!lp) -- return -ENOMEM; -- -- /* - * Get user flags. - */ - lp->curr_flags = lp->user_flags; -@@ -1038,10 +995,10 @@ - * Use at least 2. - * Donnot use more than our maximum. - */ -- reqtags = device_queue_depth(np, device->id, device->lun); -+ reqtags = device_queue_depth(np, sdev->id, sdev->lun); - if (reqtags > tp->usrtags) - reqtags = tp->usrtags; -- if (!device->tagged_supported) -+ if (!sdev->tagged_supported) - reqtags = 0; - #if 1 /* Avoid to locally queue commands for no good reasons */ - if (reqtags > SYM_CONF_MAX_TAG) -@@ -1050,19 +1007,30 @@ - #else - depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2); - #endif -- scsi_adjust_queue_depth(device, -- (device->tagged_supported ? -+ scsi_adjust_queue_depth(sdev, -+ (sdev->tagged_supported ? - MSG_SIMPLE_TAG : 0), - depth_to_use); - lp->s.scdev_depth = depth_to_use; -- sym_tune_dev_queuing(tp, device->lun, reqtags); -+ sym_tune_dev_queuing(tp, sdev->lun, reqtags); - -- if (!spi_initial_dv(device->sdev_target)) -- spi_dv_device(device); -+ if (!spi_initial_dv(sdev->sdev_target)) -+ spi_dv_device(sdev); - - return 0; - } - -+static void sym53c8xx_slave_destroy(struct scsi_device *sdev) -+{ -+ struct sym_hcb *np = sym_get_hcb(sdev->host); -+ struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun); -+ -+ if (lp->itlq_tbl) -+ sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL"); -+ kfree(lp->cb_tags); -+ sym_mfree_dma(lp, sizeof(*lp), "LCB"); -+} -+ - /* - * Linux entry point for info() function - */ -@@ -1497,7 +1465,7 @@ - { - #if SYM_CONF_DMA_ADDRESSING_MODE > 0 - #if SYM_CONF_DMA_ADDRESSING_MODE == 1 --#define DMA_DAC_MASK 0x000000ffffffffffULL /* 40-bit */ -+#define DMA_DAC_MASK DMA_40BIT_MASK - #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 - #define DMA_DAC_MASK DMA_64BIT_MASK - #endif -@@ -1820,15 +1788,25 @@ - static void __devinit - sym_init_device(struct pci_dev *pdev, struct sym_device *device) - { -- int i; -+ int i = 2; -+ struct pci_bus_region bus_addr; - - device->host_id = SYM_SETUP_HOST_ID; - device->pdev = pdev; - -- i = pci_get_base_address(pdev, 1, &device->mmio_base); -- pci_get_base_address(pdev, i, &device->ram_base); -+ pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]); -+ device->mmio_base = bus_addr.start; -+ -+ /* -+ * If the BAR is 64-bit, resource 2 will be occupied by the -+ * upper 32 bits -+ */ -+ if (!pdev->resource[i].flags) -+ i++; -+ pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]); -+ device->ram_base = bus_addr.start; - --#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED -+#ifdef CONFIG_SCSI_SYM53C8XX_MMIO - if (device->mmio_base) - device->s.ioaddr = pci_iomap(pdev, 1, - pci_resource_len(pdev, 1)); -@@ -1926,6 +1904,7 @@ - .queuecommand = sym53c8xx_queue_command, - .slave_alloc = sym53c8xx_slave_alloc, - .slave_configure = sym53c8xx_slave_configure, -+ .slave_destroy = sym53c8xx_slave_destroy, - .eh_abort_handler = sym53c8xx_eh_abort_handler, - .eh_device_reset_handler = sym53c8xx_eh_device_reset_handler, - .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler, -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_glue.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_glue.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_glue.h 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_glue.h 2005-12-18 08:29:09.000000000 -0700 -@@ -68,8 +68,7 @@ - */ - #define SYM_CONF_TIMER_INTERVAL ((HZ+1)/2) - --#define SYM_OPT_HANDLE_DIR_UNKNOWN --#define SYM_OPT_HANDLE_DEVICE_QUEUEING -+#undef SYM_OPT_HANDLE_DEVICE_QUEUEING - #define SYM_OPT_LIMIT_COMMAND_REORDERING - - /* -@@ -268,6 +267,5 @@ - void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target); - int sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); - void sym_log_bus_error(struct sym_hcb *np); --void sym_sniff_inquiry(struct sym_hcb *np, struct scsi_cmnd *cmd, int resid); - - #endif /* SYM_GLUE_H */ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_hipd.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_hipd.c ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_hipd.c 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_hipd.c 2005-12-18 08:29:09.000000000 -0700 -@@ -40,6 +40,7 @@ - - #include - #include /* for timeouts in units of HZ */ -+#include - - #include "sym_glue.h" - #include "sym_nvram.h" -@@ -70,32 +71,12 @@ - printf (".\n"); - } - --/* -- * Print out the content of a SCSI message. -- */ --static int sym_show_msg (u_char * msg) --{ -- u_char i; -- printf ("%x",*msg); -- if (*msg==M_EXTENDED) { -- for (i=1;i<8;i++) { -- if (i-1>msg[1]) break; -- printf ("-%x",msg[i]); -- } -- return (i+1); -- } else if ((*msg & 0xf0) == 0x20) { -- printf ("-%x",msg[1]); -- return (2); -- } -- return (1); --} -- - static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg) - { - sym_print_addr(cp->cmd, "%s: ", label); - -- sym_show_msg(msg); -- printf(".\n"); -+ scsi_print_msg(msg); -+ printf("\n"); - } - - static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg) -@@ -103,8 +84,8 @@ - struct sym_tcb *tp = &np->target[target]; - dev_info(&tp->starget->dev, "%s: ", label); - -- sym_show_msg(msg); -- printf(".\n"); -+ scsi_print_msg(msg); -+ printf("\n"); - } - - /* -@@ -635,29 +616,6 @@ - } - } - -- --/* -- * Print out the list of targets that have some flag disabled by user. -- */ --static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg) --{ -- int cnt; -- int i; -- -- for (cnt = 0, i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) { -- if (i == np->myaddr) -- continue; -- if (np->target[i].usrflags & mask) { -- if (!cnt++) -- printf("%s: %s disabled for targets", -- sym_name(np), msg); -- printf(" %d", i); -- } -- } -- if (cnt) -- printf(".\n"); --} -- - /* - * Save initial settings of some IO registers. - * Assumed to have been set by BIOS. -@@ -962,7 +920,7 @@ - tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED); - tp->usrtags = SYM_SETUP_MAX_TAG; - -- sym_nvram_setup_target(np, i, nvram); -+ sym_nvram_setup_target(tp, i, nvram); - - if (!tp->usrtags) - tp->usrflags &= ~SYM_TAGS_ENABLED; -@@ -1005,13 +963,6 @@ - sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl, - np->rv_ctest3, np->rv_ctest4, np->rv_ctest5); - } -- /* -- * Let user be aware of targets that have some disable flags set. -- */ -- sym_print_targets_flag(np, SYM_SCAN_BOOT_DISABLED, "SCAN AT BOOT"); -- if (sym_verbose) -- sym_print_targets_flag(np, SYM_SCAN_LUNS_DISABLED, -- "SCAN FOR LUNS"); - - return 0; - } -@@ -1021,8 +972,8 @@ - * - * Has to be called with interrupts disabled. - */ --#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED --static int sym_regtest (struct sym_hcb *np) -+#ifdef CONFIG_SCSI_SYM53C8XX_MMIO -+static int sym_regtest(struct sym_hcb *np) - { - register volatile u32 data; - /* -@@ -1040,20 +991,25 @@ - #endif - printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n", - (unsigned) data); -- return (0x10); -+ return 0x10; - } -- return (0); -+ return 0; -+} -+#else -+static inline int sym_regtest(struct sym_hcb *np) -+{ -+ return 0; - } - #endif - --static int sym_snooptest (struct sym_hcb *np) -+static int sym_snooptest(struct sym_hcb *np) - { -- u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat; -- int i, err=0; --#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED -- err |= sym_regtest (np); -- if (err) return (err); --#endif -+ u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat; -+ int i, err; -+ -+ err = sym_regtest(np); -+ if (err) -+ return err; - restart_test: - /* - * Enable Master Parity Checking as we intend -@@ -1142,7 +1098,7 @@ - err |= 4; - } - -- return (err); -+ return err; - } - - /* -@@ -3654,7 +3610,7 @@ - * If result is dp_sg = SYM_CONF_MAX_SG, then we are at the - * end of the data. - */ -- tmp = scr_to_cpu(sym_goalp(cp)); -+ tmp = scr_to_cpu(cp->goalp); - dp_sg = SYM_CONF_MAX_SG; - if (dp_scr != tmp) - dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4); -@@ -3761,7 +3717,7 @@ - * And our alchemy:) allows to easily calculate the data - * script address we want to return for the next data phase. - */ -- dp_ret = cpu_to_scr(sym_goalp(cp)); -+ dp_ret = cpu_to_scr(cp->goalp); - dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4); - - /* -@@ -3857,7 +3813,7 @@ - * If all data has been transferred, - * there is no residual. - */ -- if (cp->phys.head.lastp == sym_goalp(cp)) -+ if (cp->phys.head.lastp == cp->goalp) - return resid; - - /* -@@ -4664,30 +4620,7 @@ - goto out; - cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); - --#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING -- /* -- * If the LCB is not yet available and the LUN -- * has been probed ok, try to allocate the LCB. -- */ -- if (!lp && sym_is_bit(tp->lun_map, ln)) { -- lp = sym_alloc_lcb(np, tn, ln); -- if (!lp) -- goto out_free; -- } --#endif -- -- /* -- * If the LCB is not available here, then the -- * logical unit is not yet discovered. For those -- * ones only accept 1 SCSI IO per logical unit, -- * since we cannot allow disconnections. -- */ -- if (!lp) { -- if (!sym_is_bit(tp->busy0_map, ln)) -- sym_set_bit(tp->busy0_map, ln); -- else -- goto out_free; -- } else { -+ { - /* - * If we have been asked for a tagged command. - */ -@@ -4696,7 +4629,8 @@ - * Debugging purpose. - */ - #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING -- assert(lp->busy_itl == 0); -+ if (lp->busy_itl != 0) -+ goto out_free; - #endif - /* - * Allocate resources for tags if not yet. -@@ -4741,7 +4675,8 @@ - * Debugging purpose. - */ - #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING -- assert(lp->busy_itl == 0 && lp->busy_itlq == 0); -+ if (lp->busy_itl != 0 || lp->busy_itlq != 0) -+ goto out_free; - #endif - /* - * Count this nexus for this LUN. -@@ -4840,12 +4775,6 @@ - lp->head.resel_sa = - cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun)); - } -- /* -- * Otherwise, we only accept 1 IO per LUN. -- * Clear the bit that keeps track of this IO. -- */ -- else -- sym_clr_bit(tp->busy0_map, cp->lun); - - /* - * We donnot queue more than 1 ccb per target -@@ -4997,20 +4926,7 @@ - struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln) - { - struct sym_tcb *tp = &np->target[tn]; -- struct sym_lcb *lp = sym_lp(tp, ln); -- -- /* -- * Already done, just return. -- */ -- if (lp) -- return lp; -- -- /* -- * Donnot allow LUN control block -- * allocation for not probed LUNs. -- */ -- if (!sym_is_bit(tp->lun_map, ln)) -- return NULL; -+ struct sym_lcb *lp = NULL; - - /* - * Initialize the target control block if not yet. -@@ -5082,13 +4998,7 @@ - lp->started_max = SYM_CONF_MAX_TASK; - lp->started_limit = SYM_CONF_MAX_TASK; - #endif -- /* -- * If we are busy, count the IO. -- */ -- if (sym_is_bit(tp->busy0_map, ln)) { -- lp->busy_itl = 1; -- sym_clr_bit(tp->busy0_map, ln); -- } -+ - fail: - return lp; - } -@@ -5103,12 +5013,6 @@ - int i; - - /* -- * If LCB not available, try to allocate it. -- */ -- if (!lp && !(lp = sym_alloc_lcb(np, tn, ln))) -- goto fail; -- -- /* - * Allocate the task table and and the tag allocation - * circular buffer. We want both or none. - */ -@@ -5481,8 +5385,7 @@ - /* - * Donnot start more than 1 command after an error. - */ -- if (lp) -- sym_start_next_ccbs(np, lp, 1); -+ sym_start_next_ccbs(np, lp, 1); - #endif - } - -@@ -5521,17 +5424,11 @@ - lp = sym_lp(tp, cp->lun); - - /* -- * Assume device discovered on first success. -- */ -- if (!lp) -- sym_set_bit(tp->lun_map, cp->lun); -- -- /* - * If all data have been transferred, given than no - * extended error did occur, there is no residual. - */ - resid = 0; -- if (cp->phys.head.lastp != sym_goalp(cp)) -+ if (cp->phys.head.lastp != cp->goalp) - resid = sym_compute_residual(np, cp); - - /* -@@ -5551,15 +5448,6 @@ - */ - sym_set_cam_result_ok(cp, cmd, resid); - --#ifdef SYM_OPT_SNIFF_INQUIRY -- /* -- * On standard INQUIRY response (EVPD and CmDt -- * not set), sniff out device capabilities. -- */ -- if (cp->cdb_buf[0] == INQUIRY && !(cp->cdb_buf[1] & 0x3)) -- sym_sniff_inquiry(np, cmd, resid); --#endif -- - #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING - /* - * If max number of started ccbs had been reduced, -@@ -5587,7 +5475,7 @@ - /* - * Requeue a couple of awaiting scsi commands. - */ -- if (lp && !sym_que_empty(&lp->waiting_ccbq)) -+ if (!sym_que_empty(&lp->waiting_ccbq)) - sym_start_next_ccbs(np, lp, 2); - #endif - /* -@@ -5830,8 +5718,7 @@ - SYM_QUEHEAD *qp; - struct sym_ccb *cp; - struct sym_tcb *tp; -- struct sym_lcb *lp; -- int target, lun; -+ int target; - - if (np->scriptz0) - sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0"); -@@ -5857,16 +5744,6 @@ - - for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) { - tp = &np->target[target]; -- for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) { -- lp = sym_lp(tp, lun); -- if (!lp) -- continue; -- if (lp->itlq_tbl) -- sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, -- "ITLQ_TBL"); -- kfree(lp->cb_tags); -- sym_mfree_dma(lp, sizeof(*lp), "LCB"); -- } - #if SYM_CONF_MAX_LUN > 1 - kfree(tp->lunmp); - #endif -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_hipd.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_hipd.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_hipd.h 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_hipd.h 2005-12-18 08:29:09.000000000 -0700 -@@ -48,12 +48,6 @@ - * They may be defined in platform specific headers, if they - * are useful. - * -- * SYM_OPT_HANDLE_DIR_UNKNOWN -- * When this option is set, the SCRIPTS used by the driver -- * are able to handle SCSI transfers with direction not -- * supplied by user. -- * (set for Linux-2.0.X) -- * - * SYM_OPT_HANDLE_DEVICE_QUEUEING - * When this option is set, the driver will use a queue per - * device and handle QUEUE FULL status requeuing internally. -@@ -64,7 +58,6 @@ - * (set for Linux) - */ - #if 0 --#define SYM_OPT_HANDLE_DIR_UNKNOWN - #define SYM_OPT_HANDLE_DEVICE_QUEUEING - #define SYM_OPT_LIMIT_COMMAND_REORDERING - #endif -@@ -416,19 +409,6 @@ - struct sym_lcb **lunmp; /* Other LCBs [1..MAX_LUN] */ - #endif - -- /* -- * Bitmap that tells about LUNs that succeeded at least -- * 1 IO and therefore assumed to be a real device. -- * Avoid useless allocation of the LCB structure. -- */ -- u32 lun_map[(SYM_CONF_MAX_LUN+31)/32]; -- -- /* -- * Bitmap that tells about LUNs that haven't yet an LCB -- * allocated (not discovered or LCB allocation failed). -- */ -- u32 busy0_map[(SYM_CONF_MAX_LUN+31)/32]; -- - #ifdef SYM_HAVE_STCB - /* - * O/S specific data structure. -@@ -454,8 +434,10 @@ - * Other user settable limits and options. - * These limits are read from the NVRAM if present. - */ -- u_char usrflags; -- u_short usrtags; -+ unsigned char usrflags; -+ unsigned char usr_period; -+ unsigned char usr_width; -+ unsigned short usrtags; - struct scsi_target *starget; - }; - -@@ -672,9 +654,6 @@ - */ - u32 savep; /* Jump address to saved data pointer */ - u32 lastp; /* SCRIPTS address at end of data */ --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- u32 wlastp; --#endif - - /* - * Status fields. -@@ -804,9 +783,6 @@ - SYM_QUEHEAD link_ccbq; /* Link to free/busy CCB queue */ - u32 startp; /* Initial data pointer */ - u32 goalp; /* Expected last data pointer */ --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- u32 wgoalp; --#endif - int ext_sg; /* Extreme data pointer, used */ - int ext_ofs; /* to calculate the residual. */ - #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING -@@ -821,12 +797,6 @@ - - #define CCB_BA(cp,lbl) cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl)) - --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN --#define sym_goalp(cp) ((cp->host_flags & HF_DATA_IN) ? cp->goalp : cp->wgoalp) --#else --#define sym_goalp(cp) (cp->goalp) --#endif -- - typedef struct device *m_pool_ident_t; - - /* -@@ -1077,9 +1047,10 @@ - void sym_print_xerr(struct scsi_cmnd *cmd, int x_status); - int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int); - struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision); --void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); - #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING - void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn); -+#else -+void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp); - #endif - void sym_start_up(struct sym_hcb *np, int reason); - void sym_interrupt(struct sym_hcb *np); -@@ -1136,71 +1107,6 @@ - #endif - - /* -- * Set up data pointers used by SCRIPTS. -- * Called from O/S specific code. -- */ --static inline void sym_setup_data_pointers(struct sym_hcb *np, -- struct sym_ccb *cp, int dir) --{ -- u32 lastp, goalp; -- -- /* -- * No segments means no data. -- */ -- if (!cp->segments) -- dir = DMA_NONE; -- -- /* -- * Set the data pointer. -- */ -- switch(dir) { --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- case DMA_BIDIRECTIONAL: --#endif -- case DMA_TO_DEVICE: -- goalp = SCRIPTA_BA(np, data_out2) + 8; -- lastp = goalp - 8 - (cp->segments * (2*4)); --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- cp->wgoalp = cpu_to_scr(goalp); -- if (dir != DMA_BIDIRECTIONAL) -- break; -- cp->phys.head.wlastp = cpu_to_scr(lastp); -- /* fall through */ --#else -- break; --#endif -- case DMA_FROM_DEVICE: -- cp->host_flags |= HF_DATA_IN; -- goalp = SCRIPTA_BA(np, data_in2) + 8; -- lastp = goalp - 8 - (cp->segments * (2*4)); -- break; -- case DMA_NONE: -- default: --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- cp->host_flags |= HF_DATA_IN; --#endif -- lastp = goalp = SCRIPTB_BA(np, no_data); -- break; -- } -- -- /* -- * Set all pointers values needed by SCRIPTS. -- */ -- cp->phys.head.lastp = cpu_to_scr(lastp); -- cp->phys.head.savep = cpu_to_scr(lastp); -- cp->startp = cp->phys.head.savep; -- cp->goalp = cpu_to_scr(goalp); -- --#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN -- /* -- * If direction is unknown, start at data_io. -- */ -- if (dir == DMA_BIDIRECTIONAL) -- cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io)); --#endif --} -- --/* - * MEMORY ALLOCATOR. - */ - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_malloc.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_malloc.c ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_malloc.c 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_malloc.c 2005-09-27 06:03:22.000000000 -0600 -@@ -37,11 +37,7 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - --#ifdef __FreeBSD__ --#include --#else - #include "sym_glue.h" --#endif - - /* - * Simple power of two buddy-like generic allocator. -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_nvram.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_nvram.c ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_nvram.c 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_nvram.c 2005-12-12 09:00:09.000000000 -0700 -@@ -92,29 +92,32 @@ - * Get target set-up from Symbios format NVRAM. - */ - static void --sym_Symbios_setup_target(struct sym_hcb *np, int target, Symbios_nvram *nvram) -+sym_Symbios_setup_target(struct sym_tcb *tp, int target, Symbios_nvram *nvram) - { -- struct sym_tcb *tp = &np->target[target]; - Symbios_target *tn = &nvram->target[target]; - -- tp->usrtags = -- (tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? SYM_SETUP_MAX_TAG : 0; -- -+ if (!(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)) -+ tp->usrtags = 0; - if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE)) - tp->usrflags &= ~SYM_DISC_ENABLED; - if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME)) - tp->usrflags |= SYM_SCAN_BOOT_DISABLED; - if (!(tn->flags & SYMBIOS_SCAN_LUNS)) - tp->usrflags |= SYM_SCAN_LUNS_DISABLED; -+ tp->usr_period = (tn->sync_period + 3) / 4; -+ tp->usr_width = (tn->bus_width == 0x8) ? 0 : 1; - } - -+static const unsigned char Tekram_sync[16] = { -+ 25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21, 6, 7, 9, 10 -+}; -+ - /* - * Get target set-up from Tekram format NVRAM. - */ - static void --sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram) -+sym_Tekram_setup_target(struct sym_tcb *tp, int target, Tekram_nvram *nvram) - { -- struct sym_tcb *tp = &np->target[target]; - struct Tekram_target *tn = &nvram->target[target]; - - if (tn->flags & TEKRAM_TAGGED_COMMANDS) { -@@ -124,22 +127,22 @@ - if (tn->flags & TEKRAM_DISCONNECT_ENABLE) - tp->usrflags |= SYM_DISC_ENABLED; - -- /* If any device does not support parity, we will not use this option */ -- if (!(tn->flags & TEKRAM_PARITY_CHECK)) -- np->rv_scntl0 &= ~0x0a; /* SCSI parity checking disabled */ -+ if (tn->flags & TEKRAM_SYNC_NEGO) -+ tp->usr_period = Tekram_sync[tn->sync_index & 0xf]; -+ tp->usr_width = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0; - } - - /* - * Get target setup from NVRAM. - */ --void sym_nvram_setup_target(struct sym_hcb *np, int target, struct sym_nvram *nvp) -+void sym_nvram_setup_target(struct sym_tcb *tp, int target, struct sym_nvram *nvp) - { - switch (nvp->type) { - case SYM_SYMBIOS_NVRAM: -- sym_Symbios_setup_target(np, target, &nvp->data.Symbios); -+ sym_Symbios_setup_target(tp, target, &nvp->data.Symbios); - break; - case SYM_TEKRAM_NVRAM: -- sym_Tekram_setup_target(np, target, &nvp->data.Tekram); -+ sym_Tekram_setup_target(tp, target, &nvp->data.Tekram); - break; - default: - break; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_nvram.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_nvram.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_nvram.h 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_nvram.h 2005-12-12 09:00:09.000000000 -0700 -@@ -194,12 +194,12 @@ - - #if SYM_CONF_NVRAM_SUPPORT - void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram); --void sym_nvram_setup_target (struct sym_hcb *np, int target, struct sym_nvram *nvp); -+void sym_nvram_setup_target (struct sym_tcb *tp, int target, struct sym_nvram *nvp); - int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp); - char *sym_nvram_type(struct sym_nvram *nvp); - #else - static inline void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { } --static inline void sym_nvram_setup_target(struct sym_hcb *np, struct sym_nvram *nvram) { } -+static inline void sym_nvram_setup_target(struct sym_tcb *tp, struct sym_nvram *nvram) { } - static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp) - { - nvp->type = 0; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_comm.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_comm.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_comm.h 2005-12-27 13:25:48.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_comm.h 1969-12-31 17:00:00.000000000 -0700 -@@ -1,792 +0,0 @@ --/****************************************************************************** --** High Performance device driver for the Symbios 53C896 controller. --** --** Copyright (C) 1998-2001 Gerard Roudier --** --** This driver also supports all the Symbios 53C8XX controller family, --** except 53C810 revisions < 16, 53C825 revisions < 16 and all --** revisions of 53C815 controllers. --** --** This driver is based on the Linux port of the FreeBSD ncr driver. --** --** Copyright (C) 1994 Wolfgang Stanglmeier --** --**----------------------------------------------------------------------------- --** --** This program is free software; you can redistribute it and/or modify --** it under the terms of the GNU General Public License as published by --** the Free Software Foundation; either version 2 of the License, or --** (at your option) any later version. --** --** This program is distributed in the hope that it will be useful, --** but WITHOUT ANY WARRANTY; without even the implied warranty of --** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --** GNU General Public License for more details. --** --** You should have received a copy of the GNU General Public License --** along with this program; if not, write to the Free Software --** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. --** --**----------------------------------------------------------------------------- --** --** The Linux port of the FreeBSD ncr driver has been achieved in --** november 1995 by: --** --** Gerard Roudier --** --** Being given that this driver originates from the FreeBSD version, and --** in order to keep synergy on both, any suggested enhancements and corrections --** received on Linux are automatically a potential candidate for the FreeBSD --** version. --** --** The original driver has been written for 386bsd and FreeBSD by --** Wolfgang Stanglmeier --** Stefan Esser --** --**----------------------------------------------------------------------------- --** --** Major contributions: --** -------------------- --** --** NVRAM detection and reading. --** Copyright (C) 1997 Richard Waltham --** --******************************************************************************* --*/ -- --/*========================================================== --** --** Debugging tags --** --**========================================================== --*/ -- --#define DEBUG_ALLOC (0x0001) --#define DEBUG_PHASE (0x0002) --#define DEBUG_QUEUE (0x0008) --#define DEBUG_RESULT (0x0010) --#define DEBUG_POINTER (0x0020) --#define DEBUG_SCRIPT (0x0040) --#define DEBUG_TINY (0x0080) --#define DEBUG_TIMING (0x0100) --#define DEBUG_NEGO (0x0200) --#define DEBUG_TAGS (0x0400) --#define DEBUG_SCATTER (0x0800) --#define DEBUG_IC (0x1000) -- --/* --** Enable/Disable debug messages. --** Can be changed at runtime too. --*/ -- --#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT --static int ncr_debug = SCSI_NCR_DEBUG_FLAGS; -- #define DEBUG_FLAGS ncr_debug --#else -- #define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS --#endif -- --static inline struct list_head *ncr_list_pop(struct list_head *head) --{ -- if (!list_empty(head)) { -- struct list_head *elem = head->next; -- -- list_del(elem); -- return elem; -- } -- -- return NULL; --} -- --#ifdef __sparc__ --#include --#endif -- --/*========================================================== --** --** Simple power of two buddy-like allocator. --** --** This simple code is not intended to be fast, but to --** provide power of 2 aligned memory allocations. --** Since the SCRIPTS processor only supplies 8 bit --** arithmetic, this allocator allows simple and fast --** address calculations from the SCRIPTS code. --** In addition, cache line alignment is guaranteed for --** power of 2 cache line size. --** Enhanced in linux-2.3.44 to provide a memory pool --** per pcidev to support dynamic dma mapping. (I would --** have preferred a real bus astraction, btw). --** --**========================================================== --*/ -- --#define MEMO_SHIFT 4 /* 16 bytes minimum memory chunk */ --#if PAGE_SIZE >= 8192 --#define MEMO_PAGE_ORDER 0 /* 1 PAGE maximum */ --#else --#define MEMO_PAGE_ORDER 1 /* 2 PAGES maximum */ --#endif --#define MEMO_FREE_UNUSED /* Free unused pages immediately */ --#define MEMO_WARN 1 --#define MEMO_GFP_FLAGS GFP_ATOMIC --#define MEMO_CLUSTER_SHIFT (PAGE_SHIFT+MEMO_PAGE_ORDER) --#define MEMO_CLUSTER_SIZE (1UL << MEMO_CLUSTER_SHIFT) --#define MEMO_CLUSTER_MASK (MEMO_CLUSTER_SIZE-1) -- --typedef u_long m_addr_t; /* Enough bits to bit-hack addresses */ --typedef struct device *m_bush_t; /* Something that addresses DMAable */ -- --typedef struct m_link { /* Link between free memory chunks */ -- struct m_link *next; --} m_link_s; -- --typedef struct m_vtob { /* Virtual to Bus address translation */ -- struct m_vtob *next; -- m_addr_t vaddr; -- m_addr_t baddr; --} m_vtob_s; --#define VTOB_HASH_SHIFT 5 --#define VTOB_HASH_SIZE (1UL << VTOB_HASH_SHIFT) --#define VTOB_HASH_MASK (VTOB_HASH_SIZE-1) --#define VTOB_HASH_CODE(m) \ -- ((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK) -- --typedef struct m_pool { /* Memory pool of a given kind */ -- m_bush_t bush; -- m_addr_t (*getp)(struct m_pool *); -- void (*freep)(struct m_pool *, m_addr_t); -- int nump; -- m_vtob_s *(vtob[VTOB_HASH_SIZE]); -- struct m_pool *next; -- struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1]; --} m_pool_s; -- --static void *___m_alloc(m_pool_s *mp, int size) --{ -- int i = 0; -- int s = (1 << MEMO_SHIFT); -- int j; -- m_addr_t a; -- m_link_s *h = mp->h; -- -- if (size > (PAGE_SIZE << MEMO_PAGE_ORDER)) -- return NULL; -- -- while (size > s) { -- s <<= 1; -- ++i; -- } -- -- j = i; -- while (!h[j].next) { -- if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { -- h[j].next = (m_link_s *)mp->getp(mp); -- if (h[j].next) -- h[j].next->next = NULL; -- break; -- } -- ++j; -- s <<= 1; -- } -- a = (m_addr_t) h[j].next; -- if (a) { -- h[j].next = h[j].next->next; -- while (j > i) { -- j -= 1; -- s >>= 1; -- h[j].next = (m_link_s *) (a+s); -- h[j].next->next = NULL; -- } -- } --#ifdef DEBUG -- printk("___m_alloc(%d) = %p\n", size, (void *) a); --#endif -- return (void *) a; --} -- --static void ___m_free(m_pool_s *mp, void *ptr, int size) --{ -- int i = 0; -- int s = (1 << MEMO_SHIFT); -- m_link_s *q; -- m_addr_t a, b; -- m_link_s *h = mp->h; -- --#ifdef DEBUG -- printk("___m_free(%p, %d)\n", ptr, size); --#endif -- -- if (size > (PAGE_SIZE << MEMO_PAGE_ORDER)) -- return; -- -- while (size > s) { -- s <<= 1; -- ++i; -- } -- -- a = (m_addr_t) ptr; -- -- while (1) { --#ifdef MEMO_FREE_UNUSED -- if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { -- mp->freep(mp, a); -- break; -- } --#endif -- b = a ^ s; -- q = &h[i]; -- while (q->next && q->next != (m_link_s *) b) { -- q = q->next; -- } -- if (!q->next) { -- ((m_link_s *) a)->next = h[i].next; -- h[i].next = (m_link_s *) a; -- break; -- } -- q->next = q->next->next; -- a = a & b; -- s <<= 1; -- ++i; -- } --} -- --static DEFINE_SPINLOCK(ncr53c8xx_lock); -- --static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags) --{ -- void *p; -- -- p = ___m_alloc(mp, size); -- -- if (DEBUG_FLAGS & DEBUG_ALLOC) -- printk ("new %-10s[%4d] @%p.\n", name, size, p); -- -- if (p) -- memset(p, 0, size); -- else if (uflags & MEMO_WARN) -- printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size); -- -- return p; --} -- --#define __m_calloc(mp, s, n) __m_calloc2(mp, s, n, MEMO_WARN) -- --static void __m_free(m_pool_s *mp, void *ptr, int size, char *name) --{ -- if (DEBUG_FLAGS & DEBUG_ALLOC) -- printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr); -- -- ___m_free(mp, ptr, size); -- --} -- --/* -- * With pci bus iommu support, we use a default pool of unmapped memory -- * for memory we donnot need to DMA from/to and one pool per pcidev for -- * memory accessed by the PCI chip. `mp0' is the default not DMAable pool. -- */ -- --static m_addr_t ___mp0_getp(m_pool_s *mp) --{ -- m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER); -- if (m) -- ++mp->nump; -- return m; --} -- --static void ___mp0_freep(m_pool_s *mp, m_addr_t m) --{ -- free_pages(m, MEMO_PAGE_ORDER); -- --mp->nump; --} -- --static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep}; -- --/* -- * DMAable pools. -- */ -- --/* -- * With pci bus iommu support, we maintain one pool per pcidev and a -- * hashed reverse table for virtual to bus physical address translations. -- */ --static m_addr_t ___dma_getp(m_pool_s *mp) --{ -- m_addr_t vp; -- m_vtob_s *vbp; -- -- vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB"); -- if (vbp) { -- dma_addr_t daddr; -- vp = (m_addr_t) dma_alloc_coherent(mp->bush, -- PAGE_SIZE<vaddr = vp; -- vbp->baddr = daddr; -- vbp->next = mp->vtob[hc]; -- mp->vtob[hc] = vbp; -- ++mp->nump; -- return vp; -- } -- } -- if (vbp) -- __m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); -- return 0; --} -- --static void ___dma_freep(m_pool_s *mp, m_addr_t m) --{ -- m_vtob_s **vbpp, *vbp; -- int hc = VTOB_HASH_CODE(m); -- -- vbpp = &mp->vtob[hc]; -- while (*vbpp && (*vbpp)->vaddr != m) -- vbpp = &(*vbpp)->next; -- if (*vbpp) { -- vbp = *vbpp; -- *vbpp = (*vbpp)->next; -- dma_free_coherent(mp->bush, PAGE_SIZE<vaddr, (dma_addr_t)vbp->baddr); -- __m_free(&mp0, vbp, sizeof(*vbp), "VTOB"); -- --mp->nump; -- } --} -- --static inline m_pool_s *___get_dma_pool(m_bush_t bush) --{ -- m_pool_s *mp; -- for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next); -- return mp; --} -- --static m_pool_s *___cre_dma_pool(m_bush_t bush) --{ -- m_pool_s *mp; -- mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL"); -- if (mp) { -- memset(mp, 0, sizeof(*mp)); -- mp->bush = bush; -- mp->getp = ___dma_getp; -- mp->freep = ___dma_freep; -- mp->next = mp0.next; -- mp0.next = mp; -- } -- return mp; --} -- --static void ___del_dma_pool(m_pool_s *p) --{ -- struct m_pool **pp = &mp0.next; -- -- while (*pp && *pp != p) -- pp = &(*pp)->next; -- if (*pp) { -- *pp = (*pp)->next; -- __m_free(&mp0, p, sizeof(*p), "MPOOL"); -- } --} -- --static void *__m_calloc_dma(m_bush_t bush, int size, char *name) --{ -- u_long flags; -- struct m_pool *mp; -- void *m = NULL; -- -- spin_lock_irqsave(&ncr53c8xx_lock, flags); -- mp = ___get_dma_pool(bush); -- if (!mp) -- mp = ___cre_dma_pool(bush); -- if (mp) -- m = __m_calloc(mp, size, name); -- if (mp && !mp->nump) -- ___del_dma_pool(mp); -- spin_unlock_irqrestore(&ncr53c8xx_lock, flags); -- -- return m; --} -- --static void __m_free_dma(m_bush_t bush, void *m, int size, char *name) --{ -- u_long flags; -- struct m_pool *mp; -- -- spin_lock_irqsave(&ncr53c8xx_lock, flags); -- mp = ___get_dma_pool(bush); -- if (mp) -- __m_free(mp, m, size, name); -- if (mp && !mp->nump) -- ___del_dma_pool(mp); -- spin_unlock_irqrestore(&ncr53c8xx_lock, flags); --} -- --static m_addr_t __vtobus(m_bush_t bush, void *m) --{ -- u_long flags; -- m_pool_s *mp; -- int hc = VTOB_HASH_CODE(m); -- m_vtob_s *vp = NULL; -- m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK; -- -- spin_lock_irqsave(&ncr53c8xx_lock, flags); -- mp = ___get_dma_pool(bush); -- if (mp) { -- vp = mp->vtob[hc]; -- while (vp && (m_addr_t) vp->vaddr != a) -- vp = vp->next; -- } -- spin_unlock_irqrestore(&ncr53c8xx_lock, flags); -- return vp ? vp->baddr + (((m_addr_t) m) - a) : 0; --} -- --#define _m_calloc_dma(np, s, n) __m_calloc_dma(np->dev, s, n) --#define _m_free_dma(np, p, s, n) __m_free_dma(np->dev, p, s, n) --#define m_calloc_dma(s, n) _m_calloc_dma(np, s, n) --#define m_free_dma(p, s, n) _m_free_dma(np, p, s, n) --#define _vtobus(np, p) __vtobus(np->dev, p) --#define vtobus(p) _vtobus(np, p) -- --/* -- * Deal with DMA mapping/unmapping. -- */ -- --/* To keep track of the dma mapping (sg/single) that has been set */ --#define __data_mapped SCp.phase --#define __data_mapping SCp.have_data_in -- --static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd) --{ -- switch(cmd->__data_mapped) { -- case 2: -- dma_unmap_sg(dev, cmd->buffer, cmd->use_sg, -- cmd->sc_data_direction); -- break; -- case 1: -- dma_unmap_single(dev, cmd->__data_mapping, -- cmd->request_bufflen, -- cmd->sc_data_direction); -- break; -- } -- cmd->__data_mapped = 0; --} -- --static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd) --{ -- dma_addr_t mapping; -- -- if (cmd->request_bufflen == 0) -- return 0; -- -- mapping = dma_map_single(dev, cmd->request_buffer, -- cmd->request_bufflen, -- cmd->sc_data_direction); -- cmd->__data_mapped = 1; -- cmd->__data_mapping = mapping; -- -- return mapping; --} -- --static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) --{ -- int use_sg; -- -- if (cmd->use_sg == 0) -- return 0; -- -- use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg, -- cmd->sc_data_direction); -- cmd->__data_mapped = 2; -- cmd->__data_mapping = use_sg; -- -- return use_sg; --} -- --#define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd) --#define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->dev, cmd) --#define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd) -- --/*========================================================== --** --** Driver setup. --** --** This structure is initialized from linux config --** options. It can be overridden at boot-up by the boot --** command line. --** --**========================================================== --*/ --static struct ncr_driver_setup -- driver_setup = SCSI_NCR_DRIVER_SETUP; -- --#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT --static struct ncr_driver_setup -- driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; --#endif -- --#define initverbose (driver_setup.verbose) --#define bootverbose (np->verbose) -- -- --/*=================================================================== --** --** Driver setup from the boot command line --** --**=================================================================== --*/ -- --#ifdef MODULE --#define ARG_SEP ' ' --#else --#define ARG_SEP ',' --#endif -- --#define OPT_TAGS 1 --#define OPT_MASTER_PARITY 2 --#define OPT_SCSI_PARITY 3 --#define OPT_DISCONNECTION 4 --#define OPT_SPECIAL_FEATURES 5 --#define OPT_UNUSED_1 6 --#define OPT_FORCE_SYNC_NEGO 7 --#define OPT_REVERSE_PROBE 8 --#define OPT_DEFAULT_SYNC 9 --#define OPT_VERBOSE 10 --#define OPT_DEBUG 11 --#define OPT_BURST_MAX 12 --#define OPT_LED_PIN 13 --#define OPT_MAX_WIDE 14 --#define OPT_SETTLE_DELAY 15 --#define OPT_DIFF_SUPPORT 16 --#define OPT_IRQM 17 --#define OPT_PCI_FIX_UP 18 --#define OPT_BUS_CHECK 19 --#define OPT_OPTIMIZE 20 --#define OPT_RECOVERY 21 --#define OPT_SAFE_SETUP 22 --#define OPT_USE_NVRAM 23 --#define OPT_EXCLUDE 24 --#define OPT_HOST_ID 25 -- --#ifdef SCSI_NCR_IARB_SUPPORT --#define OPT_IARB 26 --#endif -- --static char setup_token[] __initdata = -- "tags:" "mpar:" -- "spar:" "disc:" -- "specf:" "ultra:" -- "fsn:" "revprob:" -- "sync:" "verb:" -- "debug:" "burst:" -- "led:" "wide:" -- "settle:" "diff:" -- "irqm:" "pcifix:" -- "buschk:" "optim:" -- "recovery:" -- "safe:" "nvram:" -- "excl:" "hostid:" --#ifdef SCSI_NCR_IARB_SUPPORT -- "iarb:" --#endif -- ; /* DONNOT REMOVE THIS ';' */ -- --#ifdef MODULE --#define ARG_SEP ' ' --#else --#define ARG_SEP ',' --#endif -- --static int __init get_setup_token(char *p) --{ -- char *cur = setup_token; -- char *pc; -- int i = 0; -- -- while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { -- ++pc; -- ++i; -- if (!strncmp(p, cur, pc - cur)) -- return i; -- cur = pc; -- } -- return 0; --} -- -- --static int __init sym53c8xx__setup(char *str) --{ --#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT -- char *cur = str; -- char *pc, *pv; -- int i, val, c; -- int xi = 0; -- -- while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { -- char *pe; -- -- val = 0; -- pv = pc; -- c = *++pv; -- -- if (c == 'n') -- val = 0; -- else if (c == 'y') -- val = 1; -- else -- val = (int) simple_strtoul(pv, &pe, 0); -- -- switch (get_setup_token(cur)) { -- case OPT_TAGS: -- driver_setup.default_tags = val; -- if (pe && *pe == '/') { -- i = 0; -- while (*pe && *pe != ARG_SEP && -- i < sizeof(driver_setup.tag_ctrl)-1) { -- driver_setup.tag_ctrl[i++] = *pe++; -- } -- driver_setup.tag_ctrl[i] = '\0'; -- } -- break; -- case OPT_MASTER_PARITY: -- driver_setup.master_parity = val; -- break; -- case OPT_SCSI_PARITY: -- driver_setup.scsi_parity = val; -- break; -- case OPT_DISCONNECTION: -- driver_setup.disconnection = val; -- break; -- case OPT_SPECIAL_FEATURES: -- driver_setup.special_features = val; -- break; -- case OPT_FORCE_SYNC_NEGO: -- driver_setup.force_sync_nego = val; -- break; -- case OPT_REVERSE_PROBE: -- driver_setup.reverse_probe = val; -- break; -- case OPT_DEFAULT_SYNC: -- driver_setup.default_sync = val; -- break; -- case OPT_VERBOSE: -- driver_setup.verbose = val; -- break; -- case OPT_DEBUG: -- driver_setup.debug = val; -- break; -- case OPT_BURST_MAX: -- driver_setup.burst_max = val; -- break; -- case OPT_LED_PIN: -- driver_setup.led_pin = val; -- break; -- case OPT_MAX_WIDE: -- driver_setup.max_wide = val? 1:0; -- break; -- case OPT_SETTLE_DELAY: -- driver_setup.settle_delay = val; -- break; -- case OPT_DIFF_SUPPORT: -- driver_setup.diff_support = val; -- break; -- case OPT_IRQM: -- driver_setup.irqm = val; -- break; -- case OPT_PCI_FIX_UP: -- driver_setup.pci_fix_up = val; -- break; -- case OPT_BUS_CHECK: -- driver_setup.bus_check = val; -- break; -- case OPT_OPTIMIZE: -- driver_setup.optimize = val; -- break; -- case OPT_RECOVERY: -- driver_setup.recovery = val; -- break; -- case OPT_USE_NVRAM: -- driver_setup.use_nvram = val; -- break; -- case OPT_SAFE_SETUP: -- memcpy(&driver_setup, &driver_safe_setup, -- sizeof(driver_setup)); -- break; -- case OPT_EXCLUDE: -- if (xi < SCSI_NCR_MAX_EXCLUDES) -- driver_setup.excludes[xi++] = val; -- break; -- case OPT_HOST_ID: -- driver_setup.host_id = val; -- break; --#ifdef SCSI_NCR_IARB_SUPPORT -- case OPT_IARB: -- driver_setup.iarb = val; -- break; --#endif -- default: -- printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); -- break; -- } -- -- if ((cur = strchr(cur, ARG_SEP)) != NULL) -- ++cur; -- } --#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ -- return 1; --} -- --/*=================================================================== --** --** Get device queue depth from boot command line. --** --**=================================================================== --*/ --#define DEF_DEPTH (driver_setup.default_tags) --#define ALL_TARGETS -2 --#define NO_TARGET -1 --#define ALL_LUNS -2 --#define NO_LUN -1 -- --static int device_queue_depth(int unit, int target, int lun) --{ -- int c, h, t, u, v; -- char *p = driver_setup.tag_ctrl; -- char *ep; -- -- h = -1; -- t = NO_TARGET; -- u = NO_LUN; -- while ((c = *p++) != 0) { -- v = simple_strtoul(p, &ep, 0); -- switch(c) { -- case '/': -- ++h; -- t = ALL_TARGETS; -- u = ALL_LUNS; -- break; -- case 't': -- if (t != target) -- t = (target == v) ? v : NO_TARGET; -- u = ALL_LUNS; -- break; -- case 'u': -- if (u != lun) -- u = (lun == v) ? v : NO_LUN; -- break; -- case 'q': -- if (h == unit && -- (t == ALL_TARGETS || t == target) && -- (u == ALL_LUNS || u == lun)) -- return v; -- break; -- case '-': -- t = ALL_TARGETS; -- u = ALL_LUNS; -- break; -- default: -- break; -- } -- p = ep; -- } -- return DEF_DEPTH; --} -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_defs.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_defs.h ---- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_defs.h 2005-12-27 13:25:48.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_defs.h 1969-12-31 17:00:00.000000000 -0700 -@@ -1,1320 +0,0 @@ --/****************************************************************************** --** High Performance device driver for the Symbios 53C896 controller. --** --** Copyright (C) 1998-2001 Gerard Roudier --** --** This driver also supports all the Symbios 53C8XX controller family, --** except 53C810 revisions < 16, 53C825 revisions < 16 and all --** revisions of 53C815 controllers. --** --** This driver is based on the Linux port of the FreeBSD ncr driver. --** --** Copyright (C) 1994 Wolfgang Stanglmeier --** --**----------------------------------------------------------------------------- --** --** This program is free software; you can redistribute it and/or modify --** it under the terms of the GNU General Public License as published by --** the Free Software Foundation; either version 2 of the License, or --** (at your option) any later version. --** --** This program is distributed in the hope that it will be useful, --** but WITHOUT ANY WARRANTY; without even the implied warranty of --** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --** GNU General Public License for more details. --** --** You should have received a copy of the GNU General Public License --** along with this program; if not, write to the Free Software --** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. --** --**----------------------------------------------------------------------------- --** --** The Linux port of the FreeBSD ncr driver has been achieved in --** november 1995 by: --** --** Gerard Roudier --** --** Being given that this driver originates from the FreeBSD version, and --** in order to keep synergy on both, any suggested enhancements and corrections --** received on Linux are automatically a potential candidate for the FreeBSD --** version. --** --** The original driver has been written for 386bsd and FreeBSD by --** Wolfgang Stanglmeier --** Stefan Esser --** --**----------------------------------------------------------------------------- --** --** Major contributions: --** -------------------- --** --** NVRAM detection and reading. --** Copyright (C) 1997 Richard Waltham --** --** Added support for MIPS big endian systems. --** Carsten Langgaard, carstenl@mips.com --** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. --** --** Added support for HP PARISC big endian systems. --** Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. --** --******************************************************************************* --*/ -- --#ifndef SYM53C8XX_DEFS_H --#define SYM53C8XX_DEFS_H -- --#include -- --/* --** If you want a driver as small as possible, donnot define the --** following options. --*/ --#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT --#define SCSI_NCR_DEBUG_INFO_SUPPORT -- --/* --** To disable integrity checking, do not define the --** following option. --*/ --#ifdef CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK --# define SCSI_NCR_ENABLE_INTEGRITY_CHECK --#endif -- --/* --------------------------------------------------------------------- --** Take into account kernel configured parameters. --** Most of these options can be overridden at startup by a command line. --** --------------------------------------------------------------------- --*/ -- --/* -- * For Ultra2 and Ultra3 SCSI support option, use special features. -- * -- * Value (default) means: -- * bit 0 : all features enabled, except: -- * bit 1 : PCI Write And Invalidate. -- * bit 2 : Data Phase Mismatch handling from SCRIPTS. -- * -- * Use boot options ncr53c8xx=specf:1 if you want all chip features to be -- * enabled by the driver. -- */ --#define SCSI_NCR_SETUP_SPECIAL_FEATURES (3) -- --#define SCSI_NCR_MAX_SYNC (80) -- --/* -- * Allow tags from 2 to 256, default 8 -- */ --#ifdef CONFIG_SCSI_NCR53C8XX_MAX_TAGS --#if CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2 --#define SCSI_NCR_MAX_TAGS (2) --#elif CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256 --#define SCSI_NCR_MAX_TAGS (256) --#else --#define SCSI_NCR_MAX_TAGS CONFIG_SCSI_NCR53C8XX_MAX_TAGS --#endif --#else --#define SCSI_NCR_MAX_TAGS (8) --#endif -- --/* -- * Allow tagged command queuing support if configured with default number -- * of tags set to max (see above). -- */ --#ifdef CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS --#define SCSI_NCR_SETUP_DEFAULT_TAGS CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS --#elif defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE --#define SCSI_NCR_SETUP_DEFAULT_TAGS SCSI_NCR_MAX_TAGS --#else --#define SCSI_NCR_SETUP_DEFAULT_TAGS (0) --#endif -- --/* -- * Immediate arbitration -- */ --#if defined(CONFIG_SCSI_NCR53C8XX_IARB) --#define SCSI_NCR_IARB_SUPPORT --#endif -- --/* -- * Sync transfer frequency at startup. -- * Allow from 5Mhz to 80Mhz default 20 Mhz. -- */ --#ifndef CONFIG_SCSI_NCR53C8XX_SYNC --#define CONFIG_SCSI_NCR53C8XX_SYNC (20) --#elif CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC --#undef CONFIG_SCSI_NCR53C8XX_SYNC --#define CONFIG_SCSI_NCR53C8XX_SYNC SCSI_NCR_MAX_SYNC --#endif -- --#if CONFIG_SCSI_NCR53C8XX_SYNC == 0 --#define SCSI_NCR_SETUP_DEFAULT_SYNC (255) --#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 5 --#define SCSI_NCR_SETUP_DEFAULT_SYNC (50) --#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 20 --#define SCSI_NCR_SETUP_DEFAULT_SYNC (250/(CONFIG_SCSI_NCR53C8XX_SYNC)) --#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 33 --#define SCSI_NCR_SETUP_DEFAULT_SYNC (11) --#elif CONFIG_SCSI_NCR53C8XX_SYNC <= 40 --#define SCSI_NCR_SETUP_DEFAULT_SYNC (10) --#else --#define SCSI_NCR_SETUP_DEFAULT_SYNC (9) --#endif -- --/* -- * Disallow disconnections at boot-up -- */ --#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT --#define SCSI_NCR_SETUP_DISCONNECTION (0) --#else --#define SCSI_NCR_SETUP_DISCONNECTION (1) --#endif -- --/* -- * Force synchronous negotiation for all targets -- */ --#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO --#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (1) --#else --#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO (0) --#endif -- --/* -- * Disable master parity checking (flawed hardwares need that) -- */ --#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK --#define SCSI_NCR_SETUP_MASTER_PARITY (0) --#else --#define SCSI_NCR_SETUP_MASTER_PARITY (1) --#endif -- --/* -- * Disable scsi parity checking (flawed devices may need that) -- */ --#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK --#define SCSI_NCR_SETUP_SCSI_PARITY (0) --#else --#define SCSI_NCR_SETUP_SCSI_PARITY (1) --#endif -- --/* -- * Settle time after reset at boot-up -- */ --#define SCSI_NCR_SETUP_SETTLE_TIME (2) -- --/* --** Bridge quirks work-around option defaulted to 1. --*/ --#ifndef SCSI_NCR_PCIQ_WORK_AROUND_OPT --#define SCSI_NCR_PCIQ_WORK_AROUND_OPT 1 --#endif -- --/* --** Work-around common bridge misbehaviour. --** --** - Do not flush posted writes in the opposite --** direction on read. --** - May reorder DMA writes to memory. --** --** This option should not affect performances --** significantly, so it is the default. --*/ --#if SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1 --#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM --#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES --#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS -- --/* --** Same as option 1, but also deal with --** misconfigured interrupts. --** --** - Edge triggerred instead of level sensitive. --** - No interrupt line connected. --** - IRQ number misconfigured. --** --** If no interrupt is delivered, the driver will --** catch the interrupt conditions 10 times per --** second. No need to say that this option is --** not recommended. --*/ --#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2 --#define SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM --#define SCSI_NCR_PCIQ_MAY_REORDER_WRITES --#define SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS --#define SCSI_NCR_PCIQ_BROKEN_INTR -- --/* --** Some bridge designers decided to flush --** everything prior to deliver the interrupt. --** This option tries to deal with such a --** behaviour. --*/ --#elif SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3 --#define SCSI_NCR_PCIQ_SYNC_ON_INTR --#endif -- --/* --** Other parameters not configurable with "make config" --** Avoid to change these constants, unless you know what you are doing. --*/ -- --#define SCSI_NCR_ALWAYS_SIMPLE_TAG --#define SCSI_NCR_MAX_SCATTER (127) --#define SCSI_NCR_MAX_TARGET (16) -- --/* --** Compute some desirable value for CAN_QUEUE --** and CMD_PER_LUN. --** The driver will use lower values if these --** ones appear to be too large. --*/ --#define SCSI_NCR_CAN_QUEUE (8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET) --#define SCSI_NCR_CMD_PER_LUN (SCSI_NCR_MAX_TAGS) -- --#define SCSI_NCR_SG_TABLESIZE (SCSI_NCR_MAX_SCATTER) --#define SCSI_NCR_TIMER_INTERVAL (HZ) -- --#if 1 /* defined CONFIG_SCSI_MULTI_LUN */ --#define SCSI_NCR_MAX_LUN (16) --#else --#define SCSI_NCR_MAX_LUN (1) --#endif -- --/* -- * IO functions definition for big/little endian CPU support. -- * For now, the NCR is only supported in little endian addressing mode, -- */ -- --#ifdef __BIG_ENDIAN -- --#define inw_l2b inw --#define inl_l2b inl --#define outw_b2l outw --#define outl_b2l outl -- --#define readb_raw readb --#define writeb_raw writeb -- --#if defined(SCSI_NCR_BIG_ENDIAN) --#define readw_l2b __raw_readw --#define readl_l2b __raw_readl --#define writew_b2l __raw_writew --#define writel_b2l __raw_writel --#define readw_raw __raw_readw --#define readl_raw __raw_readl --#define writew_raw __raw_writew --#define writel_raw __raw_writel --#else /* Other big-endian */ --#define readw_l2b readw --#define readl_l2b readl --#define writew_b2l writew --#define writel_b2l writel --#define readw_raw readw --#define readl_raw readl --#define writew_raw writew --#define writel_raw writel --#endif -- --#else /* little endian */ -- --#define inw_raw inw --#define inl_raw inl --#define outw_raw outw --#define outl_raw outl -- --#define readb_raw readb --#define readw_raw readw --#define readl_raw readl --#define writeb_raw writeb --#define writew_raw writew --#define writel_raw writel -- --#endif -- --#if !defined(__hppa__) && !defined(__mips__) --#ifdef SCSI_NCR_BIG_ENDIAN --#error "The NCR in BIG ENDIAN addressing mode is not (yet) supported" --#endif --#endif -- --#define MEMORY_BARRIER() mb() -- -- --/* -- * If the NCR uses big endian addressing mode over the -- * PCI, actual io register addresses for byte and word -- * accesses must be changed according to lane routing. -- * Btw, ncr_offb() and ncr_offw() macros only apply to -- * constants and so donnot generate bloated code. -- */ -- --#if defined(SCSI_NCR_BIG_ENDIAN) -- --#define ncr_offb(o) (((o)&~3)+((~((o)&3))&3)) --#define ncr_offw(o) (((o)&~3)+((~((o)&3))&2)) -- --#else -- --#define ncr_offb(o) (o) --#define ncr_offw(o) (o) -- --#endif -- --/* -- * If the CPU and the NCR use same endian-ness addressing, -- * no byte reordering is needed for script patching. -- * Macro cpu_to_scr() is to be used for script patching. -- * Macro scr_to_cpu() is to be used for getting a DWORD -- * from the script. -- */ -- --#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN) -- --#define cpu_to_scr(dw) cpu_to_le32(dw) --#define scr_to_cpu(dw) le32_to_cpu(dw) -- --#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN) -- --#define cpu_to_scr(dw) cpu_to_be32(dw) --#define scr_to_cpu(dw) be32_to_cpu(dw) -- --#else -- --#define cpu_to_scr(dw) (dw) --#define scr_to_cpu(dw) (dw) -- --#endif -- --/* -- * Access to the controller chip. -- * -- * If the CPU and the NCR use same endian-ness addressing, -- * no byte reordering is needed for accessing chip io -- * registers. Functions suffixed by '_raw' are assumed -- * to access the chip over the PCI without doing byte -- * reordering. Functions suffixed by '_l2b' are -- * assumed to perform little-endian to big-endian byte -- * reordering, those suffixed by '_b2l' blah, blah, -- * blah, ... -- */ -- --/* -- * MEMORY mapped IO input / output -- */ -- --#define INB_OFF(o) readb_raw((char __iomem *)np->reg + ncr_offb(o)) --#define OUTB_OFF(o, val) writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o)) -- --#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN) -- --#define INW_OFF(o) readw_l2b((char __iomem *)np->reg + ncr_offw(o)) --#define INL_OFF(o) readl_l2b((char __iomem *)np->reg + (o)) -- --#define OUTW_OFF(o, val) writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o)) --#define OUTL_OFF(o, val) writel_b2l((val), (char __iomem *)np->reg + (o)) -- --#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN) -- --#define INW_OFF(o) readw_b2l((char __iomem *)np->reg + ncr_offw(o)) --#define INL_OFF(o) readl_b2l((char __iomem *)np->reg + (o)) -- --#define OUTW_OFF(o, val) writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o)) --#define OUTL_OFF(o, val) writel_l2b((val), (char __iomem *)np->reg + (o)) -- --#else -- --#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS --/* Only 8 or 32 bit transfers allowed */ --#define INW_OFF(o) (readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1)) --#else --#define INW_OFF(o) readw_raw((char __iomem *)np->reg + ncr_offw(o)) --#endif --#define INL_OFF(o) readl_raw((char __iomem *)np->reg + (o)) -- --#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS --/* Only 8 or 32 bit transfers allowed */ --#define OUTW_OFF(o, val) do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0) --#else --#define OUTW_OFF(o, val) writew_raw((val), (char __iomem *)np->reg + ncr_offw(o)) --#endif --#define OUTL_OFF(o, val) writel_raw((val), (char __iomem *)np->reg + (o)) -- --#endif -- --#define INB(r) INB_OFF (offsetof(struct ncr_reg,r)) --#define INW(r) INW_OFF (offsetof(struct ncr_reg,r)) --#define INL(r) INL_OFF (offsetof(struct ncr_reg,r)) -- --#define OUTB(r, val) OUTB_OFF (offsetof(struct ncr_reg,r), (val)) --#define OUTW(r, val) OUTW_OFF (offsetof(struct ncr_reg,r), (val)) --#define OUTL(r, val) OUTL_OFF (offsetof(struct ncr_reg,r), (val)) -- --/* -- * Set bit field ON, OFF -- */ -- --#define OUTONB(r, m) OUTB(r, INB(r) | (m)) --#define OUTOFFB(r, m) OUTB(r, INB(r) & ~(m)) --#define OUTONW(r, m) OUTW(r, INW(r) | (m)) --#define OUTOFFW(r, m) OUTW(r, INW(r) & ~(m)) --#define OUTONL(r, m) OUTL(r, INL(r) | (m)) --#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m)) -- --/* -- * We normally want the chip to have a consistent view -- * of driver internal data structures when we restart it. -- * Thus these macros. -- */ --#define OUTL_DSP(v) \ -- do { \ -- MEMORY_BARRIER(); \ -- OUTL (nc_dsp, (v)); \ -- } while (0) -- --#define OUTONB_STD() \ -- do { \ -- MEMORY_BARRIER(); \ -- OUTONB (nc_dcntl, (STD|NOCOM)); \ -- } while (0) -- -- --/* --** NCR53C8XX devices features table. --*/ --struct ncr_chip { -- unsigned short revision_id; -- unsigned char burst_max; /* log-base-2 of max burst */ -- unsigned char offset_max; -- unsigned char nr_divisor; -- unsigned int features; --#define FE_LED0 (1<<0) --#define FE_WIDE (1<<1) /* Wide data transfers */ --#define FE_ULTRA (1<<2) /* Ultra speed 20Mtrans/sec */ --#define FE_DBLR (1<<4) /* Clock doubler present */ --#define FE_QUAD (1<<5) /* Clock quadrupler present */ --#define FE_ERL (1<<6) /* Enable read line */ --#define FE_CLSE (1<<7) /* Cache line size enable */ --#define FE_WRIE (1<<8) /* Write & Invalidate enable */ --#define FE_ERMP (1<<9) /* Enable read multiple */ --#define FE_BOF (1<<10) /* Burst opcode fetch */ --#define FE_DFS (1<<11) /* DMA fifo size */ --#define FE_PFEN (1<<12) /* Prefetch enable */ --#define FE_LDSTR (1<<13) /* Load/Store supported */ --#define FE_RAM (1<<14) /* On chip RAM present */ --#define FE_VARCLK (1<<15) /* SCSI clock may vary */ --#define FE_RAM8K (1<<16) /* On chip RAM sized 8Kb */ --#define FE_64BIT (1<<17) /* Have a 64-bit PCI interface */ --#define FE_IO256 (1<<18) /* Requires full 256 bytes in PCI space */ --#define FE_NOPM (1<<19) /* Scripts handles phase mismatch */ --#define FE_LEDC (1<<20) /* Hardware control of LED */ --#define FE_DIFF (1<<21) /* Support Differential SCSI */ --#define FE_66MHZ (1<<23) /* 66MHz PCI Support */ --#define FE_DAC (1<<24) /* Support DAC cycles (64 bit addressing) */ --#define FE_ISTAT1 (1<<25) /* Have ISTAT1, MBOX0, MBOX1 registers */ --#define FE_DAC_IN_USE (1<<26) /* Platform does DAC cycles */ --#define FE_EHP (1<<27) /* 720: Even host parity */ --#define FE_MUX (1<<28) /* 720: Multiplexed bus */ --#define FE_EA (1<<29) /* 720: Enable Ack */ -- --#define FE_CACHE_SET (FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP) --#define FE_SCSI_SET (FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80) --#define FE_SPECIAL_SET (FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM) --}; -- -- --/* --** Driver setup structure. --** --** This structure is initialized from linux config options. --** It can be overridden at boot-up by the boot command line. --*/ --#define SCSI_NCR_MAX_EXCLUDES 8 --struct ncr_driver_setup { -- u8 master_parity; -- u8 scsi_parity; -- u8 disconnection; -- u8 special_features; -- u8 force_sync_nego; -- u8 reverse_probe; -- u8 pci_fix_up; -- u8 use_nvram; -- u8 verbose; -- u8 default_tags; -- u16 default_sync; -- u16 debug; -- u8 burst_max; -- u8 led_pin; -- u8 max_wide; -- u8 settle_delay; -- u8 diff_support; -- u8 irqm; -- u8 bus_check; -- u8 optimize; -- u8 recovery; -- u8 host_id; -- u16 iarb; -- u32 excludes[SCSI_NCR_MAX_EXCLUDES]; -- char tag_ctrl[100]; --}; -- --/* --** Initial setup. --** Can be overriden at startup by a command line. --*/ --#define SCSI_NCR_DRIVER_SETUP \ --{ \ -- SCSI_NCR_SETUP_MASTER_PARITY, \ -- SCSI_NCR_SETUP_SCSI_PARITY, \ -- SCSI_NCR_SETUP_DISCONNECTION, \ -- SCSI_NCR_SETUP_SPECIAL_FEATURES, \ -- SCSI_NCR_SETUP_FORCE_SYNC_NEGO, \ -- 0, \ -- 0, \ -- 1, \ -- 0, \ -- SCSI_NCR_SETUP_DEFAULT_TAGS, \ -- SCSI_NCR_SETUP_DEFAULT_SYNC, \ -- 0x00, \ -- 7, \ -- 0, \ -- 1, \ -- SCSI_NCR_SETUP_SETTLE_TIME, \ -- 0, \ -- 0, \ -- 1, \ -- 0, \ -- 0, \ -- 255, \ -- 0x00 \ --} -- --/* --** Boot fail safe setup. --** Override initial setup from boot command line: --** ncr53c8xx=safe:y --*/ --#define SCSI_NCR_DRIVER_SAFE_SETUP \ --{ \ -- 0, \ -- 1, \ -- 0, \ -- 0, \ -- 0, \ -- 0, \ -- 0, \ -- 1, \ -- 2, \ -- 0, \ -- 255, \ -- 0x00, \ -- 255, \ -- 0, \ -- 0, \ -- 10, \ -- 1, \ -- 1, \ -- 1, \ -- 0, \ -- 0, \ -- 255 \ --} -- --/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/ -- --/*----------------------------------------------------------------- --** --** The ncr 53c810 register structure. --** --**----------------------------------------------------------------- --*/ -- --struct ncr_reg { --/*00*/ u8 nc_scntl0; /* full arb., ena parity, par->ATN */ -- --/*01*/ u8 nc_scntl1; /* no reset */ -- #define ISCON 0x10 /* connected to scsi */ -- #define CRST 0x08 /* force reset */ -- #define IARB 0x02 /* immediate arbitration */ -- --/*02*/ u8 nc_scntl2; /* no disconnect expected */ -- #define SDU 0x80 /* cmd: disconnect will raise error */ -- #define CHM 0x40 /* sta: chained mode */ -- #define WSS 0x08 /* sta: wide scsi send [W]*/ -- #define WSR 0x01 /* sta: wide scsi received [W]*/ -- --/*03*/ u8 nc_scntl3; /* cnf system clock dependent */ -- #define EWS 0x08 /* cmd: enable wide scsi [W]*/ -- #define ULTRA 0x80 /* cmd: ULTRA enable */ -- /* bits 0-2, 7 rsvd for C1010 */ -- --/*04*/ u8 nc_scid; /* cnf host adapter scsi address */ -- #define RRE 0x40 /* r/w:e enable response to resel. */ -- #define SRE 0x20 /* r/w:e enable response to select */ -- --/*05*/ u8 nc_sxfer; /* ### Sync speed and count */ -- /* bits 6-7 rsvd for C1010 */ -- --/*06*/ u8 nc_sdid; /* ### Destination-ID */ -- --/*07*/ u8 nc_gpreg; /* ??? IO-Pins */ -- --/*08*/ u8 nc_sfbr; /* ### First byte in phase */ -- --/*09*/ u8 nc_socl; -- #define CREQ 0x80 /* r/w: SCSI-REQ */ -- #define CACK 0x40 /* r/w: SCSI-ACK */ -- #define CBSY 0x20 /* r/w: SCSI-BSY */ -- #define CSEL 0x10 /* r/w: SCSI-SEL */ -- #define CATN 0x08 /* r/w: SCSI-ATN */ -- #define CMSG 0x04 /* r/w: SCSI-MSG */ -- #define CC_D 0x02 /* r/w: SCSI-C_D */ -- #define CI_O 0x01 /* r/w: SCSI-I_O */ -- --/*0a*/ u8 nc_ssid; -- --/*0b*/ u8 nc_sbcl; -- --/*0c*/ u8 nc_dstat; -- #define DFE 0x80 /* sta: dma fifo empty */ -- #define MDPE 0x40 /* int: master data parity error */ -- #define BF 0x20 /* int: script: bus fault */ -- #define ABRT 0x10 /* int: script: command aborted */ -- #define SSI 0x08 /* int: script: single step */ -- #define SIR 0x04 /* int: script: interrupt instruct. */ -- #define IID 0x01 /* int: script: illegal instruct. */ -- --/*0d*/ u8 nc_sstat0; -- #define ILF 0x80 /* sta: data in SIDL register lsb */ -- #define ORF 0x40 /* sta: data in SODR register lsb */ -- #define OLF 0x20 /* sta: data in SODL register lsb */ -- #define AIP 0x10 /* sta: arbitration in progress */ -- #define LOA 0x08 /* sta: arbitration lost */ -- #define WOA 0x04 /* sta: arbitration won */ -- #define IRST 0x02 /* sta: scsi reset signal */ -- #define SDP 0x01 /* sta: scsi parity signal */ -- --/*0e*/ u8 nc_sstat1; -- #define FF3210 0xf0 /* sta: bytes in the scsi fifo */ -- --/*0f*/ u8 nc_sstat2; -- #define ILF1 0x80 /* sta: data in SIDL register msb[W]*/ -- #define ORF1 0x40 /* sta: data in SODR register msb[W]*/ -- #define OLF1 0x20 /* sta: data in SODL register msb[W]*/ -- #define DM 0x04 /* sta: DIFFSENS mismatch (895/6 only) */ -- #define LDSC 0x02 /* sta: disconnect & reconnect */ -- --/*10*/ u8 nc_dsa; /* --> Base page */ --/*11*/ u8 nc_dsa1; --/*12*/ u8 nc_dsa2; --/*13*/ u8 nc_dsa3; -- --/*14*/ u8 nc_istat; /* --> Main Command and status */ -- #define CABRT 0x80 /* cmd: abort current operation */ -- #define SRST 0x40 /* mod: reset chip */ -- #define SIGP 0x20 /* r/w: message from host to ncr */ -- #define SEM 0x10 /* r/w: message between host + ncr */ -- #define CON 0x08 /* sta: connected to scsi */ -- #define INTF 0x04 /* sta: int on the fly (reset by wr)*/ -- #define SIP 0x02 /* sta: scsi-interrupt */ -- #define DIP 0x01 /* sta: host/script interrupt */ -- --/*15*/ u8 nc_istat1; /* 896 and later cores only */ -- #define FLSH 0x04 /* sta: chip is flushing */ -- #define SRUN 0x02 /* sta: scripts are running */ -- #define SIRQD 0x01 /* r/w: disable INT pin */ -- --/*16*/ u8 nc_mbox0; /* 896 and later cores only */ --/*17*/ u8 nc_mbox1; /* 896 and later cores only */ -- --/*18*/ u8 nc_ctest0; -- #define EHP 0x04 /* 720 even host parity */ --/*19*/ u8 nc_ctest1; -- --/*1a*/ u8 nc_ctest2; -- #define CSIGP 0x40 -- /* bits 0-2,7 rsvd for C1010 */ -- --/*1b*/ u8 nc_ctest3; -- #define FLF 0x08 /* cmd: flush dma fifo */ -- #define CLF 0x04 /* cmd: clear dma fifo */ -- #define FM 0x02 /* mod: fetch pin mode */ -- #define WRIE 0x01 /* mod: write and invalidate enable */ -- /* bits 4-7 rsvd for C1010 */ -- --/*1c*/ u32 nc_temp; /* ### Temporary stack */ -- --/*20*/ u8 nc_dfifo; --/*21*/ u8 nc_ctest4; -- #define MUX 0x80 /* 720 host bus multiplex mode */ -- #define BDIS 0x80 /* mod: burst disable */ -- #define MPEE 0x08 /* mod: master parity error enable */ -- --/*22*/ u8 nc_ctest5; -- #define DFS 0x20 /* mod: dma fifo size */ -- /* bits 0-1, 3-7 rsvd for C1010 */ --/*23*/ u8 nc_ctest6; -- --/*24*/ u32 nc_dbc; /* ### Byte count and command */ --/*28*/ u32 nc_dnad; /* ### Next command register */ --/*2c*/ u32 nc_dsp; /* --> Script Pointer */ --/*30*/ u32 nc_dsps; /* --> Script pointer save/opcode#2 */ -- --/*34*/ u8 nc_scratcha; /* Temporary register a */ --/*35*/ u8 nc_scratcha1; --/*36*/ u8 nc_scratcha2; --/*37*/ u8 nc_scratcha3; -- --/*38*/ u8 nc_dmode; -- #define BL_2 0x80 /* mod: burst length shift value +2 */ -- #define BL_1 0x40 /* mod: burst length shift value +1 */ -- #define ERL 0x08 /* mod: enable read line */ -- #define ERMP 0x04 /* mod: enable read multiple */ -- #define BOF 0x02 /* mod: burst op code fetch */ -- --/*39*/ u8 nc_dien; --/*3a*/ u8 nc_sbr; -- --/*3b*/ u8 nc_dcntl; /* --> Script execution control */ -- #define CLSE 0x80 /* mod: cache line size enable */ -- #define PFF 0x40 /* cmd: pre-fetch flush */ -- #define PFEN 0x20 /* mod: pre-fetch enable */ -- #define EA 0x20 /* mod: 720 enable-ack */ -- #define SSM 0x10 /* mod: single step mode */ -- #define IRQM 0x08 /* mod: irq mode (1 = totem pole !) */ -- #define STD 0x04 /* cmd: start dma mode */ -- #define IRQD 0x02 /* mod: irq disable */ -- #define NOCOM 0x01 /* cmd: protect sfbr while reselect */ -- /* bits 0-1 rsvd for C1010 */ -- --/*3c*/ u32 nc_adder; -- --/*40*/ u16 nc_sien; /* -->: interrupt enable */ --/*42*/ u16 nc_sist; /* <--: interrupt status */ -- #define SBMC 0x1000/* sta: SCSI Bus Mode Change (895/6 only) */ -- #define STO 0x0400/* sta: timeout (select) */ -- #define GEN 0x0200/* sta: timeout (general) */ -- #define HTH 0x0100/* sta: timeout (handshake) */ -- #define MA 0x80 /* sta: phase mismatch */ -- #define CMP 0x40 /* sta: arbitration complete */ -- #define SEL 0x20 /* sta: selected by another device */ -- #define RSL 0x10 /* sta: reselected by another device*/ -- #define SGE 0x08 /* sta: gross error (over/underflow)*/ -- #define UDC 0x04 /* sta: unexpected disconnect */ -- #define RST 0x02 /* sta: scsi bus reset detected */ -- #define PAR 0x01 /* sta: scsi parity error */ -- --/*44*/ u8 nc_slpar; --/*45*/ u8 nc_swide; --/*46*/ u8 nc_macntl; --/*47*/ u8 nc_gpcntl; --/*48*/ u8 nc_stime0; /* cmd: timeout for select&handshake*/ --/*49*/ u8 nc_stime1; /* cmd: timeout user defined */ --/*4a*/ u16 nc_respid; /* sta: Reselect-IDs */ -- --/*4c*/ u8 nc_stest0; -- --/*4d*/ u8 nc_stest1; -- #define SCLK 0x80 /* Use the PCI clock as SCSI clock */ -- #define DBLEN 0x08 /* clock doubler running */ -- #define DBLSEL 0x04 /* clock doubler selected */ -- -- --/*4e*/ u8 nc_stest2; -- #define ROF 0x40 /* reset scsi offset (after gross error!) */ -- #define DIF 0x20 /* 720 SCSI differential mode */ -- #define EXT 0x02 /* extended filtering */ -- --/*4f*/ u8 nc_stest3; -- #define TE 0x80 /* c: tolerAnt enable */ -- #define HSC 0x20 /* c: Halt SCSI Clock */ -- #define CSF 0x02 /* c: clear scsi fifo */ -- --/*50*/ u16 nc_sidl; /* Lowlevel: latched from scsi data */ --/*52*/ u8 nc_stest4; -- #define SMODE 0xc0 /* SCSI bus mode (895/6 only) */ -- #define SMODE_HVD 0x40 /* High Voltage Differential */ -- #define SMODE_SE 0x80 /* Single Ended */ -- #define SMODE_LVD 0xc0 /* Low Voltage Differential */ -- #define LCKFRQ 0x20 /* Frequency Lock (895/6 only) */ -- /* bits 0-5 rsvd for C1010 */ -- --/*53*/ u8 nc_53_; --/*54*/ u16 nc_sodl; /* Lowlevel: data out to scsi data */ --/*56*/ u8 nc_ccntl0; /* Chip Control 0 (896) */ -- #define ENPMJ 0x80 /* Enable Phase Mismatch Jump */ -- #define PMJCTL 0x40 /* Phase Mismatch Jump Control */ -- #define ENNDJ 0x20 /* Enable Non Data PM Jump */ -- #define DISFC 0x10 /* Disable Auto FIFO Clear */ -- #define DILS 0x02 /* Disable Internal Load/Store */ -- #define DPR 0x01 /* Disable Pipe Req */ -- --/*57*/ u8 nc_ccntl1; /* Chip Control 1 (896) */ -- #define ZMOD 0x80 /* High Impedance Mode */ -- #define DIC 0x10 /* Disable Internal Cycles */ -- #define DDAC 0x08 /* Disable Dual Address Cycle */ -- #define XTIMOD 0x04 /* 64-bit Table Ind. Indexing Mode */ -- #define EXTIBMV 0x02 /* Enable 64-bit Table Ind. BMOV */ -- #define EXDBMV 0x01 /* Enable 64-bit Direct BMOV */ -- --/*58*/ u16 nc_sbdl; /* Lowlevel: data from scsi data */ --/*5a*/ u16 nc_5a_; -- --/*5c*/ u8 nc_scr0; /* Working register B */ --/*5d*/ u8 nc_scr1; /* */ --/*5e*/ u8 nc_scr2; /* */ --/*5f*/ u8 nc_scr3; /* */ -- --/*60*/ u8 nc_scrx[64]; /* Working register C-R */ --/*a0*/ u32 nc_mmrs; /* Memory Move Read Selector */ --/*a4*/ u32 nc_mmws; /* Memory Move Write Selector */ --/*a8*/ u32 nc_sfs; /* Script Fetch Selector */ --/*ac*/ u32 nc_drs; /* DSA Relative Selector */ --/*b0*/ u32 nc_sbms; /* Static Block Move Selector */ --/*b4*/ u32 nc_dbms; /* Dynamic Block Move Selector */ --/*b8*/ u32 nc_dnad64; /* DMA Next Address 64 */ --/*bc*/ u16 nc_scntl4; /* C1010 only */ -- #define U3EN 0x80 /* Enable Ultra 3 */ -- #define AIPEN 0x40 /* Allow check upper byte lanes */ -- #define XCLKH_DT 0x08 /* Extra clock of data hold on DT -- transfer edge */ -- #define XCLKH_ST 0x04 /* Extra clock of data hold on ST -- transfer edge */ -- --/*be*/ u8 nc_aipcntl0; /* Epat Control 1 C1010 only */ --/*bf*/ u8 nc_aipcntl1; /* AIP Control C1010_66 Only */ -- --/*c0*/ u32 nc_pmjad1; /* Phase Mismatch Jump Address 1 */ --/*c4*/ u32 nc_pmjad2; /* Phase Mismatch Jump Address 2 */ --/*c8*/ u8 nc_rbc; /* Remaining Byte Count */ --/*c9*/ u8 nc_rbc1; /* */ --/*ca*/ u8 nc_rbc2; /* */ --/*cb*/ u8 nc_rbc3; /* */ -- --/*cc*/ u8 nc_ua; /* Updated Address */ --/*cd*/ u8 nc_ua1; /* */ --/*ce*/ u8 nc_ua2; /* */ --/*cf*/ u8 nc_ua3; /* */ --/*d0*/ u32 nc_esa; /* Entry Storage Address */ --/*d4*/ u8 nc_ia; /* Instruction Address */ --/*d5*/ u8 nc_ia1; --/*d6*/ u8 nc_ia2; --/*d7*/ u8 nc_ia3; --/*d8*/ u32 nc_sbc; /* SCSI Byte Count (3 bytes only) */ --/*dc*/ u32 nc_csbc; /* Cumulative SCSI Byte Count */ -- -- /* Following for C1010 only */ --/*e0*/ u16 nc_crcpad; /* CRC Value */ --/*e2*/ u8 nc_crccntl0; /* CRC control register */ -- #define SNDCRC 0x10 /* Send CRC Request */ --/*e3*/ u8 nc_crccntl1; /* CRC control register */ --/*e4*/ u32 nc_crcdata; /* CRC data register */ --/*e8*/ u32 nc_e8_; /* rsvd */ --/*ec*/ u32 nc_ec_; /* rsvd */ --/*f0*/ u16 nc_dfbc; /* DMA FIFO byte count */ -- --}; -- --/*----------------------------------------------------------- --** --** Utility macros for the script. --** --**----------------------------------------------------------- --*/ -- --#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r)) --#define REG(r) REGJ (nc_, r) -- --typedef u32 ncrcmd; -- --/*----------------------------------------------------------- --** --** SCSI phases --** --** DT phases illegal for ncr driver. --** --**----------------------------------------------------------- --*/ -- --#define SCR_DATA_OUT 0x00000000 --#define SCR_DATA_IN 0x01000000 --#define SCR_COMMAND 0x02000000 --#define SCR_STATUS 0x03000000 --#define SCR_DT_DATA_OUT 0x04000000 --#define SCR_DT_DATA_IN 0x05000000 --#define SCR_MSG_OUT 0x06000000 --#define SCR_MSG_IN 0x07000000 -- --#define SCR_ILG_OUT 0x04000000 --#define SCR_ILG_IN 0x05000000 -- --/*----------------------------------------------------------- --** --** Data transfer via SCSI. --** --**----------------------------------------------------------- --** --** MOVE_ABS (LEN) --** <> --** --** MOVE_IND (LEN) --** <> --** --** MOVE_TBL --** <> --** --**----------------------------------------------------------- --*/ -- --#define OPC_MOVE 0x08000000 -- --#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l)) --#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l)) --#define SCR_MOVE_TBL (0x10000000 | OPC_MOVE) -- --#define SCR_CHMOV_ABS(l) ((0x00000000) | (l)) --#define SCR_CHMOV_IND(l) ((0x20000000) | (l)) --#define SCR_CHMOV_TBL (0x10000000) -- --struct scr_tblmove { -- u32 size; -- u32 addr; --}; -- --/*----------------------------------------------------------- --** --** Selection --** --**----------------------------------------------------------- --** --** SEL_ABS | SCR_ID (0..15) [ | REL_JMP] --** <> --** --** SEL_TBL | << dnad_offset>> [ | REL_JMP] --** <> --** --**----------------------------------------------------------- --*/ -- --#define SCR_SEL_ABS 0x40000000 --#define SCR_SEL_ABS_ATN 0x41000000 --#define SCR_SEL_TBL 0x42000000 --#define SCR_SEL_TBL_ATN 0x43000000 -- -- --#ifdef SCSI_NCR_BIG_ENDIAN --struct scr_tblsel { -- u8 sel_scntl3; -- u8 sel_id; -- u8 sel_sxfer; -- u8 sel_scntl4; --}; --#else --struct scr_tblsel { -- u8 sel_scntl4; -- u8 sel_sxfer; -- u8 sel_id; -- u8 sel_scntl3; --}; --#endif -- --#define SCR_JMP_REL 0x04000000 --#define SCR_ID(id) (((u32)(id)) << 16) -- --/*----------------------------------------------------------- --** --** Waiting for Disconnect or Reselect --** --**----------------------------------------------------------- --** --** WAIT_DISC --** dummy: <> --** --** WAIT_RESEL --** <> --** --**----------------------------------------------------------- --*/ -- --#define SCR_WAIT_DISC 0x48000000 --#define SCR_WAIT_RESEL 0x50000000 -- --/*----------------------------------------------------------- --** --** Bit Set / Reset --** --**----------------------------------------------------------- --** --** SET (flags {|.. }) --** --** CLR (flags {|.. }) --** --**----------------------------------------------------------- --*/ -- --#define SCR_SET(f) (0x58000000 | (f)) --#define SCR_CLR(f) (0x60000000 | (f)) -- --#define SCR_CARRY 0x00000400 --#define SCR_TRG 0x00000200 --#define SCR_ACK 0x00000040 --#define SCR_ATN 0x00000008 -- -- -- -- --/*----------------------------------------------------------- --** --** Memory to memory move --** --**----------------------------------------------------------- --** --** COPY (bytecount) --** << source_address >> --** << destination_address >> --** --** SCR_COPY sets the NO FLUSH option by default. --** SCR_COPY_F does not set this option. --** --** For chips which do not support this option, --** ncr_copy_and_bind() will remove this bit. --**----------------------------------------------------------- --*/ -- --#define SCR_NO_FLUSH 0x01000000 -- --#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n)) --#define SCR_COPY_F(n) (0xc0000000 | (n)) -- --/*----------------------------------------------------------- --** --** Register move and binary operations --** --**----------------------------------------------------------- --** --** SFBR_REG (reg, op, data) reg = SFBR op data --** << 0 >> --** --** REG_SFBR (reg, op, data) SFBR = reg op data --** << 0 >> --** --** REG_REG (reg, op, data) reg = reg op data --** << 0 >> --** --**----------------------------------------------------------- --** On 810A, 860, 825A, 875, 895 and 896 chips the content --** of SFBR register can be used as data (SCR_SFBR_DATA). --** The 896 has additionnal IO registers starting at --** offset 0x80. Bit 7 of register offset is stored in --** bit 7 of the SCRIPTS instruction first DWORD. --**----------------------------------------------------------- --*/ -- --#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) -- --#define SCR_SFBR_REG(reg,op,data) \ -- (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) -- --#define SCR_REG_SFBR(reg,op,data) \ -- (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) -- --#define SCR_REG_REG(reg,op,data) \ -- (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul)) -- -- --#define SCR_LOAD 0x00000000 --#define SCR_SHL 0x01000000 --#define SCR_OR 0x02000000 --#define SCR_XOR 0x03000000 --#define SCR_AND 0x04000000 --#define SCR_SHR 0x05000000 --#define SCR_ADD 0x06000000 --#define SCR_ADDC 0x07000000 -- --#define SCR_SFBR_DATA (0x00800000>>8ul) /* Use SFBR as data */ -- --/*----------------------------------------------------------- --** --** FROM_REG (reg) SFBR = reg --** << 0 >> --** --** TO_REG (reg) reg = SFBR --** << 0 >> --** --** LOAD_REG (reg, data) reg = --** << 0 >> --** --** LOAD_SFBR(data) SFBR = --** << 0 >> --** --**----------------------------------------------------------- --*/ -- --#define SCR_FROM_REG(reg) \ -- SCR_REG_SFBR(reg,SCR_OR,0) -- --#define SCR_TO_REG(reg) \ -- SCR_SFBR_REG(reg,SCR_OR,0) -- --#define SCR_LOAD_REG(reg,data) \ -- SCR_REG_REG(reg,SCR_LOAD,data) -- --#define SCR_LOAD_SFBR(data) \ -- (SCR_REG_SFBR (gpreg, SCR_LOAD, data)) -- --/*----------------------------------------------------------- --** --** LOAD from memory to register. --** STORE from register to memory. --** --** Only supported by 810A, 860, 825A, 875, 895 and 896. --** --**----------------------------------------------------------- --** --** LOAD_ABS (LEN) --** <> --** --** LOAD_REL (LEN) (DSA relative) --** <> --** --**----------------------------------------------------------- --*/ -- --#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul) --#define SCR_NO_FLUSH2 0x02000000 --#define SCR_DSA_REL2 0x10000000 -- --#define SCR_LOAD_R(reg, how, n) \ -- (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n)) -- --#define SCR_STORE_R(reg, how, n) \ -- (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n)) -- --#define SCR_LOAD_ABS(reg, n) SCR_LOAD_R(reg, SCR_NO_FLUSH2, n) --#define SCR_LOAD_REL(reg, n) SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n) --#define SCR_LOAD_ABS_F(reg, n) SCR_LOAD_R(reg, 0, n) --#define SCR_LOAD_REL_F(reg, n) SCR_LOAD_R(reg, SCR_DSA_REL2, n) -- --#define SCR_STORE_ABS(reg, n) SCR_STORE_R(reg, SCR_NO_FLUSH2, n) --#define SCR_STORE_REL(reg, n) SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n) --#define SCR_STORE_ABS_F(reg, n) SCR_STORE_R(reg, 0, n) --#define SCR_STORE_REL_F(reg, n) SCR_STORE_R(reg, SCR_DSA_REL2, n) -- -- --/*----------------------------------------------------------- --** --** Waiting for Disconnect or Reselect --** --**----------------------------------------------------------- --** --** JUMP [ | IFTRUE/IFFALSE ( ... ) ] --** <
> --** --** JUMPR [ | IFTRUE/IFFALSE ( ... ) ] --** <> --** --** CALL [ | IFTRUE/IFFALSE ( ... ) ] --** <
> --** --** CALLR [ | IFTRUE/IFFALSE ( ... ) ] --** <> --** --** RETURN [ | IFTRUE/IFFALSE ( ... ) ] --** <> --** --** INT [ | IFTRUE/IFFALSE ( ... ) ] --** <> --** --** INT_FLY [ | IFTRUE/IFFALSE ( ... ) ] --** <> --** --** Conditions: --** WHEN (phase) --** IF (phase) --** CARRYSET --** DATA (data, mask) --** --**----------------------------------------------------------- --*/ -- --#define SCR_NO_OP 0x80000000 --#define SCR_JUMP 0x80080000 --#define SCR_JUMP64 0x80480000 --#define SCR_JUMPR 0x80880000 --#define SCR_CALL 0x88080000 --#define SCR_CALLR 0x88880000 --#define SCR_RETURN 0x90080000 --#define SCR_INT 0x98080000 --#define SCR_INT_FLY 0x98180000 -- --#define IFFALSE(arg) (0x00080000 | (arg)) --#define IFTRUE(arg) (0x00000000 | (arg)) -- --#define WHEN(phase) (0x00030000 | (phase)) --#define IF(phase) (0x00020000 | (phase)) -- --#define DATA(D) (0x00040000 | ((D) & 0xff)) --#define MASK(D,M) (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff)) -- --#define CARRYSET (0x00200000) -- --/*----------------------------------------------------------- --** --** SCSI constants. --** --**----------------------------------------------------------- --*/ -- --/* --** Messages --*/ -- --#define M_COMPLETE COMMAND_COMPLETE --#define M_EXTENDED EXTENDED_MESSAGE --#define M_SAVE_DP SAVE_POINTERS --#define M_RESTORE_DP RESTORE_POINTERS --#define M_DISCONNECT DISCONNECT --#define M_ID_ERROR INITIATOR_ERROR --#define M_ABORT ABORT_TASK_SET --#define M_REJECT MESSAGE_REJECT --#define M_NOOP NOP --#define M_PARITY MSG_PARITY_ERROR --#define M_LCOMPLETE LINKED_CMD_COMPLETE --#define M_FCOMPLETE LINKED_FLG_CMD_COMPLETE --#define M_RESET TARGET_RESET --#define M_ABORT_TAG ABORT_TASK --#define M_CLEAR_QUEUE CLEAR_TASK_SET --#define M_INIT_REC INITIATE_RECOVERY --#define M_REL_REC RELEASE_RECOVERY --#define M_TERMINATE (0x11) --#define M_SIMPLE_TAG SIMPLE_QUEUE_TAG --#define M_HEAD_TAG HEAD_OF_QUEUE_TAG --#define M_ORDERED_TAG ORDERED_QUEUE_TAG --#define M_IGN_RESIDUE IGNORE_WIDE_RESIDUE --#define M_IDENTIFY (0x80) -- --#define M_X_MODIFY_DP EXTENDED_MODIFY_DATA_POINTER --#define M_X_SYNC_REQ EXTENDED_SDTR --#define M_X_WIDE_REQ EXTENDED_WDTR --#define M_X_PPR_REQ EXTENDED_PPR -- --/* --** Status --*/ -- --#define S_GOOD (0x00) --#define S_CHECK_COND (0x02) --#define S_COND_MET (0x04) --#define S_BUSY (0x08) --#define S_INT (0x10) --#define S_INT_COND_MET (0x14) --#define S_CONFLICT (0x18) --#define S_TERMINATED (0x20) --#define S_QUEUE_FULL (0x28) --#define S_ILLEGAL (0xff) --#define S_SENSE (0x80) -- --/* -- * End of ncrreg from FreeBSD -- */ -- --#endif /* defined SYM53C8XX_DEFS_H */ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/serial/serial_core.c CVS2_6_15_RC7_PA0/drivers/serial/serial_core.c ---- LINUS_2_6_15_RC7/drivers/serial/serial_core.c 2005-12-27 13:25:49.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/serial/serial_core.c 2005-11-29 11:03:08.000000000 -0700 -@@ -1961,6 +1961,7 @@ - uart_report_port(struct uart_driver *drv, struct uart_port *port) - { - char address[64]; -+ char irq[16]; - - switch (port->iotype) { - case UPIO_PORT: -@@ -1982,10 +1983,19 @@ - break; - } - -- printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n", -+#ifndef NO_IRQ -+#define NO_IRQ (-1) -+#endif -+ if (port->irq == NO_IRQ) { -+ strlcpy(irq, "polled", sizeof(irq)); -+ } else { -+ snprintf(irq, sizeof(irq), "irq = %d", port->irq); -+ } -+ -+ printk(KERN_INFO "%s%s%s%d at %s (%s) is a %s\n", - port->dev ? port->dev->bus_id : "", - port->dev ? ": " : "", -- drv->dev_name, port->line, address, port->irq, uart_type(port)); -+ drv->dev_name, port->line, address, irq, uart_type(port)); - } - - static void -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/usb/input/hid-core.c CVS2_6_15_RC7_PA0/drivers/usb/input/hid-core.c ---- LINUS_2_6_15_RC7/drivers/usb/input/hid-core.c 2005-12-27 13:25:50.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/usb/input/hid-core.c 2005-12-19 05:42:37.000000000 -0700 -@@ -760,21 +760,31 @@ - } - - /* -- * Extract/implement a data field from/to a report. -+ * Extract/implement a data field from/to a little endian report (bit array). - */ - - static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) - { -- report += (offset >> 5) << 2; offset &= 31; -- return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1); -+ u32 x; -+ -+ report += offset >> 3; /* adjust byte index */ -+ offset &= 8 - 1; -+ x = get_unaligned((u32 *) report); -+ x = le32_to_cpu(x); -+ x = (x >> offset) & ((1 << n) - 1); -+ return x; - } - - static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) - { -- report += (offset >> 5) << 2; offset &= 31; -- put_unaligned((get_unaligned((__le64*)report) -- & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset))) -- | cpu_to_le64((__u64)value << offset), (__le64*)report); -+ u32 x; -+ -+ report += offset >> 3; -+ offset &= 8 - 1; -+ x = get_unaligned((u32 *)report); -+ x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset)); -+ x |= cpu_to_le32(value << offset); -+ put_unaligned(x,(u32 *)report); - } - - /* -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/video/stifb.c CVS2_6_15_RC7_PA0/drivers/video/stifb.c ---- LINUS_2_6_15_RC7/drivers/video/stifb.c 2005-12-27 13:25:50.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/drivers/video/stifb.c 2005-12-19 08:32:13.000000000 -0700 -@@ -3,7 +3,7 @@ - * Low level Frame buffer driver for HP workstations with - * STI (standard text interface) video firmware. - * -- * Copyright (C) 2001-2004 Helge Deller -+ * Copyright (C) 2001-2005 Helge Deller - * Portions Copyright (C) 2001 Thomas Bogendoerfer - * - * Based on: -@@ -73,16 +73,13 @@ - #include "sticore.h" - - /* REGION_BASE(fb_info, index) returns the virtual address for region */ --#ifdef __LP64__ -- #define REGION_BASE(fb_info, index) \ -- (fb_info->sti->glob_cfg->region_ptrs[index] | 0xffffffff00000000) --#else -- #define REGION_BASE(fb_info, index) \ -- fb_info->sti->glob_cfg->region_ptrs[index] --#endif -+#define REGION_BASE(fb_info, index) \ -+ F_EXTEND(fb_info->sti->glob_cfg->region_ptrs[index]) - - #define NGLEDEVDEPROM_CRT_REGION 1 - -+#define NR_PALETTE 256 -+ - typedef struct { - __s32 video_config_reg; - __s32 misc_video_start; -@@ -112,7 +109,7 @@ - ngle_rom_t ngle_rom; - struct sti_struct *sti; - int deviceSpecificConfig; -- u32 pseudo_palette[256]; -+ u32 pseudo_palette[16]; - }; - - static int __initdata stifb_bpp_pref[MAX_STI_ROMS]; -@@ -352,10 +349,10 @@ - #define IS_888_DEVICE(fb) \ - (!(IS_24_DEVICE(fb))) - --#define GET_FIFO_SLOTS(fb, cnt, numslots) \ --{ while (cnt < numslots) \ -+#define GET_FIFO_SLOTS(fb, cnt, numslots) \ -+{ while (cnt < numslots) \ - cnt = READ_WORD(fb, REG_34); \ -- cnt -= numslots; \ -+ cnt -= numslots; \ - } - - #define IndexedDcd 0 /* Pixel data is indexed (pseudo) color */ -@@ -995,7 +992,7 @@ - struct stifb_info *fb = (struct stifb_info *) info; - u32 color; - -- if (regno >= 256) /* no. of hw registers */ -+ if (regno >= NR_PALETTE) - return 1; - - red >>= 8; -@@ -1005,8 +1002,8 @@ - DEBUG_OFF(); - - START_IMAGE_COLORMAP_ACCESS(fb); -- -- if (fb->info.var.grayscale) { -+ -+ if (unlikely(fb->info.var.grayscale)) { - /* gray = 0.30*R + 0.59*G + 0.11*B */ - color = ((red * 77) + - (green * 151) + -@@ -1017,17 +1014,17 @@ - (blue)); - } - -- if (info->var.bits_per_pixel == 32) { -- ((u32 *)(info->pseudo_palette))[regno] = -- (red << info->var.red.offset) | -- (green << info->var.green.offset) | -- (blue << info->var.blue.offset); -- } else { -- ((u32 *)(info->pseudo_palette))[regno] = regno; -+ if (fb->info.fix.visual == FB_VISUAL_DIRECTCOLOR) { -+ struct fb_var_screeninfo *var = &fb->info.var; -+ if (regno < 16) -+ ((u32 *)fb->info.pseudo_palette)[regno] = -+ regno << var->red.offset | -+ regno << var->green.offset | -+ regno << var->blue.offset; - } - - WRITE_IMAGE_COLOR(fb, regno, color); -- -+ - if (fb->id == S9000_ID_HCRX) { - NgleLutBltCtl lutBltCtl; - -@@ -1066,9 +1063,9 @@ - case S9000_ID_HCRX: - HYPER_ENABLE_DISABLE_DISPLAY(fb, enable); - break; -- case S9000_ID_A1659A:; /* fall through */ -- case S9000_ID_TIMBER:; -- case CRX24_OVERLAY_PLANES:; -+ case S9000_ID_A1659A: /* fall through */ -+ case S9000_ID_TIMBER: -+ case CRX24_OVERLAY_PLANES: - default: - ENABLE_DISABLE_DISPLAY(fb, enable); - break; -@@ -1250,12 +1247,10 @@ - memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom)); - if ((fb->sti->regions_phys[0] & 0xfc000000) == - (fb->sti->regions_phys[2] & 0xfc000000)) -- sti_rom_address = fb->sti->regions_phys[0]; -+ sti_rom_address = F_EXTEND(fb->sti->regions_phys[0]); - else -- sti_rom_address = fb->sti->regions_phys[1]; --#ifdef __LP64__ -- sti_rom_address |= 0xffffffff00000000; --#endif -+ sti_rom_address = F_EXTEND(fb->sti->regions_phys[1]); -+ - fb->deviceSpecificConfig = gsc_readl(sti_rom_address); - if (IS_24_DEVICE(fb)) { - if (bpp_pref == 8 || bpp_pref == 32) -@@ -1315,7 +1310,7 @@ - break; - case 32: - fix->type = FB_TYPE_PACKED_PIXELS; -- fix->visual = FB_VISUAL_TRUECOLOR; -+ fix->visual = FB_VISUAL_DIRECTCOLOR; - var->red.length = var->green.length = var->blue.length = var->transp.length = 8; - var->blue.offset = 0; - var->green.offset = 8; -@@ -1337,7 +1332,7 @@ - info->pseudo_palette = &fb->pseudo_palette; - - /* This has to been done !!! */ -- fb_alloc_cmap(&info->cmap, 256, 0); -+ fb_alloc_cmap(&info->cmap, NR_PALETTE, 0); - stifb_init_display(fb); - - if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) { -@@ -1488,7 +1483,3 @@ - MODULE_AUTHOR("Helge Deller , Thomas Bogendoerfer "); - MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines"); - MODULE_LICENSE("GPL v2"); -- --MODULE_PARM(bpp, "i"); --MODULE_PARM_DESC(mem, "Bits per pixel (default: 8)"); -- -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-generic/compat_signal.h CVS2_6_15_RC7_PA0/include/asm-generic/compat_signal.h ---- LINUS_2_6_15_RC7/include/asm-generic/compat_signal.h 1969-12-31 17:00:00.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-generic/compat_signal.h 2004-01-27 22:12:47.000000000 -0700 -@@ -0,0 +1,25 @@ -+#ifndef _ASM_GENERIC_COMPAT_SIGNAL_H -+#define _ASM_GENERIC_COMPAT_SIGNAL_H -+ -+#ifndef __ASSEMBLY__ -+#include -+ -+typedef compat_uptr_t compat_sighandler_t; -+ -+typedef struct compat_sigaltstack { -+ compat_uptr_t ss_sp; -+ compat_int_t ss_flags; -+ compat_size_t ss_size; -+} compat_stack_t; -+ -+/* Most things should be clean enough to redefine this at will, if care -+ is taken to make libc match. */ -+ -+struct compat_sigaction { -+ compat_sighandler_t sa_handler; -+ compat_uint_t sa_flags; -+ compat_sigset_t sa_mask; /* mask last for extensibility */ -+}; -+ -+#endif /* !__ASSEMBLY__ */ -+#endif /* !_ASM_GENERIC_COMPAT_SIGNAL_H */ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-ia64/compat.h CVS2_6_15_RC7_PA0/include/asm-ia64/compat.h ---- LINUS_2_6_15_RC7/include/asm-ia64/compat.h 2005-12-27 13:25:53.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-ia64/compat.h 2005-09-14 06:57:31.000000000 -0600 -@@ -15,6 +15,9 @@ - typedef s32 compat_pid_t; - typedef u16 __compat_uid_t; - typedef u16 __compat_gid_t; -+/* Define for use in compat_siginfo_t */ -+#undef __ARCH_SI_COMPAT_UID_T -+#define __ARCH_SI_COMPAT_UID_T __compat_uid32_t - typedef u32 __compat_uid32_t; - typedef u32 __compat_gid32_t; - typedef u16 compat_mode_t; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/cache.h CVS2_6_15_RC7_PA0/include/asm-parisc/cache.h ---- LINUS_2_6_15_RC7/include/asm-parisc/cache.h 2005-12-27 13:25:54.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-parisc/cache.h 2005-12-16 06:02:55.000000000 -0700 -@@ -30,14 +30,14 @@ - #define SMP_CACHE_BYTES L1_CACHE_BYTES - #define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */ - --extern void flush_data_cache_local(void); /* flushes local data-cache only */ --extern void flush_instruction_cache_local(void); /* flushes local code-cache only */ -+extern void flush_data_cache_local(void *); /* flushes local data-cache only */ -+extern void flush_instruction_cache_local(void *); /* flushes local code-cache only */ - #ifdef CONFIG_SMP - extern void flush_data_cache(void); /* flushes data-cache only (all processors) */ - extern void flush_instruction_cache(void); /* flushes i-cache only (all processors) */ - #else --#define flush_data_cache flush_data_cache_local --#define flush_instruction_cache flush_instruction_cache_local -+#define flush_data_cache() flush_data_cache_local(NULL) -+#define flush_instruction_cache() flush_instruction_cache_local(NULL) - #endif - - extern void parisc_cache_init(void); /* initializes cache-flushing */ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/io.h CVS2_6_15_RC7_PA0/include/asm-parisc/io.h ---- LINUS_2_6_15_RC7/include/asm-parisc/io.h 2005-12-27 13:25:54.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-parisc/io.h 2005-12-23 19:01:55.000000000 -0700 -@@ -41,7 +41,7 @@ - #define __raw_check_addr(addr) \ - if (((unsigned long)addr >> NYBBLE_SHIFT) != 0xe) \ - __raw_bad_addr(addr); \ -- addr = (void *)((unsigned long)addr | (0xfUL << NYBBLE_SHIFT)); -+ addr = (void __iomem *)((unsigned long)addr | (0xfUL << NYBBLE_SHIFT)); - #else - #define gsc_check_addr(addr) - #define __raw_check_addr(addr) -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/page.h CVS2_6_15_RC7_PA0/include/asm-parisc/page.h ---- LINUS_2_6_15_RC7/include/asm-parisc/page.h 2005-12-27 13:25:54.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-parisc/page.h 2005-12-12 14:28:25.000000000 -0700 -@@ -135,6 +135,13 @@ - #define pfn_valid(pfn) ((pfn) < max_mapnr) - #endif /* CONFIG_DISCONTIGMEM */ - -+#ifdef CONFIG_HUGETLB_PAGE -+#define HPAGE_SHIFT 22 /* 4MB (is this fixed?) */ -+#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) -+#define HPAGE_MASK (~(HPAGE_SIZE - 1)) -+#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) -+#endif -+ - #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) - - #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/pci.h CVS2_6_15_RC7_PA0/include/asm-parisc/pci.h ---- LINUS_2_6_15_RC7/include/asm-parisc/pci.h 2005-12-27 13:25:54.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-parisc/pci.h 2005-12-15 12:34:46.000000000 -0700 -@@ -84,11 +84,17 @@ - /* - ** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses. - ** See pcibios.c for more conversions used by Generic PCI code. -+** -+** Platform characteristics/firmware guarantee that -+** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO -+** (2) PA_VIEW == IO_VIEW for GMMIO - */ - #define PCI_BUS_ADDR(hba,a) (PCI_IS_LMMIO(hba,a) \ - ? ((a) - hba->lmmio_space_offset) /* mangle LMMIO */ \ - : (a)) /* GMMIO */ --#define PCI_HOST_ADDR(hba,a) ((a) + hba->lmmio_space_offset) -+#define PCI_HOST_ADDR(hba,a) (((a) & PCI_F_EXTEND) == 0 \ -+ ? (a) + hba->lmmio_space_offset \ -+ : (a)) - - #else /* !CONFIG_64BIT */ - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/processor.h CVS2_6_15_RC7_PA0/include/asm-parisc/processor.h ---- LINUS_2_6_15_RC7/include/asm-parisc/processor.h 2005-12-27 13:25:54.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-parisc/processor.h 2005-12-23 19:03:24.000000000 -0700 -@@ -144,16 +144,16 @@ - }) - - #define INIT_THREAD { \ -- regs: { gr: { 0, }, \ -- fr: { 0, }, \ -- sr: { 0, }, \ -- iasq: { 0, }, \ -- iaoq: { 0, }, \ -- cr27: 0, \ -+ .regs = { .gr = { 0, }, \ -+ .fr = { 0, }, \ -+ .sr = { 0, }, \ -+ .iasq = { 0, }, \ -+ .iaoq = { 0, }, \ -+ .cr27 = 0, \ - }, \ -- task_size: DEFAULT_TASK_SIZE, \ -- map_base: DEFAULT_MAP_BASE, \ -- flags: 0 \ -+ .task_size = DEFAULT_TASK_SIZE, \ -+ .map_base = DEFAULT_MAP_BASE, \ -+ .flags = 0 \ - } - - /* -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/tlbflush.h CVS2_6_15_RC7_PA0/include/asm-parisc/tlbflush.h ---- LINUS_2_6_15_RC7/include/asm-parisc/tlbflush.h 2005-12-27 13:25:54.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-parisc/tlbflush.h 2005-12-15 11:12:46.000000000 -0700 -@@ -22,6 +22,7 @@ - #define purge_tlb_end(x) spin_unlock(&pa_tlb_lock) - - extern void flush_tlb_all(void); -+extern void flush_tlb_all_local(void *); - - /* - * flush_tlb_mm() -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-s390/compat.h CVS2_6_15_RC7_PA0/include/asm-s390/compat.h ---- LINUS_2_6_15_RC7/include/asm-s390/compat.h 2005-12-27 13:25:54.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-s390/compat.h 2005-09-14 06:57:44.000000000 -0600 -@@ -15,6 +15,9 @@ - typedef s32 compat_pid_t; - typedef u16 __compat_uid_t; - typedef u16 __compat_gid_t; -+/* Define for use in compat_siginfo_t */ -+#undef __ARCH_SI_COMPAT_UID_T -+#define __ARCH_SI_COMPAT_UID_T __compat_uid32_t - typedef u32 __compat_uid32_t; - typedef u32 __compat_gid32_t; - typedef u16 compat_mode_t; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-sparc64/compat.h CVS2_6_15_RC7_PA0/include/asm-sparc64/compat.h ---- LINUS_2_6_15_RC7/include/asm-sparc64/compat.h 2005-12-27 13:25:54.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-sparc64/compat.h 2005-09-14 06:57:45.000000000 -0600 -@@ -14,6 +14,9 @@ - typedef s32 compat_pid_t; - typedef u16 __compat_uid_t; - typedef u16 __compat_gid_t; -+/* Define for use in the compat_siginfo_t */ -+#undef __ARCH_SI_COMPAT_UID_T -+#define __ARCH_SI_COMPAT_UID_T compat_uint_t - typedef u32 __compat_uid32_t; - typedef u32 __compat_gid32_t; - typedef u16 compat_mode_t; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-x86_64/compat.h CVS2_6_15_RC7_PA0/include/asm-x86_64/compat.h ---- LINUS_2_6_15_RC7/include/asm-x86_64/compat.h 2005-12-27 13:25:55.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-x86_64/compat.h 2005-11-12 20:29:21.000000000 -0700 -@@ -16,6 +16,9 @@ - typedef s32 compat_pid_t; - typedef u16 __compat_uid_t; - typedef u16 __compat_gid_t; -+/* Define for use in compat_siginfo_t */ -+#undef __ARCH_SI_COMPAT_UID_T -+#define __ARCH_SI_COMPAT_UID_T __compat_uid32_t - typedef u32 __compat_uid32_t; - typedef u32 __compat_gid32_t; - typedef u16 compat_mode_t; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-x86_64/ia32.h CVS2_6_15_RC7_PA0/include/asm-x86_64/ia32.h ---- LINUS_2_6_15_RC7/include/asm-x86_64/ia32.h 2005-12-27 13:25:55.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/asm-x86_64/ia32.h 2005-11-19 22:09:34.000000000 -0700 -@@ -6,6 +6,7 @@ - #ifdef CONFIG_IA32_EMULATION - - #include -+#include - - /* - * 32 bit structures for IA32 support. -@@ -78,58 +79,6 @@ - unsigned long long st_ino; - } __attribute__((packed)); - --typedef struct compat_siginfo{ -- int si_signo; -- int si_errno; -- int si_code; -- -- union { -- int _pad[((128/sizeof(int)) - 3)]; -- -- /* kill() */ -- struct { -- unsigned int _pid; /* sender's pid */ -- unsigned int _uid; /* sender's uid */ -- } _kill; -- -- /* POSIX.1b timers */ -- struct { -- compat_timer_t _tid; /* timer id */ -- int _overrun; /* overrun count */ -- compat_sigval_t _sigval; /* same as below */ -- int _sys_private; /* not to be passed to user */ -- int _overrun_incr; /* amount to add to overrun */ -- } _timer; -- -- /* POSIX.1b signals */ -- struct { -- unsigned int _pid; /* sender's pid */ -- unsigned int _uid; /* sender's uid */ -- compat_sigval_t _sigval; -- } _rt; -- -- /* SIGCHLD */ -- struct { -- unsigned int _pid; /* which child */ -- unsigned int _uid; /* sender's uid */ -- int _status; /* exit code */ -- compat_clock_t _utime; -- compat_clock_t _stime; -- } _sigchld; -- -- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ -- struct { -- unsigned int _addr; /* faulting insn/memory ref. */ -- } _sigfault; -- -- /* SIGPOLL */ -- struct { -- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ -- int _fd; -- } _sigpoll; -- } _sifields; --} compat_siginfo_t; -- - struct sigframe32 - { - u32 pretcode; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/linux/cache.h CVS2_6_15_RC7_PA0/include/linux/cache.h ---- LINUS_2_6_15_RC7/include/linux/cache.h 2005-12-27 13:25:55.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/linux/cache.h 2005-12-19 05:42:41.000000000 -0700 -@@ -13,7 +13,7 @@ - #define SMP_CACHE_BYTES L1_CACHE_BYTES - #endif - --#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_IA64) -+#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC) - #define __read_mostly __attribute__((__section__(".data.read_mostly"))) - #else - #define __read_mostly -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/linux/compat.h CVS2_6_15_RC7_PA0/include/linux/compat.h ---- LINUS_2_6_15_RC7/include/linux/compat.h 2005-12-27 13:25:55.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/linux/compat.h 2005-09-14 06:57:49.000000000 -0600 -@@ -6,10 +6,16 @@ - */ - #include - --#ifdef CONFIG_COMPAT -+#ifndef CONFIG_COMPAT -+ -+/* Non-native task requiring compat... doesn't exist */ -+#define is_compat_task(x) 0 -+ -+#else - - #include - #include /* for HZ */ -+#include /* Conditional process compat */ - #include - - #include -@@ -18,6 +24,11 @@ - #define compat_jiffies_to_clock_t(x) \ - (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) - -+/* Non-native task requiring compat */ -+#ifndef HAVE_ARCH_IS_COMPAT_TASK -+#define is_compat_task(x) (personality(x->personality) == PER_LINUX32) -+#endif -+ - typedef __compat_uid32_t compat_uid_t; - typedef __compat_gid32_t compat_gid_t; - -@@ -99,28 +110,6 @@ - char d_name[256]; - }; - --typedef union compat_sigval { -- compat_int_t sival_int; -- compat_uptr_t sival_ptr; --} compat_sigval_t; -- --#define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) -- --typedef struct compat_sigevent { -- compat_sigval_t sigev_value; -- compat_int_t sigev_signo; -- compat_int_t sigev_notify; -- union { -- compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE]; -- compat_int_t _tid; -- -- struct { -- compat_uptr_t _function; -- compat_uptr_t _attribute; -- } _sigev_thread; -- } _sigev_un; --} compat_sigevent_t; -- - - long compat_sys_semctl(int first, int second, int third, void __user *uptr); - long compat_sys_msgsnd(int first, int second, int third, void __user *uptr); -@@ -156,10 +145,6 @@ - unsigned long bitmap_size); - long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, - unsigned long bitmap_size); --int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from); --int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from); --int get_compat_sigevent(struct sigevent *event, -- const struct compat_sigevent __user *u_event); - - #endif /* CONFIG_COMPAT */ - #endif /* _LINUX_COMPAT_H */ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/linux/compat_siginfo.h CVS2_6_15_RC7_PA0/include/linux/compat_siginfo.h ---- LINUS_2_6_15_RC7/include/linux/compat_siginfo.h 1969-12-31 17:00:00.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/linux/compat_siginfo.h 2005-08-02 08:33:30.000000000 -0600 -@@ -0,0 +1,182 @@ -+#ifndef _ASM_GENERIC_COMPAT_SIGINFO_H -+#define _ASM_GENERIC_COMPAT_SIGINFO_H -+ -+#include -+#include -+ -+#ifndef CONFIG_COMPAT -+ -+/* No compatibility layer required, add empty definitions for the compiler */ -+ -+typedef struct compat_siginfo{ -+} compat_siginfo_t; -+ -+static inline int compat_copy_siginfo_to_user(compat_siginfo_t __user *to, -+ struct siginfo *from) -+{ -+ return -1; -+} -+ -+static inline int compat_copy_siginfo_from_user(struct siginfo *to, -+ compat_siginfo_t __user *from) -+{ -+ return -1; -+} -+ -+#else -+ -+#include -+#include -+ -+/* compat view of sigval_t */ -+typedef union compat_sigval { -+ compat_int_t sival_int; -+ compat_uptr_t sival_ptr; -+} compat_sigval_t; -+ -+/* -+ * This is the size (including padding) of the part of the -+ * struct siginfo that is before the union. -+ */ -+#ifndef __ARCH_SI_COMPAT_PREAMBLE_SIZE -+#define __ARCH_SI_COMPAT_PREAMBLE_SIZE (3 * sizeof(compat_int_t)) -+#endif -+ -+#define SI_COMPAT_MAX_SIZE 128 -+#ifndef SI_COMPAT_PAD_SIZE -+#define SI_COMPAT_PAD_SIZE \ -+ ((SI_COMPAT_MAX_SIZE - __ARCH_SI_COMPAT_PREAMBLE_SIZE) / sizeof(compat_int_t)) -+#endif -+ -+/* 32-bit view of si.uid_t */ -+#ifndef __ARCH_SI_COMPAT_UID_T -+#define __ARCH_SI_COMPAT_UID_T compat_uid_t -+#endif -+ -+/* 32-bit view of si.band_t */ -+#ifndef __ARCH_SI_COMPAT_BAND_T -+#define __ARCH_SI_COMPAT_BAND_T compat_int_t -+#endif -+ -+#ifndef HAVE_ARCH_COMPAT_SIGINFO_T -+ -+/* Compat view of siginfo_t */ -+typedef struct compat_siginfo { -+ compat_int_t si_signo; -+ compat_int_t si_errno; -+ compat_int_t si_code; -+ -+ union { -+ compat_int_t _pad[SI_COMPAT_PAD_SIZE]; -+ -+ /* kill() */ -+ struct { -+ compat_pid_t _pid; /* sender's pid */ -+ __ARCH_SI_COMPAT_UID_T _uid; /* sender's uid */ -+ } _kill; -+ -+ /* POSIX.1b timers */ -+ struct { -+ compat_timer_t _tid; /* timer id */ -+ compat_int_t _overrun; /* overrun count */ -+ char _pad[sizeof(__ARCH_SI_COMPAT_UID_T) - sizeof(compat_int_t)]; -+ compat_sigval_t _sigval; /* same as below */ -+ compat_int_t _sys_private; /* not to be passed to user */ -+ } _timer; -+ -+ /* POSIX.1b signals */ -+ struct { -+ compat_pid_t _pid; /* sender's pid */ -+ __ARCH_SI_COMPAT_UID_T _uid; /* sender's uid */ -+ compat_sigval_t _sigval; -+ } _rt; -+ -+ /* SIGCHLD */ -+ struct { -+ compat_pid_t _pid; /* which child */ -+ __ARCH_SI_COMPAT_UID_T _uid; /* sender's uid */ -+ compat_int_t _status; /* exit code */ -+ compat_clock_t _utime; -+ compat_clock_t _stime; -+ } _sigchld; -+ -+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ -+ struct { -+ compat_uptr_t _addr; /* faulting insn/memory ref. */ -+#ifdef __ARCH_SI_COMPAT_TRAPNO -+ compat_int_t _trapno; /* TRAP # which caused the signal */ -+#endif -+ } _sigfault; -+ -+ /* SIGPOLL */ -+ struct { -+ __ARCH_SI_COMPAT_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ -+ compat_int_t _fd; -+ } _sigpoll; -+ } _sifields; -+} compat_siginfo_t; -+#endif /* !HAVE_ARCH_COMPAT_SIGINFO_T */ -+ -+#ifdef __ARCH_SI_COMPAT_TRAPNO -+#define si_trapno _sifields._sigfault._trapno -+#endif -+ -+/* -+ * sigevent definitions -+ * -+ * It seems likely that SIGEV_THREAD will have to be handled from -+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the -+ * thread manager then catches and does the appropriate nonsense. -+ * However, everything is written out here so as to not get lost. -+ */ -+ -+#ifndef __ARCH_SIGEV_COMPAT_PREAMBLE_SIZE -+#define __ARCH_SIGEV_COMPAT_PREAMBLE_SIZE (sizeof(compat_int_t) * 2 + sizeof(compat_sigval_t)) -+#endif -+ -+#define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) -+ -+#ifndef HAVE_ARCH_COMPAT_SIGEVENT_T -+ -+/* 32-bit view of sigevent_t */ -+typedef struct compat_sigevent { -+ compat_sigval_t sigev_value; -+ compat_int_t sigev_signo; -+ compat_int_t sigev_notify; -+ union { -+ compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE]; -+ compat_int_t _tid; -+ -+ struct { -+ compat_uptr_t _function; -+ compat_uptr_t _attribute; /* really pthread_attr_t */ -+ } _sigev_thread; -+ } _sigev_un; -+} compat_sigevent_t; -+ -+#endif /* HAVE_ARCH_COMPAT_SIGEVENT_T */ -+ -+#ifndef HAVE_ARCH_COMPAT_COPY_SIGINFO -+ -+#include -+ -+static inline void compat_copy_siginfo(struct compat_siginfo *to, struct compat_siginfo *from) -+{ -+ if (from->si_code < 0) -+ memcpy(to, from, sizeof(*to)); -+ else -+ /* _sigchld is currently the largest know union member */ -+ memcpy(to, from, __ARCH_SI_COMPAT_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld)); -+} -+ -+#endif /* !HAVE_ARCH_COMPAT_COPY_SIGINFO */ -+ -+extern int compat_copy_siginfo_to_user(compat_siginfo_t __user *to, struct siginfo *from); -+extern int compat_copy_siginfo_from_user(struct siginfo *to, compat_siginfo_t __user *from); -+ -+extern int compat_copy_sigevent_from_user(struct sigevent *to, compat_sigevent_t __user *from); -+extern int compat_copy_sigevent_to_user(compat_sigevent_t __user *to, struct sigevent *from); -+ -+#endif /* CONFIG_COMPAT */ -+#endif /* _ASM_GENERIC_COMPAT_SIGINFO_H */ -+ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/linux/signal.h CVS2_6_15_RC7_PA0/include/linux/signal.h ---- LINUS_2_6_15_RC7/include/linux/signal.h 2005-12-27 13:25:55.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/linux/signal.h 2005-11-11 21:09:17.000000000 -0700 -@@ -233,6 +233,9 @@ - struct pt_regs; - extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); - -+int copy_siginfo_from_user(siginfo_t *to, siginfo_t __user *from); -+int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from); -+ - #endif /* __KERNEL__ */ - - #endif /* _LINUX_SIGNAL_H */ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/sound/opl3.h CVS2_6_15_RC7_PA0/include/sound/opl3.h ---- LINUS_2_6_15_RC7/include/sound/opl3.h 2005-12-27 13:25:56.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/include/sound/opl3.h 2005-09-13 18:31:04.000000000 -0600 -@@ -261,10 +261,11 @@ - } snd_opl3_voice_t; - - struct snd_opl3 { -- unsigned long l_port; -- unsigned long r_port; -+ void __iomem *l_port; -+ void __iomem *r_port; - struct resource *res_l_port; - struct resource *res_r_port; -+ int unmap_on_free; - unsigned short hardware; - /* hardware access */ - void (*command) (opl3_t * opl3, unsigned short cmd, unsigned char val); -@@ -319,6 +320,9 @@ - void snd_opl3_interrupt(snd_hwdep_t * hw); - int snd_opl3_new(snd_card_t *card, unsigned short hardware, opl3_t **ropl3); - int snd_opl3_init(opl3_t *opl3); -+int snd_opl3_create_mapped(snd_card_t * card, -+ void __iomem * l_port, void __iomem * r_port, -+ unsigned short hardware, opl3_t ** opl3); - int snd_opl3_create(snd_card_t * card, - unsigned long l_port, unsigned long r_port, - unsigned short hardware, -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/ipc/compat_mq.c CVS2_6_15_RC7_PA0/ipc/compat_mq.c ---- LINUS_2_6_15_RC7/ipc/compat_mq.c 2005-12-27 13:25:57.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/ipc/compat_mq.c 2005-03-18 06:17:54.000000000 -0700 -@@ -7,6 +7,7 @@ - */ - - #include -+#include - #include - #include - #include -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/Makefile CVS2_6_15_RC7_PA0/kernel/Makefile ---- LINUS_2_6_15_RC7/kernel/Makefile 2005-12-27 13:25:57.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/kernel/Makefile 2005-11-11 21:09:26.000000000 -0700 -@@ -19,7 +19,7 @@ - obj-$(CONFIG_PM) += power/ - obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o - obj-$(CONFIG_KEXEC) += kexec.o --obj-$(CONFIG_COMPAT) += compat.o -+obj-$(CONFIG_COMPAT) += compat.o compat_signal.o - obj-$(CONFIG_CPUSETS) += cpuset.o - obj-$(CONFIG_IKCONFIG) += configs.o - obj-$(CONFIG_STOP_MACHINE) += stop_machine.o -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/compat.c CVS2_6_15_RC7_PA0/kernel/compat.c ---- LINUS_2_6_15_RC7/kernel/compat.c 2005-12-27 13:25:57.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/kernel/compat.c 2005-09-14 06:57:58.000000000 -0600 -@@ -13,6 +13,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -439,7 +440,11 @@ - - BUG_ON(info.si_code & __SI_MASK); - info.si_code |= __SI_CHLD; -- return copy_siginfo_to_user32(uinfo, &info); -+ -+ if (compat_copy_siginfo_to_user(uinfo, &info) != 0) -+ return -EFAULT; -+ -+ return 0; - } - - static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr, -@@ -651,6 +656,44 @@ - - /* timer_create is architecture specific because it needs sigevent conversion */ - -+long compat_sys_timer_create(clockid_t which_clock, -+ compat_sigevent_t __user *timer_event_spec, -+ compat_timer_t __user * created_timer_id) -+{ -+ sigevent_t kevent; -+ timer_t ktimer; -+ mm_segment_t old_fs = get_fs(); -+ long ret; -+ -+ /* sigevent_t needs handling for 32-bit to 64-bit compat */ -+ if (timer_event_spec != NULL) -+ if (compat_copy_sigevent_from_user(&kevent, timer_event_spec) != 0) -+ return -EFAULT; -+ -+ /* Timer ID is assumed to be a non-struct simple value */ -+ if (created_timer_id != NULL) -+ if (__get_user(ktimer, created_timer_id) != 0) -+ return -EFAULT; -+ -+ set_fs(KERNEL_DS); -+ ret = sys_timer_create(which_clock, -+ timer_event_spec ? (sigevent_t __user *)&kevent : NULL, -+ created_timer_id ? (timer_t __user *)&ktimer : NULL); -+ set_fs(old_fs); -+ -+ /* Copy back the results to userspace */ -+ if (timer_event_spec != NULL) -+ if (compat_copy_sigevent_to_user(timer_event_spec, &kevent) != 0) -+ return -EFAULT; -+ -+ if (created_timer_id != NULL) -+ if (__put_user(ktimer, created_timer_id) != 0) -+ return -EFAULT; -+ -+ return ret; -+} -+ -+ - long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask, - unsigned long bitmap_size) - { -@@ -807,7 +850,7 @@ - if (sig) { - ret = sig; - if (uinfo) { -- if (copy_siginfo_to_user32(uinfo, &info)) -+ if (compat_copy_siginfo_to_user(uinfo, &info)) - ret = -EFAULT; - } - }else { -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/compat_signal.c CVS2_6_15_RC7_PA0/kernel/compat_signal.c ---- LINUS_2_6_15_RC7/kernel/compat_signal.c 1969-12-31 17:00:00.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/kernel/compat_signal.c 2005-08-02 10:22:04.000000000 -0600 -@@ -0,0 +1,280 @@ -+/* -+ * Copyright (C) 2003 Carlos O'Donell -+ * -+ * 2003-12-20 Carlos O'Donell -+ * Copied linux/kernel/compat_signal.c (copy_siginfo_to_user) -+ * and modified to use compat_siginfo_t for thunking down to -+ * 32-bit userspace from a 64-bit kernel. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or (at -+ * your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or -+ * NON INFRINGEMENT. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#ifndef HAVE_ARCH_COMPAT_COPY_SIGINFO_TO_USER -+int compat_copy_siginfo_to_user(compat_siginfo_t __user *to, siginfo_t *from) -+{ -+ int err; -+ compat_siginfo_t compat_from; -+ -+ if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t))) -+ return -EFAULT; -+ -+ /* -+ * If you change compat_siginfo_t structure *or* siginfo_t, -+ * please be sure this code is fixed accordingly. -+ * It should never copy any pad contained in the structure -+ * to avoid security leaks, but must copy the generic -+ * 3 ints plus the relevant union member. -+ */ -+ -+ /* Convert structure, don't leak anything in the copy */ -+ memset(&compat_from,'\0',sizeof(compat_siginfo_t)); -+ -+ /* Always copy si_signo, si_errno, and si_code */ -+ compat_from.si_signo = (compat_int_t)(from->si_signo); -+ compat_from.si_errno = (compat_int_t)(from->si_errno); -+ /* si_code is only a (short) value, remove kernel bits. */ -+ compat_from.si_code = (short)(from->si_code); -+ -+ err = __put_user(compat_from.si_signo, &to->si_signo); -+ err |= __put_user(compat_from.si_errno, &to->si_errno); -+ err |= __put_user(compat_from.si_code, &to->si_code); -+ -+ /* siginfo_t came from userspace, so it is the right -+ * size, no need for conversion -+ */ -+ if (from->si_code < 0) { -+ return __copy_to_user(&to->_sifields._pad, -+ &from->_sifields._pad, -+ SI_COMPAT_PAD_SIZE) -+ ? -EFAULT : 0; -+ } -+ -+ switch (from->si_code & __SI_MASK) { -+ case __SI_KILL: -+ compat_from.si_pid = (compat_pid_t)(from->si_pid); -+ compat_from.si_uid = (__ARCH_SI_COMPAT_UID_T)(from->si_uid); -+ err |= __put_user(compat_from.si_pid, &to->si_pid); -+ err |= __put_user(compat_from.si_uid, &to->si_uid); -+ break; -+ case __SI_TIMER: -+ compat_from.si_pid = (compat_timer_t)(from->si_tid); -+ compat_from.si_overrun = (compat_int_t)(from->si_overrun); -+ compat_from.si_ptr = (compat_uptr_t)((u64 __force)(from->si_ptr) & 0xffffffffUL); -+ err |= __put_user(compat_from.si_tid, &to->si_tid); -+ err |= __put_user(compat_from.si_overrun, &to->si_overrun); -+ err |= __put_user(compat_from.si_ptr, &to->si_ptr); -+ break; -+ case __SI_POLL: -+ compat_from.si_band = (__ARCH_SI_COMPAT_BAND_T)(from->si_band); -+ compat_from.si_fd = (compat_int_t)(from->si_fd); -+ err |= __put_user(compat_from.si_band, &to->si_band); -+ err |= __put_user(compat_from.si_fd, &to->si_fd); -+ break; -+ case __SI_FAULT: -+ compat_from.si_addr = (compat_uptr_t)((u64 __force)(from->si_addr) & 0xffffffffUL); -+ err |= __put_user(compat_from.si_addr, &to->si_addr); -+#ifdef __ARCH_SI_COMPAT_TRAPNO -+ compat_from.si_trapno = (compat_int_t)(from->si_addr); -+ err |= __put_user(compat_from.si_trapno, &to->si_trapno); -+#endif -+ break; -+ case __SI_CHLD: -+ compat_from.si_pid = (compat_pid_t)(from->si_pid); -+ compat_from.si_uid = (__ARCH_SI_COMPAT_UID_T)(from->si_uid); -+ compat_from.si_status = (compat_int_t)(from->si_status); -+ compat_from.si_utime = (compat_clock_t)(from->si_utime); -+ compat_from.si_stime = (compat_clock_t)(from->si_stime); -+ err |= __put_user(compat_from.si_pid, &to->si_pid); -+ err |= __put_user(compat_from.si_uid, &to->si_uid); -+ err |= __put_user(compat_from.si_status, &to->si_status); -+ err |= __put_user(compat_from.si_utime, &to->si_utime); -+ err |= __put_user(compat_from.si_stime, &to->si_stime); -+ break; -+ case __SI_RT: /* This is not generated by the kernel as of now. */ -+ case __SI_MESGQ: /* But this is */ -+ compat_from.si_pid = (compat_pid_t)(from->si_pid); -+ compat_from.si_uid = (__ARCH_SI_COMPAT_UID_T)(from->si_uid); -+ compat_from.si_int = (compat_int_t)(from->si_int); -+ compat_from.si_ptr = (compat_uptr_t)((u64 __force)(from->si_ptr) & 0xffffffffUL); -+ err |= __put_user(compat_from.si_pid, &to->si_pid); -+ err |= __put_user(compat_from.si_uid, &to->si_uid); -+ err |= __put_user(compat_from.si_int, &to->si_int); -+ err |= __put_user(compat_from.si_ptr, &to->si_ptr); -+ break; -+ default: /* this is just in case for now ... */ -+ compat_from.si_pid = (compat_pid_t)(from->si_pid); -+ compat_from.si_uid = (__ARCH_SI_COMPAT_UID_T)(from->si_uid); -+ err |= __put_user(compat_from.si_pid, &to->si_pid); -+ err |= __put_user(compat_from.si_uid, &to->si_uid); -+ break; -+ } -+ return err; -+} -+#endif -+ -+#ifndef HAVE_ARCH_COPY_SIGINFO_FROM_USER -+int compat_copy_siginfo_from_user(siginfo_t *to, compat_siginfo_t __user *from) -+{ -+ int err; -+ u64 scratch; -+ -+ if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t))) -+ return -EFAULT; -+ -+ /* -+ * If you change compat_siginfo_t structure *or* siginfo_t, -+ * please be sure this code is fixed accordingly. -+ */ -+ -+ /* Always copy si_signo, si_errno, and si_code */ -+ err = __get_user(to->si_signo, &from->si_signo); -+ err |= __get_user(to->si_errno, &from->si_errno); -+ err |= __get_user(to->si_code, &from->si_code); -+ -+ /* siginfo_t came from userspace, so it is the right -+ * size, no need for conversion -+ */ -+ if (to->si_code < 0) { -+ return __copy_from_user(&to->_sifields._pad, -+ &from->_sifields._pad, -+ SI_COMPAT_PAD_SIZE) -+ ? -EFAULT : 0; -+ } -+ -+ switch (to->si_code & __SI_MASK) { -+ case __SI_KILL: -+ err |= __get_user(to->si_pid, &from->si_pid); -+ err |= __get_user(to->si_uid, &from->si_uid); -+ break; -+ case __SI_TIMER: -+ err |= __get_user(to->si_tid, &from->si_tid); -+ err |= __get_user(to->si_overrun, &from->si_overrun); -+ err |= __get_user(scratch, &from->si_ptr); -+ to->si_ptr = (u64 __user*)scratch; -+ break; -+ case __SI_POLL: -+ err |= __get_user(to->si_band, &from->si_band); -+ err |= __get_user(to->si_fd, &from->si_fd); -+ break; -+ case __SI_FAULT: -+ err |= __get_user(scratch, &from->si_addr); -+ to->si_addr = (u64 __user*)scratch; -+#ifdef __ARCH_SI_COMPAT_TRAPNO -+ err |= __get_user(to->si_trapno, &from->si_trapno); -+#endif -+ break; -+ case __SI_CHLD: -+ err |= __get_user(to->si_pid, &from->si_pid); -+ err |= __get_user(to->si_uid, &from->si_uid); -+ err |= __get_user(to->si_status, &from->si_status); -+ err |= __get_user(to->si_utime, &from->si_utime); -+ err |= __get_user(to->si_stime, &from->si_stime); -+ break; -+ case __SI_RT: /* This is not generated by the kernel as of now. */ -+ case __SI_MESGQ: /* But this is */ -+ err |= __get_user(to->si_pid, &from->si_pid); -+ err |= __get_user(to->si_uid, &from->si_uid); -+ err |= __get_user(to->si_int, &from->si_int); -+ err |= __get_user(scratch, &from->si_ptr); -+ to->si_ptr = (u64 __user*)scratch; -+ break; -+ default: /* this is just in case for now ... */ -+ err |= __get_user(to->si_pid, &from->si_pid); -+ err |= __get_user(to->si_uid, &from->si_uid); -+ break; -+ } -+ return err; -+} -+#endif -+ -+#ifndef HAVE_ARCH_COPY_SIGEVENT_FROM_USER -+int compat_copy_sigevent_from_user(sigevent_t *to, compat_sigevent_t __user *from) -+{ -+ int err; -+ u64 scratch; -+ -+ /* copy sigval_t sigev_value -+ int_t sival_int (same) -+ uptr_t sival_ptr (32 vs 64)*/ -+ err = __get_user(to->sigev_value.sival_int, -+ &from->sigev_value.sival_int); -+ err |= __get_user(scratch, &from->sigev_value.sival_ptr); -+ to->sigev_value.sival_ptr = (u64 __user *)scratch; -+ -+ /* copy int_t sigev_signo (same)*/ -+ err |= __get_user(to->sigev_signo, &from->sigev_signo); -+ -+ /* copy int_t sigev_notify (same)*/ -+ err |= __get_user(to->sigev_notify, &from->sigev_notify); -+ -+ /* never copy _sigev_un padding */ -+ -+ /* copy int_t _tid (same), -+ good_sigevent() uses this value of */ -+ err |= __get_user(to->sigev_notify_thread_id, &from->sigev_notify_thread_id); -+ -+ /* XXX: Do not copy these, they aren't used by -+ anyone. We would need to distinguish the uses of the union. -+ copy _sigev_thread -+ uptr_t _function (32 vs 64) -+ uptr_t _attribute (32 vs 64)*/ -+ -+ return err; -+} -+#endif -+ -+#ifndef HAVE_ARCH_COPY_SIGEVENT_TO_USER -+int compat_copy_sigevent_to_user(compat_sigevent_t __user *to, sigevent_t *from) -+{ -+ int err; -+ u32 scratch; -+ -+ /* copy sigval_t sigev_value -+ int_t sival_int (same) -+ uptr_t sival_ptr (32 vs 64)*/ -+ err = __put_user(from->sigev_value.sival_int, -+ &to->sigev_value.sival_int); -+ scratch = (u32)((u64 __force)from->sigev_value.sival_ptr & 0xffffffffUL); -+ err |= __put_user((compat_uptr_t)scratch, &to->sigev_value.sival_ptr); -+ -+ /* copy int_t sigev_signo (same)*/ -+ err |= __put_user(from->sigev_signo, &to->sigev_signo); -+ -+ /* copy int_t sigev_notify (same)*/ -+ err |= __put_user(from->sigev_notify, &to->sigev_notify); -+ -+ /* never copy _sigev_un padding */ -+ -+ /* copy int_t _tid (same), -+ good_sigevent() uses this value of */ -+ err |= __put_user(from->sigev_notify_thread_id, &to->sigev_notify_thread_id); -+ -+ /* XXX: Do not copy these, they aren't used by -+ anyone. We would need to distinguish the uses of the union. -+ copy _sigev_thread -+ uptr_t _function (32 vs 64) -+ uptr_t _attribute (32 vs 64)*/ -+ -+ return err; -+} -+#endif -+ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/ptrace.c CVS2_6_15_RC7_PA0/kernel/ptrace.c ---- LINUS_2_6_15_RC7/kernel/ptrace.c 2005-12-27 13:25:57.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/kernel/ptrace.c 2005-12-04 00:25:16.000000000 -0700 -@@ -363,7 +363,7 @@ - siginfo_t newinfo; - int error = -ESRCH; - -- if (copy_from_user(&newinfo, data, sizeof (siginfo_t))) -+ if (copy_siginfo_from_user(&newinfo, data) != 0) - return -EFAULT; - - read_lock(&tasklist_lock); -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/resource.c CVS2_6_15_RC7_PA0/kernel/resource.c ---- LINUS_2_6_15_RC7/kernel/resource.c 2005-12-27 13:25:57.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/kernel/resource.c 2005-09-14 06:57:58.000000000 -0600 -@@ -181,6 +181,8 @@ - { - struct resource *tmp, **p; - -+ BUG_ON(old->child); -+ - p = &old->parent->child; - for (;;) { - tmp = *p; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/signal.c CVS2_6_15_RC7_PA0/kernel/signal.c ---- LINUS_2_6_15_RC7/kernel/signal.c 2005-12-27 13:25:57.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/kernel/signal.c 2005-11-19 22:09:36.000000000 -0700 -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2095,17 +2096,35 @@ - return do_sigpending(set, sigsetsize); - } - -+#ifndef HAVE_ARCH_COPY_SIGINFO_FROM_USER -+ -+int copy_siginfo_from_user(siginfo_t *to, siginfo_t __user *from) -+{ -+ if(is_compat_task(current)) -+ return compat_copy_siginfo_from_user(to,(compat_siginfo_t __user *)from); -+ -+ return copy_from_user(&to, from, sizeof(siginfo_t)); -+} -+ -+#endif -+ - #ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER - - int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) - { - int err; -+ -+ /* Use compat_siginfo_t with 32-bit signals */ -+ if(is_compat_task(current)){ -+ return compat_copy_siginfo_to_user((compat_siginfo_t __user *)to,from); -+ } - - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)) - ? -EFAULT : 0; -+ - /* - * If you change siginfo_t structure, please be sure - * this code is fixed accordingly. -@@ -2321,7 +2340,7 @@ - { - siginfo_t info; - -- if (copy_from_user(&info, uinfo, sizeof(siginfo_t))) -+ if (copy_siginfo_from_user(&info, uinfo)) - return -EFAULT; - - /* Not even root can pretend to send signals from the kernel. -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/mm/shmem.c CVS2_6_15_RC7_PA0/mm/shmem.c ---- LINUS_2_6_15_RC7/mm/shmem.c 2005-12-27 13:25:58.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/mm/shmem.c 2005-11-11 21:09:28.000000000 -0700 -@@ -457,7 +457,7 @@ - } while (next); - } - --static void shmem_truncate(struct inode *inode) -+/* static gcc-3.3 OPD bug - GGG */ void shmem_truncate(struct inode *inode) - { - struct shmem_inode_info *info = SHMEM_I(inode); - unsigned long idx; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/drivers/opl3/opl3_lib.c CVS2_6_15_RC7_PA0/sound/drivers/opl3/opl3_lib.c ---- LINUS_2_6_15_RC7/sound/drivers/opl3/opl3_lib.c 2005-12-27 13:26:01.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/sound/drivers/opl3/opl3_lib.c 2005-11-11 23:00:07.000000000 -0700 -@@ -40,7 +40,7 @@ - static void snd_opl2_command(opl3_t * opl3, unsigned short cmd, unsigned char val) - { - unsigned long flags; -- unsigned long port; -+ void __iomem *port; - - /* - * The original 2-OP synth requires a quite long delay -@@ -51,10 +51,10 @@ - - spin_lock_irqsave(&opl3->reg_lock, flags); - -- outb((unsigned char) cmd, port); -+ iowrite8((unsigned char) cmd, port); - udelay(10); - -- outb((unsigned char) val, port + 1); -+ iowrite8((unsigned char) val, port + 1); - udelay(30); - - spin_unlock_irqrestore(&opl3->reg_lock, flags); -@@ -63,7 +63,7 @@ - static void snd_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val) - { - unsigned long flags; -- unsigned long port; -+ void __iomem *port; - - /* - * The OPL-3 survives with just two INBs -@@ -74,13 +74,13 @@ - - spin_lock_irqsave(&opl3->reg_lock, flags); - -- outb((unsigned char) cmd, port); -- inb(opl3->l_port); -- inb(opl3->l_port); -- -- outb((unsigned char) val, port + 1); -- inb(opl3->l_port); -- inb(opl3->l_port); -+ iowrite8((unsigned char) cmd, port); -+ ioread8(opl3->l_port); -+ ioread8(opl3->l_port); -+ -+ iowrite8((unsigned char) val, port + 1); -+ ioread8(opl3->l_port); -+ ioread8(opl3->l_port); - - spin_unlock_irqrestore(&opl3->reg_lock, flags); - } -@@ -104,7 +104,7 @@ - opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK); - /* Reset the IRQ of the FM chip */ - opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET); -- signature = stat1 = inb(opl3->l_port); /* Status register */ -+ signature = stat1 = ioread8(opl3->l_port); /* Status register */ - if ((stat1 & 0xe0) != 0x00) { /* Should be 0x00 */ - snd_printd("OPL3: stat1 = 0x%x\n", stat1); - return -ENODEV; -@@ -116,7 +116,7 @@ - /* Now we have to delay at least 80us */ - udelay(200); - /* Read status after timers have expired */ -- stat2 = inb(opl3->l_port); -+ stat2 = ioread8(opl3->l_port); - /* Stop the timers */ - opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK); - /* Reset the IRQ of the FM chip */ -@@ -299,7 +299,7 @@ - return; - - opl3 = hw->private_data; -- status = inb(opl3->l_port); -+ status = ioread8(opl3->l_port); - #if 0 - snd_printk("AdLib IRQ status = 0x%x\n", status); - #endif -@@ -327,6 +327,10 @@ - opl3->private_free(opl3); - release_and_free_resource(opl3->res_l_port); - release_and_free_resource(opl3->res_r_port); -+ if (opl3->unmap_on_free) { -+ iounmap(opl3->l_port); -+ iounmap(opl3->r_port); -+ } - kfree(opl3); - return 0; - } -@@ -391,12 +395,14 @@ - return 0; - } - --int snd_opl3_create(snd_card_t * card, -- unsigned long l_port, -- unsigned long r_port, -- unsigned short hardware, -- int integrated, -- opl3_t ** ropl3) -+static int snd_opl3_create_main(snd_card_t * card, -+ void __iomem *l_port, -+ void __iomem *r_port, -+ int unmap_on_free, -+ struct resource *res_l_port, -+ struct resource *res_r_port, -+ unsigned short hardware, -+ opl3_t ** ropl3) - { - opl3_t *opl3; - int err; -@@ -404,21 +410,11 @@ - *ropl3 = NULL; - if ((err = snd_opl3_new(card, hardware, &opl3)) < 0) - return err; -- if (! integrated) { -- if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) { -- snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port); -- snd_device_free(card, opl3); -- return -EBUSY; -- } -- if (r_port != 0 && -- (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) { -- snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port); -- snd_device_free(card, opl3); -- return -EBUSY; -- } -- } - opl3->l_port = l_port; - opl3->r_port = r_port; -+ opl3->unmap_on_free = unmap_on_free; -+ opl3->res_l_port = res_l_port; -+ opl3->res_r_port = res_r_port; - - switch (opl3->hardware) { - /* some hardware doesn't support timers */ -@@ -449,6 +445,61 @@ - return 0; - } - -+int snd_opl3_create_mapped(snd_card_t * card, -+ void __iomem * l_port, -+ void __iomem * r_port, -+ unsigned short hardware, -+ opl3_t ** ropl3) -+{ -+ return snd_opl3_create_main(card, l_port, r_port, 0, NULL, NULL, hardware, ropl3); -+} -+ -+int snd_opl3_create(snd_card_t * card, -+ unsigned long l_port, -+ unsigned long r_port, -+ unsigned short hardware, -+ int integrated, -+ opl3_t ** ropl3) { -+ struct resource *res_l_port = NULL; -+ struct resource *res_r_port = NULL; -+ void __iomem *l_mapped = NULL; -+ void __iomem *r_mapped = NULL; -+ -+ if (! integrated) { -+ if ((res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) { -+ snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port); -+ goto fail; -+ } -+ if (r_port != 0 && -+ (res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) { -+ snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port); -+ goto fail; -+ } -+ } -+ -+ l_mapped = ioport_map(l_port, 2); -+ if (l_mapped == NULL) { -+ snd_printk(KERN_ERR "opl3: failed to map port 0x%lx\n", l_port); -+ goto fail; -+ } -+ r_mapped = ioport_map(r_port, 2); -+ if (r_mapped == NULL) { -+ snd_printk(KERN_ERR "opl3: failed to map port 0x%lx\n", r_port); -+ goto fail; -+ } -+ -+ return snd_opl3_create_main(card, l_mapped, r_mapped, 1, res_l_port, res_r_port, hardware, ropl3); -+ -+fail: -+ release_and_free_resource(res_l_port); -+ release_and_free_resource(res_r_port); -+ if (l_mapped) -+ iounmap(l_mapped); -+ if (r_mapped) -+ iounmap(r_mapped); -+ return -EBUSY; -+} -+ - int snd_opl3_timer_new(opl3_t * opl3, int timer1_dev, int timer2_dev) - { - int err; -@@ -528,6 +579,7 @@ - EXPORT_SYMBOL(snd_opl3_new); - EXPORT_SYMBOL(snd_opl3_init); - EXPORT_SYMBOL(snd_opl3_create); -+EXPORT_SYMBOL(snd_opl3_create_mapped); - EXPORT_SYMBOL(snd_opl3_timer_new); - EXPORT_SYMBOL(snd_opl3_hwdep_new); - -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/oss/ad1889.c CVS2_6_15_RC7_PA0/sound/oss/ad1889.c ---- LINUS_2_6_15_RC7/sound/oss/ad1889.c 2005-12-27 13:26:02.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/sound/oss/ad1889.c 2005-06-30 08:26:47.000000000 -0600 -@@ -74,7 +74,7 @@ - - DBG("Setting WAV rate to %d\n", rate); - dev->state[AD_WAV_STATE].dmabuf.rate = rate; -- AD1889_WRITEW(dev, AD_DSWAS, rate); -+ AD1889_WRITEW(dev, AD_DS_WAS, rate); - - /* Cycle the DAC to enable the new rate */ - ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0200); -@@ -88,14 +88,14 @@ - - DBG("Setting WAV format to 0x%x\n", fmt); - -- tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); -+ tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); - if (fmt & AFMT_S16_LE) { - //tmp |= 0x0100; /* set WA16 */ - tmp |= 0x0300; /* set WA16 stereo */ - } else if (fmt & AFMT_U8) { - tmp &= ~0x0100; /* clear WA16 */ - } -- AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); -+ AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); - } - - static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt) -@@ -104,13 +104,13 @@ - - DBG("Setting ADC format to 0x%x\n", fmt); - -- tmp = AD1889_READW(ad1889_dev, AD_DSRAMC); -+ tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC); - if (fmt & AFMT_S16_LE) { - tmp |= 0x0100; /* set WA16 */ - } else if (fmt & AFMT_U8) { - tmp &= ~0x0100; /* clear WA16 */ - } -- AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp); -+ AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp); - } - - static void ad1889_start_wav(ad1889_state_t *state) -@@ -144,21 +144,21 @@ - dmabuf->rd_ptr, dmabuf->dma_len); - - /* load up the current register set */ -- AD1889_WRITEL(ad1889_dev, AD_DMAWAVCC, cnt); -- AD1889_WRITEL(ad1889_dev, AD_DMAWAVICC, cnt); -- AD1889_WRITEL(ad1889_dev, AD_DMAWAVCA, dmabuf->dma_handle); -+ AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCC, cnt); -+ AD1889_WRITEL(ad1889_dev, AD_DMA_WAVICC, cnt); -+ AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCA, dmabuf->dma_handle); - - /* TODO: for now we load the base registers with the same thing */ -- AD1889_WRITEL(ad1889_dev, AD_DMAWAVBC, cnt); -- AD1889_WRITEL(ad1889_dev, AD_DMAWAVIBC, cnt); -- AD1889_WRITEL(ad1889_dev, AD_DMAWAVBA, dmabuf->dma_handle); -+ AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBC, cnt); -+ AD1889_WRITEL(ad1889_dev, AD_DMA_WAVIBC, cnt); -+ AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBA, dmabuf->dma_handle); - - /* and we're off to the races... */ -- AD1889_WRITEL(ad1889_dev, AD_DMACHSS, 0x8); -- tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); -+ AD1889_WRITEL(ad1889_dev, AD_DMA_CHSS, 0x8); -+ tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); - tmp |= 0x0400; /* set WAEN */ -- AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); -- (void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */ -+ AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); -+ (void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */ - - dmabuf->enable |= DAC_RUNNING; - -@@ -178,10 +178,10 @@ - u16 tmp; - unsigned long cnt = dmabuf->dma_len; - -- tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); -+ tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); - tmp &= ~0x0400; /* clear WAEN */ -- AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); -- (void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */ -+ AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); -+ (void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */ - pci_unmap_single(ad1889_dev->pci, dmabuf->dma_handle, - cnt, PCI_DMA_TODEVICE); - -@@ -210,7 +210,7 @@ - - spin_lock_irqsave(&state->card->lock, flags); - -- tmp = AD1889_READW(ad1889_dev, AD_DSRAMC); -+ tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC); - if (start) { - state->dmabuf.enable |= ADC_RUNNING; - tmp |= 0x0004; /* set ADEN */ -@@ -218,7 +218,7 @@ - state->dmabuf.enable &= ~ADC_RUNNING; - tmp &= ~0x0004; /* clear ADEN */ - } -- AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp); -+ AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp); - - spin_unlock_irqrestore(&state->card->lock, flags); - } -@@ -300,53 +300,53 @@ - int len, i; - ad1889_dev_t *dev = data; - ad1889_reg_t regs[] = { -- { "WSMC", AD_DSWSMC, 16 }, -- { "RAMC", AD_DSRAMC, 16 }, -- { "WADA", AD_DSWADA, 16 }, -- { "SYDA", AD_DSSYDA, 16 }, -- { "WAS", AD_DSWAS, 16 }, -- { "RES", AD_DSRES, 16 }, -- { "CCS", AD_DSCCS, 16 }, -- { "ADCBA", AD_DMAADCBA, 32 }, -- { "ADCCA", AD_DMAADCCA, 32 }, -- { "ADCBC", AD_DMAADCBC, 32 }, -- { "ADCCC", AD_DMAADCCC, 32 }, -- { "ADCIBC", AD_DMAADCIBC, 32 }, -- { "ADCICC", AD_DMAADCICC, 32 }, -- { "ADCCTRL", AD_DMAADCCTRL, 16 }, -- { "WAVBA", AD_DMAWAVBA, 32 }, -- { "WAVCA", AD_DMAWAVCA, 32 }, -- { "WAVBC", AD_DMAWAVBC, 32 }, -- { "WAVCC", AD_DMAWAVCC, 32 }, -- { "WAVIBC", AD_DMAWAVIBC, 32 }, -- { "WAVICC", AD_DMAWAVICC, 32 }, -- { "WAVCTRL", AD_DMAWAVCTRL, 16 }, -- { "DISR", AD_DMADISR, 32 }, -- { "CHSS", AD_DMACHSS, 32 }, -- { "IPC", AD_GPIOIPC, 16 }, -- { "OP", AD_GPIOOP, 16 }, -- { "IP", AD_GPIOIP, 16 }, -- { "ACIC", AD_ACIC, 16 }, -- { "AC97_RESET", 0x100 + AC97_RESET, 16 }, -- { "AC97_MASTER_VOL_STEREO", 0x100 + AC97_MASTER_VOL_STEREO, 16 }, -- { "AC97_HEADPHONE_VOL", 0x100 + AC97_HEADPHONE_VOL, 16 }, -- { "AC97_MASTER_VOL_MONO", 0x100 + AC97_MASTER_VOL_MONO, 16 }, -- { "AC97_MASTER_TONE", 0x100 + AC97_MASTER_TONE, 16 }, -- { "AC97_PCBEEP_VOL", 0x100 + AC97_PCBEEP_VOL, 16 }, -- { "AC97_PHONE_VOL", 0x100 + AC97_PHONE_VOL, 16 }, -- { "AC97_MIC_VOL", 0x100 + AC97_MIC_VOL, 16 }, -- { "AC97_LINEIN_VOL", 0x100 + AC97_LINEIN_VOL, 16 }, -- { "AC97_CD_VOL", 0x100 + AC97_CD_VOL, 16 }, -- { "AC97_VIDEO_VOL", 0x100 + AC97_VIDEO_VOL, 16 }, -- { "AC97_AUX_VOL", 0x100 + AC97_AUX_VOL, 16 }, -- { "AC97_PCMOUT_VOL", 0x100 + AC97_PCMOUT_VOL, 16 }, -- { "AC97_RECORD_SELECT", 0x100 + AC97_RECORD_SELECT, 16 }, -- { "AC97_RECORD_GAIN", 0x100 + AC97_RECORD_GAIN, 16 }, -- { "AC97_RECORD_GAIN_MIC", 0x100 + AC97_RECORD_GAIN_MIC, 16 }, -- { "AC97_GENERAL_PURPOSE", 0x100 + AC97_GENERAL_PURPOSE, 16 }, -- { "AC97_3D_CONTROL", 0x100 + AC97_3D_CONTROL, 16 }, -- { "AC97_MODEM_RATE", 0x100 + AC97_MODEM_RATE, 16 }, -- { "AC97_POWER_CONTROL", 0x100 + AC97_POWER_CONTROL, 16 }, -+ { "WSMC", AD_DS_WSMC, 16 }, -+ { "RAMC", AD_DS_RAMC, 16 }, -+ { "WADA", AD_DS_WADA, 16 }, -+ { "SYDA", AD_DS_SYDA, 16 }, -+ { "WAS", AD_DS_WAS, 16 }, -+ { "RES", AD_DS_RES, 16 }, -+ { "CCS", AD_DS_CCS, 16 }, -+ { "ADCBA", AD_DMA_ADCBA, 32 }, -+ { "ADCCA", AD_DMA_ADCCA, 32 }, -+ { "ADCBC", AD_DMA_ADCBC, 32 }, -+ { "ADCCC", AD_DMA_ADCCC, 32 }, -+ { "ADCIBC", AD_DMA_ADCIBC, 32 }, -+ { "ADCICC", AD_DMA_ADCICC, 32 }, -+ { "ADCCTRL", AD_DMA_ADCCTRL, 16 }, -+ { "WAVBA", AD_DMA_WAVBA, 32 }, -+ { "WAVCA", AD_DMA_WAVCA, 32 }, -+ { "WAVBC", AD_DMA_WAVBC, 32 }, -+ { "WAVCC", AD_DMA_WAVCC, 32 }, -+ { "WAVIBC", AD_DMA_WAVIBC, 32 }, -+ { "WAVICC", AD_DMA_WAVICC, 32 }, -+ { "WAVCTRL", AD_DMA_WAVCTRL, 16 }, -+ { "DISR", AD_DMA_DISR, 32 }, -+ { "CHSS", AD_DMA_CHSS, 32 }, -+ { "IPC", AD_GPIO_IPC, 16 }, -+ { "OP", AD_GPIO_OP, 16 }, -+ { "IP", AD_GPIO_IP, 16 }, -+ { "ACIC", AD_AC97_ACIC, 16 }, -+ { "AC97_RESET", AD_AC97_BASE + AC97_RESET, 16 }, -+ { "AC97_MASTER_VOL_STEREO", AD_AC97_BASE + AC97_MASTER_VOL_STEREO, 16 }, -+ { "AC97_HEADPHONE_VOL", AD_AC97_BASE + AC97_HEADPHONE_VOL, 16 }, -+ { "AC97_MASTER_VOL_MONO", AD_AC97_BASE + AC97_MASTER_VOL_MONO, 16 }, -+ { "AC97_MASTER_TONE", AD_AC97_BASE + AC97_MASTER_TONE, 16 }, -+ { "AC97_PCBEEP_VOL", AD_AC97_BASE + AC97_PCBEEP_VOL, 16 }, -+ { "AC97_PHONE_VOL", AD_AC97_BASE + AC97_PHONE_VOL, 16 }, -+ { "AC97_MIC_VOL", AD_AC97_BASE + AC97_MIC_VOL, 16 }, -+ { "AC97_LINEIN_VOL", AD_AC97_BASE + AC97_LINEIN_VOL, 16 }, -+ { "AC97_CD_VOL", AD_AC97_BASE + AC97_CD_VOL, 16 }, -+ { "AC97_VIDEO_VOL", AD_AC97_BASE + AC97_VIDEO_VOL, 16 }, -+ { "AC97_AUX_VOL", AD_AC97_BASE + AC97_AUX_VOL, 16 }, -+ { "AC97_PCMOUT_VOL", AD_AC97_BASE + AC97_PCMOUT_VOL, 16 }, -+ { "AC97_RECORD_SELECT", AD_AC97_BASE + AC97_RECORD_SELECT, 16 }, -+ { "AC97_RECORD_GAIN", AD_AC97_BASE + AC97_RECORD_GAIN, 16 }, -+ { "AC97_RECORD_GAIN_MIC", AD_AC97_BASE + AC97_RECORD_GAIN_MIC, 16 }, -+ { "AC97_GENERAL_PURPOSE", AD_AC97_BASE + AC97_GENERAL_PURPOSE, 16 }, -+ { "AC97_3D_CONTROL", AD_AC97_BASE + AC97_3D_CONTROL, 16 }, -+ { "AC97_MODEM_RATE", AD_AC97_BASE + AC97_MODEM_RATE, 16 }, -+ { "AC97_POWER_CONTROL", AD_AC97_BASE + AC97_POWER_CONTROL, 16 }, - { NULL } - }; - -@@ -399,9 +399,9 @@ - } - - if (dmabuf->enable & DAC_RUNNING) -- offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAWAVBA)); -+ offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_WAVBA)); - else -- offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAADCBA)); -+ offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_ADCBA)); - - return (unsigned long)bus_to_virt((unsigned long)offset) - (unsigned long)dmabuf->rawbuf; - } -@@ -638,9 +638,9 @@ - if (val > 5400 && val < 48000) - { - if (file->f_mode & FMODE_WRITE) -- AD1889_WRITEW(ad1889_dev, AD_DSWAS, val); -+ AD1889_WRITEW(ad1889_dev, AD_DS_WAS, val); - if (file->f_mode & FMODE_READ) -- AD1889_WRITEW(ad1889_dev, AD_DSRES, val); -+ AD1889_WRITEW(ad1889_dev, AD_DS_RES, val); - } - return 0; - -@@ -648,22 +648,22 @@ - if (get_user(val, p)) - return -EFAULT; - if (file->f_mode & FMODE_READ) { -- val = AD1889_READW(ad1889_dev, AD_DSWSMC); -+ val = AD1889_READW(ad1889_dev, AD_DS_WSMC); - if (val) { - val |= 0x0200; /* set WAST */ - } else { - val &= ~0x0200; /* clear WAST */ - } -- AD1889_WRITEW(ad1889_dev, AD_DSWSMC, val); -+ AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, val); - } - if (file->f_mode & FMODE_WRITE) { -- val = AD1889_READW(ad1889_dev, AD_DSRAMC); -+ val = AD1889_READW(ad1889_dev, AD_DS_RAMC); - if (val) { - val |= 0x0002; /* set ADST */ - } else { - val &= ~0x0002; /* clear ADST */ - } -- AD1889_WRITEW(ad1889_dev, AD_DSRAMC, val); -+ AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, val); - } - - return 0; -@@ -738,7 +738,7 @@ - break; - - case SOUND_PCM_READ_RATE: -- return put_user(AD1889_READW(ad1889_dev, AD_DSWAS), p); -+ return put_user(AD1889_READW(ad1889_dev, AD_DS_WAS), p); - - case SOUND_PCM_READ_CHANNELS: - case SOUND_PCM_READ_BITS: -@@ -768,7 +768,7 @@ - - ad1889_set_wav_rate(ad1889_dev, 48000); - ad1889_set_wav_fmt(ad1889_dev, AFMT_S16_LE); -- AD1889_WRITEW(ad1889_dev, AD_DSWADA, 0x0404); /* attenuation */ -+ AD1889_WRITEW(ad1889_dev, AD_DS_WADA, 0x0404); /* attenuation */ - return nonseekable_open(inode, file); - } - -@@ -825,15 +825,15 @@ - { - ad1889_dev_t *dev = ac97->private_data; - -- //DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + 0x100 + reg); -- AD1889_WRITEW(dev, 0x100 + reg, val); -+ //DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + AD_AC97_BASE + reg); -+ AD1889_WRITEW(dev, AD_AC97_BASE + reg, val); - } - - static u16 ad1889_codec_read(struct ac97_codec *ac97, u8 reg) - { - ad1889_dev_t *dev = ac97->private_data; -- //DBG("Reading from 0x%lx\n", dev->regbase + 0x100 + reg); -- return AD1889_READW(dev, 0x100 + reg); -+ //DBG("Reading from 0x%lx\n", dev->regbase + AD_AC97_BASE + reg); -+ return AD1889_READW(dev, AD_AC97_BASE + reg); - } - - static int ad1889_ac97_init(ad1889_dev_t *dev, int id) -@@ -882,24 +882,24 @@ - int retry = 200; - ad1889_dev_t *dev = pci_get_drvdata(pcidev); - -- AD1889_WRITEW(dev, AD_DSCCS, 0x8000); /* turn on clock */ -- AD1889_READW(dev, AD_DSCCS); -+ AD1889_WRITEW(dev, AD_DS_CCS, 0x8000); /* turn on clock */ -+ AD1889_READW(dev, AD_DS_CCS); - - WAIT_10MS(); - -- stat = AD1889_READW(dev, AD_ACIC); -+ stat = AD1889_READW(dev, AD_AC97_ACIC); - stat |= 0x0002; /* Reset Disable */ -- AD1889_WRITEW(dev, AD_ACIC, stat); -- (void) AD1889_READW(dev, AD_ACIC); /* flush posted write */ -+ AD1889_WRITEW(dev, AD_AC97_ACIC, stat); -+ (void) AD1889_READW(dev, AD_AC97_ACIC); /* flush posted write */ - - udelay(10); - -- stat = AD1889_READW(dev, AD_ACIC); -+ stat = AD1889_READW(dev, AD_AC97_ACIC); - stat |= 0x0001; /* Interface Enable */ -- AD1889_WRITEW(dev, AD_ACIC, stat); -+ AD1889_WRITEW(dev, AD_AC97_ACIC, stat); - - do { -- if (AD1889_READW(dev, AD_ACIC) & 0x8000) /* Ready */ -+ if (AD1889_READW(dev, AD_AC97_ACIC) & 0x8000) /* Ready */ - break; - WAIT_10MS(); - retry--; -@@ -907,16 +907,16 @@ - - if (!retry) { - printk(KERN_ERR "ad1889_aclink_reset: codec is not ready [0x%x]\n", -- AD1889_READW(dev, AD_ACIC)); -+ AD1889_READW(dev, AD_AC97_ACIC)); - return -EBUSY; - } - - /* TODO reset AC97 codec */ - /* TODO set wave/adc pci ctrl status */ - -- stat = AD1889_READW(dev, AD_ACIC); -+ stat = AD1889_READW(dev, AD_AC97_ACIC); - stat |= 0x0004; /* Audio Stream Output Enable */ -- AD1889_WRITEW(dev, AD_ACIC, stat); -+ AD1889_WRITEW(dev, AD_AC97_ACIC, stat); - return 0; - } - -@@ -934,10 +934,10 @@ - u32 stat; - ad1889_dev_t *dev = (ad1889_dev_t *)dev_id; - -- stat = AD1889_READL(dev, AD_DMADISR); -+ stat = AD1889_READL(dev, AD_DMA_DISR); - - /* clear ISR */ -- AD1889_WRITEL(dev, AD_DMADISR, stat); -+ AD1889_WRITEL(dev, AD_DMA_DISR, stat); - - if (stat & 0x8) { /* WAVI */ - DBG("WAV interrupt\n"); -@@ -963,15 +963,15 @@ - u32 tmp32; - - /* make sure the interrupt bits are setup the way we want */ -- tmp32 = AD1889_READL(dev, AD_DMAWAVCTRL); -+ tmp32 = AD1889_READL(dev, AD_DMA_WAVCTRL); - tmp32 &= ~0xff; /* flat dma, no sg, mask out the intr bits */ - tmp32 |= 0x6; /* intr on count, loop */ -- AD1889_WRITEL(dev, AD_DMAWAVCTRL, tmp32); -+ AD1889_WRITEL(dev, AD_DMA_WAVCTRL, tmp32); - - /* unmute... */ -- tmp16 = AD1889_READW(dev, AD_DSWADA); -+ tmp16 = AD1889_READW(dev, AD_DS_WADA); - tmp16 &= ~0x8080; -- AD1889_WRITEW(dev, AD_DSWADA, tmp16); -+ AD1889_WRITEW(dev, AD_DS_WADA, tmp16); - } - - static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) -@@ -1004,7 +1004,7 @@ - goto out1; - } - -- dev->regbase = ioremap_nocache(bar, AD_DSIOMEMSIZE); -+ dev->regbase = ioremap_nocache(bar, AD_DS_IOMEMSIZE); - if (!dev->regbase) { - printk(KERN_ERR DEVNAME ": unable to remap iomem\n"); - goto out2; -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/oss/ad1889.h CVS2_6_15_RC7_PA0/sound/oss/ad1889.h ---- LINUS_2_6_15_RC7/sound/oss/ad1889.h 2005-12-27 13:26:02.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/sound/oss/ad1889.h 2005-03-01 16:00:56.000000000 -0700 -@@ -1,57 +1,58 @@ - #ifndef _AD1889_H_ - #define _AD1889_H_ - --#define AD_DSWSMC 0x00 /* DMA input wave/syn mixer control */ --#define AD_DSRAMC 0x02 /* DMA output resamp/ADC mixer control */ --#define AD_DSWADA 0x04 /* DMA input wave attenuation */ --#define AD_DSSYDA 0x06 /* DMA input syn attentuation */ --#define AD_DSWAS 0x08 /* wave input sample rate */ --#define AD_DSRES 0x0a /* resampler output sample rate */ --#define AD_DSCCS 0x0c /* chip control/status */ -- --#define AD_DMARESBA 0x40 /* RES base addr */ --#define AD_DMARESCA 0x44 /* RES current addr */ --#define AD_DMARESBC 0x48 /* RES base cnt */ --#define AD_DMARESCC 0x4c /* RES current count */ --#define AD_DMAADCBA 0x50 /* ADC */ --#define AD_DMAADCCA 0x54 --#define AD_DMAADCBC 0x58 --#define AD_DMAADCCC 0x5c --#define AD_DMASYNBA 0x60 /* SYN */ --#define AD_DMASYNCA 0x64 --#define AD_DMASYNBC 0x68 --#define AD_DMASYNCC 0x6c --#define AD_DMAWAVBA 0x70 /* WAV */ --#define AD_DMAWAVCA 0x74 --#define AD_DMAWAVBC 0x78 --#define AD_DMAWAVCC 0x7c --#define AD_DMARESICC 0x80 /* RES interrupt current count */ --#define AD_DMARESIBC 0x84 /* RES interrupt base count */ --#define AD_DMAADCICC 0x88 /* ADC interrupt current count */ --#define AD_DMAADCIBC 0x8c /* ADC interrupt base count */ --#define AD_DMASYNICC 0x90 /* SYN interrupt current count */ --#define AD_DMASYNIBC 0x94 /* SYN interrupt base count */ --#define AD_DMAWAVICC 0x98 /* WAV interrupt current count */ --#define AD_DMAWAVIBC 0x9c /* WAV interrupt base count */ --#define AD_DMARESCTRL 0xa0 /* RES PCI control/status */ --#define AD_DMAADCCTRL 0xa8 /* ADC PCI control/status */ --#define AD_DMASYNCTRL 0xb0 /* SYN PCI control/status */ --#define AD_DMAWAVCTRL 0xb8 /* WAV PCI control/status */ --#define AD_DMADISR 0xc0 /* PCI DMA intr status */ --#define AD_DMACHSS 0xc4 /* PCI DMA channel stop status */ -- --#define AD_GPIOIPC 0xc8 /* IO port ctrl */ --#define AD_GPIOOP 0xca /* IO output status */ --#define AD_GPIOIP 0xcc /* IO input status */ -+#define AD_DS_WSMC 0x00 /* DMA input wave/syn mixer control */ -+#define AD_DS_RAMC 0x02 /* DMA output resamp/ADC mixer control */ -+#define AD_DS_WADA 0x04 /* DMA input wave attenuation */ -+#define AD_DS_SYDA 0x06 /* DMA input syn attentuation */ -+#define AD_DS_WAS 0x08 /* wave input sample rate */ -+#define AD_DS_RES 0x0a /* resampler output sample rate */ -+#define AD_DS_CCS 0x0c /* chip control/status */ -+ -+#define AD_DMA_RESBA 0x40 /* RES base addr */ -+#define AD_DMA_RESCA 0x44 /* RES current addr */ -+#define AD_DMA_RESBC 0x48 /* RES base cnt */ -+#define AD_DMA_RESCC 0x4c /* RES current count */ -+#define AD_DMA_ADCBA 0x50 /* ADC */ -+#define AD_DMA_ADCCA 0x54 -+#define AD_DMA_ADCBC 0x58 -+#define AD_DMA_ADCCC 0x5c -+#define AD_DMA_SYNBA 0x60 /* SYN */ -+#define AD_DMA_SYNCA 0x64 -+#define AD_DMA_SYNBC 0x68 -+#define AD_DMA_SYNCC 0x6c -+#define AD_DMA_WAVBA 0x70 /* WAV */ -+#define AD_DMA_WAVCA 0x74 -+#define AD_DMA_WAVBC 0x78 -+#define AD_DMA_WAVCC 0x7c -+#define AD_DMA_RESICC 0x80 /* RES interrupt current count */ -+#define AD_DMA_RESIBC 0x84 /* RES interrupt base count */ -+#define AD_DMA_ADCICC 0x88 /* ADC interrupt current count */ -+#define AD_DMA_ADCIBC 0x8c /* ADC interrupt base count */ -+#define AD_DMA_SYNICC 0x90 /* SYN interrupt current count */ -+#define AD_DMA_SYNIBC 0x94 /* SYN interrupt base count */ -+#define AD_DMA_WAVICC 0x98 /* WAV interrupt current count */ -+#define AD_DMA_WAVIBC 0x9c /* WAV interrupt base count */ -+#define AD_DMA_RESCTRL 0xa0 /* RES PCI control/status */ -+#define AD_DMA_ADCCTRL 0xa8 /* ADC PCI control/status */ -+#define AD_DMA_SYNCTRL 0xb0 /* SYN PCI control/status */ -+#define AD_DMA_WAVCTRL 0xb8 /* WAV PCI control/status */ -+#define AD_DMA_DISR 0xc0 /* PCI DMA intr status */ -+#define AD_DMA_CHSS 0xc4 /* PCI DMA channel stop status */ -+ -+#define AD_GPIO_IPC 0xc8 /* IO port ctrl */ -+#define AD_GPIO_OP 0xca /* IO output status */ -+#define AD_GPIO_IP 0xcc /* IO input status */ - - /* AC97 registers, 0x100 - 0x17f; see ac97.h */ --#define AD_ACIC 0x180 /* AC Link interface ctrl */ -+#define AD_AC97_BASE 0x100 /* ac97 base register */ -+#define AD_AC97_ACIC 0x180 /* AC Link interface ctrl */ - - /* OPL3; BAR1 */ --#define AD_OPLM0AS 0x00 /* Music0 address/status */ --#define AD_OPLM0DATA 0x01 /* Music0 data */ --#define AD_OPLM1A 0x02 /* Music1 address */ --#define AD_OPLM1DATA 0x03 /* Music1 data */ -+#define AD_OPL_M0AS 0x00 /* Music0 address/status */ -+#define AD_OPL_M0DATA 0x01 /* Music0 data */ -+#define AD_OPL_M1A 0x02 /* Music1 address */ -+#define AD_OPL_M1DATA 0x03 /* Music1 data */ - /* 0x04-0x0f reserved */ - - /* MIDI; BAR2 */ -@@ -59,9 +60,9 @@ - #define AD_MISC 0x01 /* MIDI status/cmd */ - /* 0x02-0xff reserved */ - --#define AD_DSIOMEMSIZE 512 --#define AD_OPLMEMSIZE 16 --#define AD_MIDIMEMSIZE 16 -+#define AD_DS_IOMEMSIZE 512 -+#define AD_OPL_MEMSIZE 16 -+#define AD_MIDI_MEMSIZE 16 - - #define AD_WAV_STATE 0 - #define AD_ADC_STATE 1 -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/oss/harmony.c CVS2_6_15_RC7_PA0/sound/oss/harmony.c ---- LINUS_2_6_15_RC7/sound/oss/harmony.c 2005-12-27 13:26:02.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/sound/oss/harmony.c 2005-12-19 13:43:22.000000000 -0700 -@@ -1236,7 +1236,7 @@ - } - - /* Set the HPA of harmony */ -- harmony.hpa = (struct harmony_hpa *)dev->hpa; -+ harmony.hpa = (struct harmony_hpa *)dev->hpa.start; - harmony.dev = dev; - - /* Grab the ID and revision from the device */ -@@ -1250,7 +1250,7 @@ - - printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", " - "h/w id %i, rev. %i at 0x%lx, IRQ %i\n", -- id, rev, dev->hpa, harmony.dev->irq); -+ id, rev, dev->hpa.start, harmony.dev->irq); - - /* Make sure the control bit isn't set, although I don't think it - ever is. */ -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/pci/Kconfig CVS2_6_15_RC7_PA0/sound/pci/Kconfig ---- LINUS_2_6_15_RC7/sound/pci/Kconfig 2005-12-27 13:26:03.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/sound/pci/Kconfig 2005-11-11 21:09:48.000000000 -0700 -@@ -321,6 +321,14 @@ - To compile this as a module, choose M here: the module - will be called snd-ad1889. - -+config SND_AD1889_OPL3 -+ bool "Analog Devices AD1889 OPL3 Support (Experimental)" -+ depends on SND_AD1889 && EXPERIMENTAL -+ select SND_OPL3_LIB -+ help -+ Say Y here to include support for the OPL3-compatible interface -+ provided on an Analog Devices AD1889. -+ - config SND_ALS4000 - tristate "Avance Logic ALS4000" - depends on SND && ISA_DMA_API -diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/pci/ad1889.c CVS2_6_15_RC7_PA0/sound/pci/ad1889.c ---- LINUS_2_6_15_RC7/sound/pci/ad1889.c 2005-12-27 13:26:03.000000000 -0700 -+++ CVS2_6_15_RC7_PA0/sound/pci/ad1889.c 2005-11-11 21:09:48.000000000 -0700 -@@ -45,6 +45,10 @@ - #include - #include - -+#ifdef CONFIG_SND_AD1889_OPL3 -+#include -+#endif -+ - #include - - #include "ad1889.h" -@@ -55,6 +59,7 @@ - MODULE_AUTHOR("Kyle McMartin , Thibaut Varene "); - MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver"); - MODULE_LICENSE("GPL"); -+MODULE_VERSION(AD1889_DRVVER); - MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1889}}"); - - static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -@@ -94,11 +99,20 @@ - unsigned long bar; - void __iomem *iobase; - -+#ifdef CONFIG_SND_AD1889_OPL3 -+ unsigned long opl3_bar; -+ void __iomem *opl3_iobase; -+ -+ opl3_t *opl3; -+ snd_hwdep_t *opl3hwdep; -+#endif -+ - ac97_t *ac97; - ac97_bus_t *ac97_bus; - snd_pcm_t *pcm; - snd_info_entry_t *proc; - -+ struct snd_dma_device dma; - snd_pcm_substream_t *psubs; - snd_pcm_substream_t *csubs; - -@@ -112,25 +126,25 @@ - static inline u16 - ad1889_readw(struct snd_ad1889 *chip, unsigned reg) - { -- return readw(chip->iobase + reg); -+ return ioread16(chip->iobase + reg); - } - - static inline void - ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val) - { -- writew(val, chip->iobase + reg); -+ iowrite16(val, chip->iobase + reg); - } - - static inline u32 - ad1889_readl(struct snd_ad1889 *chip, unsigned reg) - { -- return readl(chip->iobase + reg); -+ return ioread32(chip->iobase + reg); - } - - static inline void - ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val) - { -- writel(val, chip->iobase + reg); -+ iowrite32(val, chip->iobase + reg); - } - - static inline void -@@ -620,6 +634,9 @@ - if ((st & AD_DMA_DISR_ADCI) && chip->csubs) - snd_pcm_period_elapsed(chip->csubs); - -+ ad1889_readl(chip, AD_DMA_DISR); /* flush */ -+ /* XXX under some circumstances the DISR write flush may not happen */ -+ - return IRQ_HANDLED; - } - -@@ -658,6 +675,9 @@ - chip->psubs = NULL; - chip->csubs = NULL; - -+ chip->dma.dev = &chip->pci->dev; -+ chip->dma.type = SNDRV_DMA_TYPE_DEV; -+ - err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), - BUFFER_BYTES_MAX / 2, -@@ -874,6 +894,11 @@ - if (chip->iobase) - iounmap(chip->iobase); - -+#ifdef CONFIG_SND_AD1889_OPL3 -+ if (chip->opl3_iobase) -+ iounmap(chip->opl3_iobase); -+#endif -+ - pci_release_regions(chip->pci); - pci_disable_device(chip->pci); - -@@ -954,6 +979,17 @@ - - spin_lock_init(&chip->lock); /* only now can we call ad1889_free */ - -+#ifdef CONFIG_SND_AD1889_OPL3 -+ chip->opl3_bar = pci_resource_start(pci, 1); -+ chip->opl3_iobase = ioremap_nocache(chip->opl3_bar, -+ pci_resource_len(pci, 1)); -+ if (chip->opl3_iobase == NULL) { -+ printk(KERN_ERR PFX "unable to reserve region.\n"); -+ snd_ad1889_free(chip); -+ return -EBUSY; -+ } -+#endif -+ - if (request_irq(pci->irq, snd_ad1889_interrupt, - SA_INTERRUPT|SA_SHIRQ, card->driver, (void*)chip)) { - printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq); -@@ -1029,6 +1065,22 @@ - if (err < 0) - goto free_and_ret; - -+#ifdef CONFIG_SND_AD1889_OPL3 -+ err = snd_opl3_create_mapped(card, chip->opl3_iobase, -+ chip->opl3_iobase + 2, OPL3_HW_OPL3, -+ &chip->opl3); -+ if (err) { -+ printk(KERN_ERR PFX "failed to create opl3\n"); -+ goto free_and_ret; -+ } -+ -+ err = snd_opl3_hwdep_new(chip->opl3, 0, 0, &chip->opl3hwdep); -+ if (err) { -+ printk(KERN_ERR PFX "failed to create opl3hwdep\n"); -+ goto free_and_ret; -+ } -+#endif -+ - err = snd_ad1889_pcm_init(chip, 0, NULL); - if (err < 0) - goto free_and_ret; diff --git a/debian/patches/powerpc-mv643xx-spinlock-fix-support.patch b/debian/patches/powerpc-mv643xx-spinlock-fix-support.patch deleted file mode 100644 index 338dfd312..000000000 --- a/debian/patches/powerpc-mv643xx-spinlock-fix-support.patch +++ /dev/null @@ -1,66 +0,0 @@ -Date: Wed, 28 Dec 2005 15:40:01 -0700 -To: netdev@vger.kernel.org -Subject: [PATCH 4/4] mv643xx: Don't call request_irq with a held lock -Message-ID: <20051228224001.GD5742@xyzzy.farnsworth.org> -References: <20051228223449.GA5742@xyzzy.farnsworth.org> - -From: Dale Farnsworth - -We can't call request_irq() while holding a spin lock. - -Signed-off-by: Dale Farnsworth - -Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c -=================================================================== ---- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c -+++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c -@@ -655,34 +655,24 @@ static int mv643xx_eth_open(struct net_d - unsigned int port_num = mp->port_num; - int err; - -- spin_lock_irq(&mp->lock); -- - err = request_irq(dev->irq, mv643xx_eth_int_handler, - SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); -- - if (err) { - printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n", - port_num); -- err = -EAGAIN; -- goto out; -+ return -EAGAIN; - } - -+ spin_lock_irq(&mp->lock); -+ - if (mv643xx_eth_real_open(dev)) { - printk("%s: Error opening interface\n", dev->name); -+ free_irq(dev->irq, dev); - err = -EBUSY; -- goto out_free; - } - - spin_unlock_irq(&mp->lock); - -- return 0; -- --out_free: -- free_irq(dev->irq, dev); -- --out: -- spin_unlock_irq(&mp->lock); -- - return err; - } - - -_______________________________________________ -Linuxppc-dev mailing list -Linuxppc-dev@ozlabs.org -https://ozlabs.org/mailman/listinfo/linuxppc-dev ---------------------------------------------------------------------------------------- -Wanadoo vous informe que cet e-mail a ete controle par l'anti-virus mail. -Aucun virus connu a ce jour par nos services n'a ete detecte. - - - diff --git a/debian/patches/series/1 b/debian/patches/series/1 index ef27d3df4..bcdab29d0 100644 --- a/debian/patches/series/1 +++ b/debian/patches/series/1 @@ -7,11 +7,8 @@ + ia64-irq-affinity-upfix.patch + powerpc-mkvmlinuz-support.patch + powerpc-build-links.patch -#FIXME + powerpc-mv643xx-spinlock-fix-support.patch + powerpc-prep-utah-ide-interrupt.patch + powerpc-mv643xx-hotplug-support.patch -#FIXME + powerpc-serial.patch -#FIXME + powerpc-apus.patch + sparc64-hme-lockup.patch + sparc64-atyfb-xl-gr.patch + mips-makefile.patch diff --git a/debian/patches/vserver-powerpc-fix01.patch b/debian/patches/vserver-powerpc-fix01.patch deleted file mode 100644 index 71f6d99d6..000000000 --- a/debian/patches/vserver-powerpc-fix01.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/arch/powerpc/kernel/asm-offsets.c 2006-02-21 03:41:53.000000000 -0500 -+++ b/arch/powerpc/kernel/asm-offsets.c 2006-02-21 04:21:08.000000000 -0500 -@@ -230,6 +230,7 @@ int main(void) - - DEFINE(CLONE_VM, CLONE_VM); - DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); -+ DEFINE(CLONE_KTHREAD, CLONE_KTHREAD); - - #ifndef CONFIG_PPC64 - DEFINE(MM_PGD, offsetof(struct mm_struct, pgd)); From 5848cdcc1c876d0f0e102385c32add9187283203 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 2 Apr 2006 20:21:44 +0000 Subject: [PATCH 028/108] debian/arch/defines: Change abiname to trunk. svn path=/dists/trunk/linux-2.6/; revision=6360 --- debian/arch/defines | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/arch/defines b/debian/arch/defines index f59c6ff23..72d7ec7fd 100644 --- a/debian/arch/defines +++ b/debian/arch/defines @@ -1,5 +1,5 @@ [abiname] -abiname: 1 +abiname: trunk [base] arches: From 1c2491ce774d97edfd0ed0d84563e56dc7cf7ac1 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 2 Apr 2006 20:22:53 +0000 Subject: [PATCH 029/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6361 --- debian/bin/gencontrol.py | 6 ++++-- debian/changelog | 5 ++++- debian/rules.real | 12 ++++++------ debian/templates/control.headers.arch.in | 10 ---------- debian/templates/control.support.in | 7 +++++++ 5 files changed, 21 insertions(+), 19 deletions(-) create mode 100644 debian/templates/control.support.in diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 910a19fb0..3848438ee 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -21,11 +21,13 @@ class gencontrol(debian_linux.gencontrol.gencontrol): vars.update(self.config.get(('image', arch), {})) def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra): + packages_support = self.process_packages(self.templates["control.support"], vars) headers_arch = self.templates["control.headers.arch"] packages_headers_arch = self.process_packages(headers_arch, vars) - extra['headers_arch_depends'] = packages_headers_arch[2]['Depends'] + + extra['headers_arch_depends'] = packages_headers_arch[-1]['Depends'] = package_relation_list() - for package in packages_headers_arch: + for package in packages_support + packages_headers_arch: name = package['Package'] if packages.has_key(name): package = packages.get(name) diff --git a/debian/changelog b/debian/changelog index fde3b38a2..65dfe7542 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,9 @@ linux-2.6 (2.6.16-5) UNRELEASED; urgency=low [ Bastian Blank ] * Provide real dependency packages for module building. + - Add linux-headers-$version-$abiname-all and + linux-headers-$version-$abiname-all-$arch. + * Rename support package to linux-support-$version-$abiname. * Fix module package output. * Include .kernelrelease in headers packages. (closes: #359813) * Disable Cumana partition support completely. (closes: #359207) @@ -15,7 +18,7 @@ linux-2.6 (2.6.16-5) UNRELEASED; urgency=low [ dann frazier ] * [ia64] initramfs-tools works now, no longer restrict initramfs-generators - -- dann frazier Thu, 30 Mar 2006 15:45:35 -0700 + -- Bastian Blank Sun, 2 Apr 2006 16:21:29 +0200 linux-2.6 (2.6.16-4) unstable; urgency=medium diff --git a/debian/rules.real b/debian/rules.real index 087dc4242..4c799ac9b 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -66,7 +66,7 @@ endif # # Targets # -binary-arch-arch: install-headers-all install-headers-$(ARCH) +binary-arch-arch: install-support install-headers-$(ARCH) binary-arch-subarch: install-header-$(ARCH)-$(SUBARCH) binary-arch-flavour: install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) ifeq ($(MODULES),True) @@ -317,14 +317,14 @@ install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): $(STAMPS_DIR)/build-$(ARCH)-$(SUBA $(MAKE) -f debian/rules.real install-base -install-headers-all: PACKAGE_NAME = linux-headers-$(VERSION) -install-headers-all: DH_OPTIONS = -p$(PACKAGE_NAME) -install-headers-all: +install-support: PACKAGE_NAME = linux-support-$(UPSTREAMVERSION)$(ABINAME) +install-support: DH_OPTIONS = -p$(PACKAGE_NAME) +install-support: dh_testdir dh_testroot chmod a+x debian/modules/gencontrol.py - dh_install debian/arch debian/lib debian/modules '/usr/src/linux-headers-$(VERSION)' - dh_python -V 2.4 /usr/src/linux-headers-$(VERSION)/lib/python + dh_install debian/arch debian/lib debian/modules /usr/src/$(PACKAGE_NAME) + dh_python -V 2.4 /usr/src/$(PACKAGE_NAME)/lib/python $(MAKE) -f debian/rules.real install-base install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): REAL_VERSION = $(UPSTREAMVERSION)$(ABINAME)$(LOCALVERSION) diff --git a/debian/templates/control.headers.arch.in b/debian/templates/control.headers.arch.in index b2ccee9d4..aed754692 100644 --- a/debian/templates/control.headers.arch.in +++ b/debian/templates/control.headers.arch.in @@ -1,12 +1,3 @@ -Package: linux-headers-@version@ -Section: devel -Priority: optional -Depends: python2.4-minimal -Description: All header files for Linux kernel @version@ - This package depends against all architecture-specific kernel header files - for Linux kernel version @upstreamversion@, generally used for building out-of-tree - kernel modules. - Package: linux-headers-@upstreamversion@@abiname@-all Section: devel Priority: optional @@ -21,7 +12,6 @@ Package: linux-headers-@upstreamversion@@abiname@-all-@arch@ Section: devel Priority: optional Provides: linux-headers-@major@-all-@arch@, linux-headers-@version@-all-@arch@ -Depends: linux-headers-@version@ (= ${Source-Version}) Description: All header files for Linux kernel @version@ This package depends against all architecture-specific kernel header files for Linux kernel version @upstreamversion@, generally used for building out-of-tree diff --git a/debian/templates/control.support.in b/debian/templates/control.support.in new file mode 100644 index 000000000..c3a04f630 --- /dev/null +++ b/debian/templates/control.support.in @@ -0,0 +1,7 @@ +Package: linux-support-@upstreamversion@@abiname@ +Section: devel +Priority: optional +Depends: python2.4-minimal +Description: Support files for Linux kernel @upstreamversion@ + This package provides support files for the Linux kernel build. + From eec85fb83313abe446e6513816c5b638f44e96f4 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 2 Apr 2006 20:43:04 +0000 Subject: [PATCH 030/108] * debian/bin/gencontrol.py: Support support to main packages. * debian/rules.real: Build support package in binary-indep. * debian/templates/control.support.in: Set Architecture to all. svn path=/dists/trunk/linux-2.6/; revision=6362 --- debian/bin/gencontrol.py | 5 +++-- debian/rules.real | 3 ++- debian/templates/control.support.in | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 3848438ee..454d579c3 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -17,17 +17,18 @@ class gencontrol(debian_linux.gencontrol.gencontrol): tree = self.templates["control.tree"] packages.append(self.process_real_tree(tree[0], vars)) + packages.extend(self.process_packages(self.templates["control.support"], vars)) + def do_arch_setup(self, vars, makeflags, arch): vars.update(self.config.get(('image', arch), {})) def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra): - packages_support = self.process_packages(self.templates["control.support"], vars) headers_arch = self.templates["control.headers.arch"] packages_headers_arch = self.process_packages(headers_arch, vars) extra['headers_arch_depends'] = packages_headers_arch[-1]['Depends'] = package_relation_list() - for package in packages_support + packages_headers_arch: + for package in packages_headers_arch: name = package['Package'] if packages.has_key(name): package = packages.get(name) diff --git a/debian/rules.real b/debian/rules.real index 4c799ac9b..9fce54b8f 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -66,7 +66,7 @@ endif # # Targets # -binary-arch-arch: install-support install-headers-$(ARCH) +binary-arch-arch: install-headers-$(ARCH) binary-arch-subarch: install-header-$(ARCH)-$(SUBARCH) binary-arch-flavour: install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) ifeq ($(MODULES),True) @@ -74,6 +74,7 @@ ifeq ($(MODULES),True) endif binary-indep: install-doc install-patch install-source install-tree +binary-indep: install-support build: $(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) diff --git a/debian/templates/control.support.in b/debian/templates/control.support.in index c3a04f630..4a2d7d7a7 100644 --- a/debian/templates/control.support.in +++ b/debian/templates/control.support.in @@ -1,4 +1,5 @@ Package: linux-support-@upstreamversion@@abiname@ +Architecture: all Section: devel Priority: optional Depends: python2.4-minimal From 767ed78061faec1481857d5b032a5f8ab0a054bf Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 2 Apr 2006 21:22:00 +0000 Subject: [PATCH 031/108] Update xen patch. * debian/patches/series/1-extra, debian/patches/series/3-extra, debian/patches/series/99experimental.1-extra: Update. * debian/patches/xen-tree-merge-22448.patch: Remove. * debian/patches/xen-tree-merge-21966.patch: Add. svn path=/dists/trunk/linux-2.6/; revision=6363 --- debian/patches/series/1-extra | 1 - debian/patches/series/3-extra | 2 +- debian/patches/series/99experimental.1-extra | 1 + ...21966.patch => xen-tree-merge-22448.patch} | 4188 +++++++++++------ 4 files changed, 2834 insertions(+), 1358 deletions(-) rename debian/patches/{xen-tree-merge-21966.patch => xen-tree-merge-22448.patch} (95%) diff --git a/debian/patches/series/1-extra b/debian/patches/series/1-extra index ed6de817d..a6048204e 100644 --- a/debian/patches/series/1-extra +++ b/debian/patches/series/1-extra @@ -3,6 +3,5 @@ + vserver-version.patch *_vserver *_xen-vserver + vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver + vserver-xen-clash.patch *_xen-vserver -+ xen-tree-merge-21966.patch *_xen *_xen-vserver + mips-tulip.patch mipsel + mips-tulip_dc21143.patch mipsel diff --git a/debian/patches/series/3-extra b/debian/patches/series/3-extra index ac7d9ed55..466fd7294 100644 --- a/debian/patches/series/3-extra +++ b/debian/patches/series/3-extra @@ -1 +1 @@ -+ vserver-vs2.0.2-rc14-update.patch *_vserver ++ vserver-vs2.0.2-rc14-update.patch *_vserver *_xen-vserver diff --git a/debian/patches/series/99experimental.1-extra b/debian/patches/series/99experimental.1-extra index 0bc1bcd37..b6d0d8ba5 100644 --- a/debian/patches/series/99experimental.1-extra +++ b/debian/patches/series/99experimental.1-extra @@ -1 +1,2 @@ ++ xen-tree-merge-22448.patch *_xen *_xen-vserver + xen-tls.patch *_xen *_xen-vserver diff --git a/debian/patches/xen-tree-merge-21966.patch b/debian/patches/xen-tree-merge-22448.patch similarity index 95% rename from debian/patches/xen-tree-merge-21966.patch rename to debian/patches/xen-tree-merge-22448.patch index 48414aabf..d52f410b6 100644 --- a/debian/patches/xen-tree-merge-21966.patch +++ b/debian/patches/xen-tree-merge-22448.patch @@ -491,10 +491,10 @@ index 7e9ac99..fa783e6 100644 +endif diff --git a/arch/i386/kernel/acpi/boot-xen.c b/arch/i386/kernel/acpi/boot-xen.c new file mode 100644 -index 0000000..29b491e +index 0000000..96e4525 --- /dev/null +++ b/arch/i386/kernel/acpi/boot-xen.c -@@ -0,0 +1,1163 @@ +@@ -0,0 +1,1161 @@ +/* + * boot.c - Architecture-Specific Low-Level ACPI Boot Support + * @@ -543,6 +543,7 @@ index 0000000..29b491e + +static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } + ++ +#else /* X86 */ + +#ifdef CONFIG_X86_LOCAL_APIC @@ -1610,9 +1611,6 @@ index 0000000..29b491e + disable_acpi(); + return error; + } -+#ifdef __i386__ -+ check_acpi_pci(); -+#endif + + acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + @@ -1845,10 +1843,10 @@ index 010aecf..753f1d7 100644 +endif diff --git a/arch/i386/kernel/cpu/common-xen.c b/arch/i386/kernel/cpu/common-xen.c new file mode 100644 -index 0000000..2fc25e8 +index 0000000..db05bd0 --- /dev/null +++ b/arch/i386/kernel/cpu/common-xen.c -@@ -0,0 +1,723 @@ +@@ -0,0 +1,719 @@ +#include +#include +#include @@ -1885,8 +1883,6 @@ index 0000000..2fc25e8 + +struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; + -+extern void machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c); -+ +extern int disable_pse; + +static void default_init(struct cpuinfo_x86 * c) @@ -2134,10 +2130,10 @@ index 0000000..2fc25e8 + c->x86_capability[4] = excap; + c->x86 = (tfms >> 8) & 15; + c->x86_model = (tfms >> 4) & 15; -+ if (c->x86 == 0xf) { ++ if (c->x86 == 0xf) + c->x86 += (tfms >> 20) & 0xff; ++ if (c->x86 >= 0x6) + c->x86_model += ((tfms >> 16) & 0xF) << 4; -+ } + c->x86_mask = tfms & 15; + } else { + /* Have CPUID level 0 only - unheard of */ @@ -2278,8 +2274,6 @@ index 0000000..2fc25e8 + c->x86_vendor, c->x86_model); + } + -+ machine_specific_modify_cpu_capabilities(c); -+ + /* Now the feature flags better reflect actual CPU features! */ + + printk(KERN_DEBUG "CPU: After all inits, caps:"); @@ -2602,10 +2596,10 @@ index a25b701..06df4fe 100644 +endif diff --git a/arch/i386/kernel/cpu/mtrr/main-xen.c b/arch/i386/kernel/cpu/mtrr/main-xen.c new file mode 100644 -index 0000000..407cc78 +index 0000000..8f09bd7 --- /dev/null +++ b/arch/i386/kernel/cpu/mtrr/main-xen.c -@@ -0,0 +1,187 @@ +@@ -0,0 +1,196 @@ +#include +#include +#include @@ -2616,6 +2610,8 @@ index 0000000..407cc78 +#include +#include "mtrr.h" + ++static DECLARE_MUTEX(mtrr_sem); ++ +void generic_get_mtrr(unsigned int reg, unsigned long *base, + unsigned int *size, mtrr_type * type) +{ @@ -2671,12 +2667,15 @@ index 0000000..407cc78 + int error; + dom0_op_t op; + ++ down(&mtrr_sem); ++ + op.cmd = DOM0_ADD_MEMTYPE; + op.u.add_memtype.mfn = base; + op.u.add_memtype.nr_mfns = size; + op.u.add_memtype.type = type; + error = HYPERVISOR_dom0_op(&op); + if (error) { ++ up(&mtrr_sem); + BUG_ON(error > 0); + return error; + } @@ -2684,6 +2683,8 @@ index 0000000..407cc78 + if (increment) + ++usage_table[op.u.add_memtype.reg]; + ++ up(&mtrr_sem); ++ + return op.u.add_memtype.reg; +} + @@ -2712,17 +2713,18 @@ index 0000000..407cc78 + +int mtrr_del_page(int reg, unsigned long base, unsigned long size) +{ -+ int i, max; ++ unsigned i; + mtrr_type ltype; + unsigned long lbase; + unsigned int lsize; + int error = -EINVAL; + dom0_op_t op; + -+ max = num_var_ranges; ++ down(&mtrr_sem); ++ + if (reg < 0) { + /* Search for existing MTRR */ -+ for (i = 0; i < max; ++i) { ++ for (i = 0; i < num_var_ranges; ++i) { + mtrr_if->get(i, &lbase, &lsize, <ype); + if (lbase == base && lsize == size) { + reg = i; @@ -2751,6 +2753,7 @@ index 0000000..407cc78 + } + error = reg; + out: ++ up(&mtrr_sem); + return error; +} + @@ -2803,10 +2806,10 @@ index 0000000..7a5d206 +#include "../../x86_64/kernel/early_printk-xen.c" diff --git a/arch/i386/kernel/entry-xen.S b/arch/i386/kernel/entry-xen.S new file mode 100644 -index 0000000..a86e8f5 +index 0000000..ec17d1c --- /dev/null +++ b/arch/i386/kernel/entry-xen.S -@@ -0,0 +1,857 @@ +@@ -0,0 +1,861 @@ +/* + * linux/arch/i386/entry.S + * @@ -2888,6 +2891,10 @@ index 0000000..a86e8f5 +/* Pseudo-eflags. */ +NMI_MASK = 0x80000000 + ++#ifndef CONFIG_XEN ++#define DISABLE_INTERRUPTS cli ++#define ENABLE_INTERRUPTS sti ++#else +/* Offsets into shared_info_t. */ +#define evtchn_upcall_pending /* 0 */ +#define evtchn_upcall_mask 1 @@ -2895,33 +2902,24 @@ index 0000000..a86e8f5 +#define sizeof_vcpu_shift 6 + +#ifdef CONFIG_SMP -+#define preempt_disable(reg) incl TI_preempt_count(reg) -+#define preempt_enable(reg) decl TI_preempt_count(reg) -+#define XEN_GET_VCPU_INFO(reg) preempt_disable(%ebp) ; \ -+ movl TI_cpu(%ebp),reg ; \ -+ shl $sizeof_vcpu_shift,reg ; \ -+ addl HYPERVISOR_shared_info,reg -+#define XEN_PUT_VCPU_INFO(reg) preempt_enable(%ebp) -+#define XEN_PUT_VCPU_INFO_fixup .byte 0xff,0xff,0xff ++#define GET_VCPU_INFO movl TI_cpu(%ebp),%esi ; \ ++ shl $sizeof_vcpu_shift,%esi ; \ ++ addl HYPERVISOR_shared_info,%esi +#else -+#define XEN_GET_VCPU_INFO(reg) movl HYPERVISOR_shared_info,reg -+#define XEN_PUT_VCPU_INFO(reg) -+#define XEN_PUT_VCPU_INFO_fixup ++#define GET_VCPU_INFO movl HYPERVISOR_shared_info,%esi +#endif + -+#define XEN_LOCKED_BLOCK_EVENTS(reg) movb $1,evtchn_upcall_mask(reg) -+#define XEN_LOCKED_UNBLOCK_EVENTS(reg) movb $0,evtchn_upcall_mask(reg) -+#define XEN_BLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg) ; \ -+ XEN_LOCKED_BLOCK_EVENTS(reg) ; \ -+ XEN_PUT_VCPU_INFO(reg) -+#define XEN_UNBLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg) ; \ -+ XEN_LOCKED_UNBLOCK_EVENTS(reg) ; \ -+ XEN_PUT_VCPU_INFO(reg) -+#define XEN_TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg) ++#define __DISABLE_INTERRUPTS movb $1,evtchn_upcall_mask(%esi) ++#define __ENABLE_INTERRUPTS movb $0,evtchn_upcall_mask(%esi) ++#define DISABLE_INTERRUPTS GET_VCPU_INFO ; \ ++ __DISABLE_INTERRUPTS ++#define ENABLE_INTERRUPTS GET_VCPU_INFO ; \ ++ __ENABLE_INTERRUPTS ++#define __TEST_PENDING testb $0xFF,evtchn_upcall_pending(%esi) ++#endif + +#ifdef CONFIG_PREEMPT -+#define preempt_stop GET_THREAD_INFO(%ebp) ; \ -+ XEN_BLOCK_EVENTS(%esi) ++#define preempt_stop cli +#else +#define preempt_stop +#define resume_kernel restore_nocheck @@ -2968,21 +2966,6 @@ index 0000000..a86e8f5 +.previous + + -+#define RESTORE_ALL \ -+ RESTORE_REGS \ -+ addl $4, %esp; \ -+1: iret; \ -+.section .fixup,"ax"; \ -+2: pushl $0; \ -+ pushl $do_iret_error; \ -+ jmp error_code; \ -+.previous; \ -+.section __ex_table,"a";\ -+ .align 4; \ -+ .long 1b,2b; \ -+.previous -+ -+ +ENTRY(ret_from_fork) + pushl %eax + call schedule_tail @@ -3008,7 +2991,7 @@ index 0000000..a86e8f5 + testl $(VM_MASK | 2), %eax + jz resume_kernel +ENTRY(resume_userspace) -+ XEN_BLOCK_EVENTS(%esi) # make sure we don't miss an interrupt ++ DISABLE_INTERRUPTS # make sure we don't miss an interrupt + # setting need_resched or sigpending + # between sampling and the iret + movl TI_flags(%ebp), %ecx @@ -3019,15 +3002,15 @@ index 0000000..a86e8f5 + +#ifdef CONFIG_PREEMPT +ENTRY(resume_kernel) -+ XEN_BLOCK_EVENTS(%esi) ++ cli + cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? + jnz restore_nocheck +need_resched: + movl TI_flags(%ebp), %ecx # need_resched set ? + testb $_TIF_NEED_RESCHED, %cl + jz restore_all -+ testb $0xFF,EVENT_MASK(%esp) # interrupts off (exception path) ? -+ jnz restore_all ++ testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ? ++ jz restore_all + call preempt_schedule_irq + jmp need_resched +#endif @@ -3098,7 +3081,7 @@ index 0000000..a86e8f5 + call *sys_call_table(,%eax,4) + movl %eax,EAX(%esp) # store the return value +syscall_exit: -+ XEN_BLOCK_EVENTS(%esi) # make sure we don't miss an interrupt ++ DISABLE_INTERRUPTS # make sure we don't miss an interrupt + # setting need_resched or sigpending + # between sampling and the iret + movl TI_flags(%ebp), %ecx @@ -3106,7 +3089,7 @@ index 0000000..a86e8f5 + jne syscall_exit_work + +restore_all: -+#if 0 /* XEN */ ++#ifndef CONFIG_XEN + movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS + # Warning: OLDSS(%esp) contains the wrong/random values if we + # are returning to the kernel. @@ -3116,22 +3099,26 @@ index 0000000..a86e8f5 + andl $(VM_MASK | (4 << 8) | 3), %eax + cmpl $((4 << 8) | 3), %eax + je ldt_ss # returning to user-space with LDT SS -+#endif /* XEN */ ++restore_nocheck: ++#else +restore_nocheck: + testl $(VM_MASK|NMI_MASK), EFLAGS(%esp) + jnz hypervisor_iret + movb EVENT_MASK(%esp), %al + notb %al # %al == ~saved_mask -+ XEN_GET_VCPU_INFO(%esi) ++ GET_VCPU_INFO + andb evtchn_upcall_mask(%esi),%al + andb $1,%al # %al == mask & ~saved_mask + jnz restore_all_enable_events # != 0 => reenable event delivery -+ XEN_PUT_VCPU_INFO(%esi) ++#endif + RESTORE_REGS + addl $4, %esp +1: iret +.section .fixup,"ax" +iret_exc: ++#ifndef CONFIG_XEN ++ sti ++#endif + pushl $0 # no error code + pushl $do_iret_error + jmp error_code @@ -3141,13 +3128,7 @@ index 0000000..a86e8f5 + .long 1b,iret_exc +.previous + -+hypervisor_iret: -+ andl $~NMI_MASK, EFLAGS(%esp) -+ RESTORE_REGS -+ addl $4, %esp -+ jmp hypercall_page + (__HYPERVISOR_iret * 32) -+ -+#if 0 /* XEN */ ++#ifndef CONFIG_XEN +ldt_ss: + larl OLDSS(%esp), %eax + jnz restore_nocheck @@ -3172,7 +3153,13 @@ index 0000000..a86e8f5 + .align 4 + .long 1b,iret_exc +.previous -+#endif /* XEN */ ++#else ++hypervisor_iret: ++ andl $~NMI_MASK, EFLAGS(%esp) ++ RESTORE_REGS ++ addl $4, %esp ++ jmp hypercall_page + (__HYPERVISOR_iret * 32) ++#endif + + # perform work that needs to be done immediately before resumption + ALIGN @@ -3181,7 +3168,7 @@ index 0000000..a86e8f5 + jz work_notifysig +work_resched: + call schedule -+ XEN_BLOCK_EVENTS(%esi) # make sure we don't miss an interrupt ++ DISABLE_INTERRUPTS # make sure we don't miss an interrupt + # setting need_resched or sigpending + # between sampling and the iret + movl TI_flags(%ebp), %ecx @@ -3233,7 +3220,7 @@ index 0000000..a86e8f5 +syscall_exit_work: + testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl + jz work_pending -+ XEN_UNBLOCK_EVENTS(%esi) # could let do_syscall_trace() call ++ ENABLE_INTERRUPTS # could let do_syscall_trace() call + # schedule() instead + movl %esp, %eax + movl $1, %edx @@ -3253,7 +3240,7 @@ index 0000000..a86e8f5 + movl $-ENOSYS,EAX(%esp) + jmp resume_userspace + -+#if 0 /* XEN */ ++#ifndef CONFIG_XEN +#define FIXUP_ESPFIX_STACK \ + movl %esp, %eax; \ + /* switch to 32bit stack using the pointer on top of 16bit stack */ \ @@ -3312,7 +3299,9 @@ index 0000000..a86e8f5 + +/* The include is where all of the SMP etc. interrupts come from */ +#include "entry_arch.h" -+#endif /* XEN */ ++#else ++#define UNWIND_ESPFIX_STACK ++#endif + +ENTRY(divide_error) + pushl $0 # no error code @@ -3331,7 +3320,7 @@ index 0000000..a86e8f5 + pushl %ebx + cld + pushl %es -+# UNWIND_ESPFIX_STACK ++ UNWIND_ESPFIX_STACK + popl %ecx + movl ES(%esp), %edi # get the function address + movl ORIG_EAX(%esp), %edx # get the error code @@ -3344,6 +3333,7 @@ index 0000000..a86e8f5 + call *%edi + jmp ret_from_exception + ++#ifdef CONFIG_XEN +# A note on the "critical region" in our callback handler. +# We want to avoid stacking callback handlers due to events occurring +# during handling of the last event. To do this, we keep events disabled @@ -3370,14 +3360,23 @@ index 0000000..a86e8f5 + + ALIGN +restore_all_enable_events: -+ XEN_LOCKED_UNBLOCK_EVENTS(%esi) ++ __ENABLE_INTERRUPTS +scrit: /**** START OF CRITICAL REGION ****/ -+ XEN_TEST_PENDING(%esi) ++ __TEST_PENDING + jnz 14f # process more events if necessary... -+ XEN_PUT_VCPU_INFO(%esi) -+ RESTORE_ALL -+14: XEN_LOCKED_BLOCK_EVENTS(%esi) -+ XEN_PUT_VCPU_INFO(%esi) ++ RESTORE_REGS ++ addl $4, %esp ++1: iret ++.section .fixup,"ax" ++2: pushl $0 ++ pushl $do_iret_error ++ jmp error_code ++.previous ++.section __ex_table,"a" ++ .align 4 ++ .long 1b,2b ++.previous ++14: __DISABLE_INTERRUPTS + jmp 11b +ecrit: /**** END OF CRITICAL REGION ****/ +# [How we do the fixup]. We want to merge the current stack frame with the @@ -3393,7 +3392,6 @@ index 0000000..a86e8f5 + cmpb $0xff,%al # 0xff => vcpu_info critical region + jne 15f + GET_THREAD_INFO(%ebp) -+ XEN_PUT_VCPU_INFO(%esi) # abort vcpu_info critical region + xorl %eax,%eax +15: mov %esp,%esi + add %eax,%esi # %esi points at end of src region @@ -3411,9 +3409,8 @@ index 0000000..a86e8f5 + jmp 11b + +critical_fixup_table: -+ .byte 0xff,0xff,0xff # testb $0xff,(%esi) = XEN_TEST_PENDING ++ .byte 0xff,0xff,0xff # testb $0xff,(%esi) = __TEST_PENDING + .byte 0xff,0xff # jnz 14f -+ XEN_PUT_VCPU_INFO_fixup + .byte 0x00 # pop %ebx + .byte 0x04 # pop %ecx + .byte 0x08 # pop %edx @@ -3426,7 +3423,6 @@ index 0000000..a86e8f5 + .byte 0x24,0x24,0x24 # add $4,%esp + .byte 0x28 # iret + .byte 0xff,0xff,0xff,0xff # movb $1,1(%esi) -+ XEN_PUT_VCPU_INFO_fixup + .byte 0x00,0x00 # jmp 11b + +# Hypervisor uses this for application faults while it executes. @@ -3455,6 +3451,7 @@ index 0000000..a86e8f5 + .long 3b,8b; \ + .long 4b,9b; \ +.previous ++#endif + +ENTRY(coprocessor_error) + pushl $0 @@ -3469,7 +3466,17 @@ index 0000000..a86e8f5 +ENTRY(device_not_available) + pushl $-1 # mark this as an int + SAVE_ALL -+ #preempt_stop /* This is already an interrupt gate on Xen. */ ++#ifndef CONFIG_XEN ++ movl %cr0, %eax ++ testl $0x4, %eax # EM (math emulation bit) ++ je device_available_emulate ++ pushl $0 # temporary storage for ORIG_EIP ++ call math_emulate ++ addl $4, %esp ++ jmp ret_from_exception ++device_available_emulate: ++#endif ++ preempt_stop + call math_state_restore + jmp ret_from_exception + @@ -3512,16 +3519,7 @@ index 0000000..a86e8f5 + jmp ret_from_exception + .previous .text + -+ENTRY(nmi) -+ pushl %eax -+ SAVE_ALL -+ xorl %edx,%edx # zero error code -+ movl %esp,%eax # pt_regs pointer -+ call do_nmi -+ orl $NMI_MASK, EFLAGS(%esp) -+ jmp restore_all -+ -+#if 0 /* XEN */ ++#ifndef CONFIG_XEN +/* + * NMI is doubly nasty. It can happen _while_ we're handling + * a debug fault, and the debug fault hasn't yet been able to @@ -3592,7 +3590,16 @@ index 0000000..a86e8f5 + .align 4 + .long 1b,iret_exc +.previous -+#endif /* XEN */ ++#else ++ENTRY(nmi) ++ pushl %eax ++ SAVE_ALL ++ xorl %edx,%edx # zero error code ++ movl %esp,%eax # pt_regs pointer ++ call do_nmi ++ orl $NMI_MASK, EFLAGS(%esp) ++ jmp restore_all ++#endif + +KPROBE_ENTRY(int3) + pushl $-1 # mark this as an int @@ -3767,7 +3774,7 @@ index 0000000..5188b23 + */ diff --git a/arch/i386/kernel/head-xen.S b/arch/i386/kernel/head-xen.S new file mode 100644 -index 0000000..3032a00 +index 0000000..23e62c0 --- /dev/null +++ b/arch/i386/kernel/head-xen.S @@ -0,0 +1,171 @@ @@ -3805,14 +3812,14 @@ index 0000000..3032a00 + + /* get vendor info */ + xorl %eax,%eax # call CPUID with 0 -> return vendor ID -+ cpuid ++ XEN_CPUID + movl %eax,X86_CPUID # save CPUID level + movl %ebx,X86_VENDOR_ID # lo 4 chars + movl %edx,X86_VENDOR_ID+4 # next 4 chars + movl %ecx,X86_VENDOR_ID+8 # last 4 chars + + movl $1,%eax # Use the CPUID instruction to get CPU type -+ cpuid ++ XEN_CPUID + movb %al,%cl # save reg for future use + andb $0x0f,%ah # mask processor family + movb %ah,X86 @@ -4001,10 +4008,10 @@ index 0000000..c4da1cc + diff --git a/arch/i386/kernel/io_apic-xen.c b/arch/i386/kernel/io_apic-xen.c new file mode 100644 -index 0000000..5ef6513 +index 0000000..47edb05 --- /dev/null +++ b/arch/i386/kernel/io_apic-xen.c -@@ -0,0 +1,2746 @@ +@@ -0,0 +1,2747 @@ +/* + * Intel IO-APIC support for multi-Pentium hosts. + * @@ -6338,7 +6345,8 @@ index 0000000..5ef6513 + apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); + init_8259A(1); + timer_ack = 1; -+ enable_8259A_irq(0); ++ if (timer_over_8254 > 0) ++ enable_8259A_irq(0); + + pin1 = find_isa_irq_pin(0, mp_INT); + apic1 = find_isa_irq_apic(0, mp_INT); @@ -7468,10 +7476,10 @@ index 0000000..06970d9 +} diff --git a/arch/i386/kernel/microcode-xen.c b/arch/i386/kernel/microcode-xen.c new file mode 100644 -index 0000000..a0e1487 +index 0000000..07db5cc --- /dev/null +++ b/arch/i386/kernel/microcode-xen.c -@@ -0,0 +1,164 @@ +@@ -0,0 +1,165 @@ +/* + * Intel CPU Microcode Update Driver for Linux + * @@ -7499,6 +7507,7 @@ index 0000000..a0e1487 +#include +#include +#include ++#include +#include +#include +#include @@ -10057,10 +10066,10 @@ index 0000000..39d9ed1 +#endif diff --git a/arch/i386/kernel/setup-xen.c b/arch/i386/kernel/setup-xen.c new file mode 100644 -index 0000000..5368d2f +index 0000000..1e0bd6f --- /dev/null +++ b/arch/i386/kernel/setup-xen.c -@@ -0,0 +1,1874 @@ +@@ -0,0 +1,1878 @@ +/* + * linux/arch/i386/kernel/setup.c + * @@ -11868,6 +11877,10 @@ index 0000000..5368d2f + op.u.set_iopl.iopl = 1; + HYPERVISOR_physdev_op(&op); + ++#ifdef CONFIG_X86_IO_APIC ++ check_acpi_pci(); /* Checks more than just ACPI actually */ ++#endif ++ +#ifdef CONFIG_ACPI + if (!(xen_start_info->flags & SIF_INITDOMAIN)) { + printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); @@ -12650,10 +12663,10 @@ index 0000000..5a32e54 + mb(); +} diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c -index eba7f53..378708c 100644 +index 7007e17..1008255 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c -@@ -1208,6 +1208,11 @@ static void __init smp_boot_cpus(unsigne +@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne if (max_cpus <= cpucount+1) continue; @@ -12665,7 +12678,7 @@ index eba7f53..378708c 100644 if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu)) printk("CPU #%d not responding - cannot use it.\n", apicid); -@@ -1386,6 +1391,11 @@ int __devinit __cpu_up(unsigned int cpu) +@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu) return -EIO; } @@ -13488,10 +13501,10 @@ index 0bada18..99193bb 100644 +} diff --git a/arch/i386/kernel/time-xen.c b/arch/i386/kernel/time-xen.c new file mode 100644 -index 0000000..39cf69d +index 0000000..197d785 --- /dev/null +++ b/arch/i386/kernel/time-xen.c -@@ -0,0 +1,1137 @@ +@@ -0,0 +1,1173 @@ +/* + * linux/arch/i386/kernel/time.c + * @@ -13650,6 +13663,17 @@ index 0000000..39cf69d +} +__setup("independent_wallclock", __independent_wallclock); + ++/* Permitted clock jitter, in nsecs, beyond which a warning will be printed. */ ++static unsigned long permitted_clock_jitter = 10000000UL; /* 10ms */ ++static int __init __permitted_clock_jitter(char *str) ++{ ++ permitted_clock_jitter = simple_strtoul(str, NULL, 0); ++ return 1; ++} ++__setup("permitted_clock_jitter=", __permitted_clock_jitter); ++ ++int tsc_disable __devinitdata = 0; ++ +#ifdef __i386__ +static void delay_tsc(unsigned long loops) +{ @@ -13817,6 +13841,7 @@ index 0000000..39cf69d + src = &HYPERVISOR_shared_info->vcpu_info[cpu].time; + dst = &per_cpu(shadow_time, cpu); + ++ rmb(); + return (dst->version == src->version); +} + @@ -14047,11 +14072,11 @@ index 0000000..39cf69d + + do { + local_time_version = shadow->version; -+ smp_rmb(); ++ barrier(); + time = shadow->system_timestamp + get_nsec_offset(shadow); + if (!time_values_up_to_date(cpu)) + get_time_values_from_xen(); -+ smp_rmb(); ++ barrier(); + } while (local_time_version != shadow->version); + + put_cpu(); @@ -14152,10 +14177,11 @@ index 0000000..39cf69d + } while (sched_time != runstate->state_entry_time); + } while (!time_values_up_to_date(cpu)); + -+ if ((unlikely(delta < -1000000LL) || unlikely(delta_cpu < 0)) ++ if ((unlikely(delta < -(s64)permitted_clock_jitter) || ++ unlikely(delta_cpu < -(s64)permitted_clock_jitter)) + && printk_ratelimit()) { + printk("Timer ISR/%d: Time went backwards: " -+ "delta=%lld cpu_delta=%lld shadow=%lld " ++ "delta=%lld delta_cpu=%lld shadow=%lld " + "off=%lld processed=%lld cpu_processed=%lld\n", + cpu, delta, delta_cpu, shadow->system_timestamp, + (s64)get_nsec_offset(shadow), @@ -14185,8 +14211,10 @@ index 0000000..39cf69d + * HACK: Passing NULL to account_steal_time() + * ensures that the ticks are accounted as stolen. + */ -+ if (stolen > 0) { ++ if ((stolen > 0) && (delta_cpu > 0)) { + delta_cpu -= stolen; ++ if (unlikely(delta_cpu < 0)) ++ stolen += delta_cpu; /* clamp local-time progress */ + do_div(stolen, NS_PER_TICK); + per_cpu(processed_stolen_time, cpu) += stolen * NS_PER_TICK; + per_cpu(processed_system_time, cpu) += stolen * NS_PER_TICK; @@ -14198,8 +14226,10 @@ index 0000000..39cf69d + * HACK: Passing idle_task to account_steal_time() + * ensures that the ticks are accounted as idle/wait. + */ -+ if (blocked > 0) { ++ if ((blocked > 0) && (delta_cpu > 0)) { + delta_cpu -= blocked; ++ if (unlikely(delta_cpu < 0)) ++ blocked += delta_cpu; /* clamp local-time progress */ + do_div(blocked, NS_PER_TICK); + per_cpu(processed_blocked_time, cpu) += blocked * NS_PER_TICK; + per_cpu(processed_system_time, cpu) += blocked * NS_PER_TICK; @@ -14397,9 +14427,9 @@ index 0000000..39cf69d + write_seqlock_irqsave(&xtime_lock, flags); + xtime.tv_sec = sec; + xtime.tv_nsec = 0; -+ write_sequnlock_irqrestore(&xtime_lock, flags); -+ jiffies += sleep_length; ++ jiffies_64 += sleep_length; + wall_jiffies += sleep_length; ++ write_sequnlock_irqrestore(&xtime_lock, flags); + touch_softlockup_watchdog(); + return 0; +} @@ -14502,7 +14532,7 @@ index 0000000..39cf69d +} + +/* Convert jiffies to system time. */ -+static inline u64 jiffies_to_st(unsigned long j) ++u64 jiffies_to_st(unsigned long j) +{ + unsigned long seq; + long delta; @@ -14520,6 +14550,7 @@ index 0000000..39cf69d + + return st; +} ++EXPORT_SYMBOL(jiffies_to_st); + +/* + * stop_hz_timer / start_hz_timer - enter/exit 'tickless mode' on an idle cpu @@ -14605,13 +14636,31 @@ index 0000000..39cf69d + * now however. + */ +static ctl_table xen_subtable[] = { -+ {1, "independent_wallclock", &independent_wallclock, -+ sizeof(independent_wallclock), 0644, NULL, proc_dointvec}, -+ {0} ++ { ++ .ctl_name = 1, ++ .procname = "independent_wallclock", ++ .data = &independent_wallclock, ++ .maxlen = sizeof(independent_wallclock), ++ .mode = 0644, ++ .proc_handler = proc_dointvec ++ }, ++ { ++ .ctl_name = 2, ++ .procname = "permitted_clock_jitter", ++ .data = &permitted_clock_jitter, ++ .maxlen = sizeof(permitted_clock_jitter), ++ .mode = 0644, ++ .proc_handler = proc_doulongvec_minmax ++ }, ++ { 0 } +}; +static ctl_table xen_table[] = { -+ {123, "xen", NULL, 0, 0555, xen_subtable}, -+ {0} ++ { ++ .ctl_name = 123, ++ .procname = "xen", ++ .mode = 0555, ++ .child = xen_subtable}, ++ { 0 } +}; +static int __init xen_sysctl_init(void) +{ @@ -16693,10 +16742,10 @@ index 0000000..2a9ce1c +EXPORT_SYMBOL(kmap_atomic_to_page); diff --git a/arch/i386/mm/hypervisor.c b/arch/i386/mm/hypervisor.c new file mode 100644 -index 0000000..cfc359e +index 0000000..de80a51 --- /dev/null +++ b/arch/i386/mm/hypervisor.c -@@ -0,0 +1,471 @@ +@@ -0,0 +1,424 @@ +/****************************************************************************** + * mm/hypervisor.c + * @@ -16704,8 +16753,11 @@ index 0000000..cfc359e + * + * Copyright (c) 2002-2004, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -16900,56 +16952,6 @@ index 0000000..cfc359e + BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); +} + -+void xen_pte_pin(unsigned long ptr) -+{ -+ struct mmuext_op op; -+ op.cmd = MMUEXT_PIN_L1_TABLE; -+ op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT); -+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); -+} -+ -+void xen_pte_unpin(unsigned long ptr) -+{ -+ struct mmuext_op op; -+ op.cmd = MMUEXT_UNPIN_TABLE; -+ op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT); -+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); -+} -+ -+#ifdef CONFIG_X86_64 -+void xen_pud_pin(unsigned long ptr) -+{ -+ struct mmuext_op op; -+ op.cmd = MMUEXT_PIN_L3_TABLE; -+ op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT); -+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); -+} -+ -+void xen_pud_unpin(unsigned long ptr) -+{ -+ struct mmuext_op op; -+ op.cmd = MMUEXT_UNPIN_TABLE; -+ op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT); -+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); -+} -+ -+void xen_pmd_pin(unsigned long ptr) -+{ -+ struct mmuext_op op; -+ op.cmd = MMUEXT_PIN_L2_TABLE; -+ op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT); -+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); -+} -+ -+void xen_pmd_unpin(unsigned long ptr) -+{ -+ struct mmuext_op op; -+ op.cmd = MMUEXT_UNPIN_TABLE; -+ op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT); -+ BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); -+} -+#endif /* CONFIG_X86_64 */ -+ +void xen_set_ldt(unsigned long ptr, unsigned long len) +{ + struct mmuext_op op; @@ -17170,10 +17172,10 @@ index 0000000..cfc359e + */ diff --git a/arch/i386/mm/init-xen.c b/arch/i386/mm/init-xen.c new file mode 100644 -index 0000000..b490dbd +index 0000000..0e5661a --- /dev/null +++ b/arch/i386/mm/init-xen.c -@@ -0,0 +1,846 @@ +@@ -0,0 +1,854 @@ +/* + * linux/arch/i386/mm/init.c + * @@ -17205,6 +17207,8 @@ index 0000000..b490dbd +#include +#include +#include ++#include ++#include + +#include +#include @@ -17218,6 +17222,7 @@ index 0000000..b490dbd +#include +#include +#include ++#include + +extern unsigned long *contiguous_bitmap; + @@ -17732,10 +17737,15 @@ index 0000000..b490dbd + + kmap_init(); + -+ /* Switch to the real shared_info page, and clear the dummy page. */ -+ set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); -+ HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); -+ memset(empty_zero_page, 0, sizeof(empty_zero_page)); ++ if (!xen_feature(XENFEAT_auto_translated_physmap) || ++ xen_start_info->shared_info >= xen_start_info->nr_pages) { ++ /* Switch to the real shared_info page, and clear the ++ * dummy page. */ ++ set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); ++ HYPERVISOR_shared_info = ++ (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); ++ memset(empty_zero_page, 0, sizeof(empty_zero_page)); ++ } + + /* Setup mapping of lower 1st MB */ + for (i = 0; i < NR_FIX_ISAMAPS; i++) @@ -18022,10 +18032,10 @@ index 0000000..b490dbd +#endif diff --git a/arch/i386/mm/ioremap-xen.c b/arch/i386/mm/ioremap-xen.c new file mode 100644 -index 0000000..a9a32ba +index 0000000..05f3daa --- /dev/null +++ b/arch/i386/mm/ioremap-xen.c -@@ -0,0 +1,462 @@ +@@ -0,0 +1,464 @@ +/* + * arch/i386/mm/ioremap.c + * @@ -18060,13 +18070,13 @@ index 0000000..a9a32ba +#endif + +static int direct_remap_area_pte_fn(pte_t *pte, -+ struct page *pte_page, ++ struct page *pmd_page, + unsigned long address, + void *data) +{ + mmu_update_t **v = (mmu_update_t **)data; + -+ (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pte_page)) << ++ (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) << + PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK); + (*v)++; + @@ -18095,9 +18105,9 @@ index 0000000..a9a32ba + for (i = 0; i < size; i += PAGE_SIZE) { + if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) { + /* Fill in the PTE pointers. */ -+ rc = generic_page_range(mm, start_address, -+ address - start_address, -+ direct_remap_area_pte_fn, &w); ++ rc = apply_to_page_range(mm, start_address, ++ address - start_address, ++ direct_remap_area_pte_fn, &w); + if (rc) + goto out; + w = u; @@ -18121,8 +18131,9 @@ index 0000000..a9a32ba + + if (v != u) { + /* get the ptep's filled in */ -+ rc = generic_page_range(mm, start_address, address - start_address, -+ direct_remap_area_pte_fn, &w); ++ rc = apply_to_page_range(mm, start_address, ++ address - start_address, ++ direct_remap_area_pte_fn, &w); + if (rc) + goto out; + rc = -EFAULT; @@ -18170,11 +18181,11 @@ index 0000000..a9a32ba +EXPORT_SYMBOL(direct_kernel_remap_pfn_range); + +static int lookup_pte_fn( -+ pte_t *pte, struct page *pte_page, unsigned long addr, void *data) ++ pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) +{ + uint64_t *ptep = (uint64_t *)data; + if (ptep) -+ *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pte_page)) << ++ *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) << + PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK); + return 0; +} @@ -18183,13 +18194,14 @@ index 0000000..a9a32ba + unsigned long address, + uint64_t *ptep) +{ -+ return generic_page_range(mm, address, PAGE_SIZE, lookup_pte_fn, ptep); ++ return apply_to_page_range(mm, address, PAGE_SIZE, ++ lookup_pte_fn, ptep); +} + +EXPORT_SYMBOL(create_lookup_pte_addr); + +static int noop_fn( -+ pte_t *pte, struct page *pte_page, unsigned long addr, void *data) ++ pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) +{ + return 0; +} @@ -18198,7 +18210,7 @@ index 0000000..a9a32ba + unsigned long address, + unsigned long size) +{ -+ return generic_page_range(mm, address, size, noop_fn, NULL); ++ return apply_to_page_range(mm, address, size, noop_fn, NULL); +} + +EXPORT_SYMBOL(touch_pte_range); @@ -18488,12 +18500,25 @@ index 0000000..a9a32ba + * tab-width: 8 + * End: + */ +diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c +index d0cadb3..c749070 100644 +--- a/arch/i386/mm/pageattr.c ++++ b/arch/i386/mm/pageattr.c +@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns + unsigned long flags; + + set_pte_atomic(kpte, pte); /* change init_mm */ +- if (PTRS_PER_PMD > 1) ++ if (HAVE_SHARED_KERNEL_PMD) + return; + + spin_lock_irqsave(&pgd_lock, flags); diff --git a/arch/i386/mm/pgtable-xen.c b/arch/i386/mm/pgtable-xen.c new file mode 100644 -index 0000000..c2d97b5 +index 0000000..b6109de --- /dev/null +++ b/arch/i386/mm/pgtable-xen.c -@@ -0,0 +1,646 @@ +@@ -0,0 +1,652 @@ +/* + * linux/arch/i386/mm/pgtable.c + */ @@ -19083,6 +19108,8 @@ index 0000000..c2d97b5 + +void mm_pin(struct mm_struct *mm) +{ ++ if (xen_feature(XENFEAT_writable_page_tables)) ++ return; + spin_lock(&mm->page_table_lock); + __pgd_pin(mm->pgd); + spin_unlock(&mm->page_table_lock); @@ -19090,6 +19117,8 @@ index 0000000..c2d97b5 + +void mm_unpin(struct mm_struct *mm) +{ ++ if (xen_feature(XENFEAT_writable_page_tables)) ++ return; + spin_lock(&mm->page_table_lock); + __pgd_unpin(mm->pgd); + spin_unlock(&mm->page_table_lock); @@ -19098,6 +19127,8 @@ index 0000000..c2d97b5 +void mm_pin_all(void) +{ + struct page *page; ++ if (xen_feature(XENFEAT_writable_page_tables)) ++ return; + for (page = pgd_list; page; page = (struct page *)page->index) { + if (!test_bit(PG_pinned, &page->flags)) + __pgd_pin((pgd_t *)page_address(page)); @@ -20481,10 +20512,10 @@ index 8cfa4e8..e74fee6 100644 +obj-$(CONFIG_ACPI_SLEEP) += cpu.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig -index a85ea9d..cea9e5c 100644 +index a85ea9d..3f6f231 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig -@@ -50,6 +50,53 @@ config GENERIC_IOMAP +@@ -50,6 +50,60 @@ config GENERIC_IOMAP bool default y @@ -20534,6 +20565,13 @@ index a85ea9d..cea9e5c 100644 + default n if XEN && !XEN_VT + help + Hack to turn off CONFIG_VT for domU ++ ++config XEN_SYSFS ++ bool "Export Xen attributes in sysfs" ++ depends on XEN && SYSFS ++ default y ++ help ++ Xen hypervisor attributes will show up under /sys/hypervisor/. + config SCHED_NO_NO_OMIT_FRAME_POINTER bool @@ -20865,10 +20903,10 @@ index 0000000..33aecaa +patched/reworked in drivers/xen to work with xenlinux/ia64. diff --git a/arch/ia64/xen/drivers/coreMakefile b/arch/ia64/xen/drivers/coreMakefile new file mode 100644 -index 0000000..40c4f13 +index 0000000..7a35e75 --- /dev/null +++ b/arch/ia64/xen/drivers/coreMakefile -@@ -0,0 +1,24 @@ +@@ -0,0 +1,26 @@ +# +# Makefile for the linux kernel. +# @@ -20893,6 +20931,8 @@ index 0000000..40c4f13 +obj-$(CONFIG_SMP) += smp.o # setup_profiling_timer def'd in ia64 +obj-$(CONFIG_NET) += skbuff.o # until networking is up on ia64 +endif ++obj-$(CONFIG_SYSFS) += hypervisor_sysfs.o ++obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o diff --git a/arch/ia64/xen/drivers/evtchn_ia64.c b/arch/ia64/xen/drivers/evtchn_ia64.c new file mode 100644 index 0000000..fa753e5 @@ -21432,10 +21472,10 @@ index 0000000..8d441df +#endif diff --git a/arch/ia64/xen/hypercall.S b/arch/ia64/xen/hypercall.S new file mode 100644 -index 0000000..6fb0a90 +index 0000000..6a12ed9 --- /dev/null +++ b/arch/ia64/xen/hypercall.S -@@ -0,0 +1,323 @@ +@@ -0,0 +1,365 @@ +/* + * Support routines for Xen hypercalls + * @@ -21692,7 +21732,6 @@ index 0000000..6fb0a90 + st8 [r11]=r10 + ;; + br.ret.sptk.many rp -+ ;; +END(xen_set_rr) + +GLOBAL_ENTRY(xen_fc) @@ -21702,7 +21741,16 @@ index 0000000..6fb0a90 +(p7) fc r32;; +(p7) br.ret.sptk.many rp + ;; -+ ptc.e r96 // this is a "privified" fc r32 ++ movl r9=XSI_PSR_IC ++ mov r8=r32 ++ ;; ++ ld8 r10=[r9] ++ ;; ++ st8 [r9]=r0 ++ ;; ++ XEN_HYPER_FC ++ ;; ++ st8 [r9]=r10 + ;; + br.ret.sptk.many rp +END(xen_fc) @@ -21714,7 +21762,16 @@ index 0000000..6fb0a90 +(p7) mov r8=cpuid[r32];; +(p7) br.ret.sptk.many rp + ;; -+ mov r72=rr[r32] // this is a "privified" mov r8=cpuid[r32] ++ movl r9=XSI_PSR_IC ++ mov r8=r32 ++ ;; ++ ld8 r10=[r9] ++ ;; ++ st8 [r9]=r0 ++ ;; ++ XEN_HYPER_GET_CPUID ++ ;; ++ st8 [r9]=r10 + ;; + br.ret.sptk.many rp +END(xen_get_cpuid) @@ -21726,7 +21783,16 @@ index 0000000..6fb0a90 +(p7) mov r8=pmd[r32];; +(p7) br.ret.sptk.many rp + ;; -+ mov r72=pmc[r32] // this is a "privified" mov r8=pmd[r32] ++ movl r9=XSI_PSR_IC ++ mov r8=r32 ++ ;; ++ ld8 r10=[r9] ++ ;; ++ st8 [r9]=r0 ++ ;; ++ XEN_HYPER_GET_PMD ++ ;; ++ st8 [r9]=r10 + ;; + br.ret.sptk.many rp +END(xen_get_pmd) @@ -21739,10 +21805,20 @@ index 0000000..6fb0a90 +(p7) mov r8=ar24;; +(p7) br.ret.sptk.many rp + ;; -+ mov ar24=r72 // this is a "privified" mov r8=ar.eflg ++ movl r9=XSI_PSR_IC ++ mov r8=r32 ++ ;; ++ ld8 r10=[r9] ++ ;; ++ st8 [r9]=r0 ++ ;; ++ XEN_HYPER_GET_EFLAG ++ ;; ++ st8 [r9]=r10 + ;; + br.ret.sptk.many rp +END(xen_get_eflag) ++ +// some bits aren't set if pl!=0, see SDM vol1 3.1.8 +GLOBAL_ENTRY(xen_set_eflag) + movl r8=running_on_xen;; @@ -21751,13 +21827,19 @@ index 0000000..6fb0a90 +(p7) mov ar24=r32 +(p7) br.ret.sptk.many rp + ;; -+ // FIXME: this remains no-op'd because it generates -+ // a privileged register (general exception) trap rather than -+ // a privileged operation fault -+ //mov ar24=r32 ++ movl r9=XSI_PSR_IC ++ mov r8=r32 ++ ;; ++ ld8 r10=[r9] ++ ;; ++ st8 [r9]=r0 ++ ;; ++ XEN_HYPER_SET_EFLAG ++ ;; ++ st8 [r9]=r10 + ;; + br.ret.sptk.many rp -+END(xen_get_eflag) ++END(xen_set_eflag) +#endif diff --git a/arch/ia64/xen/xen_ksyms.c b/arch/ia64/xen/xen_ksyms.c new file mode 100644 @@ -22685,10 +22767,10 @@ index 0000000..3bc6cdb + diff --git a/arch/ia64/xen/xenivt.S b/arch/ia64/xen/xenivt.S new file mode 100644 -index 0000000..d53b52a +index 0000000..793d1b4 --- /dev/null +++ b/arch/ia64/xen/xenivt.S -@@ -0,0 +1,2044 @@ +@@ -0,0 +1,2032 @@ +/* + * arch/ia64/xen/ivt.S + * @@ -23414,16 +23496,12 @@ index 0000000..d53b52a + movl r30=1f // load continuation point in case of nested fault + ;; +#ifdef CONFIG_XEN -+#if 1 + mov r18=r8; + mov r8=r16; + XEN_HYPER_THASH;; + mov r17=r8; + mov r8=r18;; +#else -+ tak r17=r80 // "privified" thash -+#endif -+#else + thash r17=r16 // compute virtual address of L3 PTE +#endif + mov r29=b0 // save b0 in case of nested fault @@ -23503,16 +23581,12 @@ index 0000000..d53b52a +#endif /* CONFIG_ITANIUM */ + ;; +#ifdef CONFIG_XEN -+#if 1 + mov r18=r8; + mov r8=r16; + XEN_HYPER_THASH;; + mov r17=r8; + mov r8=r18;; +#else -+ tak r17=r80 // "privified" thash -+#endif -+#else + thash r17=r16 // compute virtual address of L3 PTE +#endif + mov r29=b0 // save b0 in case of nested fault) @@ -23589,16 +23663,12 @@ index 0000000..d53b52a + movl r30=1f // load continuation point in case of nested fault + ;; +#ifdef CONFIG_XEN -+#if 1 + mov r18=r8; + mov r8=r16; + XEN_HYPER_THASH;; + mov r17=r8; + mov r8=r18;; +#else -+ tak r17=r80 // "privified" thash -+#endif -+#else + thash r17=r16 // compute virtual address of L3 PTE +#endif + mov r31=pr @@ -25249,7 +25319,7 @@ index 544665e..dece10d 100644 int is_remapped(void *virt) diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig -index e18eb79..75e35a5 100644 +index e18eb79..a700ee7 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -119,6 +119,22 @@ config GENERIC_CPU @@ -25311,7 +25381,7 @@ index e18eb79..75e35a5 100644 config MTRR bool "MTRR (Memory Type Range Register) support" -+ depends on !X86_64_XEN ++ depends on !XEN_UNPRIVILEGED_GUEST ---help--- On Intel P6 family processors (Pentium Pro, Pentium II and later) the Memory Type Range Registers (MTRRs) may be used to control @@ -26515,10 +26585,10 @@ index 4fe9707..aa84f6e 100644 +boot-$(CONFIG_XEN) := ../../../i386/kernel/acpi/boot-xen.o diff --git a/arch/x86_64/kernel/apic-xen.c b/arch/x86_64/kernel/apic-xen.c new file mode 100644 -index 0000000..f27b0e3 +index 0000000..3152b91 --- /dev/null +++ b/arch/x86_64/kernel/apic-xen.c -@@ -0,0 +1,200 @@ +@@ -0,0 +1,198 @@ +/* + * Local APIC handling, local APIC timers + * @@ -26635,8 +26705,6 @@ index 0000000..f27b0e3 + irq_exit(); +} + -+int __initdata unsync_tsc_on_multicluster; -+ +/* + * This interrupt should _never_ happen with our APIC/SMP architecture + */ @@ -27797,10 +27865,10 @@ index 0000000..c1eb6b5 +__setup("earlyprintk=", setup_early_printk); diff --git a/arch/x86_64/kernel/entry-xen.S b/arch/x86_64/kernel/entry-xen.S new file mode 100644 -index 0000000..dc41c56 +index 0000000..546d3a6 --- /dev/null +++ b/arch/x86_64/kernel/entry-xen.S -@@ -0,0 +1,1138 @@ +@@ -0,0 +1,1139 @@ +/* + * linux/arch/x86_64/entry.S + * @@ -28619,7 +28687,7 @@ index 0000000..dc41c56 + jmp error_exit + +#ifdef CONFIG_X86_LOCAL_APIC -+ENTRY(nmi) ++KPROBE_ENTRY(nmi) + zeroentry do_nmi_callback +ENTRY(do_nmi_callback) + addq $8, %rsp @@ -28629,6 +28697,7 @@ index 0000000..dc41c56 + XEN_BLOCK_EVENTS(%rsi) + GET_THREAD_INFO(%rcx) + jmp retint_restore_args ++ .previous .text +#endif + + ALIGN @@ -34277,10 +34346,10 @@ index 0000000..4c40063 +#endif diff --git a/arch/x86_64/kernel/setup-xen.c b/arch/x86_64/kernel/setup-xen.c new file mode 100644 -index 0000000..be0853d +index 0000000..be3961b --- /dev/null +++ b/arch/x86_64/kernel/setup-xen.c -@@ -0,0 +1,1619 @@ +@@ -0,0 +1,1647 @@ +/* + * linux/arch/x86-64/kernel/setup.c + * @@ -34376,6 +34445,11 @@ index 0000000..be0853d +/* Allows setting of maximum possible memory size */ +unsigned long xen_override_max_pfn; + ++static int xen_panic_event(struct notifier_block *, unsigned long, void *); ++static struct notifier_block xen_panic_block = { ++ xen_panic_event, NULL, 0 /* try to go last */ ++}; ++ +unsigned long *phys_to_machine_mapping; +unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[512]; + @@ -34895,6 +34969,14 @@ index 0000000..be0853d +void __init setup_arch(char **cmdline_p) +{ + unsigned long kernel_end; ++#if defined(CONFIG_XEN) && defined(CONFIG_X86_LOCAL_APIC) ++ struct xennmi_callback cb; ++#endif ++ ++#ifdef CONFIG_XEN ++ /* Register a call for panic conditions. */ ++ notifier_chain_register(&panic_notifier_list, &xen_panic_block); ++#endif + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + kernel_end = 0; /* dummy */ @@ -34932,6 +35014,13 @@ index 0000000..be0853d +#ifdef CONFIG_XEN + setup_xen_features(); + ++ if (xen_feature(XENFEAT_auto_translated_physmap) && ++ xen_start_info->shared_info < xen_start_info->nr_pages) { ++ HYPERVISOR_shared_info = ++ (shared_info_t *)__va(xen_start_info->shared_info); ++ memset(empty_zero_page, 0, sizeof(empty_zero_page)); ++ } ++ + HYPERVISOR_vm_assist(VMASST_CMD_enable, + VMASST_TYPE_writable_pagetables); + @@ -34941,10 +35030,9 @@ index 0000000..be0853d + (unsigned long) system_call); + +#ifdef CONFIG_X86_LOCAL_APIC -+ HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi); ++ cb.handler_address = (unsigned long)&nmi; ++ HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); +#endif -+ -+ modify_cpu_capabilities(&boot_cpu_data); +#endif + + if (!MOUNT_ROOT_RDONLY) @@ -35245,6 +35333,17 @@ index 0000000..be0853d +#endif /* !CONFIG_XEN */ +} + ++#ifdef CONFIG_XEN ++static int ++xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr) ++{ ++ HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash); ++ /* we're never actually going to get here... */ ++ return NOTIFY_DONE; ++} ++#endif /* !CONFIG_XEN */ ++ ++ +static int __cpuinit get_model_name(struct cpuinfo_x86 *c) +{ + unsigned int *v; @@ -35670,8 +35769,6 @@ index 0000000..be0853d + select_idle_routine(c); + detect_ht(c); + -+ modify_cpu_capabilities(c); -+ + /* + * On SMP, boot_cpu_data holds the common feature set between + * all CPUs; so make sure that we indicate which features are @@ -38988,10 +39085,10 @@ index 0000000..dfd2f2d +__setup("pagefaulttrace", enable_pagefaulttrace); diff --git a/arch/x86_64/mm/init-xen.c b/arch/x86_64/mm/init-xen.c new file mode 100644 -index 0000000..0d09c4e +index 0000000..edf63e8 --- /dev/null +++ b/arch/x86_64/mm/init-xen.c -@@ -0,0 +1,1107 @@ +@@ -0,0 +1,1101 @@ +/* + * linux/arch/x86_64/mm/init.c + * @@ -39238,7 +39335,6 @@ index 0000000..0d09c4e + if (pud_none(*pud)) { + pmd = (pmd_t *) spp_getpage(); + make_page_readonly(pmd, XENFEAT_writable_page_tables); -+ xen_pmd_pin(__pa(pmd)); + set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); + if (pmd != pmd_offset(pud, 0)) { + printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0)); @@ -39249,7 +39345,6 @@ index 0000000..0d09c4e + if (pmd_none(*pmd)) { + pte = (pte_t *) spp_getpage(); + make_page_readonly(pte, XENFEAT_writable_page_tables); -+ xen_pte_pin(__pa(pte)); + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); + if (pte != pte_offset_kernel(pmd, 0)) { + printk("PAGETABLE BUG #02!\n"); @@ -39291,7 +39386,6 @@ index 0000000..0d09c4e + + pmd = (pmd_t *) spp_getpage(); + make_page_readonly(pmd, XENFEAT_writable_page_tables); -+ xen_pmd_pin(__pa(pmd)); + + set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); + @@ -39305,7 +39399,6 @@ index 0000000..0d09c4e + if (pmd_none(*pmd)) { + pte = (pte_t *) spp_getpage(); + make_page_readonly(pte, XENFEAT_writable_page_tables); -+ xen_pte_pin(__pa(pte)); + + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); + if (pte != pte_offset_kernel(pmd, 0)) { @@ -39455,7 +39548,6 @@ index 0000000..0d09c4e + } + pte = pte_save; + early_make_page_readonly(pte, XENFEAT_writable_page_tables); -+ xen_pte_pin(pte_phys); + set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE)); + } +} @@ -39494,7 +39586,6 @@ index 0000000..0d09c4e + + pmd = alloc_static_page(&pmd_phys); + early_make_page_readonly(pmd, XENFEAT_writable_page_tables); -+ xen_pmd_pin(pmd_phys); + spin_lock(&init_mm.page_table_lock); + set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); + phys_pmd_init(pmd, paddr, end); @@ -39539,9 +39630,6 @@ index 0000000..0d09c4e + + xen_pgd_pin(__pa_symbol(init_level4_pgt)); + xen_pgd_pin(__pa_symbol(init_level4_user_pgt)); -+ xen_pud_pin(__pa_symbol(level3_kernel_pgt)); -+ xen_pud_pin(__pa_symbol(level3_user_pgt)); -+ xen_pmd_pin(__pa_symbol(level2_kernel_pgt)); + + set_pgd((pgd_t *)(init_level4_user_pgt + 511), + mk_kernel_pgd(__pa_symbol(level3_user_pgt))); @@ -39575,7 +39663,6 @@ index 0000000..0d09c4e + pte_page = alloc_static_page(&phys); + early_make_page_readonly( + pte_page, XENFEAT_writable_page_tables); -+ xen_pte_pin(phys); + set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER)); + } else { + addr = page[pmd_index(va)]; @@ -39656,7 +39743,6 @@ index 0000000..0d09c4e + pud = alloc_static_page(&pud_phys); + early_make_page_readonly(pud, XENFEAT_writable_page_tables); + } -+ xen_pud_pin(pud_phys); + next = start + PGDIR_SIZE; + if (next > end) + next = end; @@ -39751,10 +39837,16 @@ index 0000000..0d09c4e + free_area_init_node(0, NODE_DATA(0), zones, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes); + -+ set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); -+ HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); ++ if (!xen_feature(XENFEAT_auto_translated_physmap) || ++ xen_start_info->shared_info >= xen_start_info->nr_pages) { ++ /* Switch to the real shared_info page, and clear the ++ * dummy page. */ ++ set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info); ++ HYPERVISOR_shared_info = ++ (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); ++ memset(empty_zero_page, 0, sizeof(empty_zero_page)); ++ } + -+ memset(empty_zero_page, 0, sizeof(empty_zero_page)); + init_mm.context.pinned = 1; + + /* Setup mapping of lower 1st MB */ @@ -39931,7 +40023,6 @@ index 0000000..0d09c4e + ClearPageReserved(virt_to_page(addr)); + set_page_count(virt_to_page(addr), 1); + memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); -+ xen_pte_unpin(__pa(addr)); + make_page_writable( + __va(__pa(addr)), XENFEAT_writable_page_tables); + /* @@ -40101,10 +40192,10 @@ index 0000000..0d09c4e + */ diff --git a/arch/x86_64/mm/pageattr-xen.c b/arch/x86_64/mm/pageattr-xen.c new file mode 100644 -index 0000000..a2305bc +index 0000000..8ac6663 --- /dev/null +++ b/arch/x86_64/mm/pageattr-xen.c -@@ -0,0 +1,382 @@ +@@ -0,0 +1,391 @@ +/* + * Copyright 2002 Andi Kleen, SuSE Labs. + * Thanks to Ben LaHaise for precious feedback. @@ -40178,6 +40269,9 @@ index 0000000..a2305bc + +void mm_pin(struct mm_struct *mm) +{ ++ if (xen_feature(XENFEAT_writable_page_tables)) ++ return; ++ + spin_lock(&mm->page_table_lock); + + mm_walk(mm, PAGE_KERNEL_RO); @@ -40201,6 +40295,9 @@ index 0000000..a2305bc + +void mm_unpin(struct mm_struct *mm) +{ ++ if (xen_feature(XENFEAT_writable_page_tables)) ++ return; ++ + spin_lock(&mm->page_table_lock); + + xen_pgd_unpin(__pa(mm->pgd)); @@ -40223,6 +40320,9 @@ index 0000000..a2305bc + +void mm_pin_all(void) +{ ++ if (xen_feature(XENFEAT_writable_page_tables)) ++ return; ++ + while (!list_empty(&mm_unpinned)) + mm_pin(list_entry(mm_unpinned.next, struct mm_struct, + context.unpinned)); @@ -40572,6 +40672,22 @@ index 31d4f3f..a60095a 100644 if (!rsdp) { printk(KERN_WARNING PREFIX "Unable to map RSDP\n"); return -ENODEV; +diff --git a/drivers/base/bus.c b/drivers/base/bus.c +index c314156..ae89ed5 100644 +--- a/drivers/base/bus.c ++++ b/drivers/base/bus.c +@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device + up(&dev->sem); + if (dev->parent) + up(&dev->parent->sem); ++ ++ if (err > 0) /* success */ ++ err = count; ++ else if (err == 0) /* driver didn't accept device */ ++ err = -ENODEV; + } + put_device(dev); + put_bus(bus); diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 29c41f4..e65a3ef 100644 --- a/drivers/char/mem.c @@ -42100,10 +42216,10 @@ index 7c74e73..73116e3 100644 /* diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig new file mode 100644 -index 0000000..7a6a569 +index 0000000..f452b2f --- /dev/null +++ b/drivers/xen/Kconfig -@@ -0,0 +1,200 @@ +@@ -0,0 +1,210 @@ +# +# This Kconfig describe xen options +# @@ -42136,12 +42252,14 @@ index 0000000..7a6a569 + default !XEN_PRIVILEGED_GUEST + +config XEN_PCIDEV_BACKEND -+ bool "PCI device backend driver" -+ select PCI -+ default y if XEN_PRIVILEGED_GUEST ++ tristate "PCI device backend driver" ++ depends PCI ++ default XEN_PRIVILEGED_GUEST + help + The PCI device backend driver allows the kernel to export arbitrary -+ PCI devices to other guests. ++ PCI devices to other guests. If you select this to be a module, you ++ will need to make sure no other driver has bound to the device(s) ++ you want to make visible to other guests. + +choice + prompt "PCI Backend Mode" @@ -42293,6 +42411,14 @@ index 0000000..7a6a569 + Disable serial port drivers, allowing the Xen console driver + to provide a serial console at ttyS0. + ++config XEN_SYSFS ++ tristate "Export Xen attributes in sysfs" ++ depends on XEN ++ depends on SYSFS ++ default y ++ help ++ Xen hypervisor attributes will show up under /sys/hypervisor/. ++ +endmenu + +config HAVE_ARCH_ALLOC_SKB @@ -42342,10 +42468,10 @@ index 0000000..0e3a348 +obj-y += balloon.o diff --git a/drivers/xen/balloon/balloon.c b/drivers/xen/balloon/balloon.c new file mode 100644 -index 0000000..6a70087 +index 0000000..6f8039a --- /dev/null +++ b/drivers/xen/balloon/balloon.c -@@ -0,0 +1,585 @@ +@@ -0,0 +1,592 @@ +/****************************************************************************** + * balloon.c + * @@ -42355,8 +42481,11 @@ index 0000000..6a70087 + * Copyright (c) 2003-2004, M Williamson, K Fraser + * Copyright (c) 2005 Dan M. Smith, IBM Corporation + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -42816,6 +42945,7 @@ index 0000000..6a70087 + return -1; + + current_pages = min(xen_start_info->nr_pages, max_pfn); ++ totalram_pages = current_pages; + target_pages = current_pages; + balloon_low = 0; + balloon_high = 0; @@ -42861,7 +42991,7 @@ index 0000000..6a70087 +} + +static int dealloc_pte_fn( -+ pte_t *pte, struct page *pte_page, unsigned long addr, void *data) ++ pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) +{ + unsigned long mfn = pte_mfn(*pte); + int ret; @@ -42891,10 +43021,11 @@ index 0000000..6a70087 + scrub_pages(vstart, 1 << order); + + balloon_lock(flags); -+ ret = generic_page_range( -+ &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL); ++ ret = apply_to_page_range(&init_mm, vstart, ++ PAGE_SIZE << order, dealloc_pte_fn, NULL); + BUG_ON(ret); + current_pages -= 1UL << order; ++ totalram_pages = current_pages; + balloon_unlock(flags); + + schedule_work(&balloon_worker); @@ -42918,9 +43049,11 @@ index 0000000..6a70087 + schedule_work(&balloon_worker); +} + -+EXPORT_SYMBOL(balloon_update_driver_allowance); -+EXPORT_SYMBOL(balloon_alloc_empty_page_range); -+EXPORT_SYMBOL(balloon_dealloc_empty_page_range); ++EXPORT_SYMBOL_GPL(balloon_update_driver_allowance); ++EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range); ++EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range); ++ ++MODULE_LICENSE("Dual BSD/GPL"); + +/* + * Local variables: @@ -42942,10 +43075,10 @@ index 0000000..8bab63d +blkbk-y := blkback.o xenbus.o interface.o vbd.o diff --git a/drivers/xen/blkback/blkback.c b/drivers/xen/blkback/blkback.c new file mode 100644 -index 0000000..d624caf +index 0000000..2de5f1c --- /dev/null +++ b/drivers/xen/blkback/blkback.c -@@ -0,0 +1,596 @@ +@@ -0,0 +1,620 @@ +/****************************************************************************** + * arch/xen/drivers/blkif/backend/main.c + * @@ -42957,6 +43090,30 @@ index 0000000..d624caf + * + * Copyright (c) 2003-2004, Keir Fraser & Steve Hand + * Copyright (c) 2005, Christopher Clark ++ * ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. + */ + +#include @@ -43544,10 +43701,35 @@ index 0000000..d624caf + */ diff --git a/drivers/xen/blkback/common.h b/drivers/xen/blkback/common.h new file mode 100644 -index 0000000..aab5a9f +index 0000000..502a02c --- /dev/null +++ b/drivers/xen/blkback/common.h -@@ -0,0 +1,123 @@ +@@ -0,0 +1,148 @@ ++/* ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ + +#ifndef __BLKIF__BACKEND__COMMON_H__ +#define __BLKIF__BACKEND__COMMON_H__ @@ -43673,16 +43855,40 @@ index 0000000..aab5a9f + */ diff --git a/drivers/xen/blkback/interface.c b/drivers/xen/blkback/interface.c new file mode 100644 -index 0000000..090d107 +index 0000000..75b9f74 --- /dev/null +++ b/drivers/xen/blkback/interface.c -@@ -0,0 +1,164 @@ +@@ -0,0 +1,188 @@ +/****************************************************************************** + * arch/xen/drivers/blkif/backend/interface.c + * + * Block-device interface management. + * + * Copyright (c) 2004, Keir Fraser ++ * ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. + */ + +#include "common.h" @@ -43843,16 +44049,40 @@ index 0000000..090d107 + */ diff --git a/drivers/xen/blkback/vbd.c b/drivers/xen/blkback/vbd.c new file mode 100644 -index 0000000..b2d0939 +index 0000000..d1d38dc --- /dev/null +++ b/drivers/xen/blkback/vbd.c -@@ -0,0 +1,102 @@ +@@ -0,0 +1,126 @@ +/****************************************************************************** + * blkback/vbd.c + * + * Routines for managing virtual block devices (VBDs). + * + * Copyright (c) 2003-2005, Keir Fraser & Steve Hand ++ * ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. + */ + +#include "common.h" @@ -43951,10 +44181,10 @@ index 0000000..b2d0939 + */ diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c new file mode 100644 -index 0000000..b1934d1 +index 0000000..82625a9 --- /dev/null +++ b/drivers/xen/blkback/xenbus.c -@@ -0,0 +1,421 @@ +@@ -0,0 +1,419 @@ +/* Xenbus code for blkif backend + Copyright (C) 2005 Rusty Russell + Copyright (C) 2005 XenSource Ltd @@ -44073,15 +44303,13 @@ index 0000000..b1934d1 + const struct xenbus_device_id *id) +{ + int err; -+ struct backend_info *be = kmalloc(sizeof(struct backend_info), ++ struct backend_info *be = kzalloc(sizeof(struct backend_info), + GFP_KERNEL); + if (!be) { + xenbus_dev_fatal(dev, -ENOMEM, + "allocating backend structure"); + return -ENOMEM; + } -+ memset(be, 0, sizeof(*be)); -+ + be->dev = dev; + dev->data = be; + @@ -44401,10 +44629,10 @@ index 0000000..182ef65 + diff --git a/drivers/xen/blkfront/blkfront.c b/drivers/xen/blkfront/blkfront.c new file mode 100644 -index 0000000..c8c9dec +index 0000000..6e29fa3 --- /dev/null +++ b/drivers/xen/blkfront/blkfront.c -@@ -0,0 +1,831 @@ +@@ -0,0 +1,821 @@ +/****************************************************************************** + * blkfront.c + * @@ -44497,26 +44725,21 @@ index 0000000..c8c9dec + return err; + } + -+ info = kmalloc(sizeof(*info), GFP_KERNEL); ++ info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); + return -ENOMEM; + } ++ + info->xbdev = dev; + info->vdevice = vdevice; + info->connected = BLKIF_STATE_DISCONNECTED; -+ info->mi = NULL; -+ info->gd = NULL; + INIT_WORK(&info->work, blkif_restart_queue, (void *)info); + -+ info->shadow_free = 0; -+ memset(info->shadow, 0, sizeof(info->shadow)); + for (i = 0; i < BLK_RING_SIZE; i++) + info->shadow[i].req.id = i+1; + info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; + -+ info->users = 0; -+ + /* Front end dir is a number, which is used as the id. */ + info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0); + dev->data = info; @@ -44759,11 +44982,7 @@ index 0000000..c8c9dec + + DPRINTK("blkfront_closing: %s removed\n", dev->nodename); + -+ if (info->mi) { -+ DPRINTK("Calling xlvbd_del\n"); -+ xlvbd_del(info); -+ info->mi = NULL; -+ } ++ xlvbd_del(info); + + xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed); +} @@ -45226,7 +45445,6 @@ index 0000000..c8c9dec + +MODULE_LICENSE("Dual BSD/GPL"); + -+ +/* + * Local variables: + * c-file-style: "linux" @@ -45238,10 +45456,10 @@ index 0000000..c8c9dec + */ diff --git a/drivers/xen/blkfront/block.h b/drivers/xen/blkfront/block.h new file mode 100644 -index 0000000..ecede04 +index 0000000..d6a9314 --- /dev/null +++ b/drivers/xen/blkfront/block.h -@@ -0,0 +1,162 @@ +@@ -0,0 +1,165 @@ +/****************************************************************************** + * block.h + * @@ -45251,8 +45469,11 @@ index 0000000..ecede04 + * Modifications by Mark A. Williamson are (c) Intel Research Cambridge + * Copyright (c) 2004-2005, Christian Limpach + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -45406,10 +45627,10 @@ index 0000000..ecede04 + */ diff --git a/drivers/xen/blkfront/vbd.c b/drivers/xen/blkfront/vbd.c new file mode 100644 -index 0000000..d97f798 +index 0000000..830b3dd --- /dev/null +++ b/drivers/xen/blkfront/vbd.c -@@ -0,0 +1,323 @@ +@@ -0,0 +1,327 @@ +/****************************************************************************** + * vbd.c + * @@ -45419,8 +45640,11 @@ index 0000000..d97f798 + * Modifications by Mark A. Williamson are (c) Intel Research Cambridge + * Copyright (c) 2004-2005, Christian Limpach + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -45509,12 +45733,10 @@ index 0000000..d97f798 +{ + struct xlbd_major_info *ptr; + -+ ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL); ++ ptr = kzalloc(sizeof(struct xlbd_major_info), GFP_KERNEL); + if (ptr == NULL) + return NULL; + -+ memset(ptr, 0, sizeof(struct xlbd_major_info)); -+ + ptr->major = major; + + switch (index) { @@ -45628,6 +45850,10 @@ index 0000000..d97f798 + int nr_minors = 1; + int err = -ENODEV; + ++ BUG_ON(info->gd != NULL); ++ BUG_ON(info->mi != NULL); ++ BUG_ON(info->rq != NULL); ++ + mi = xlbd_get_major_info(vdevice); + if (mi == NULL) + goto out; @@ -45680,6 +45906,7 @@ index 0000000..d97f798 + out: + if (mi) + xlbd_put_major_info(mi); ++ info->mi = NULL; + return err; +} + @@ -45706,22 +45933,20 @@ index 0000000..d97f798 +void +xlvbd_del(struct blkfront_info *info) +{ -+ struct block_device *bd; -+ -+ bd = bdget(info->dev); -+ if (bd == NULL) -+ return; -+ -+ if (info->gd == NULL) ++ if (info->mi == NULL) + return; + ++ BUG_ON(info->gd == NULL); + del_gendisk(info->gd); + put_disk(info->gd); ++ info->gd = NULL; ++ + xlbd_put_major_info(info->mi); + info->mi = NULL; -+ blk_cleanup_queue(info->rq); + -+ bdput(bd); ++ BUG_ON(info->rq == NULL); ++ blk_cleanup_queue(info->rq); ++ info->rq = NULL; +} + +/* @@ -46928,10 +47153,10 @@ index 0000000..99cb7bf + */ diff --git a/drivers/xen/blktap/xenbus.c b/drivers/xen/blktap/xenbus.c new file mode 100644 -index 0000000..3dc9167 +index 0000000..d97660d --- /dev/null +++ b/drivers/xen/blktap/xenbus.c -@@ -0,0 +1,234 @@ +@@ -0,0 +1,233 @@ +/* Xenbus code for blkif tap + + A Warfield. @@ -47075,12 +47300,11 @@ index 0000000..3dc9167 + char *frontend; + int err; + -+ be = kmalloc(sizeof(*be), GFP_KERNEL); ++ be = kzalloc(sizeof(*be), GFP_KERNEL); + if (!be) { + xenbus_dev_error(dev, -ENOMEM, "allocating backend structure"); + return -ENOMEM; + } -+ memset(be, 0, sizeof(*be)); + + frontend = NULL; + err = xenbus_gather(dev->nodename, @@ -47382,10 +47606,10 @@ index 0000000..35de3e9 +obj-y := console.o xencons_ring.o diff --git a/drivers/xen/console/console.c b/drivers/xen/console/console.c new file mode 100644 -index 0000000..ae8255c +index 0000000..360e550 --- /dev/null +++ b/drivers/xen/console/console.c -@@ -0,0 +1,643 @@ +@@ -0,0 +1,648 @@ +/****************************************************************************** + * console.c + * @@ -47393,8 +47617,11 @@ index 0000000..ae8255c + * + * Copyright (c) 2002-2004, K A Fraser. + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -48020,6 +48247,8 @@ index 0000000..ae8255c + +module_init(xencons_init); + ++MODULE_LICENSE("Dual BSD/GPL"); ++ +/* + * Local variables: + * c-file-style: "linux" @@ -48031,10 +48260,36 @@ index 0000000..ae8255c + */ diff --git a/drivers/xen/console/xencons_ring.c b/drivers/xen/console/xencons_ring.c new file mode 100644 -index 0000000..8abb0a4 +index 0000000..3bb5631 --- /dev/null +++ b/drivers/xen/console/xencons_ring.c -@@ -0,0 +1,125 @@ +@@ -0,0 +1,151 @@ ++/* ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. ++ */ ++ +#include +#include +#include @@ -48162,10 +48417,10 @@ index 0000000..8abb0a4 + */ diff --git a/drivers/xen/core/Makefile b/drivers/xen/core/Makefile new file mode 100644 -index 0000000..1d57a5b +index 0000000..a971d3c --- /dev/null +++ b/drivers/xen/core/Makefile -@@ -0,0 +1,9 @@ +@@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# @@ -48175,12 +48430,14 @@ index 0000000..1d57a5b +obj-$(CONFIG_PROC_FS) += xen_proc.o +obj-$(CONFIG_NET) += skbuff.o +obj-$(CONFIG_SMP) += smpboot.o ++obj-$(CONFIG_SYSFS) += hypervisor_sysfs.o ++obj-$(CONFIG_XEN_SYSFS) += xen_sysfs.o diff --git a/drivers/xen/core/evtchn.c b/drivers/xen/core/evtchn.c new file mode 100644 -index 0000000..58f08c6 +index 0000000..5fbd1e0 --- /dev/null +++ b/drivers/xen/core/evtchn.c -@@ -0,0 +1,822 @@ +@@ -0,0 +1,863 @@ +/****************************************************************************** + * evtchn.c + * @@ -48188,8 +48445,11 @@ index 0000000..58f08c6 + * + * Copyright (c) 2002-2005, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -48238,17 +48498,37 @@ index 0000000..58f08c6 + +/* Packed IRQ information: binding type, sub-type index, and event channel. */ +static u32 irq_info[NR_IRQS]; ++ +/* Binding types. */ +enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN }; ++ +/* Constructor for packed IRQ information. */ -+#define mk_irq_info(type, index, evtchn) \ -+ (((u32)(type) << 24) | ((u32)(index) << 16) | (u32)(evtchn)) ++static inline u32 mk_irq_info(u32 type, u32 index, u32 evtchn) ++{ ++ return ((type << 24) | (index << 16) | evtchn); ++} ++ +/* Convenient shorthand for packed representation of an unbound IRQ. */ +#define IRQ_UNBOUND mk_irq_info(IRQT_UNBOUND, 0, 0) -+/* Accessor macros for packed IRQ information. */ -+#define evtchn_from_irq(irq) ((u16)(irq_info[irq])) -+#define index_from_irq(irq) ((u8)(irq_info[irq] >> 16)) -+#define type_from_irq(irq) ((u8)(irq_info[irq] >> 24)) ++ ++/* ++ * Accessors for packed IRQ information. ++ */ ++ ++static inline unsigned int evtchn_from_irq(int irq) ++{ ++ return (u16)(irq_info[irq]); ++} ++ ++static inline unsigned int index_from_irq(int irq) ++{ ++ return (u8)(irq_info[irq] >> 16); ++} ++ ++static inline unsigned int type_from_irq(int irq) ++{ ++ return (u8)(irq_info[irq] >> 24); ++} + +/* IRQ <-> VIRQ mapping. */ +DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]); @@ -48270,10 +48550,13 @@ index 0000000..58f08c6 +static u8 cpu_evtchn[NR_EVENT_CHANNELS]; +static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG]; + -+#define active_evtchns(cpu,sh,idx) \ -+ ((sh)->evtchn_pending[idx] & \ -+ cpu_evtchn_mask[cpu][idx] & \ -+ ~(sh)->evtchn_mask[idx]) ++static inline unsigned long active_evtchns(unsigned int cpu, shared_info_t *sh, ++ unsigned int idx) ++{ ++ return (sh->evtchn_pending[idx] & ++ cpu_evtchn_mask[cpu][idx] & ++ ~sh->evtchn_mask[idx]); ++} + +static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) +{ @@ -48289,16 +48572,31 @@ index 0000000..58f08c6 + memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0])); +} + -+#define cpu_from_evtchn(evtchn) (cpu_evtchn[evtchn]) ++static inline unsigned int cpu_from_evtchn(unsigned int evtchn) ++{ ++ return cpu_evtchn[evtchn]; ++} + +#else + -+#define active_evtchns(cpu,sh,idx) \ -+ ((sh)->evtchn_pending[idx] & \ -+ ~(sh)->evtchn_mask[idx]) -+#define bind_evtchn_to_cpu(chn,cpu) ((void)0) -+#define init_evtchn_cpu_bindings() ((void)0) -+#define cpu_from_evtchn(evtchn) (0) ++static inline unsigned long active_evtchns(unsigned int cpu, shared_info_t *sh, ++ unsigned int idx) ++{ ++ return (sh->evtchn_pending[idx] & ~sh->evtchn_mask[idx]); ++} ++ ++static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) ++{ ++} ++ ++static void init_evtchn_cpu_bindings(void) ++{ ++} ++ ++static inline unsigned int cpu_from_evtchn(unsigned int evtchn) ++{ ++ return 0; ++} + +#endif + @@ -48330,7 +48628,7 @@ index 0000000..58f08c6 +{ + (void)HYPERVISOR_xen_version(0, NULL); +} -+EXPORT_SYMBOL(force_evtchn_callback); ++EXPORT_SYMBOL_GPL(force_evtchn_callback); + +/* NB. Interrupts are disabled on entry. */ +asmlinkage void evtchn_do_upcall(struct pt_regs *regs) @@ -48506,7 +48804,7 @@ index 0000000..58f08c6 + + return irq; +} -+EXPORT_SYMBOL(bind_evtchn_to_irqhandler); ++EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler); + +int bind_virq_to_irqhandler( + unsigned int virq, @@ -48528,7 +48826,7 @@ index 0000000..58f08c6 + + return irq; +} -+EXPORT_SYMBOL(bind_virq_to_irqhandler); ++EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler); + +int bind_ipi_to_irqhandler( + unsigned int ipi, @@ -48550,14 +48848,14 @@ index 0000000..58f08c6 + + return irq; +} -+EXPORT_SYMBOL(bind_ipi_to_irqhandler); ++EXPORT_SYMBOL_GPL(bind_ipi_to_irqhandler); + +void unbind_from_irqhandler(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); + unbind_from_irq(irq); +} -+EXPORT_SYMBOL(unbind_from_irqhandler); ++EXPORT_SYMBOL_GPL(unbind_from_irqhandler); + +#ifdef CONFIG_SMP +static void do_nothing_function(void *ign) @@ -48822,14 +49120,14 @@ index 0000000..58f08c6 + if (VALID_EVTCHN(evtchn)) + notify_remote_via_evtchn(evtchn); +} -+EXPORT_SYMBOL(notify_remote_via_irq); ++EXPORT_SYMBOL_GPL(notify_remote_via_irq); + +void mask_evtchn(int port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + synch_set_bit(port, &s->evtchn_mask[0]); +} -+EXPORT_SYMBOL(mask_evtchn); ++EXPORT_SYMBOL_GPL(mask_evtchn); + +void unmask_evtchn(int port) +{ @@ -48860,7 +49158,7 @@ index 0000000..58f08c6 + force_evtchn_callback(); + } +} -+EXPORT_SYMBOL(unmask_evtchn); ++EXPORT_SYMBOL_GPL(unmask_evtchn); + +void irq_resume(void) +{ @@ -49005,7 +49303,7 @@ index 0000000..58f08c6 + */ diff --git a/drivers/xen/core/features.c b/drivers/xen/core/features.c new file mode 100644 -index 0000000..297d13f +index 0000000..ad1f0b4 --- /dev/null +++ b/drivers/xen/core/features.c @@ -0,0 +1,29 @@ @@ -49023,7 +49321,7 @@ index 0000000..297d13f +#include + +u8 xen_features[XENFEAT_NR_SUBMAPS * 32] __read_mostly; -+EXPORT_SYMBOL(xen_features); ++EXPORT_SYMBOL_GPL(xen_features); + +void setup_xen_features(void) +{ @@ -49040,10 +49338,10 @@ index 0000000..297d13f +} diff --git a/drivers/xen/core/gnttab.c b/drivers/xen/core/gnttab.c new file mode 100644 -index 0000000..0f1a295 +index 0000000..1049934 --- /dev/null +++ b/drivers/xen/core/gnttab.c -@@ -0,0 +1,426 @@ +@@ -0,0 +1,460 @@ +/****************************************************************************** + * gnttab.c + * @@ -49052,8 +49350,11 @@ index 0000000..0f1a295 + * Copyright (c) 2005, Christopher Clark + * Copyright (c) 2004-2005, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -49077,6 +49378,8 @@ index 0000000..0f1a295 +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -49096,21 +49399,21 @@ index 0000000..0f1a295 + printk(KERN_WARNING "xen_grant: " fmt, ##args) + + -+EXPORT_SYMBOL(gnttab_grant_foreign_access); -+EXPORT_SYMBOL(gnttab_end_foreign_access_ref); -+EXPORT_SYMBOL(gnttab_end_foreign_access); -+EXPORT_SYMBOL(gnttab_query_foreign_access); -+EXPORT_SYMBOL(gnttab_grant_foreign_transfer); -+EXPORT_SYMBOL(gnttab_end_foreign_transfer_ref); -+EXPORT_SYMBOL(gnttab_end_foreign_transfer); -+EXPORT_SYMBOL(gnttab_alloc_grant_references); -+EXPORT_SYMBOL(gnttab_free_grant_references); -+EXPORT_SYMBOL(gnttab_free_grant_reference); -+EXPORT_SYMBOL(gnttab_claim_grant_reference); -+EXPORT_SYMBOL(gnttab_release_grant_reference); -+EXPORT_SYMBOL(gnttab_request_free_callback); -+EXPORT_SYMBOL(gnttab_grant_foreign_access_ref); -+EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref); ++EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); ++EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref); ++EXPORT_SYMBOL_GPL(gnttab_end_foreign_access); ++EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); ++EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer); ++EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref); ++EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer); ++EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references); ++EXPORT_SYMBOL_GPL(gnttab_free_grant_references); ++EXPORT_SYMBOL_GPL(gnttab_free_grant_reference); ++EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference); ++EXPORT_SYMBOL_GPL(gnttab_release_grant_reference); ++EXPORT_SYMBOL_GPL(gnttab_request_free_callback); ++EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref); ++EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref); + +/* External tools reserve first few grant table entries. */ +#define NR_RESERVED_ENTRIES 8 @@ -49123,7 +49426,7 @@ index 0000000..0f1a295 +static grant_ref_t gnttab_free_head; +static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED; + -+static grant_entry_t *shared; ++static grant_entry_t *shared = NULL; + +static struct gnttab_free_callback *gnttab_free_callback_list = NULL; + @@ -49400,26 +49703,57 @@ index 0000000..0f1a295 + spin_unlock_irqrestore(&gnttab_list_lock, flags); +} + ++#ifndef __ia64__ ++static int map_pte_fn(pte_t *pte, struct page *pmd_page, ++ unsigned long addr, void *data) ++{ ++ unsigned long **frames = (unsigned long **)data; ++ ++ set_pte_at(&init_mm, addr, pte, pfn_pte_ma((*frames)[0], PAGE_KERNEL)); ++ (*frames)++; ++ return 0; ++} ++ ++static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, ++ unsigned long addr, void *data) ++{ ++ ++ set_pte_at(&init_mm, addr, pte, __pte(0)); ++ return 0; ++} ++#endif ++ +int +gnttab_resume(void) +{ + gnttab_setup_table_t setup; -+ unsigned long frames[NR_GRANT_FRAMES]; -+ int i; ++ unsigned long frames[NR_GRANT_FRAMES]; ++ int rc; ++#ifndef __ia64__ ++ void *pframes = frames; ++ struct vm_struct *area; ++#endif + + setup.dom = DOMID_SELF; + setup.nr_frames = NR_GRANT_FRAMES; + setup.frame_list = frames; + -+ BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1)); -+ BUG_ON(setup.status != 0); ++ rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1); ++ BUG_ON(rc || setup.status); + -+#ifdef __ia64__ ++#ifndef __ia64__ ++ if (shared == NULL) { ++ area = get_vm_area(PAGE_SIZE * NR_GRANT_FRAMES, VM_IOREMAP); ++ BUG_ON(area == NULL); ++ shared = area->addr; ++ } ++ rc = apply_to_page_range(&init_mm, (unsigned long)shared, ++ PAGE_SIZE * NR_GRANT_FRAMES, ++ map_pte_fn, &pframes); ++ BUG_ON(rc); ++#else + shared = __va(frames[0] << PAGE_SHIFT); + printk("grant table at %p\n", shared); -+#else -+ for (i = 0; i < NR_GRANT_FRAMES; i++) -+ set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT); +#endif + + return 0; @@ -49428,10 +49762,12 @@ index 0000000..0f1a295 +int +gnttab_suspend(void) +{ -+ int i; + -+ for (i = 0; i < NR_GRANT_FRAMES; i++) -+ clear_fixmap(FIX_GNTTAB_END - i); ++#ifndef __ia64__ ++ apply_to_page_range(&init_mm, (unsigned long)shared, ++ PAGE_SIZE * NR_GRANT_FRAMES, ++ unmap_pte_fn, NULL); ++#endif + + return 0; +} @@ -49446,10 +49782,6 @@ index 0000000..0f1a295 + + BUG_ON(gnttab_resume()); + -+#ifndef __ia64__ -+ shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END); -+#endif -+ + for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++) + gnttab_list[i] = i + 1; + gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES; @@ -49470,12 +49802,75 @@ index 0000000..0f1a295 + * tab-width: 8 + * End: + */ +diff --git a/drivers/xen/core/hypervisor_sysfs.c b/drivers/xen/core/hypervisor_sysfs.c +new file mode 100644 +index 0000000..f963902 +--- /dev/null ++++ b/drivers/xen/core/hypervisor_sysfs.c +@@ -0,0 +1,57 @@ ++/* ++ * copyright (c) 2006 IBM Corporation ++ * Authored by: Mike D. Day ++ * ++ * 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 ++ ++decl_subsys(hypervisor, NULL, NULL); ++ ++static ssize_t hyp_sysfs_show(struct kobject *kobj, ++ struct attribute *attr, ++ char *buffer) ++{ ++ struct hyp_sysfs_attr *hyp_attr; ++ hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr); ++ if (hyp_attr->show) ++ return hyp_attr->show(hyp_attr, buffer); ++ return 0; ++} ++ ++static ssize_t hyp_sysfs_store(struct kobject *kobj, ++ struct attribute *attr, ++ const char *buffer, ++ size_t len) ++{ ++ struct hyp_sysfs_attr *hyp_attr; ++ hyp_attr = container_of(attr, struct hyp_sysfs_attr, attr); ++ if (hyp_attr->store) ++ return hyp_attr->store(hyp_attr, buffer, len); ++ return 0; ++} ++ ++struct sysfs_ops hyp_sysfs_ops = { ++ .show = hyp_sysfs_show, ++ .store = hyp_sysfs_store, ++}; ++ ++static struct kobj_type hyp_sysfs_kobj_type = { ++ .sysfs_ops = &hyp_sysfs_ops, ++}; ++ ++static int __init hypervisor_subsys_init(void) ++{ ++ hypervisor_subsys.kset.kobj.ktype = &hyp_sysfs_kobj_type; ++ return subsystem_register(&hypervisor_subsys); ++} ++ ++device_initcall(hypervisor_subsys_init); ++EXPORT_SYMBOL_GPL(hypervisor_subsys); diff --git a/drivers/xen/core/reboot.c b/drivers/xen/core/reboot.c new file mode 100644 -index 0000000..1fa1f56 +index 0000000..e63e404 --- /dev/null +++ b/drivers/xen/core/reboot.c -@@ -0,0 +1,441 @@ +@@ -0,0 +1,425 @@ +#define __KERNEL_SYSCALLS__ +#include +#include @@ -49503,9 +49898,10 @@ index 0000000..1fa1f56 +EXPORT_SYMBOL(pm_power_off); +#endif + ++extern void ctrl_alt_del(void); ++ +#define SHUTDOWN_INVALID -1 +#define SHUTDOWN_POWEROFF 0 -+#define SHUTDOWN_REBOOT 1 +#define SHUTDOWN_SUSPEND 2 +/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only + * report a crash, not be instructed to crash! @@ -49600,7 +49996,7 @@ index 0000000..1fa1f56 + lock_cpu_hotplug(); +#ifdef CONFIG_SMP + /* -+ * Take all other CPUs offline. We hold the hotplug semaphore to ++ * Take all other CPUs offline. We hold the hotplug mutex to + * avoid other processes bringing up CPUs under our feet. + */ + cpus_clear(prev_online_cpus); @@ -49712,33 +50108,19 @@ index 0000000..1fa1f56 +{ + static char *envp[] = { "HOME=/", "TERM=linux", + "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; -+ static char *restart_argv[] = { "/sbin/reboot", NULL }; + static char *poweroff_argv[] = { "/sbin/poweroff", NULL }; + + extern asmlinkage long sys_reboot(int magic1, int magic2, + unsigned int cmd, void *arg); + -+ daemonize("shutdown"); -+ -+ switch (shutting_down) { -+ case SHUTDOWN_POWEROFF: -+ case SHUTDOWN_HALT: ++ if ((shutting_down == SHUTDOWN_POWEROFF) || ++ (shutting_down == SHUTDOWN_HALT)) { + if (execve("/sbin/poweroff", poweroff_argv, envp) < 0) { + sys_reboot(LINUX_REBOOT_MAGIC1, + LINUX_REBOOT_MAGIC2, + LINUX_REBOOT_CMD_POWER_OFF, + NULL); + } -+ break; -+ -+ case SHUTDOWN_REBOOT: -+ if (execve("/sbin/reboot", restart_argv, envp) < 0) { -+ sys_reboot(LINUX_REBOOT_MAGIC1, -+ LINUX_REBOOT_MAGIC2, -+ LINUX_REBOOT_CMD_RESTART, -+ NULL); -+ } -+ break; + } + + shutting_down = SHUTDOWN_INVALID; /* could try again */ @@ -49809,7 +50191,7 @@ index 0000000..1fa1f56 + if (strcmp(str, "poweroff") == 0) + shutting_down = SHUTDOWN_POWEROFF; + else if (strcmp(str, "reboot") == 0) -+ shutting_down = SHUTDOWN_REBOOT; ++ ctrl_alt_del(); + else if (strcmp(str, "suspend") == 0) + shutting_down = SHUTDOWN_SUSPEND; + else if (strcmp(str, "halt") == 0) @@ -49869,8 +50251,6 @@ index 0000000..1fa1f56 +}; +#endif + -+static struct notifier_block xenstore_notifier; -+ +static int setup_shutdown_watcher(struct notifier_block *notifier, + unsigned long event, + void *data) @@ -49898,11 +50278,10 @@ index 0000000..1fa1f56 + +static int __init setup_shutdown_event(void) +{ -+ -+ xenstore_notifier.notifier_call = setup_shutdown_watcher; -+ ++ static struct notifier_block xenstore_notifier = { ++ .notifier_call = setup_shutdown_watcher ++ }; + register_xenstore_notifier(&xenstore_notifier); -+ + return 0; +} + @@ -50572,6 +50951,323 @@ index 0000000..c5a8c14 + * tab-width: 8 + * End: + */ +diff --git a/drivers/xen/core/xen_sysfs.c b/drivers/xen/core/xen_sysfs.c +new file mode 100644 +index 0000000..e26ab7f +--- /dev/null ++++ b/drivers/xen/core/xen_sysfs.c +@@ -0,0 +1,311 @@ ++/* ++ * copyright (c) 2006 IBM Corporation ++ * Authored by: Mike D. Day ++ * ++ * 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 ++#include ++#include ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Mike D. Day "); ++ ++static ssize_t type_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ return sprintf(buffer, "xen\n"); ++} ++ ++HYPERVISOR_ATTR_RO(type); ++ ++static int __init xen_sysfs_type_init(void) ++{ ++ return sysfs_create_file(&hypervisor_subsys.kset.kobj, &type_attr.attr); ++} ++ ++static void xen_sysfs_type_destroy(void) ++{ ++ sysfs_remove_file(&hypervisor_subsys.kset.kobj, &type_attr.attr); ++} ++ ++/* xen version attributes */ ++static ssize_t major_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int version = HYPERVISOR_xen_version(XENVER_version, NULL); ++ if (version) ++ return sprintf(buffer, "%d\n", version >> 16); ++ return -ENODEV; ++} ++ ++HYPERVISOR_ATTR_RO(major); ++ ++static ssize_t minor_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int version = HYPERVISOR_xen_version(XENVER_version, NULL); ++ if (version) ++ return sprintf(buffer, "%d\n", version & 0xff); ++ return -ENODEV; ++} ++ ++HYPERVISOR_ATTR_RO(minor); ++ ++static ssize_t extra_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int ret; ++ char *extra = kmalloc(XEN_EXTRAVERSION_LEN, GFP_KERNEL); ++ if (extra) { ++ ret = HYPERVISOR_xen_version(XENVER_extraversion, extra); ++ if (!ret) ++ return sprintf(buffer, "%s\n", extra); ++ kfree(extra); ++ } else ++ ret = -ENOMEM; ++ return ret; ++} ++ ++HYPERVISOR_ATTR_RO(extra); ++ ++static struct attribute *version_attrs[] = { ++ &major_attr.attr, ++ &minor_attr.attr, ++ &extra_attr.attr, ++ NULL ++}; ++ ++static struct attribute_group version_group = { ++ .name = "version", ++ .attrs = version_attrs, ++}; ++ ++static int __init xen_sysfs_version_init(void) ++{ ++ return sysfs_create_group(&hypervisor_subsys.kset.kobj, &version_group); ++} ++ ++static void xen_sysfs_version_destroy(void) ++{ ++ sysfs_remove_group(&hypervisor_subsys.kset.kobj, &version_group); ++} ++ ++/* xen compilation attributes */ ++ ++static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int ret; ++ struct xen_compile_info *info = ++ kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); ++ if (info) { ++ ret = HYPERVISOR_xen_version(XENVER_compile_info, info); ++ if (!ret) ++ ret = sprintf(buffer, "%s\n", info->compiler); ++ kfree(info); ++ } else ++ ret = -ENOMEM; ++ ++ return ret; ++} ++ ++HYPERVISOR_ATTR_RO(compiler); ++ ++static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int ret; ++ struct xen_compile_info *info; ++ ++ info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); ++ if (info) { ++ ret = HYPERVISOR_xen_version(XENVER_compile_info, info); ++ if (!ret) ++ ret = sprintf(buffer, "%s\n", info->compile_by); ++ kfree(info); ++ } else ++ ret = -ENOMEM; ++ return ret; ++} ++ ++HYPERVISOR_ATTR_RO(compiled_by); ++ ++static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int ret; ++ struct xen_compile_info *info; ++ ++ info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); ++ if (info) { ++ ret = HYPERVISOR_xen_version(XENVER_compile_info, info); ++ if (!ret) ++ ret = sprintf(buffer, "%s\n", info->compile_date); ++ kfree(info); ++ } else ++ ret = -ENOMEM; ++ return ret; ++} ++ ++HYPERVISOR_ATTR_RO(compile_date); ++ ++static struct attribute *xen_compile_attrs[] = { ++ &compiler_attr.attr, ++ &compiled_by_attr.attr, ++ &compile_date_attr.attr, ++ NULL ++}; ++ ++static struct attribute_group xen_compilation_group = { ++ .name = "compilation", ++ .attrs = xen_compile_attrs, ++}; ++ ++int __init static xen_compilation_init(void) ++{ ++ return sysfs_create_group(&hypervisor_subsys.kset.kobj, ++ &xen_compilation_group); ++} ++ ++static void xen_compilation_destroy(void) ++{ ++ sysfs_remove_group(&hypervisor_subsys.kset.kobj, ++ &xen_compilation_group); ++} ++ ++/* xen properties info */ ++ ++static ssize_t capabilities_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int ret; ++ char *caps = kmalloc(XEN_CAPABILITIES_INFO_LEN, GFP_KERNEL); ++ if (caps) { ++ ret = HYPERVISOR_xen_version(XENVER_capabilities, caps); ++ if (!ret) ++ ret = sprintf(buffer, "%s\n", caps); ++ kfree(caps); ++ } else ++ ret = -ENOMEM; ++ return ret; ++} ++ ++HYPERVISOR_ATTR_RO(capabilities); ++ ++static ssize_t changeset_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int ret; ++ char *cset = kmalloc(XEN_CHANGESET_INFO_LEN, GFP_KERNEL); ++ if (cset) { ++ ret = HYPERVISOR_xen_version(XENVER_changeset, cset); ++ if (!ret) ++ ret = sprintf(buffer, "%s\n", cset); ++ kfree(cset); ++ } else ++ ret = -ENOMEM; ++ return ret; ++} ++ ++HYPERVISOR_ATTR_RO(changeset); ++ ++static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ int ret; ++ struct xen_platform_parameters *parms = ++ kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL); ++ if (parms) { ++ ret = HYPERVISOR_xen_version(XENVER_platform_parameters, parms); ++ if (!ret) ++ ret = sprintf(buffer, "%lx\n", parms->virt_start); ++ kfree(parms); ++ } else ++ ret = -ENOMEM; ++ return ret; ++} ++ ++HYPERVISOR_ATTR_RO(virtual_start); ++ ++/* eventually there will be several more features to export */ ++static ssize_t xen_feature_show(int index, char *buffer) ++{ ++ int ret; ++ ++ struct xen_feature_info *info = ++ kmalloc(sizeof(struct xen_feature_info), GFP_KERNEL); ++ if (info) { ++ info->submap_idx = index; ++ ret = HYPERVISOR_xen_version(XENVER_get_features, info); ++ if (!ret) ++ ret = sprintf(buffer, "%d\n", info->submap); ++ kfree(info); ++ } else ++ ret = -ENOMEM; ++ return ret; ++} ++ ++static ssize_t writable_pt_show(struct hyp_sysfs_attr *attr, char *buffer) ++{ ++ return xen_feature_show(XENFEAT_writable_page_tables, buffer); ++} ++ ++HYPERVISOR_ATTR_RO(writable_pt); ++ ++static struct attribute *xen_properties_attrs[] = { ++ &capabilities_attr.attr, ++ &changeset_attr.attr, ++ &virtual_start_attr.attr, ++ &writable_pt_attr.attr, ++ NULL ++}; ++ ++static struct attribute_group xen_properties_group = { ++ .name = "properties", ++ .attrs = xen_properties_attrs, ++}; ++ ++static int __init xen_properties_init(void) ++{ ++ return sysfs_create_group(&hypervisor_subsys.kset.kobj, ++ &xen_properties_group); ++} ++ ++static void xen_properties_destroy(void) ++{ ++ sysfs_remove_group(&hypervisor_subsys.kset.kobj, &xen_properties_group); ++} ++ ++static int __init hyper_sysfs_init(void) ++{ ++ int ret = xen_sysfs_type_init(); ++ if (ret) ++ goto out; ++ ret = xen_sysfs_version_init(); ++ if (ret) ++ goto version_out; ++ ret = xen_compilation_init(); ++ if (ret) ++ goto comp_out; ++ ret = xen_properties_init(); ++ if (!ret) ++ goto out; ++ ++ xen_compilation_destroy(); ++comp_out: ++ xen_sysfs_version_destroy(); ++version_out: ++ xen_sysfs_type_destroy(); ++out: ++ return ret; ++} ++ ++static void hyper_sysfs_exit(void) ++{ ++ xen_properties_destroy(); ++ xen_compilation_destroy(); ++ xen_sysfs_version_destroy(); ++ xen_sysfs_type_destroy(); ++ ++} ++ ++module_init(hyper_sysfs_init); ++module_exit(hyper_sysfs_exit); diff --git a/drivers/xen/evtchn/Makefile b/drivers/xen/evtchn/Makefile new file mode 100644 index 0000000..7b082a0 @@ -50582,10 +51278,10 @@ index 0000000..7b082a0 +obj-y := evtchn.o diff --git a/drivers/xen/evtchn/evtchn.c b/drivers/xen/evtchn/evtchn.c new file mode 100644 -index 0000000..7222429 +index 0000000..2975fe0 --- /dev/null +++ b/drivers/xen/evtchn/evtchn.c -@@ -0,0 +1,459 @@ +@@ -0,0 +1,464 @@ +/****************************************************************************** + * evtchn.c + * @@ -50594,8 +51290,11 @@ index 0000000..7222429 + * Copyright (c) 2004-2005, K A Fraser + * Multi-process extensions Copyright (c) 2004, Steven Smith + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -51036,6 +51735,8 @@ index 0000000..7222429 +module_init(evtchn_init); +module_exit(evtchn_cleanup); + ++MODULE_LICENSE("Dual BSD/GPL"); ++ +/* + * Local variables: + * c-file-style: "linux" @@ -51047,19 +51748,21 @@ index 0000000..7222429 + */ diff --git a/drivers/xen/net_driver_util.c b/drivers/xen/net_driver_util.c new file mode 100644 -index 0000000..10688f9 +index 0000000..43b9fb7 --- /dev/null +++ b/drivers/xen/net_driver_util.c -@@ -0,0 +1,67 @@ +@@ -0,0 +1,68 @@ +/***************************************************************************** + * + * Utility functions for Xen network devices. + * + * Copyright (c) 2005 XenSource Ltd. + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following -+ * license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this source file (the "Software"), to deal in the Software without @@ -51080,7 +51783,6 @@ index 0000000..10688f9 + * DEALINGS IN THE SOFTWARE. + */ + -+ +#include +#include +#include @@ -51107,7 +51809,7 @@ index 0000000..10688f9 + kfree(macstr); + return 0; +} -+EXPORT_SYMBOL(xen_net_read_mac); ++EXPORT_SYMBOL_GPL(xen_net_read_mac); + +/* + * Local variables: @@ -51131,12 +51833,36 @@ index 0000000..d5d2328 +netloop-y := loopback.o diff --git a/drivers/xen/netback/common.h b/drivers/xen/netback/common.h new file mode 100644 -index 0000000..61f8d58 +index 0000000..ab52a03 --- /dev/null +++ b/drivers/xen/netback/common.h -@@ -0,0 +1,110 @@ +@@ -0,0 +1,134 @@ +/****************************************************************************** + * arch/xen/drivers/netif/backend/common.h ++ * ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. + */ + +#ifndef __NETIF__BACKEND__COMMON_H__ @@ -51247,16 +51973,40 @@ index 0000000..61f8d58 + */ diff --git a/drivers/xen/netback/interface.c b/drivers/xen/netback/interface.c new file mode 100644 -index 0000000..a27533c +index 0000000..79944d6 --- /dev/null +++ b/drivers/xen/netback/interface.c -@@ -0,0 +1,320 @@ +@@ -0,0 +1,344 @@ +/****************************************************************************** + * arch/xen/drivers/netif/backend/interface.c + * + * Network-device interface management. + * + * Copyright (c) 2004-2005, Keir Fraser ++ * ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. + */ + +#include "common.h" @@ -51573,10 +52323,10 @@ index 0000000..a27533c + */ diff --git a/drivers/xen/netback/loopback.c b/drivers/xen/netback/loopback.c new file mode 100644 -index 0000000..a5a11cc +index 0000000..e9f354a --- /dev/null +++ b/drivers/xen/netback/loopback.c -@@ -0,0 +1,231 @@ +@@ -0,0 +1,255 @@ +/****************************************************************************** + * netback/loopback.c + * @@ -51598,6 +52348,30 @@ index 0000000..a5a11cc + * (to avoid confusing the Etherbridge). + * + * Copyright (c) 2005 K A Fraser ++ * ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. + */ + +#include @@ -51810,10 +52584,10 @@ index 0000000..a5a11cc + */ diff --git a/drivers/xen/netback/netback.c b/drivers/xen/netback/netback.c new file mode 100644 -index 0000000..64173fa +index 0000000..41d4bf9 --- /dev/null +++ b/drivers/xen/netback/netback.c -@@ -0,0 +1,835 @@ +@@ -0,0 +1,859 @@ +/****************************************************************************** + * drivers/xen/netback/netback.c + * @@ -51824,6 +52598,30 @@ index 0000000..64173fa + * drivers/xen/netfront/netfront.c + * + * Copyright (c) 2002-2005, K A Fraser ++ * ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this source file (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, modify, ++ * merge, publish, distribute, sublicense, and/or sell copies of the Software, ++ * and to permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++ * IN THE SOFTWARE. + */ + +#include "common.h" @@ -52123,7 +52921,7 @@ index 0000000..64173fa + if (make_rx_response(netif, id, status, + (unsigned long)skb->data & ~PAGE_MASK, + size, skb->proto_csum_valid ? -+ NETRXF_csum_valid : 0) && ++ NETRXF_data_validated : 0) && + (rx_notify[irq] == 0)) { + rx_notify[irq] = 1; + notify_list[notify_nr++] = irq; @@ -52651,7 +53449,7 @@ index 0000000..64173fa + */ diff --git a/drivers/xen/netback/xenbus.c b/drivers/xen/netback/xenbus.c new file mode 100644 -index 0000000..64bebdb +index 0000000..52a4fc9 --- /dev/null +++ b/drivers/xen/netback/xenbus.c @@ -0,0 +1,327 @@ @@ -52733,14 +53531,13 @@ index 0000000..64bebdb + const struct xenbus_device_id *id) +{ + int err; -+ struct backend_info *be = kmalloc(sizeof(struct backend_info), ++ struct backend_info *be = kzalloc(sizeof(struct backend_info), + GFP_KERNEL); + if (!be) { + xenbus_dev_fatal(dev, -ENOMEM, + "allocating backend structure"); + return -ENOMEM; + } -+ memset(be, 0, sizeof(*be)); + + be->dev = dev; + dev->data = be; @@ -52871,7 +53668,8 @@ index 0000000..64bebdb + break; + + case XenbusStateClosed: -+ kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); ++ if (be->netif != NULL) ++ kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); + device_unregister(&dev->dev); + break; + @@ -53006,10 +53804,10 @@ index 0000000..dc22829 +xennet-objs := netfront.o diff --git a/drivers/xen/netfront/netfront.c b/drivers/xen/netfront/netfront.c new file mode 100644 -index 0000000..79d8645 +index 0000000..220e9aa --- /dev/null +++ b/drivers/xen/netfront/netfront.c -@@ -0,0 +1,1500 @@ +@@ -0,0 +1,1506 @@ +/****************************************************************************** + * Virtual network driver for conversing with remote driver backends. + * @@ -53080,21 +53878,12 @@ index 0000000..79d8645 +#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE) +#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE) + -+#ifndef __GFP_NOWARN -+#define __GFP_NOWARN 0 -+#endif -+#define alloc_xen_skb(_l) __dev_alloc_skb((_l), GFP_ATOMIC|__GFP_NOWARN) -+ -+#define init_skb_shinfo(_skb) \ -+ do { \ -+ atomic_set(&(skb_shinfo(_skb)->dataref), 1); \ -+ skb_shinfo(_skb)->nr_frags = 0; \ -+ skb_shinfo(_skb)->frag_list = NULL; \ -+ } while (0) -+ -+static unsigned long rx_pfn_array[NET_RX_RING_SIZE]; -+static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1]; -+static mmu_update_t rx_mmu[NET_RX_RING_SIZE]; ++static inline void init_skb_shinfo(struct sk_buff *skb) ++{ ++ atomic_set(&(skb_shinfo(skb)->dataref), 1); ++ skb_shinfo(skb)->nr_frags = 0; ++ skb_shinfo(skb)->frag_list = NULL; ++} + +struct netfront_info +{ @@ -53149,16 +53938,28 @@ index 0000000..79d8645 + int tx_ring_ref; + int rx_ring_ref; + u8 mac[ETH_ALEN]; ++ ++ unsigned long rx_pfn_array[NET_RX_RING_SIZE]; ++ multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1]; ++ mmu_update_t rx_mmu[NET_RX_RING_SIZE]; +}; + -+/* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ -+#define ADD_ID_TO_FREELIST(_list, _id) \ -+ (_list)[(_id)] = (_list)[0]; \ -+ (_list)[0] = (void *)(unsigned long)(_id); -+#define GET_ID_FROM_FREELIST(_list) \ -+ ({ unsigned long _id = (unsigned long)(_list)[0]; \ -+ (_list)[0] = (_list)[_id]; \ -+ (unsigned short)_id; }) ++/* ++ * Access macros for acquiring freeing slots in {tx,rx}_skbs[]. ++ */ ++ ++static inline void add_id_to_freelist(struct sk_buff **list, unsigned short id) ++{ ++ list[id] = list[0]; ++ list[0] = (void *)(unsigned long)id; ++} ++ ++static inline unsigned short get_id_from_freelist(struct sk_buff **list) ++{ ++ unsigned int id = (unsigned int)(unsigned long)list[0]; ++ list[0] = list[id]; ++ return id; ++} + +#ifdef DEBUG +static char *be_state_name[] = { @@ -53499,7 +54300,7 @@ index 0000000..79d8645 + gnttab_release_grant_reference( + &np->gref_tx_head, np->grant_tx_ref[id]); + np->grant_tx_ref[id] = GRANT_INVALID_REF; -+ ADD_ID_TO_FREELIST(np->tx_skbs, id); ++ add_id_to_freelist(np->tx_skbs, id); + dev_kfree_skb_irq(skb); + } + @@ -53560,9 +54361,10 @@ index 0000000..79d8645 + * Subtract dev_alloc_skb headroom (16 bytes) and shared info + * tailroom then round down to SKB_DATA_ALIGN boundary. + */ -+ skb = alloc_xen_skb( ++ skb = __dev_alloc_skb( + ((PAGE_SIZE - sizeof(struct skb_shared_info)) & -+ (-SKB_DATA_ALIGN(1))) - 16); ++ (-SKB_DATA_ALIGN(1))) - 16, ++ GFP_ATOMIC|__GFP_NOWARN); + if (skb == NULL) { + /* Any skbuffs queued for refill? Force them out. */ + if (i != 0) @@ -53591,7 +54393,7 @@ index 0000000..79d8645 + + skb->dev = dev; + -+ id = GET_ID_FROM_FREELIST(np->rx_skbs); ++ id = get_id_from_freelist(np->rx_skbs); + + np->rx_skbs[id] = skb; + @@ -53603,13 +54405,13 @@ index 0000000..79d8645 + np->xbdev->otherend_id, + __pa(skb->head) >> PAGE_SHIFT); + RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref; -+ rx_pfn_array[i] = virt_to_mfn(skb->head); ++ np->rx_pfn_array[i] = virt_to_mfn(skb->head); + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* Remove this page before passing back to Xen. */ + set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, + INVALID_P2M_ENTRY); -+ MULTI_update_va_mapping(rx_mcl+i, ++ MULTI_update_va_mapping(np->rx_mcl+i, + (unsigned long)skb->head, + __pte(0), 0); + } @@ -53618,7 +54420,7 @@ index 0000000..79d8645 + /* Tell the ballon driver what is going on. */ + balloon_update_driver_allowance(i); + -+ reservation.extent_start = rx_pfn_array; ++ reservation.extent_start = np->rx_pfn_array; + reservation.nr_extents = i; + reservation.extent_order = 0; + reservation.address_bits = 0; @@ -53626,19 +54428,19 @@ index 0000000..79d8645 + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* After all PTEs have been zapped, flush the TLB. */ -+ rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = ++ np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = + UVMF_TLB_FLUSH|UVMF_ALL; + + /* Give away a batch of pages. */ -+ rx_mcl[i].op = __HYPERVISOR_memory_op; -+ rx_mcl[i].args[0] = XENMEM_decrease_reservation; -+ rx_mcl[i].args[1] = (unsigned long)&reservation; ++ np->rx_mcl[i].op = __HYPERVISOR_memory_op; ++ np->rx_mcl[i].args[0] = XENMEM_decrease_reservation; ++ np->rx_mcl[i].args[1] = (unsigned long)&reservation; + + /* Zap PTEs and give away pages in one big multicall. */ -+ (void)HYPERVISOR_multicall(rx_mcl, i+1); ++ (void)HYPERVISOR_multicall(np->rx_mcl, i+1); + + /* Check return status of HYPERVISOR_memory_op(). */ -+ if (unlikely(rx_mcl[i].result != i)) ++ if (unlikely(np->rx_mcl[i].result != i)) + panic("Unable to reduce memory reservation\n"); + } else + if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, @@ -53671,7 +54473,8 @@ index 0000000..79d8645 + if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= + PAGE_SIZE)) { + struct sk_buff *nskb; -+ if (unlikely((nskb = alloc_xen_skb(skb->len)) == NULL)) ++ nskb = __dev_alloc_skb(skb->len, GFP_ATOMIC|__GFP_NOWARN); ++ if (unlikely(nskb == NULL)) + goto drop; + skb_put(nskb, skb->len); + memcpy(nskb->data, skb->data, skb->len); @@ -53689,7 +54492,7 @@ index 0000000..79d8645 + + i = np->tx.req_prod_pvt; + -+ id = GET_ID_FROM_FREELIST(np->tx_skbs); ++ id = get_id_from_freelist(np->tx_skbs); + np->tx_skbs[id] = skb; + + tx = RING_GET_REQUEST(&np->tx, i); @@ -53754,8 +54557,8 @@ index 0000000..79d8645 + struct sk_buff *skb, *nskb; + netif_rx_response_t *rx; + RING_IDX i, rp; -+ mmu_update_t *mmu = rx_mmu; -+ multicall_entry_t *mcl = rx_mcl; ++ mmu_update_t *mmu = np->rx_mmu; ++ multicall_entry_t *mcl = np->rx_mcl; + int work_done, budget, more_to_do = 1; + struct sk_buff_head rxq; + unsigned long flags; @@ -53811,14 +54614,14 @@ index 0000000..79d8645 + np->grant_rx_ref[rx->id] = GRANT_INVALID_REF; + + skb = np->rx_skbs[rx->id]; -+ ADD_ID_TO_FREELIST(np->rx_skbs, rx->id); ++ add_id_to_freelist(np->rx_skbs, rx->id); + + /* NB. We handle skb overflow later. */ + skb->data = skb->head + rx->offset; + skb->len = rx->status; + skb->tail = skb->data + skb->len; + -+ if (rx->flags & NETRXF_csum_valid) ++ if (rx->flags & NETRXF_data_validated) + skb->ip_summed = CHECKSUM_UNNECESSARY; + + np->stats.rx_packets++; @@ -53846,22 +54649,22 @@ index 0000000..79d8645 + balloon_update_driver_allowance(-work_done); + + /* Do all the remapping work, and M2P updates, in one big hypercall. */ -+ if (likely((mcl - rx_mcl) != 0)) { ++ if (likely((mcl - np->rx_mcl) != 0)) { + mcl->op = __HYPERVISOR_mmu_update; -+ mcl->args[0] = (unsigned long)rx_mmu; -+ mcl->args[1] = mmu - rx_mmu; ++ mcl->args[0] = (unsigned long)np->rx_mmu; ++ mcl->args[1] = mmu - np->rx_mmu; + mcl->args[2] = 0; + mcl->args[3] = DOMID_SELF; + mcl++; -+ (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); ++ (void)HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl); + } + + while ((skb = __skb_dequeue(&rxq)) != NULL) { -+ if (skb->len > (dev->mtu + ETH_HLEN)) { ++ if (skb->len > (dev->mtu + ETH_HLEN + 4)) { + if (net_ratelimit()) + printk(KERN_INFO "Received packet too big for " + "MTU (%d > %d)\n", -+ skb->len - ETH_HLEN, dev->mtu); ++ skb->len - ETH_HLEN - 4, dev->mtu); + skb->len = 0; + skb->tail = skb->data; + init_skb_shinfo(skb); @@ -53886,7 +54689,8 @@ index 0000000..79d8645 + 16 - (skb->data - skb->head)); + } + -+ nskb = alloc_xen_skb(skb->len + 2); ++ nskb = __dev_alloc_skb(skb->len + 2, ++ GFP_ATOMIC|__GFP_NOWARN); + if (nskb != NULL) { + skb_reserve(nskb, 2); + skb_put(nskb, skb->len); @@ -54512,26 +55316,26 @@ index 0000000..79d8645 + */ diff --git a/drivers/xen/pciback/Makefile b/drivers/xen/pciback/Makefile new file mode 100644 -index 0000000..e031caa +index 0000000..bfe77e6 --- /dev/null +++ b/drivers/xen/pciback/Makefile @@ -0,0 +1,10 @@ -+obj-y += pciback.o ++obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback.o + +pciback-y := pci_stub.o pciback_ops.o xenbus.o +pciback-y += conf_space.o conf_space_header.o -+pciback-${CONFIG_XEN_PCIDEV_BACKEND_VPCI} += vpci.o -+pciback-${CONFIG_XEN_PCIDEV_BACKEND_PASS} += passthrough.o ++pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o ++pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o + +ifeq ($(CONFIG_XEN_PCIDEV_BE_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif diff --git a/drivers/xen/pciback/conf_space.c b/drivers/xen/pciback/conf_space.c new file mode 100644 -index 0000000..f08eafa +index 0000000..9d1fe1e --- /dev/null +++ b/drivers/xen/pciback/conf_space.c -@@ -0,0 +1,324 @@ +@@ -0,0 +1,342 @@ +/* + * PCI Backend - Functions for creating a virtual configuration space for + * exported PCI Devices. @@ -54548,6 +55352,9 @@ index 0000000..f08eafa +#include "pciback.h" +#include "conf_space.h" + ++static int permissive = 0; ++module_param(permissive, bool, 0644); ++ +#define DEFINE_PCI_CONFIG(op,size,type) \ +int pciback_##op##_config_##size \ +(struct pci_dev *dev, int offset, type value, void *data) \ @@ -54732,7 +55539,7 @@ index 0000000..f08eafa + +int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value) +{ -+ int err = 0; ++ int err = 0, handled = 0; + struct pciback_dev_data *dev_data = pci_get_drvdata(dev); + struct config_field_entry *cfg_entry; + struct config_field *field; @@ -54767,6 +55574,21 @@ index 0000000..f08eafa + field_start - req_start); + + err = conf_space_write(dev, cfg_entry, offset, tmp_val); ++ handled = 1; ++ } ++ } ++ ++ if (!handled && !err && permissive) { ++ switch (size) { ++ case 1: ++ err = pci_write_config_byte(dev, offset, (u8)value); ++ break; ++ case 2: ++ err = pci_write_config_word(dev, offset, (u16)value); ++ break; ++ case 4: ++ err = pci_write_config_dword(dev, offset, (u32)value); ++ break; + } + } + @@ -54961,10 +55783,10 @@ index 0000000..3ef8365 +#endif /* __XEN_PCIBACK_CONF_SPACE_H__ */ diff --git a/drivers/xen/pciback/conf_space_header.c b/drivers/xen/pciback/conf_space_header.c new file mode 100644 -index 0000000..17607d3 +index 0000000..0b9fce3 --- /dev/null +++ b/drivers/xen/pciback/conf_space_header.c -@@ -0,0 +1,269 @@ +@@ -0,0 +1,267 @@ +/* + * PCI Backend - Handles the virtual fields in the configuration space headers. + * @@ -54991,21 +55813,19 @@ index 0000000..17607d3 + if (unlikely(verbose_request)) + printk(KERN_DEBUG "pciback: %s: enable\n", + pci_name(dev)); -+ dev->is_enabled = 1; -+ pcibios_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1); ++ pci_enable_device(dev); + } else if (dev->is_enabled && !is_enable_cmd(value)) { + if (unlikely(verbose_request)) + printk(KERN_DEBUG "pciback: %s: disable\n", + pci_name(dev)); -+ pciback_disable_device(dev); ++ pci_disable_device(dev); + } + + if (!dev->is_busmaster && is_master_cmd(value)) { + if (unlikely(verbose_request)) + printk(KERN_DEBUG "pciback: %s: set bus master\n", + pci_name(dev)); -+ dev->is_busmaster = 1; -+ pcibios_set_master(dev); ++ pci_set_master(dev); + } + + if (value & PCI_COMMAND_INVALIDATE) { @@ -55236,10 +56056,10 @@ index 0000000..17607d3 +} diff --git a/drivers/xen/pciback/passthrough.c b/drivers/xen/pciback/passthrough.c new file mode 100644 -index 0000000..e5b7fbb +index 0000000..5ee7638 --- /dev/null +++ b/drivers/xen/pciback/passthrough.c -@@ -0,0 +1,116 @@ +@@ -0,0 +1,157 @@ +/* + * PCI Backend - Provides restricted access to the real PCI bus topology + * to the frontend @@ -55249,10 +56069,13 @@ index 0000000..e5b7fbb + +#include +#include ++#include +#include "pciback.h" + +struct passthrough_dev_data { ++ /* Access to dev_list must be protected by lock */ + struct list_head dev_list; ++ spinlock_t lock; +}; + +struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev, @@ -55261,33 +56084,66 @@ index 0000000..e5b7fbb +{ + struct passthrough_dev_data *dev_data = pdev->pci_dev_data; + struct pci_dev_entry *dev_entry; ++ struct pci_dev *dev = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_data->lock, flags); + + list_for_each_entry(dev_entry, &dev_data->dev_list, list) { + if (domain == (unsigned int)pci_domain_nr(dev_entry->dev->bus) + && bus == (unsigned int)dev_entry->dev->bus->number -+ && devfn == dev_entry->dev->devfn) -+ return dev_entry->dev; ++ && devfn == dev_entry->dev->devfn) { ++ dev = dev_entry->dev; ++ break; ++ } + } + -+ return NULL; ++ spin_unlock_irqrestore(&dev_data->lock, flags); ++ ++ return dev; +} + -+/* Must hold pciback_device->dev_lock when calling this */ +int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev) +{ + struct passthrough_dev_data *dev_data = pdev->pci_dev_data; + struct pci_dev_entry *dev_entry; ++ unsigned long flags; + + dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL); + if (!dev_entry) + return -ENOMEM; + dev_entry->dev = dev; + ++ spin_lock_irqsave(&dev_data->lock, flags); + list_add_tail(&dev_entry->list, &dev_data->dev_list); ++ spin_unlock_irqrestore(&dev_data->lock, flags); + + return 0; +} + ++void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev) ++{ ++ struct passthrough_dev_data *dev_data = pdev->pci_dev_data; ++ struct pci_dev_entry *dev_entry, *t; ++ struct pci_dev *found_dev = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev_data->lock, flags); ++ ++ list_for_each_entry_safe(dev_entry, t, &dev_data->dev_list, list) { ++ if (dev_entry->dev == dev) { ++ list_del(&dev_entry->list); ++ found_dev = dev_entry->dev; ++ kfree(dev_entry); ++ } ++ } ++ ++ spin_unlock_irqrestore(&dev_data->lock, flags); ++ ++ if (found_dev) ++ pcistub_put_pci_dev(found_dev); ++} ++ +int pciback_init_devices(struct pciback_device *pdev) +{ + struct passthrough_dev_data *dev_data; @@ -55296,6 +56152,8 @@ index 0000000..e5b7fbb + if (!dev_data) + return -ENOMEM; + ++ spin_lock_init(&dev_data->lock); ++ + INIT_LIST_HEAD(&dev_data->dev_list); + + pdev->pci_dev_data = dev_data; @@ -55313,6 +56171,8 @@ index 0000000..e5b7fbb + int found; + unsigned int domain, bus; + ++ spin_lock(&dev_data->lock); ++ + list_for_each_entry(dev_entry, &dev_data->dev_list, list) { + /* Only publish this device as a root if none of its + * parent bridges are exported @@ -55338,10 +56198,11 @@ index 0000000..e5b7fbb + } + } + ++ spin_unlock(&dev_data->lock); ++ + return err; +} + -+/* Must hold pciback_device->dev_lock when calling this */ +void pciback_release_devices(struct pciback_device *pdev) +{ + struct passthrough_dev_data *dev_data = pdev->pci_dev_data; @@ -55358,10 +56219,10 @@ index 0000000..e5b7fbb +} diff --git a/drivers/xen/pciback/pci_stub.c b/drivers/xen/pciback/pci_stub.c new file mode 100644 -index 0000000..aa76d75 +index 0000000..e0dc110 --- /dev/null +++ b/drivers/xen/pciback/pci_stub.c -@@ -0,0 +1,377 @@ +@@ -0,0 +1,695 @@ +/* + * PCI Stub Driver - Grabs devices in backend to be exported later + * @@ -55371,110 +56232,190 @@ index 0000000..aa76d75 +#include +#include +#include ++#include +#include +#include "pciback.h" + +static char *pci_devs_to_hide = NULL; +module_param_named(hide, pci_devs_to_hide, charp, 0444); + -+struct pci_stub_device_id { ++struct pcistub_device_id { + struct list_head slot_list; + int domain; + unsigned char bus; + unsigned int devfn; +}; -+LIST_HEAD(pci_stub_device_ids); ++static LIST_HEAD(pcistub_device_ids); ++static DEFINE_SPINLOCK(device_ids_lock); + -+struct pci_stub_device { ++struct pcistub_device { ++ struct kref kref; + struct list_head dev_list; ++ spinlock_t lock; ++ + struct pci_dev *dev; -+ atomic_t in_use; ++ struct pciback_device *pdev; /* non-NULL if struct pci_dev is in use */ +}; -+/* Access to pci_stub_devices & seized_devices lists and the initialize_devices -+ * flag must be locked with pci_stub_devices_lock ++/* Access to pcistub_devices & seized_devices lists and the initialize_devices ++ * flag must be locked with pcistub_devices_lock + */ -+DEFINE_SPINLOCK(pci_stub_devices_lock); -+LIST_HEAD(pci_stub_devices); ++static DEFINE_SPINLOCK(pcistub_devices_lock); ++static LIST_HEAD(pcistub_devices); + +/* wait for device_initcall before initializing our devices + * (see pcistub_init_devices_late) + */ +static int initialize_devices = 0; -+LIST_HEAD(seized_devices); ++static LIST_HEAD(seized_devices); + -+static inline struct pci_dev *get_pci_dev(struct pci_stub_device *psdev) ++static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev) +{ -+ if (atomic_dec_and_test(&psdev->in_use)) -+ return psdev->dev; -+ else { -+ atomic_inc(&psdev->in_use); ++ struct pcistub_device *psdev; ++ ++ dev_dbg(&dev->dev, "pcistub_device_alloc\n"); ++ ++ psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC); ++ if (!psdev) ++ return NULL; ++ ++ psdev->dev = pci_dev_get(dev); ++ if (!psdev->dev) { ++ kfree(psdev); + return NULL; + } ++ ++ kref_init(&psdev->kref); ++ spin_lock_init(&psdev->lock); ++ ++ return psdev; +} + -+struct pci_dev *pcistub_get_pci_dev_by_slot(int domain, int bus, ++/* Don't call this directly as it's called by pcistub_device_put */ ++static void pcistub_device_release(struct kref *kref) ++{ ++ struct pcistub_device *psdev; ++ ++ psdev = container_of(kref, struct pcistub_device, kref); ++ ++ dev_dbg(&psdev->dev->dev, "pcistub_device_release\n"); ++ ++ /* Clean-up the device */ ++ pciback_reset_device(psdev->dev); ++ pciback_config_free(psdev->dev); ++ kfree(pci_get_drvdata(psdev->dev)); ++ pci_set_drvdata(psdev->dev, NULL); ++ ++ pci_dev_put(psdev->dev); ++ ++ kfree(psdev); ++} ++ ++static inline void pcistub_device_get(struct pcistub_device *psdev) ++{ ++ kref_get(&psdev->kref); ++} ++ ++static inline void pcistub_device_put(struct pcistub_device *psdev) ++{ ++ kref_put(&psdev->kref, pcistub_device_release); ++} ++ ++static struct pci_dev *pcistub_device_get_pci_dev(struct pciback_device *pdev, ++ struct pcistub_device *psdev) ++{ ++ struct pci_dev *pci_dev = NULL; ++ unsigned long flags; ++ ++ pcistub_device_get(psdev); ++ ++ spin_lock_irqsave(&psdev->lock, flags); ++ if (!psdev->pdev) { ++ psdev->pdev = pdev; ++ pci_dev = psdev->dev; ++ } ++ spin_unlock_irqrestore(&psdev->lock, flags); ++ ++ if (!pci_dev) ++ pcistub_device_put(psdev); ++ ++ return pci_dev; ++} ++ ++struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev, ++ int domain, int bus, + int slot, int func) +{ -+ struct pci_stub_device *psdev; ++ struct pcistub_device *psdev; + struct pci_dev *found_dev = NULL; ++ unsigned long flags; + -+ spin_lock(&pci_stub_devices_lock); ++ spin_lock_irqsave(&pcistub_devices_lock, flags); + -+ list_for_each_entry(psdev, &pci_stub_devices, dev_list) { ++ list_for_each_entry(psdev, &pcistub_devices, dev_list) { + if (psdev->dev != NULL + && domain == pci_domain_nr(psdev->dev->bus) + && bus == psdev->dev->bus->number + && PCI_DEVFN(slot, func) == psdev->dev->devfn) { -+ found_dev = get_pci_dev(psdev); ++ found_dev = pcistub_device_get_pci_dev(pdev, psdev); + break; + } + } + -+ spin_unlock(&pci_stub_devices_lock); ++ spin_unlock_irqrestore(&pcistub_devices_lock, flags); + return found_dev; +} + -+struct pci_dev *pcistub_get_pci_dev(struct pci_dev *dev) ++struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev, ++ struct pci_dev *dev) +{ -+ struct pci_stub_device *psdev; ++ struct pcistub_device *psdev; + struct pci_dev *found_dev = NULL; ++ unsigned long flags; + -+ spin_lock(&pci_stub_devices_lock); ++ spin_lock_irqsave(&pcistub_devices_lock, flags); + -+ list_for_each_entry(psdev, &pci_stub_devices, dev_list) { ++ list_for_each_entry(psdev, &pcistub_devices, dev_list) { + if (psdev->dev == dev) { -+ found_dev = get_pci_dev(psdev); ++ found_dev = pcistub_device_get_pci_dev(pdev, psdev); + break; + } + } + -+ spin_unlock(&pci_stub_devices_lock); ++ spin_unlock_irqrestore(&pcistub_devices_lock, flags); + return found_dev; +} + +void pcistub_put_pci_dev(struct pci_dev *dev) +{ -+ struct pci_stub_device *psdev; ++ struct pcistub_device *psdev, *found_psdev = NULL; ++ unsigned long flags; + -+ spin_lock(&pci_stub_devices_lock); ++ spin_lock_irqsave(&pcistub_devices_lock, flags); + -+ list_for_each_entry(psdev, &pci_stub_devices, dev_list) { ++ list_for_each_entry(psdev, &pcistub_devices, dev_list) { + if (psdev->dev == dev) { -+ /* Cleanup our device -+ * (so it's ready for the next domain) -+ */ -+ pciback_reset_device(psdev->dev); -+ -+ atomic_inc(&psdev->in_use); ++ found_psdev = psdev; + break; + } + } + -+ spin_unlock(&pci_stub_devices_lock); ++ spin_unlock_irqrestore(&pcistub_devices_lock, flags); ++ ++ /* Cleanup our device ++ * (so it's ready for the next domain) ++ */ ++ pciback_reset_device(found_psdev->dev); ++ pciback_config_reset(found_psdev->dev); ++ ++ spin_lock_irqsave(&found_psdev->lock, flags); ++ found_psdev->pdev = NULL; ++ spin_unlock_irqrestore(&found_psdev->lock, flags); ++ ++ pcistub_device_put(found_psdev); +} + -+static int __devinit pcistub_match(struct pci_dev *dev, -+ struct pci_stub_device_id *pdev_id) ++static int __devinit pcistub_match_one(struct pci_dev *dev, ++ struct pcistub_device_id *pdev_id) +{ + /* Match the specified device by domain, bus, slot, func and also if + * any of the device's parent bridges match. @@ -55489,23 +56430,44 @@ index 0000000..aa76d75 + return 0; +} + ++static int __devinit pcistub_match(struct pci_dev *dev) ++{ ++ struct pcistub_device_id *pdev_id; ++ unsigned long flags; ++ int found = 0; ++ ++ spin_lock_irqsave(&device_ids_lock, flags); ++ list_for_each_entry(pdev_id, &pcistub_device_ids, slot_list) { ++ if (pcistub_match_one(dev, pdev_id)) { ++ found = 1; ++ break; ++ } ++ } ++ spin_unlock_irqrestore(&device_ids_lock, flags); ++ ++ return found; ++} ++ +static int __devinit pcistub_init_device(struct pci_dev *dev) +{ + struct pciback_dev_data *dev_data; + int err = 0; + ++ dev_dbg(&dev->dev, "initializing...\n"); ++ + /* The PCI backend is not intended to be a module (or to work with + * removable PCI devices (yet). If it were, pciback_config_free() + * would need to be called somewhere to free the memory allocated + * here and then to call kfree(pci_get_drvdata(psdev->dev)). + */ -+ dev_data = kmalloc(sizeof(*dev_data), GFP_KERNEL); ++ dev_data = kmalloc(sizeof(*dev_data), GFP_ATOMIC); + if (!dev_data) { + err = -ENOMEM; + goto out; + } + pci_set_drvdata(dev, dev_data); + ++ dev_dbg(&dev->dev, "initializing config\n"); + err = pciback_config_init(dev); + if (err) + goto out; @@ -55517,14 +56479,15 @@ index 0000000..aa76d75 + * This makes the assumption that the device's resources won't + * change after this point (otherwise this code may break!) + */ ++ dev_dbg(&dev->dev, "enabling device\n"); + err = pci_enable_device(dev); + if (err) + goto config_release; + + /* Now disable the device (this also ensures some private device + * data is setup before we export) -+ * This calls pciback_config_reset(dev) + */ ++ dev_dbg(&dev->dev, "reset device\n"); + pciback_reset_device(dev); + + return 0; @@ -55546,62 +56509,82 @@ index 0000000..aa76d75 + */ +static int __init pcistub_init_devices_late(void) +{ -+ struct pci_stub_device *psdev, *t; ++ struct pcistub_device *psdev; ++ unsigned long flags; + int err = 0; + -+ spin_lock(&pci_stub_devices_lock); ++ pr_debug("pciback: pcistub_init_devices_late\n"); + -+ list_for_each_entry_safe(psdev, t, &seized_devices, dev_list) { ++ spin_lock_irqsave(&pcistub_devices_lock, flags); ++ ++ while (!list_empty(&seized_devices)) { ++ psdev = container_of(seized_devices.next, ++ struct pcistub_device, dev_list); + list_del(&psdev->dev_list); ++ ++ spin_unlock_irqrestore(&pcistub_devices_lock, flags); ++ + err = pcistub_init_device(psdev->dev); + if (err) { -+ printk(KERN_ERR -+ "pciback: %s error %d initializing device\n", -+ pci_name(psdev->dev), err); ++ dev_err(&psdev->dev->dev, ++ "error %d initializing device\n", err); + kfree(psdev); -+ continue; ++ psdev = NULL; + } + -+ list_add_tail(&psdev->dev_list, &pci_stub_devices); ++ spin_lock_irqsave(&pcistub_devices_lock, flags); ++ ++ if (psdev) ++ list_add_tail(&psdev->dev_list, &pcistub_devices); + } + + initialize_devices = 1; + -+ spin_unlock(&pci_stub_devices_lock); ++ spin_unlock_irqrestore(&pcistub_devices_lock, flags); + + return 0; +} + -+device_initcall(pcistub_init_devices_late); -+ +static int __devinit pcistub_seize(struct pci_dev *dev) +{ -+ struct pci_stub_device *psdev; ++ struct pcistub_device *psdev; ++ unsigned long flags; ++ int initialize_devices_copy; + int err = 0; + -+ psdev = kmalloc(sizeof(*psdev), GFP_KERNEL); ++ psdev = pcistub_device_alloc(dev); + if (!psdev) + return -ENOMEM; + -+ psdev->dev = dev; -+ atomic_set(&psdev->in_use, 1); ++ /* initialize_devices has to be accessed under a spin lock. But since ++ * it can only change from 0 -> 1, if it's already 1, we don't have to ++ * worry about it changing. That's why we can take a *copy* of ++ * initialize_devices and wait till we're outside of the lock to ++ * check if it's 1 (don't ever check if it's 0 outside of the lock) ++ */ ++ spin_lock_irqsave(&pcistub_devices_lock, flags); + -+ spin_lock(&pci_stub_devices_lock); ++ initialize_devices_copy = initialize_devices; + -+ if (initialize_devices) { ++ if (!initialize_devices_copy) { ++ dev_dbg(&dev->dev, "deferring initialization\n"); ++ list_add(&psdev->dev_list, &seized_devices); ++ } ++ ++ spin_unlock_irqrestore(&pcistub_devices_lock, flags); ++ ++ if (initialize_devices_copy) { ++ /* don't want irqs disabled when calling pcistub_init_device */ + err = pcistub_init_device(psdev->dev); + if (err) + goto out; + -+ list_add(&psdev->dev_list, &pci_stub_devices); -+ } else -+ list_add(&psdev->dev_list, &seized_devices); ++ list_add(&psdev->dev_list, &pcistub_devices); ++ } + + out: -+ spin_unlock(&pci_stub_devices_lock); -+ + if (err) -+ kfree(psdev); ++ pcistub_device_put(psdev); + + return err; +} @@ -55609,47 +56592,78 @@ index 0000000..aa76d75 +static int __devinit pcistub_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ -+ struct pci_stub_device_id *pdev_id; -+ struct pci_dev *seized_dev; + int err = 0; + -+ list_for_each_entry(pdev_id, &pci_stub_device_ids, slot_list) { ++ dev_dbg(&dev->dev, "probing...\n"); + -+ if (!pcistub_match(dev, pdev_id)) -+ continue; ++ if (pcistub_match(dev)) { + + if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL + && dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { -+ printk(KERN_ERR -+ "pciback: %s: can't export pci devices that " -+ "don't have a normal (0) or bridge (1) " -+ "header type!\n", pci_name(dev)); -+ break; -+ } -+ -+ pr_info("pciback: seizing PCI device %s\n", pci_name(dev)); -+ seized_dev = pci_dev_get(dev); -+ -+ if (seized_dev) { -+ err = pcistub_seize(seized_dev); -+ if (err) { -+ pci_dev_put(dev); -+ goto out; -+ } -+ -+ /* Success! */ ++ dev_err(&dev->dev, "can't export pci devices that " ++ "don't have a normal (0) or bridge (1) " ++ "header type!\n"); ++ err = -ENODEV; + goto out; + } -+ } + -+ /* Didn't find the device */ -+ err = -ENODEV; ++ dev_info(&dev->dev, "seizing device\n"); ++ err = pcistub_seize(dev); ++ } else ++ /* Didn't find the device */ ++ err = -ENODEV; + + out: + return err; +} + -+struct pci_device_id pcistub_ids[] = { ++static void pcistub_remove(struct pci_dev *dev) ++{ ++ struct pcistub_device *psdev, *found_psdev = NULL; ++ unsigned long flags; ++ ++ dev_dbg(&dev->dev, "removing\n"); ++ ++ spin_lock_irqsave(&pcistub_devices_lock, flags); ++ ++ list_for_each_entry(psdev, &pcistub_devices, dev_list) { ++ if (psdev->dev == dev) { ++ found_psdev = psdev; ++ break; ++ } ++ } ++ ++ spin_unlock_irqrestore(&pcistub_devices_lock, flags); ++ ++ if (found_psdev) { ++ dev_dbg(&dev->dev, "found device to remove - in use? %p\n", ++ found_psdev->pdev); ++ ++ if (found_psdev->pdev) { ++ printk(KERN_WARNING "pciback: ****** removing device " ++ "%s while still in-use! ******\n", ++ pci_name(found_psdev->dev)); ++ printk(KERN_WARNING "pciback: ****** driver domain may " ++ "still access this device's i/o resources!\n"); ++ printk(KERN_WARNING "pciback: ****** shutdown driver " ++ "domain before binding device\n"); ++ printk(KERN_WARNING "pciback: ****** to other drivers " ++ "or domains\n"); ++ ++ pciback_release_pci_dev(found_psdev->pdev, ++ found_psdev->dev); ++ } ++ ++ spin_lock_irqsave(&pcistub_devices_lock, flags); ++ list_del(&found_psdev->dev_list); ++ spin_unlock_irqrestore(&pcistub_devices_lock, flags); ++ ++ /* the final put for releasing from the list */ ++ pcistub_device_put(found_psdev); ++ } ++} ++ ++static struct pci_device_id pcistub_ids[] = { + { + .vendor = PCI_ANY_ID, + .device = PCI_ANY_ID, @@ -55664,16 +56678,152 @@ index 0000000..aa76d75 + * for a normal device. I don't want it to be loaded automatically. + */ + -+struct pci_driver pciback_pci_driver = { ++static struct pci_driver pciback_pci_driver = { + .name = "pciback", + .id_table = pcistub_ids, + .probe = pcistub_probe, ++ .remove = pcistub_remove, +}; + ++static inline int str_to_slot(const char *buf, int *domain, int *bus, ++ int *slot, int *func) ++{ ++ int err; ++ ++ err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func); ++ if (err == 4) ++ return 0; ++ else if (err < 0) ++ return -EINVAL; ++ ++ /* try again without domain */ ++ *domain = 0; ++ err = sscanf(buf, " %x:%x.%x", bus, slot, func); ++ if (err == 3) ++ return 0; ++ ++ return -EINVAL; ++} ++ ++static int pcistub_device_id_add(int domain, int bus, int slot, int func) ++{ ++ struct pcistub_device_id *pci_dev_id; ++ unsigned long flags; ++ ++ pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); ++ if (!pci_dev_id) ++ return -ENOMEM; ++ ++ pci_dev_id->domain = domain; ++ pci_dev_id->bus = bus; ++ pci_dev_id->devfn = PCI_DEVFN(slot, func); ++ ++ pr_debug("pciback: wants to seize %04x:%02x:%02x.%01x\n", ++ domain, bus, slot, func); ++ ++ spin_lock_irqsave(&device_ids_lock, flags); ++ list_add_tail(&pci_dev_id->slot_list, &pcistub_device_ids); ++ spin_unlock_irqrestore(&device_ids_lock, flags); ++ ++ return 0; ++} ++ ++static int pcistub_device_id_remove(int domain, int bus, int slot, int func) ++{ ++ struct pcistub_device_id *pci_dev_id, *t; ++ int devfn = PCI_DEVFN(slot, func); ++ int err = -ENOENT; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&device_ids_lock, flags); ++ list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids, slot_list) { ++ ++ if (pci_dev_id->domain == domain ++ && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) { ++ /* Don't break; here because it's possible the same ++ * slot could be in the list more than once ++ */ ++ list_del(&pci_dev_id->slot_list); ++ kfree(pci_dev_id); ++ ++ err = 0; ++ ++ pr_debug("pciback: removed %04x:%02x:%02x.%01x from " ++ "seize list\n", domain, bus, slot, func); ++ } ++ } ++ spin_unlock_irqrestore(&device_ids_lock, flags); ++ ++ return err; ++} ++ ++static ssize_t pcistub_slot_add(struct device_driver *drv, const char *buf, ++ size_t count) ++{ ++ int domain, bus, slot, func; ++ int err; ++ ++ err = str_to_slot(buf, &domain, &bus, &slot, &func); ++ if (err) ++ goto out; ++ ++ err = pcistub_device_id_add(domain, bus, slot, func); ++ ++ out: ++ if (!err) ++ err = count; ++ return err; ++} ++ ++DRIVER_ATTR(new_slot, S_IWUSR, NULL, pcistub_slot_add); ++ ++static ssize_t pcistub_slot_remove(struct device_driver *drv, const char *buf, ++ size_t count) ++{ ++ int domain, bus, slot, func; ++ int err; ++ ++ err = str_to_slot(buf, &domain, &bus, &slot, &func); ++ if (err) ++ goto out; ++ ++ err = pcistub_device_id_remove(domain, bus, slot, func); ++ ++ out: ++ if (!err) ++ err = count; ++ return err; ++} ++ ++DRIVER_ATTR(remove_slot, S_IWUSR, NULL, pcistub_slot_remove); ++ ++static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf) ++{ ++ struct pcistub_device_id *pci_dev_id; ++ size_t count = 0; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&device_ids_lock, flags); ++ list_for_each_entry(pci_dev_id, &pcistub_device_ids, slot_list) { ++ if (count >= PAGE_SIZE) ++ break; ++ ++ count += scnprintf(buf + count, PAGE_SIZE - count, ++ "%04x:%02x:%02x.%01x\n", ++ pci_dev_id->domain, pci_dev_id->bus, ++ PCI_SLOT(pci_dev_id->devfn), ++ PCI_FUNC(pci_dev_id->devfn)); ++ } ++ spin_unlock_irqrestore(&device_ids_lock, flags); ++ ++ return count; ++} ++ ++DRIVER_ATTR(slots, S_IRUSR, pcistub_slot_show, NULL); ++ +static int __init pcistub_init(void) +{ + int pos = 0; -+ struct pci_stub_device_id *pci_dev_id; + int err = 0; + int domain, bus, slot, func; + int parsed; @@ -55694,34 +56844,28 @@ index 0000000..aa76d75 + goto parse_error; + } + -+ pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); -+ if (!pci_dev_id) { -+ err = -ENOMEM; ++ err = pcistub_device_id_add(domain, bus, slot, func); ++ if (err) + goto out; -+ } -+ -+ pci_dev_id->domain = domain; -+ pci_dev_id->bus = bus; -+ pci_dev_id->devfn = PCI_DEVFN(slot, func); -+ -+ pr_debug -+ ("pciback: wants to seize %04x:%02x:%02x.%01x\n", -+ domain, bus, slot, func); -+ -+ list_add_tail(&pci_dev_id->slot_list, -+ &pci_stub_device_ids); + + /* if parsed<=0, we've reached the end of the string */ + pos += parsed; + } while (parsed > 0 && pci_devs_to_hide[pos]); -+ -+ /* If we're the first PCI Device Driver to register, we're the -+ * first one to get offered PCI devices as they become -+ * available (and thus we can be the first to grab them) -+ */ -+ pci_register_driver(&pciback_pci_driver); + } + ++ /* If we're the first PCI Device Driver to register, we're the ++ * first one to get offered PCI devices as they become ++ * available (and thus we can be the first to grab them) ++ */ ++ err = pci_register_driver(&pciback_pci_driver); ++ if (err < 0) ++ goto out; ++ ++ driver_create_file(&pciback_pci_driver.driver, &driver_attr_new_slot); ++ driver_create_file(&pciback_pci_driver.driver, ++ &driver_attr_remove_slot); ++ driver_create_file(&pciback_pci_driver.driver, &driver_attr_slots); ++ + out: + return err; + @@ -55731,6 +56875,7 @@ index 0000000..aa76d75 + return -EINVAL; +} + ++#ifndef MODULE +/* + * fs_initcall happens before device_initcall + * so pciback *should* get called first (b/c we @@ -55739,12 +56884,46 @@ index 0000000..aa76d75 + * driver to register) + */ +fs_initcall(pcistub_init); ++#endif ++ ++static int __init pciback_init(void) ++{ ++#ifdef MODULE ++ int err; ++ ++ err = pcistub_init(); ++ if (err < 0) ++ return err; ++#endif ++ ++ pcistub_init_devices_late(); ++ pciback_xenbus_register(); ++ ++ return 0; ++} ++ ++static void __exit pciback_cleanup(void) ++{ ++ pciback_xenbus_unregister(); ++ ++ driver_remove_file(&pciback_pci_driver.driver, &driver_attr_new_slot); ++ driver_remove_file(&pciback_pci_driver.driver, ++ &driver_attr_remove_slot); ++ driver_remove_file(&pciback_pci_driver.driver, &driver_attr_slots); ++ ++ pci_unregister_driver(&pciback_pci_driver); ++} ++ ++module_init(pciback_init); ++module_exit(pciback_cleanup); ++ ++MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/xen/pciback/pciback.h b/drivers/xen/pciback/pciback.h new file mode 100644 -index 0000000..a1f408b +index 0000000..aaa0d75 --- /dev/null +++ b/drivers/xen/pciback/pciback.h -@@ -0,0 +1,73 @@ +@@ -0,0 +1,78 @@ +/* + * PCI Backend Common Data Structures & Function Declarations + * @@ -55784,13 +56963,14 @@ index 0000000..a1f408b +}; + +/* Get/Put PCI Devices that are hidden from the PCI Backend Domain */ -+struct pci_dev *pcistub_get_pci_dev_by_slot(int domain, int bus, ++struct pci_dev *pcistub_get_pci_dev_by_slot(struct pciback_device *pdev, ++ int domain, int bus, + int slot, int func); -+struct pci_dev *pcistub_get_pci_dev(struct pci_dev *dev); ++struct pci_dev *pcistub_get_pci_dev(struct pciback_device *pdev, ++ struct pci_dev *dev); +void pcistub_put_pci_dev(struct pci_dev *dev); + +/* Ensure a device is turned off or reset */ -+void pciback_disable_device(struct pci_dev *dev); +void pciback_reset_device(struct pci_dev *pdev); + +/* Access a virtual configuration space for a PCI device */ @@ -55805,6 +56985,7 @@ index 0000000..a1f408b +typedef int (*publish_pci_root_cb) (struct pciback_device * pdev, + unsigned int domain, unsigned int bus); +int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev); ++void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev); +struct pci_dev *pciback_get_pci_dev(struct pciback_device *pdev, + unsigned int domain, unsigned int bus, + unsigned int devfn); @@ -55816,14 +56997,17 @@ index 0000000..a1f408b +/* Handles events from front-end */ +irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs); + ++int pciback_xenbus_register(void); ++void pciback_xenbus_unregister(void); ++ +extern int verbose_request; +#endif diff --git a/drivers/xen/pciback/pciback_ops.c b/drivers/xen/pciback/pciback_ops.c new file mode 100644 -index 0000000..9019608 +index 0000000..48305f5 --- /dev/null +++ b/drivers/xen/pciback/pciback_ops.c -@@ -0,0 +1,84 @@ +@@ -0,0 +1,74 @@ +/* + * PCI Backend Operations - respond to PCI requests from Frontend + * @@ -55831,26 +57015,15 @@ index 0000000..9019608 + */ +#include +#include ++#include +#include "pciback.h" + +int verbose_request = 0; +module_param(verbose_request, int, 0644); + -+/* For those architectures without a pcibios_disable_device */ -+void __attribute__ ((weak)) pcibios_disable_device(struct pci_dev *dev) { } -+ -+void pciback_disable_device(struct pci_dev *dev) -+{ -+ if (dev->is_enabled) { -+ dev->is_enabled = 0; -+ pcibios_disable_device(dev); -+ } -+} -+ +/* Ensure a device is "turned off" and ready to be exported. -+ * This also sets up the device's private data to keep track of what should -+ * be in the base address registers (BARs) so that we can keep the -+ * client from manipulating them directly. ++ * (Also see pciback_config_reset to ensure virtual configuration space is ++ * ready to be re-exported) + */ +void pciback_reset_device(struct pci_dev *dev) +{ @@ -55858,7 +57031,7 @@ index 0000000..9019608 + + /* Disable devices (but not bridges) */ + if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) { -+ pciback_disable_device(dev); ++ pci_disable_device(dev); + + pci_write_config_word(dev, PCI_COMMAND, 0); + @@ -55904,16 +57077,17 @@ index 0000000..9019608 + + wmb(); + clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags); ++ notify_remote_via_irq(pdev->evtchn_irq); + + out: + return IRQ_HANDLED; +} diff --git a/drivers/xen/pciback/vpci.c b/drivers/xen/pciback/vpci.c new file mode 100644 -index 0000000..17d554d +index 0000000..84bc4b9 --- /dev/null +++ b/drivers/xen/pciback/vpci.c -@@ -0,0 +1,163 @@ +@@ -0,0 +1,204 @@ +/* + * PCI Backend - Provides a Virtual PCI bus (with real devices) + * to the frontend @@ -55924,12 +57098,15 @@ index 0000000..17d554d +#include +#include +#include ++#include +#include "pciback.h" + +#define PCI_SLOT_MAX 32 + +struct vpci_dev_data { ++ /* Access to dev_list must be protected by lock */ + struct list_head dev_list[PCI_SLOT_MAX]; ++ spinlock_t lock; +}; + +static inline struct list_head *list_first(struct list_head *head) @@ -55941,25 +57118,29 @@ index 0000000..17d554d + unsigned int domain, unsigned int bus, + unsigned int devfn) +{ -+ struct pci_dev_entry *dev_entry; ++ struct pci_dev_entry *entry; ++ struct pci_dev *dev = NULL; + struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; ++ unsigned long flags; + + if (domain != 0 || bus != 0) + return NULL; + + if (PCI_SLOT(devfn) < PCI_SLOT_MAX) { -+ /* we don't need to lock the list here because once the backend -+ * is in operation, it won't have any more devices addeded -+ * (or removed). -+ */ -+ list_for_each_entry(dev_entry, ++ spin_lock_irqsave(&vpci_dev->lock, flags); ++ ++ list_for_each_entry(entry, + &vpci_dev->dev_list[PCI_SLOT(devfn)], + list) { -+ if (PCI_FUNC(dev_entry->dev->devfn) == PCI_FUNC(devfn)) -+ return dev_entry->dev; ++ if (PCI_FUNC(entry->dev->devfn) == PCI_FUNC(devfn)) { ++ dev = entry->dev; ++ break; ++ } + } ++ ++ spin_unlock_irqrestore(&vpci_dev->lock, flags); + } -+ return NULL; ++ return dev; +} + +static inline int match_slot(struct pci_dev *l, struct pci_dev *r) @@ -55971,12 +57152,12 @@ index 0000000..17d554d + return 0; +} + -+/* Must hold pciback_device->dev_lock when calling this */ +int pciback_add_pci_dev(struct pciback_device *pdev, struct pci_dev *dev) +{ + int err = 0, slot; + struct pci_dev_entry *t, *dev_entry; + struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; ++ unsigned long flags; + + if ((dev->class >> 24) == PCI_BASE_CLASS_BRIDGE) { + err = -EFAULT; @@ -55995,6 +57176,8 @@ index 0000000..17d554d + + dev_entry->dev = dev; + ++ spin_lock_irqsave(&vpci_dev->lock, flags); ++ + /* Keep multi-function devices together on the virtual PCI bus */ + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { + if (!list_empty(&vpci_dev->dev_list[slot])) { @@ -56008,7 +57191,7 @@ index 0000000..17d554d + PCI_FUNC(dev->devfn)); + list_add_tail(&dev_entry->list, + &vpci_dev->dev_list[slot]); -+ goto out; ++ goto unlock; + } + } + } @@ -56021,7 +57204,7 @@ index 0000000..17d554d + pci_name(dev), slot); + list_add_tail(&dev_entry->list, + &vpci_dev->dev_list[slot]); -+ goto out; ++ goto unlock; + } + } + @@ -56029,10 +57212,41 @@ index 0000000..17d554d + xenbus_dev_fatal(pdev->xdev, err, + "No more space on root virtual PCI bus"); + ++ unlock: ++ spin_unlock_irqrestore(&vpci_dev->lock, flags); + out: + return err; +} + ++void pciback_release_pci_dev(struct pciback_device *pdev, struct pci_dev *dev) ++{ ++ int slot; ++ struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; ++ struct pci_dev *found_dev = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&vpci_dev->lock, flags); ++ ++ for (slot = 0; slot < PCI_SLOT_MAX; slot++) { ++ struct pci_dev_entry *e, *tmp; ++ list_for_each_entry_safe(e, tmp, &vpci_dev->dev_list[slot], ++ list) { ++ if (e->dev == dev) { ++ list_del(&e->list); ++ found_dev = e->dev; ++ kfree(e); ++ goto out; ++ } ++ } ++ } ++ ++ out: ++ spin_unlock_irqrestore(&vpci_dev->lock, flags); ++ ++ if (found_dev) ++ pcistub_put_pci_dev(found_dev); ++} ++ +int pciback_init_devices(struct pciback_device *pdev) +{ + int slot; @@ -56042,6 +57256,8 @@ index 0000000..17d554d + if (!vpci_dev) + return -ENOMEM; + ++ spin_lock_init(&vpci_dev->lock); ++ + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { + INIT_LIST_HEAD(&vpci_dev->dev_list[slot]); + } @@ -56058,7 +57274,6 @@ index 0000000..17d554d + return publish_cb(pdev, 0, 0); +} + -+/* Must hold pciback_device->dev_lock when calling this */ +void pciback_release_devices(struct pciback_device *pdev) +{ + int slot; @@ -56079,10 +57294,10 @@ index 0000000..17d554d +} diff --git a/drivers/xen/pciback/xenbus.c b/drivers/xen/pciback/xenbus.c new file mode 100644 -index 0000000..b3dc7fb +index 0000000..f338de1 --- /dev/null +++ b/drivers/xen/pciback/xenbus.c -@@ -0,0 +1,439 @@ +@@ -0,0 +1,441 @@ +/* + * PCI Backend Xenbus Setup - handles setup with frontend and xend + * @@ -56097,7 +57312,7 @@ index 0000000..b3dc7fb + +#define INVALID_EVTCHN_IRQ (-1) + -+struct pciback_device *alloc_pdev(struct xenbus_device *xdev) ++static struct pciback_device *alloc_pdev(struct xenbus_device *xdev) +{ + struct pciback_device *pdev; + @@ -56123,7 +57338,7 @@ index 0000000..b3dc7fb + return pdev; +} + -+void free_pdev(struct pciback_device *pdev) ++static void free_pdev(struct pciback_device *pdev) +{ + if (pdev->be_watching) + unregister_xenbus_watch(&pdev->be_watch); @@ -56332,7 +57547,7 @@ index 0000000..b3dc7fb + dev_dbg(&pdev->xdev->dev, "exporting dom %x bus %x slot %x func %x\n", + domain, bus, slot, func); + -+ dev = pcistub_get_pci_dev_by_slot(domain, bus, slot, func); ++ dev = pcistub_get_pci_dev_by_slot(pdev, domain, bus, slot, func); + if (!dev) { + err = -EINVAL; + xenbus_dev_fatal(pdev->xdev, err, @@ -56515,13 +57730,15 @@ index 0000000..b3dc7fb + .otherend_changed = pciback_frontend_changed, +}; + -+static __init int pciback_xenbus_register(void) ++int __init pciback_xenbus_register(void) +{ + return xenbus_register_backend(&xenbus_pciback_driver); +} + -+/* Must only initialize our xenbus driver after the pcistub driver */ -+device_initcall(pciback_xenbus_register); ++void __exit pciback_xenbus_unregister(void) ++{ ++ xenbus_unregister_driver(&xenbus_pciback_driver); ++} diff --git a/drivers/xen/pcifront/Makefile b/drivers/xen/pcifront/Makefile new file mode 100644 index 0000000..621e988 @@ -56537,10 +57754,10 @@ index 0000000..621e988 +endif diff --git a/drivers/xen/pcifront/pci.c b/drivers/xen/pcifront/pci.c new file mode 100644 -index 0000000..d383410 +index 0000000..4239f00 --- /dev/null +++ b/drivers/xen/pcifront/pci.c -@@ -0,0 +1,44 @@ +@@ -0,0 +1,46 @@ +/* + * PCI Frontend Operations - ensure only one PCI frontend runs at a time + * @@ -56561,8 +57778,10 @@ index 0000000..d383410 + + spin_lock(&pcifront_dev_lock); + -+ if (!pcifront_dev) ++ if (!pcifront_dev) { + dev_info(&pdev->xdev->dev, "Installing PCI frontend\n"); ++ pcifront_dev = pdev; ++ } + else { + dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n"); + err = -EEXIST; @@ -56587,10 +57806,10 @@ index 0000000..d383410 +} diff --git a/drivers/xen/pcifront/pci_op.c b/drivers/xen/pcifront/pci_op.c new file mode 100644 -index 0000000..9679192 +index 0000000..38906ad --- /dev/null +++ b/drivers/xen/pcifront/pci_op.c -@@ -0,0 +1,245 @@ +@@ -0,0 +1,272 @@ +/* + * PCI Frontend Operations - Communicates with frontend + * @@ -56601,6 +57820,7 @@ index 0000000..9679192 +#include +#include +#include ++#include +#include +#include "pcifront.h" + @@ -56634,8 +57854,9 @@ index 0000000..9679192 + int err = 0; + struct xen_pci_op *active_op = &pdev->sh_info->op; + unsigned long irq_flags; -+ -+ unsigned int volatile ttl = (1U << 29); ++ evtchn_port_t port = pdev->evtchn; ++ nsec_t ns, ns_timeout; ++ struct timeval tv; + + spin_lock_irqsave(&pdev->sh_info_lock, irq_flags); + @@ -56644,14 +57865,27 @@ index 0000000..9679192 + /* Go */ + wmb(); + set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags); -+ notify_remote_via_evtchn(pdev->evtchn); ++ notify_remote_via_evtchn(port); + -+ /* IRQs are disabled for the pci config. space reads/writes, -+ * which means no event channel to notify us that the backend -+ * is done so spin while waiting for the answer */ -+ while (test_bit -+ (_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags)) { -+ if (!ttl) { ++ /* ++ * We set a poll timeout of 3 seconds but give up on return after ++ * 2 seconds. It is better to time out too late rather than too early ++ * (in the latter case we end up continually re-executing poll() with a ++ * timeout in the past). 1s difference gives plenty of slack for error. ++ */ ++ do_gettimeofday(&tv); ++ ns_timeout = timeval_to_ns(&tv) + 2 * (nsec_t)NSEC_PER_SEC; ++ ++ clear_evtchn(port); ++ ++ while (test_bit(_XEN_PCIF_active, ++ (unsigned long *)&pdev->sh_info->flags)) { ++ if (HYPERVISOR_poll(&port, 1, jiffies + 3*HZ)) ++ BUG(); ++ clear_evtchn(port); ++ do_gettimeofday(&tv); ++ ns = timeval_to_ns(&tv); ++ if (ns > ns_timeout) { + dev_err(&pdev->xdev->dev, + "pciback not responding!!!\n"); + clear_bit(_XEN_PCIF_active, @@ -56659,7 +57893,6 @@ index 0000000..9679192 + err = XEN_PCI_ERR_dev_not_found; + goto out; + } -+ ttl--; + } + + memcpy(op, active_op, sizeof(struct xen_pci_op)); @@ -56752,7 +57985,7 @@ index 0000000..9679192 + + if (!r->parent && r->start && r->flags) { + dev_dbg(&pdev->xdev->dev, "claiming resource %s/%d\n", -+ pci_name(dev), i); ++ pci_name(dev), i); + pci_claim_resource(dev, i); + } + } @@ -56813,25 +58046,38 @@ index 0000000..9679192 + return err; +} + ++static void free_root_bus_devs(struct pci_bus *bus) ++{ ++ struct pci_dev *dev; ++ ++ spin_lock(&pci_bus_lock); ++ while (!list_empty(&bus->devices)) { ++ dev = container_of(bus->devices.next, struct pci_dev, bus_list); ++ spin_unlock(&pci_bus_lock); ++ ++ dev_dbg(&dev->dev, "removing device\n"); ++ pci_remove_bus_device(dev); ++ ++ spin_lock(&pci_bus_lock); ++ } ++ spin_unlock(&pci_bus_lock); ++} ++ +void pcifront_free_roots(struct pcifront_device *pdev) +{ + struct pci_bus_entry *bus_entry, *t; + ++ dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n"); ++ + list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) { -+ /* TODO: Removing a PCI Bus is untested (as it normally -+ * just goes away on domain shutdown) -+ */ + list_del(&bus_entry->list); + -+ spin_lock(&pci_bus_lock); -+ list_del(&bus_entry->bus->node); -+ spin_unlock(&pci_bus_lock); ++ free_root_bus_devs(bus_entry->bus); + + kfree(bus_entry->bus->sysdata); + + device_unregister(bus_entry->bus->bridge); -+ -+ /* Do we need to free() the bus itself? */ ++ pci_remove_bus(bus_entry->bus); + + kfree(bus_entry); + } @@ -56884,10 +58130,10 @@ index 0000000..70bbf3b +#endif /* __XEN_PCIFRONT_H__ */ diff --git a/drivers/xen/pcifront/xenbus.c b/drivers/xen/pcifront/xenbus.c new file mode 100644 -index 0000000..c596ed4 +index 0000000..eed89eb --- /dev/null +++ b/drivers/xen/pcifront/xenbus.c -@@ -0,0 +1,295 @@ +@@ -0,0 +1,297 @@ +/* + * PCI Frontend Xenbus Setup - handles setup with backend (imports page/evtchn) + * @@ -56940,6 +58186,8 @@ index 0000000..c596ed4 +{ + dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev); + ++ pcifront_free_roots(pdev); ++ + if (pdev->evtchn != INVALID_EVTCHN) + xenbus_free_evtchn(pdev->xdev, pdev->evtchn); + @@ -58874,10 +60122,10 @@ index 0000000..1fda74e + */ diff --git a/drivers/xen/tpmback/xenbus.c b/drivers/xen/tpmback/xenbus.c new file mode 100644 -index 0000000..9a2be8d +index 0000000..6ce5f07 --- /dev/null +++ b/drivers/xen/tpmback/xenbus.c -@@ -0,0 +1,333 @@ +@@ -0,0 +1,331 @@ +/* Xenbus code for tpmif backend + Copyright (C) 2005 IBM Corporation + Copyright (C) 2005 Rusty Russell @@ -58947,7 +60195,7 @@ index 0000000..9a2be8d + const struct xenbus_device_id *id) +{ + int err; -+ struct backend_info *be = kmalloc(sizeof(struct backend_info), ++ struct backend_info *be = kzalloc(sizeof(struct backend_info), + GFP_KERNEL); + + if (!be) { @@ -58956,8 +60204,6 @@ index 0000000..9a2be8d + return -ENOMEM; + } + -+ memset(be, 0, sizeof(*be)); -+ + be->is_instance_set = 0; + be->dev = dev; + dev->data = be; @@ -59221,10 +60467,10 @@ index 0000000..d43666f +obj-$(CONFIG_XEN_TPMDEV_FRONTEND) += tpmfront.o diff --git a/drivers/xen/tpmfront/tpmfront.c b/drivers/xen/tpmfront/tpmfront.c new file mode 100644 -index 0000000..62e3d56 +index 0000000..03a2ab9 --- /dev/null +++ b/drivers/xen/tpmfront/tpmfront.c -@@ -0,0 +1,728 @@ +@@ -0,0 +1,731 @@ +/* + * Copyright (c) 2005, IBM Corporation + * @@ -59235,9 +60481,12 @@ index 0000000..62e3d56 + * + * Copyright (c) 2002-2004, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: -+ * ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: ++ * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, @@ -59267,8 +60516,7 @@ index 0000000..62e3d56 +#include +#include +#include -+ -+#include ++#include +#include +#include +#include @@ -59377,8 +60625,8 @@ index 0000000..62e3d56 + +**************************************************************/ + -+static DECLARE_MUTEX(upperlayer_lock); -+static DECLARE_MUTEX(suspend_lock); ++static DEFINE_MUTEX(upperlayer_lock); ++static DEFINE_MUTEX(suspend_lock); +static struct tpmfe_device *upperlayer_tpmfe; + +/* @@ -59388,9 +60636,9 @@ index 0000000..62e3d56 +{ + int sent; + -+ down(&suspend_lock); ++ mutex_lock(&suspend_lock); + sent = tpm_xmit(tp, buf, count, 0, ptr); -+ up(&suspend_lock); ++ mutex_unlock(&suspend_lock); + + return sent; +} @@ -59403,7 +60651,7 @@ index 0000000..62e3d56 +{ + int rc = 0; + -+ down(&upperlayer_lock); ++ mutex_lock(&upperlayer_lock); + if (NULL == upperlayer_tpmfe) { + upperlayer_tpmfe = tpmfe_dev; + tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE; @@ -59414,7 +60662,7 @@ index 0000000..62e3d56 + } else { + rc = -EBUSY; + } -+ up(&upperlayer_lock); ++ mutex_unlock(&upperlayer_lock); + return rc; +} +EXPORT_SYMBOL(tpm_fe_register_receiver); @@ -59424,9 +60672,9 @@ index 0000000..62e3d56 + */ +void tpm_fe_unregister_receiver(void) +{ -+ down(&upperlayer_lock); ++ mutex_lock(&upperlayer_lock); + upperlayer_tpmfe = NULL; -+ up(&upperlayer_lock); ++ mutex_unlock(&upperlayer_lock); +} +EXPORT_SYMBOL(tpm_fe_unregister_receiver); + @@ -59439,12 +60687,12 @@ index 0000000..62e3d56 +{ + int rc = 0; + -+ down(&upperlayer_lock); ++ mutex_lock(&upperlayer_lock); + + if (upperlayer_tpmfe && upperlayer_tpmfe->receive) + rc = upperlayer_tpmfe->receive(buf, count, ptr); + -+ up(&upperlayer_lock); ++ mutex_unlock(&upperlayer_lock); + return rc; +} + @@ -59537,7 +60785,8 @@ index 0000000..62e3d56 + goto abort_transaction; + } + -+ err = xenbus_switch_state(dev, xbt, XenbusStateInitialised); ++ err = xenbus_printf(xbt, dev->nodename, ++ "state", "%d", XenbusStateInitialised); + if (err) { + goto abort_transaction; + } @@ -59638,7 +60887,7 @@ index 0000000..62e3d56 + u32 ctr; + + /* lock, so no app can send */ -+ down(&suspend_lock); ++ mutex_lock(&suspend_lock); + tp->is_suspended = 1; + + for (ctr = 0; atomic_read(&tp->tx_busy) && ctr <= 25; ctr++) { @@ -59870,7 +61119,7 @@ index 0000000..62e3d56 + * Notify upper layer about the state of the connection + * to the BE. + */ -+ down(&upperlayer_lock); ++ mutex_lock(&upperlayer_lock); + + if (upperlayer_tpmfe != NULL) { + if (tp->is_connected) { @@ -59879,7 +61128,7 @@ index 0000000..62e3d56 + upperlayer_tpmfe->status(0); + } + } -+ up(&upperlayer_lock); ++ mutex_unlock(&upperlayer_lock); +} + + @@ -59888,21 +61137,21 @@ index 0000000..62e3d56 + /* + * Don't notify upper layer if we are in suspend mode and + * should disconnect - assumption is that we will resume -+ * The semaphore keeps apps from sending. ++ * The mutex keeps apps from sending. + */ + if (is_connected == 0 && tp->is_suspended == 1) { + return; + } + + /* -+ * Unlock the semaphore if we are connected again ++ * Unlock the mutex if we are connected again + * after being suspended - now resuming. + * This also removes the suspend state. + */ + if (is_connected == 1 && tp->is_suspended == 1) { + tp->is_suspended = 0; + /* unlock, so apps can resume sending */ -+ up(&suspend_lock); ++ mutex_unlock(&suspend_lock); + } + + if (is_connected != tp->is_connected) { @@ -60001,7 +61250,7 @@ index 0000000..66568ba + */ diff --git a/drivers/xen/util.c b/drivers/xen/util.c new file mode 100644 -index 0000000..7f76a39 +index 0000000..d7980f1 --- /dev/null +++ b/drivers/xen/util.c @@ -0,0 +1,80 @@ @@ -60013,9 +61262,9 @@ index 0000000..7f76a39 +#include +#include + -+static int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data) ++static int f(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) +{ -+ /* generic_page_range() does all the hard work. */ ++ /* apply_to_page_range() does all the hard work. */ + return 0; +} + @@ -60031,8 +61280,8 @@ index 0000000..7f76a39 + * This ensures that page tables are constructed for this region + * of kernel virtual address space and mapped into init_mm. + */ -+ if (generic_page_range(&init_mm, (unsigned long)area->addr, -+ area->size, f, NULL)) { ++ if (apply_to_page_range(&init_mm, (unsigned long)area->addr, ++ area->size, f, NULL)) { + free_vm_area(area); + return NULL; + } @@ -60101,10 +61350,10 @@ index 0000000..4ef620c +xenbus-objs += xenbus_dev.o diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c new file mode 100644 -index 0000000..fea04d0 +index 0000000..8126705 --- /dev/null +++ b/drivers/xen/xenbus/xenbus_client.c -@@ -0,0 +1,405 @@ +@@ -0,0 +1,408 @@ +/****************************************************************************** + * Client-facing interface for the Xenbus driver. In other words, the + * interface between the Xenbus and the device-specific code, be it the @@ -60112,8 +61361,11 @@ index 0000000..fea04d0 + * + * Copyright (C) 2005 XenSource Ltd + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -60165,7 +61417,7 @@ index 0000000..fea04d0 + + return err; +} -+EXPORT_SYMBOL(xenbus_watch_path); ++EXPORT_SYMBOL_GPL(xenbus_watch_path); + + +int xenbus_watch_path2(struct xenbus_device *dev, const char *path, @@ -60185,7 +61437,7 @@ index 0000000..fea04d0 + kfree(state); + return err; +} -+EXPORT_SYMBOL(xenbus_watch_path2); ++EXPORT_SYMBOL_GPL(xenbus_watch_path2); + + +int xenbus_switch_state(struct xenbus_device *dev, @@ -60222,7 +61474,7 @@ index 0000000..fea04d0 + + return 0; +} -+EXPORT_SYMBOL(xenbus_switch_state); ++EXPORT_SYMBOL_GPL(xenbus_switch_state); + + +/** @@ -60285,7 +61537,7 @@ index 0000000..fea04d0 + _dev_error(dev, err, fmt, ap); + va_end(ap); +} -+EXPORT_SYMBOL(xenbus_dev_error); ++EXPORT_SYMBOL_GPL(xenbus_dev_error); + + +void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, @@ -60299,7 +61551,7 @@ index 0000000..fea04d0 + + xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing); +} -+EXPORT_SYMBOL(xenbus_dev_fatal); ++EXPORT_SYMBOL_GPL(xenbus_dev_fatal); + + +int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn) @@ -60309,7 +61561,7 @@ index 0000000..fea04d0 + xenbus_dev_fatal(dev, err, "granting access to ring page"); + return err; +} -+EXPORT_SYMBOL(xenbus_grant_ring); ++EXPORT_SYMBOL_GPL(xenbus_grant_ring); + + +int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port) @@ -60326,7 +61578,7 @@ index 0000000..fea04d0 + *port = op.u.alloc_unbound.port; + return err; +} -+EXPORT_SYMBOL(xenbus_alloc_evtchn); ++EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn); + + +int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port) @@ -60345,7 +61597,7 @@ index 0000000..fea04d0 + *port = op.u.bind_interdomain.local_port; + return err; +} -+EXPORT_SYMBOL(xenbus_bind_evtchn); ++EXPORT_SYMBOL_GPL(xenbus_bind_evtchn); + + +int xenbus_free_evtchn(struct xenbus_device *dev, int port) @@ -60397,7 +61649,7 @@ index 0000000..fea04d0 + *vaddr = area->addr; + return 0; +} -+EXPORT_SYMBOL(xenbus_map_ring_valloc); ++EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc); + + +int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref, @@ -60421,7 +61673,7 @@ index 0000000..fea04d0 + + return op.status; +} -+EXPORT_SYMBOL(xenbus_map_ring); ++EXPORT_SYMBOL_GPL(xenbus_map_ring); + + +/* Based on Rusty Russell's skeleton driver's unmap_page */ @@ -60466,7 +61718,7 @@ index 0000000..fea04d0 + + return op.status; +} -+EXPORT_SYMBOL(xenbus_unmap_ring_vfree); ++EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree); + + +int xenbus_unmap_ring(struct xenbus_device *dev, @@ -60486,7 +61738,7 @@ index 0000000..fea04d0 + + return op.status; +} -+EXPORT_SYMBOL(xenbus_unmap_ring); ++EXPORT_SYMBOL_GPL(xenbus_unmap_ring); + + +XenbusState xenbus_read_driver_state(const char *path) @@ -60498,7 +61750,7 @@ index 0000000..fea04d0 + + return result; +} -+EXPORT_SYMBOL(xenbus_read_driver_state); ++EXPORT_SYMBOL_GPL(xenbus_read_driver_state); + + +/* @@ -60512,10 +61764,10 @@ index 0000000..fea04d0 + */ diff --git a/drivers/xen/xenbus/xenbus_comms.c b/drivers/xen/xenbus/xenbus_comms.c new file mode 100644 -index 0000000..6d06b4d +index 0000000..041b7db --- /dev/null +++ b/drivers/xen/xenbus/xenbus_comms.c -@@ -0,0 +1,211 @@ +@@ -0,0 +1,218 @@ +/****************************************************************************** + * xenbus_comms.c + * @@ -60523,8 +61775,11 @@ index 0000000..6d06b4d + * + * Copyright (C) 2005 Rusty Russell, IBM Corporation + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -60624,8 +61879,10 @@ index 0000000..6d06b4d + cons = intf->req_cons; + prod = intf->req_prod; + mb(); -+ if (!check_indexes(cons, prod)) ++ if (!check_indexes(cons, prod)) { ++ intf->req_cons = intf->req_prod = 0; + return -EIO; ++ } + + dst = get_output_chunk(cons, prod, intf->req, &avail); + if (avail == 0) @@ -60668,8 +61925,10 @@ index 0000000..6d06b4d + cons = intf->rsp_cons; + prod = intf->rsp_prod; + mb(); -+ if (!check_indexes(cons, prod)) ++ if (!check_indexes(cons, prod)) { ++ intf->rsp_cons = intf->rsp_prod = 0; + return -EIO; ++ } + + src = get_input_chunk(cons, prod, intf->rsp, &avail); + if (avail == 0) @@ -60729,17 +61988,20 @@ index 0000000..6d06b4d + */ diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h new file mode 100644 -index 0000000..59ca0d3 +index 0000000..a378b2d --- /dev/null +++ b/drivers/xen/xenbus/xenbus_comms.h -@@ -0,0 +1,50 @@ +@@ -0,0 +1,53 @@ +/* + * Private include for xenbus communications. + * + * Copyright (C) 2005 Rusty Russell, IBM Corporation + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -60785,10 +62047,10 @@ index 0000000..59ca0d3 + */ diff --git a/drivers/xen/xenbus/xenbus_dev.c b/drivers/xen/xenbus/xenbus_dev.c new file mode 100644 -index 0000000..cdab7e8 +index 0000000..282cdaf --- /dev/null +++ b/drivers/xen/xenbus/xenbus_dev.c -@@ -0,0 +1,238 @@ +@@ -0,0 +1,252 @@ +/* + * xenbus_dev.c + * @@ -60798,8 +62060,11 @@ index 0000000..cdab7e8 + * Copyright (c) 2005, Christian Limpach + * Copyright (c) 2005, Rusty Russell, IBM Corporation + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -60827,6 +62092,7 @@ index 0000000..cdab7e8 +#include +#include +#include ++#include + +#include "xenbus_comms.h" + @@ -60970,11 +62236,10 @@ index 0000000..cdab7e8 + + nonseekable_open(inode, filp); + -+ u = kmalloc(sizeof(*u), GFP_KERNEL); ++ u = kzalloc(sizeof(*u), GFP_KERNEL); + if (u == NULL) + return -ENOMEM; + -+ memset(u, 0, sizeof(*u)); + INIT_LIST_HEAD(&u->transactions); + init_waitqueue_head(&u->read_waitq); + @@ -60999,11 +62264,22 @@ index 0000000..cdab7e8 + return 0; +} + ++static unsigned int xenbus_dev_poll(struct file *file, poll_table *wait) ++{ ++ struct xenbus_dev_data *u = file->private_data; ++ ++ poll_wait(file, &u->read_waitq, wait); ++ if (u->read_cons != u->read_prod) ++ return POLLIN | POLLRDNORM; ++ return 0; ++} ++ +static struct file_operations xenbus_dev_file_ops = { + .read = xenbus_dev_read, + .write = xenbus_dev_write, + .open = xenbus_dev_open, + .release = xenbus_dev_release, ++ .poll = xenbus_dev_poll, +}; + +static int __init @@ -61029,10 +62305,10 @@ index 0000000..cdab7e8 + */ diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c new file mode 100644 -index 0000000..d43f9fb +index 0000000..61158a6 --- /dev/null +++ b/drivers/xen/xenbus/xenbus_probe.c -@@ -0,0 +1,1081 @@ +@@ -0,0 +1,1069 @@ +/****************************************************************************** + * Talks to Xen Store to figure out what devices we have. + * @@ -61040,8 +62316,11 @@ index 0000000..d43f9fb + * Copyright (C) 2005 Mike Wray, Hewlett-Packard + * Copyright (C) 2005 XenSource Ltd + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -61084,9 +62363,7 @@ index 0000000..d43f9fb + +#include "xenbus_comms.h" + -+extern struct semaphore xenwatch_mutex; -+ -+#define streq(a, b) (strcmp((a), (b)) == 0) ++extern struct mutex xenwatch_mutex; + +static struct notifier_block *xenstore_chain; + @@ -61094,8 +62371,8 @@ index 0000000..d43f9fb +static const struct xenbus_device_id * +match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev) +{ -+ for (; !streq(arr->devicetype, ""); arr++) { -+ if (streq(arr->devicetype, dev->devicetype)) ++ for (; *arr->devicetype != '\0'; arr++) { ++ if (!strcmp(arr->devicetype, dev->devicetype)) + return arr; + } + return NULL; @@ -61141,6 +62418,23 @@ index 0000000..d43f9fb +} + + ++static void free_otherend_details(struct xenbus_device *dev) ++{ ++ kfree(dev->otherend); ++ dev->otherend = NULL; ++} ++ ++ ++static void free_otherend_watch(struct xenbus_device *dev) ++{ ++ if (dev->otherend_watch.node) { ++ unregister_xenbus_watch(&dev->otherend_watch); ++ kfree(dev->otherend_watch.node); ++ dev->otherend_watch.node = NULL; ++ } ++} ++ ++ +static int read_otherend_details(struct xenbus_device *xendev, + char *id_node, char *path_node) +{ @@ -61158,8 +62452,7 @@ index 0000000..d43f9fb + !xenbus_exists(XBT_NULL, xendev->otherend, "")) { + xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s", + xendev->nodename); -+ kfree(xendev->otherend); -+ xendev->otherend = NULL; ++ free_otherend_details(xendev); + return -ENOENT; + } + @@ -61179,23 +62472,6 @@ index 0000000..d43f9fb +} + + -+static void free_otherend_details(struct xenbus_device *dev) -+{ -+ kfree(dev->otherend); -+ dev->otherend = NULL; -+} -+ -+ -+static void free_otherend_watch(struct xenbus_device *dev) -+{ -+ if (dev->otherend_watch.node) { -+ unregister_xenbus_watch(&dev->otherend_watch); -+ kfree(dev->otherend_watch.node); -+ dev->otherend_watch.node = NULL; -+ } -+} -+ -+ +/* Bus type for frontend drivers. */ +static int xenbus_probe_frontend(const char *type, const char *name); +static struct xen_bus_type xenbus_frontend = { @@ -61431,9 +62707,9 @@ index 0000000..d43f9fb + drv->driver.probe = xenbus_dev_probe; + drv->driver.remove = xenbus_dev_remove; + -+ down(&xenwatch_mutex); ++ mutex_lock(&xenwatch_mutex); + ret = driver_register(&drv->driver); -+ up(&xenwatch_mutex); ++ mutex_unlock(&xenwatch_mutex); + return ret; +} + @@ -61443,7 +62719,7 @@ index 0000000..d43f9fb + + return xenbus_register_driver_common(drv, &xenbus_frontend); +} -+EXPORT_SYMBOL(xenbus_register_frontend); ++EXPORT_SYMBOL_GPL(xenbus_register_frontend); + +int xenbus_register_backend(struct xenbus_driver *drv) +{ @@ -61451,13 +62727,13 @@ index 0000000..d43f9fb + + return xenbus_register_driver_common(drv, &xenbus_backend); +} -+EXPORT_SYMBOL(xenbus_register_backend); ++EXPORT_SYMBOL_GPL(xenbus_register_backend); + +void xenbus_unregister_driver(struct xenbus_driver *drv) +{ + driver_unregister(&drv->driver); +} -+EXPORT_SYMBOL(xenbus_unregister_driver); ++EXPORT_SYMBOL_GPL(xenbus_unregister_driver); + +struct xb_find_info +{ @@ -61470,7 +62746,7 @@ index 0000000..d43f9fb + struct xenbus_device *xendev = to_xenbus_device(dev); + struct xb_find_info *info = data; + -+ if (streq(xendev->nodename, info->nodename)) { ++ if (!strcmp(xendev->nodename, info->nodename)) { + info->dev = xendev; + get_device(dev); + return 1; @@ -61522,15 +62798,10 @@ index 0000000..d43f9fb + } while (info.dev); +} + -+static void xenbus_dev_free(struct xenbus_device *xendev) -+{ -+ kfree(xendev); -+} -+ +static void xenbus_dev_release(struct device *dev) +{ + if (dev) -+ xenbus_dev_free(to_xenbus_device(dev)); ++ kfree(to_xenbus_device(dev)); +} + +/* Simplified asprintf. */ @@ -61587,10 +62858,9 @@ index 0000000..d43f9fb + } + + stringlen = strlen(nodename) + 1 + strlen(type) + 1; -+ xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL); ++ xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL); + if (!xendev) + return -ENOMEM; -+ memset(xendev, 0, sizeof(*xendev)); + + /* Copy the strings into the extra space. */ + @@ -61620,7 +62890,7 @@ index 0000000..d43f9fb + + return 0; +fail: -+ xenbus_dev_free(xendev); ++ kfree(xendev); + return err; +} + @@ -61881,7 +63151,7 @@ index 0000000..d43f9fb + bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, suspend_dev); + xs_suspend(); +} -+EXPORT_SYMBOL(xenbus_suspend); ++EXPORT_SYMBOL_GPL(xenbus_suspend); + +void xenbus_resume(void) +{ @@ -61890,7 +63160,7 @@ index 0000000..d43f9fb + bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev); + bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev); +} -+EXPORT_SYMBOL(xenbus_resume); ++EXPORT_SYMBOL_GPL(xenbus_resume); + + +/* A flag to determine if xenstored is 'ready' (i.e. has started) */ @@ -61908,13 +63178,13 @@ index 0000000..d43f9fb + + return ret; +} -+EXPORT_SYMBOL(register_xenstore_notifier); ++EXPORT_SYMBOL_GPL(register_xenstore_notifier); + +void unregister_xenstore_notifier(struct notifier_block *nb) +{ + notifier_chain_unregister(&xenstore_chain, nb); +} -+EXPORT_SYMBOL(unregister_xenstore_notifier); ++EXPORT_SYMBOL_GPL(unregister_xenstore_notifier); + + +static int all_devices_ready_(struct device *dev, void *data) @@ -61992,9 +63262,8 @@ index 0000000..d43f9fb + if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0)) + return -EINVAL; + -+ vma->vm_pgoff = mfn_to_pfn(xen_start_info->store_mfn); -+ -+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, ++ if (remap_pfn_range(vma, vma->vm_start, ++ mfn_to_pfn(xen_start_info->store_mfn), + size, vma->vm_page_prot)) + return -EAGAIN; + @@ -62056,10 +63325,6 @@ index 0000000..d43f9fb + if (!page) + return -ENOMEM; + -+ /* We don't refcnt properly, so set reserved on page. -+ * (this allocation is permanent) */ -+ SetPageReserved(virt_to_page(page)); -+ + xen_start_info->store_mfn = + pfn_to_mfn(virt_to_phys((void *)page) >> + PAGE_SHIFT); @@ -62074,7 +63339,7 @@ index 0000000..d43f9fb + xen_start_info->store_evtchn = op.u.alloc_unbound.port; + + /* And finally publish the above info in /proc/xen */ -+ xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0400); ++ xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600); + if (xsd_kva_intf) { + memcpy(&xsd_kva_fops, xsd_kva_intf->proc_fops, + sizeof(xsd_kva_fops)); @@ -62085,7 +63350,8 @@ index 0000000..d43f9fb + xsd_port_intf = create_xen_proc_entry("xsd_port", 0400); + if (xsd_port_intf) + xsd_port_intf->read_proc = xsd_port_read; -+ } ++ } else ++ xenstored_ready = 1; + + /* Initialize the interface to xenstore. */ + err = xs_init(); @@ -62095,10 +63361,8 @@ index 0000000..d43f9fb + return err; + } + -+ if (!dom0) { -+ xenstored_ready = 1; ++ if (!dom0) + xenbus_probe(NULL); -+ } + + return 0; +} @@ -62116,10 +63380,10 @@ index 0000000..d43f9fb + */ diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c new file mode 100644 -index 0000000..ad43b0c +index 0000000..7e343ef --- /dev/null +++ b/drivers/xen/xenbus/xenbus_xs.c -@@ -0,0 +1,830 @@ +@@ -0,0 +1,839 @@ +/****************************************************************************** + * xenbus_xs.c + * @@ -62128,8 +63392,11 @@ index 0000000..ad43b0c + * + * Copyright (C) 2005 Rusty Russell, IBM Corporation + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -62160,14 +63427,13 @@ index 0000000..ad43b0c +#include +#include +#include ++#include +#include +#include "xenbus_comms.h" + +/* xenbus_probe.c */ +extern char *kasprintf(const char *fmt, ...); + -+#define streq(a, b) (strcmp((a), (b)) == 0) -+ +struct xs_stored_msg { + struct list_head list; + @@ -62195,7 +63461,7 @@ index 0000000..ad43b0c + wait_queue_head_t reply_waitq; + + /* One request at a time. */ -+ struct semaphore request_mutex; ++ struct mutex request_mutex; + + /* Protect transactions against save/restore. */ + struct rw_semaphore suspend_mutex; @@ -62218,14 +63484,14 @@ index 0000000..ad43b0c + * carrying out work. + */ +static pid_t xenwatch_pid; -+/* static */ DECLARE_MUTEX(xenwatch_mutex); ++/* static */ DEFINE_MUTEX(xenwatch_mutex); +static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq); + +static int get_error(const char *errorstring) +{ + unsigned int i; + -+ for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) { ++ for (i = 0; strcmp(errorstring, xsd_errors[i].errstring) != 0; i++) { + if (i == ARRAY_SIZE(xsd_errors) - 1) { + printk(KERN_WARNING + "XENBUS xen store gave: unknown error %s", @@ -62275,12 +63541,12 @@ index 0000000..ad43b0c + msg.type = XS_DEBUG; + msg.len = sizeof("print") + count + 1; + -+ down(&xs_state.request_mutex); ++ mutex_lock(&xs_state.request_mutex); + xb_write(&msg, sizeof(msg)); + xb_write("print", sizeof("print")); + xb_write(str, count); + xb_write("", 1); -+ up(&xs_state.request_mutex); ++ mutex_unlock(&xs_state.request_mutex); +} + +void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg) @@ -62292,7 +63558,7 @@ index 0000000..ad43b0c + if (req_msg.type == XS_TRANSACTION_START) + down_read(&xs_state.suspend_mutex); + -+ down(&xs_state.request_mutex); ++ mutex_lock(&xs_state.request_mutex); + + err = xb_write(msg, sizeof(*msg) + msg->len); + if (err) { @@ -62301,7 +63567,7 @@ index 0000000..ad43b0c + } else + ret = read_reply(&msg->type, &msg->len); + -+ up(&xs_state.request_mutex); ++ mutex_unlock(&xs_state.request_mutex); + + if ((msg->type == XS_TRANSACTION_END) || + ((req_msg.type == XS_TRANSACTION_START) && @@ -62330,25 +63596,25 @@ index 0000000..ad43b0c + for (i = 0; i < num_vecs; i++) + msg.len += iovec[i].iov_len; + -+ down(&xs_state.request_mutex); ++ mutex_lock(&xs_state.request_mutex); + + err = xb_write(&msg, sizeof(msg)); + if (err) { -+ up(&xs_state.request_mutex); ++ mutex_unlock(&xs_state.request_mutex); + return ERR_PTR(err); + } + + for (i = 0; i < num_vecs; i++) { + err = xb_write(iovec[i].iov_base, iovec[i].iov_len);; + if (err) { -+ up(&xs_state.request_mutex); ++ mutex_unlock(&xs_state.request_mutex); + return ERR_PTR(err); + } + } + + ret = read_reply(&msg.type, len); + -+ up(&xs_state.request_mutex); ++ mutex_unlock(&xs_state.request_mutex); + + if (IS_ERR(ret)) + return ret; @@ -62359,7 +63625,14 @@ index 0000000..ad43b0c + return ERR_PTR(-err); + } + -+ BUG_ON(msg.type != type); ++ if (msg.type != type) { ++ if (printk_ratelimit()) ++ printk(KERN_WARNING ++ "XENBUS unexpected type [%d], expected [%d]\n", ++ msg.type, type); ++ kfree(ret); ++ return ERR_PTR(-EINVAL); ++ } + return ret; +} + @@ -62448,7 +63721,7 @@ index 0000000..ad43b0c + + return split(strings, len, num); +} -+EXPORT_SYMBOL(xenbus_directory); ++EXPORT_SYMBOL_GPL(xenbus_directory); + +/* Check if a path exists. Return 1 if it does. */ +int xenbus_exists(xenbus_transaction_t t, @@ -62463,7 +63736,7 @@ index 0000000..ad43b0c + kfree(d); + return 1; +} -+EXPORT_SYMBOL(xenbus_exists); ++EXPORT_SYMBOL_GPL(xenbus_exists); + +/* Get the value of a single file. + * Returns a kmalloced value: call free() on it after use. @@ -62483,7 +63756,7 @@ index 0000000..ad43b0c + kfree(path); + return ret; +} -+EXPORT_SYMBOL(xenbus_read); ++EXPORT_SYMBOL_GPL(xenbus_read); + +/* Write the value of a single file. + * Returns -err on failure. @@ -62508,7 +63781,7 @@ index 0000000..ad43b0c + kfree(path); + return ret; +} -+EXPORT_SYMBOL(xenbus_write); ++EXPORT_SYMBOL_GPL(xenbus_write); + +/* Create a new directory. */ +int xenbus_mkdir(xenbus_transaction_t t, @@ -62525,7 +63798,7 @@ index 0000000..ad43b0c + kfree(path); + return ret; +} -+EXPORT_SYMBOL(xenbus_mkdir); ++EXPORT_SYMBOL_GPL(xenbus_mkdir); + +/* Destroy a file or directory (directories must be empty). */ +int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node) @@ -62541,7 +63814,7 @@ index 0000000..ad43b0c + kfree(path); + return ret; +} -+EXPORT_SYMBOL(xenbus_rm); ++EXPORT_SYMBOL_GPL(xenbus_rm); + +/* Start a transaction: changes by others will not be seen during this + * transaction, and changes will not be visible to others until end. @@ -62562,7 +63835,7 @@ index 0000000..ad43b0c + kfree(id_str); + return 0; +} -+EXPORT_SYMBOL(xenbus_transaction_start); ++EXPORT_SYMBOL_GPL(xenbus_transaction_start); + +/* End a transaction. + * If abandon is true, transaction is discarded instead of committed. @@ -62583,7 +63856,7 @@ index 0000000..ad43b0c + + return err; +} -+EXPORT_SYMBOL(xenbus_transaction_end); ++EXPORT_SYMBOL_GPL(xenbus_transaction_end); + +/* Single read and scanf: returns -errno or num scanned. */ +int xenbus_scanf(xenbus_transaction_t t, @@ -62606,7 +63879,7 @@ index 0000000..ad43b0c + return -ERANGE; + return ret; +} -+EXPORT_SYMBOL(xenbus_scanf); ++EXPORT_SYMBOL_GPL(xenbus_scanf); + +/* Single printf and write: returns -errno or 0. */ +int xenbus_printf(xenbus_transaction_t t, @@ -62632,7 +63905,7 @@ index 0000000..ad43b0c + + return ret; +} -+EXPORT_SYMBOL(xenbus_printf); ++EXPORT_SYMBOL_GPL(xenbus_printf); + +/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */ +int xenbus_gather(xenbus_transaction_t t, const char *dir, ...) @@ -62662,7 +63935,7 @@ index 0000000..ad43b0c + va_end(ap); + return ret; +} -+EXPORT_SYMBOL(xenbus_gather); ++EXPORT_SYMBOL_GPL(xenbus_gather); + +static int xs_watch(const char *path, const char *token) +{ @@ -62732,7 +64005,7 @@ index 0000000..ad43b0c + + return err; +} -+EXPORT_SYMBOL(register_xenbus_watch); ++EXPORT_SYMBOL_GPL(register_xenbus_watch); + +void unregister_xenbus_watch(struct xenbus_watch *watch) +{ @@ -62770,16 +64043,16 @@ index 0000000..ad43b0c + + /* Flush any currently-executing callback, unless we are it. :-) */ + if (current->pid != xenwatch_pid) { -+ down(&xenwatch_mutex); -+ up(&xenwatch_mutex); ++ mutex_lock(&xenwatch_mutex); ++ mutex_unlock(&xenwatch_mutex); + } +} -+EXPORT_SYMBOL(unregister_xenbus_watch); ++EXPORT_SYMBOL_GPL(unregister_xenbus_watch); + +void xs_suspend(void) +{ + down_write(&xs_state.suspend_mutex); -+ down(&xs_state.request_mutex); ++ mutex_lock(&xs_state.request_mutex); +} + +void xs_resume(void) @@ -62787,7 +64060,7 @@ index 0000000..ad43b0c + struct xenbus_watch *watch; + char token[sizeof(watch) * 2 + 1]; + -+ up(&xs_state.request_mutex); ++ mutex_unlock(&xs_state.request_mutex); + + /* No need for watches_lock: the suspend_mutex is sufficient. */ + list_for_each_entry(watch, &watches, list) { @@ -62810,7 +64083,7 @@ index 0000000..ad43b0c + if (kthread_should_stop()) + break; + -+ down(&xenwatch_mutex); ++ mutex_lock(&xenwatch_mutex); + + spin_lock(&watch_events_lock); + ent = watch_events.next; @@ -62828,7 +64101,7 @@ index 0000000..ad43b0c + kfree(msg); + } + -+ up(&xenwatch_mutex); ++ mutex_unlock(&xenwatch_mutex); + } + + return 0; @@ -62921,7 +64194,7 @@ index 0000000..ad43b0c + spin_lock_init(&xs_state.reply_lock); + init_waitqueue_head(&xs_state.reply_waitq); + -+ init_MUTEX(&xs_state.request_mutex); ++ mutex_init(&xs_state.request_mutex); + init_rwsem(&xs_state.suspend_mutex); + + /* Initialize the shared memory rings to talk to xenstored */ @@ -63711,10 +64984,10 @@ index 622815b..3173498 100644 if (IO_APIC_IRQ(i)) diff --git a/include/asm-i386/hypercall.h b/include/asm-i386/hypercall.h new file mode 100644 -index 0000000..1b2605e +index 0000000..f920d4b --- /dev/null +++ b/include/asm-i386/hypercall.h -@@ -0,0 +1,329 @@ +@@ -0,0 +1,357 @@ +/****************************************************************************** + * hypercall.h + * @@ -63722,8 +64995,11 @@ index 0000000..1b2605e + * + * Copyright (c) 2002-2004, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -63754,6 +65030,7 @@ index 0000000..1b2605e +#include +#include +#include ++#include + +#define __STR(x) #x +#define STR(x) __STR(x) @@ -63890,6 +65167,31 @@ index 0000000..1b2605e + return _hypercall2(int, sched_op, cmd, arg); +} + ++static inline int ++HYPERVISOR_sched_op_new( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, sched_op_new, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_poll( ++ evtchn_port_t *ports, unsigned int nr_ports, u64 timeout) ++{ ++ struct sched_poll sched_poll = { ++ .ports = ports, ++ .nr_ports = nr_ports, ++ .timeout = jiffies_to_st(timeout) ++ }; ++ ++ int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll); ++ ++ if (rc == -ENOSYS) ++ rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0); ++ ++ return rc; ++} ++ +static inline long +HYPERVISOR_set_timer_op( + u64 timeout) @@ -64025,8 +65327,7 @@ index 0000000..1b2605e + +static inline int +HYPERVISOR_nmi_op( -+ unsigned long op, -+ unsigned long arg) ++ unsigned long op, void *arg) +{ + return _hypercall2(int, nmi_op, op, arg); +} @@ -64046,7 +65347,7 @@ index 0000000..1b2605e + */ diff --git a/include/asm-i386/hypervisor.h b/include/asm-i386/hypervisor.h new file mode 100644 -index 0000000..021e2de +index 0000000..f721acc --- /dev/null +++ b/include/asm-i386/hypervisor.h @@ -0,0 +1,168 @@ @@ -64057,8 +65358,11 @@ index 0000000..021e2de + * + * Copyright (c) 2002-2004, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -64134,12 +65438,6 @@ index 0000000..021e2de +void xen_l4_entry_update(pgd_t *ptr, pgd_t val); /* x86_64 only */ +void xen_pgd_pin(unsigned long ptr); +void xen_pgd_unpin(unsigned long ptr); -+void xen_pud_pin(unsigned long ptr); /* x86_64 only */ -+void xen_pud_unpin(unsigned long ptr); /* x86_64 only */ -+void xen_pmd_pin(unsigned long ptr); /* x86_64 only */ -+void xen_pmd_unpin(unsigned long ptr); /* x86_64 only */ -+void xen_pte_pin(unsigned long ptr); -+void xen_pte_unpin(unsigned long ptr); + +void xen_set_ldt(unsigned long ptr, unsigned long bytes); +void xen_machphys_update(unsigned long mfn, unsigned long pfn); @@ -64158,6 +65456,9 @@ index 0000000..021e2de +void xen_destroy_contiguous_region( + unsigned long vstart, unsigned int order); + ++/* Turn jiffies into Xen system time. */ ++u64 jiffies_to_st(unsigned long jiffies); ++ +#include + +#if defined(CONFIG_X86_64) @@ -64532,13 +65833,19 @@ index 0000000..b8beb05 +#endif /* __ASM_MACH_PAGE_H */ diff --git a/include/asm-i386/mach-default/mach_pgtable.h b/include/asm-i386/mach-default/mach_pgtable.h new file mode 100644 -index 0000000..118b32c +index 0000000..9dccb55 --- /dev/null +++ b/include/asm-i386/mach-default/mach_pgtable.h -@@ -0,0 +1,45 @@ +@@ -0,0 +1,51 @@ +#ifndef __ASM_MACH_PGTABLE_H +#define __ASM_MACH_PGTABLE_H + ++#ifdef CONFIG_X86_PAE ++#define HAVE_SHARED_KERNEL_PMD 1 ++#else ++#define HAVE_SHARED_KERNEL_PMD 0 ++#endif ++ +extern pgd_t swapper_pg_dir[1024]; + +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) @@ -64583,32 +65890,17 @@ index 0000000..118b32c +#endif /* __ASM_MACH_PGTABLE_H */ diff --git a/include/asm-i386/mach-default/mach_processor.h b/include/asm-i386/mach-default/mach_processor.h new file mode 100644 -index 0000000..7d6b3b2 +index 0000000..708e572 --- /dev/null +++ b/include/asm-i386/mach-default/mach_processor.h -@@ -0,0 +1,53 @@ +@@ -0,0 +1,38 @@ +#ifndef __ASM_MACH_PROCESSOR_H +#define __ASM_MACH_PROCESSOR_H + -+static inline void set_in_cr4(unsigned long mask) -+{ -+ unsigned cr4; -+ mmu_cr4_features |= mask; -+ cr4 = read_cr4(); -+ cr4 |= mask; -+ write_cr4(cr4); -+} ++#define CPUID_STR "cpuid" + -+static inline void clear_in_cr4(unsigned long mask) -+{ -+ unsigned cr4; -+ mmu_cr4_features &= ~mask; -+ cr4 = read_cr4(); -+ cr4 &= ~mask; -+ write_cr4(cr4); -+} -+ -+static inline void mach_load_esp0(struct tss_struct *tss, struct thread_struct *thread) ++static inline void mach_update_kernel_stack(unsigned long esp0, ++ unsigned short ss0) +{ +} + @@ -65586,45 +66878,23 @@ index 0000000..3e2a1db +#endif /* __ASM_MACH_PGTABLE_H */ diff --git a/include/asm-i386/mach-xen/mach_processor.h b/include/asm-i386/mach-xen/mach_processor.h new file mode 100644 -index 0000000..4080373 +index 0000000..dffd6c5 --- /dev/null +++ b/include/asm-i386/mach-xen/mach_processor.h -@@ -0,0 +1,57 @@ +@@ -0,0 +1,35 @@ +#ifndef __ASM_MACH_PROCESSOR_H +#define __ASM_MACH_PROCESSOR_H + ++#define CPUID_STR XEN_CPUID ++ +#include + -+static inline void __unsupported_cr4(void) ++static inline void mach_update_kernel_stack(unsigned long esp0, ++ unsigned short ss0) +{ -+ const char *msg = "Xen unsupported cr4 update\n"; -+ -+ (void)HYPERVISOR_console_io( -+ CONSOLEIO_write, __builtin_strlen(msg), (char *)msg); -+ BUG(); ++ HYPERVISOR_stack_switch(ss0, esp0); +} + -+static inline void set_in_cr4(unsigned long mask) -+{ -+ mmu_cr4_features |= mask; -+ switch (mask) { -+ case X86_CR4_OSFXSR: -+ case X86_CR4_OSXMMEXCPT: -+ break; -+ default: -+ __unsupported_cr4(); -+ } -+} -+ -+static inline void clear_in_cr4(unsigned long mask) -+{ -+ mmu_cr4_features &= ~mask; -+ __unsupported_cr4(); -+} -+ -+#define mach_load_esp0(tss, thread) \ -+ HYPERVISOR_stack_switch(__KERNEL_DS, (thread)->esp0) -+ +/* + * These special macros can be used to get or set a debugging register + */ @@ -65902,10 +67172,10 @@ index 0000000..8daed2c +#endif /* !_MACH_TRAPS_H */ diff --git a/include/asm-i386/mach-xen/setup_arch_post.h b/include/asm-i386/mach-xen/setup_arch_post.h new file mode 100644 -index 0000000..49c3f2a +index 0000000..646cf78 --- /dev/null +++ b/include/asm-i386/mach-xen/setup_arch_post.h -@@ -0,0 +1,50 @@ +@@ -0,0 +1,45 @@ +/** + * machine_specific_memory_setup - Hook for machine specific memory setup. + * @@ -65924,18 +67194,6 @@ index 0000000..49c3f2a + return "Xen"; +} + -+void __devinit machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c) -+{ -+ clear_bit(X86_FEATURE_VME, c->x86_capability); -+ clear_bit(X86_FEATURE_DE, c->x86_capability); -+ clear_bit(X86_FEATURE_PSE, c->x86_capability); -+ clear_bit(X86_FEATURE_PGE, c->x86_capability); -+ clear_bit(X86_FEATURE_SEP, c->x86_capability); -+ if (!(xen_start_info->flags & SIF_PRIVILEGED)) -+ clear_bit(X86_FEATURE_MTRR, c->x86_capability); -+ c->hlt_works_ok = 0; -+} -+ +extern void hypervisor_callback(void); +extern void failsafe_callback(void); +extern void nmi(void); @@ -65943,14 +67201,21 @@ index 0000000..49c3f2a +static void __init machine_specific_arch_setup(void) +{ + struct xen_platform_parameters pp; ++ struct xennmi_callback cb; ++ ++ if (xen_feature(XENFEAT_auto_translated_physmap) && ++ xen_start_info->shared_info < xen_start_info->nr_pages) { ++ HYPERVISOR_shared_info = ++ (shared_info_t *)__va(xen_start_info->shared_info); ++ memset(empty_zero_page, 0, sizeof(empty_zero_page)); ++ } + + HYPERVISOR_set_callbacks( + __KERNEL_CS, (unsigned long)hypervisor_callback, + __KERNEL_CS, (unsigned long)failsafe_callback); + -+ HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi); -+ -+ machine_specific_modify_cpu_capabilities(&boot_cpu_data); ++ cb.handler_address = (unsigned long)&nmi; ++ HYPERVISOR_nmi_op(XENNMI_register_callback, &cb); + + if (HYPERVISOR_xen_version(XENVER_platform_parameters, + &pp) == 0) @@ -66335,7 +67600,7 @@ index f1a8b45..5f45788 100644 pgprot_val(pgprot)) & __supported_pte_mask); } diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h -index 088a945..d933743 100644 +index 088a945..956bd43 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h @@ -34,7 +34,6 @@ struct vm_area_struct; @@ -66364,7 +67629,24 @@ index 088a945..d933743 100644 static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { -@@ -278,7 +276,8 @@ static inline pte_t ptep_get_and_clear_f +@@ -269,7 +267,16 @@ static inline pte_t ptep_get_and_clear_f + pte_t pte; + if (full) { + pte = *ptep; ++#ifdef CONFIG_X86_PAE ++ /* Cannot do this in a single step, as the compiler may ++ issue the two stores in either order, but the hypervisor ++ must not see the high part before the low one. */ ++ ptep->pte_low = 0; ++ barrier(); ++ ptep->pte_high = 0; ++#else + *ptep = __pte(0); ++#endif + } else { + pte = ptep_get_and_clear(mm, addr, ptep); + } +@@ -278,7 +285,8 @@ static inline pte_t ptep_get_and_clear_f static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { @@ -66374,7 +67656,7 @@ index 088a945..d933743 100644 } /* -@@ -399,9 +398,9 @@ extern void noexec_setup(const char *str +@@ -399,9 +407,9 @@ extern void noexec_setup(const char *str #if defined(CONFIG_HIGHPTE) #define pte_offset_map(dir, address) \ @@ -66386,7 +67668,7 @@ index 088a945..d933743 100644 #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) #else -@@ -423,14 +422,6 @@ extern void noexec_setup(const char *str +@@ -423,14 +431,6 @@ extern void noexec_setup(const char *str * bit at the same time. */ #define update_mmu_cache(vma,address,pte) do { } while (0) @@ -66401,7 +67683,7 @@ index 088a945..d933743 100644 #endif /* !__ASSEMBLY__ */ -@@ -438,9 +429,6 @@ extern void noexec_setup(const char *str +@@ -438,9 +438,6 @@ extern void noexec_setup(const char *str #define kern_addr_valid(addr) (1) #endif /* CONFIG_FLATMEM */ @@ -66412,10 +67694,18 @@ index 088a945..d933743 100644 #define GET_IOSPACE(pfn) 0 #define GET_PFN(pfn) (pfn) diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h -index feca5d9..2e7bec8 100644 +index feca5d9..36eff94 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h -@@ -90,8 +90,10 @@ struct cpuinfo_x86 { +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + /* flag for disabling the tsc */ + extern int tsc_disable; +@@ -90,8 +91,10 @@ struct cpuinfo_x86 { extern struct cpuinfo_x86 boot_cpu_data; extern struct cpuinfo_x86 new_cpu_data; @@ -66426,32 +67716,61 @@ index feca5d9..2e7bec8 100644 #ifdef CONFIG_SMP extern struct cpuinfo_x86 cpu_data[]; -@@ -232,24 +234,6 @@ static inline unsigned int cpuid_edx(uns +@@ -143,7 +146,7 @@ static inline void detect_ht(struct cpui */ - extern unsigned long mmu_cr4_features; + static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) + { +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), +@@ -155,7 +158,7 @@ static inline void cpuid(unsigned int op + static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, + int *edx) + { +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), +@@ -170,7 +173,7 @@ static inline unsigned int cpuid_eax(uns + { + unsigned int eax; --static inline void set_in_cr4 (unsigned long mask) --{ -- unsigned cr4; -- mmu_cr4_features |= mask; -- cr4 = read_cr4(); -- cr4 |= mask; -- write_cr4(cr4); --} -- --static inline void clear_in_cr4 (unsigned long mask) --{ -- unsigned cr4; -- mmu_cr4_features &= ~mask; -- cr4 = read_cr4(); -- cr4 &= ~mask; -- write_cr4(cr4); --} -- - /* - * NSC/Cyrix CPU configuration register indexes - */ -@@ -333,7 +317,9 @@ extern int bootloader_type; +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (eax) + : "0" (op) + : "bx", "cx", "dx"); +@@ -180,7 +183,7 @@ static inline unsigned int cpuid_ebx(uns + { + unsigned int eax, ebx; + +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (eax), "=b" (ebx) + : "0" (op) + : "cx", "dx" ); +@@ -190,7 +193,7 @@ static inline unsigned int cpuid_ecx(uns + { + unsigned int eax, ecx; + +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (eax), "=c" (ecx) + : "0" (op) + : "bx", "dx" ); +@@ -200,7 +203,7 @@ static inline unsigned int cpuid_edx(uns + { + unsigned int eax, edx; + +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (eax), "=d" (edx) + : "0" (op) + : "bx", "cx"); +@@ -333,7 +336,9 @@ extern int bootloader_type; #define IO_BITMAP_BITS 65536 #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8) #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) @@ -66461,7 +67780,7 @@ index feca5d9..2e7bec8 100644 #define INVALID_IO_BITMAP_OFFSET 0x8000 #define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000 -@@ -391,6 +377,7 @@ typedef struct { +@@ -391,6 +396,7 @@ typedef struct { struct thread_struct; @@ -66469,7 +67788,7 @@ index feca5d9..2e7bec8 100644 struct tss_struct { unsigned short back_link,__blh; unsigned long esp0; -@@ -436,6 +423,7 @@ struct tss_struct { +@@ -436,6 +442,7 @@ struct tss_struct { */ unsigned long stack[64]; } __attribute__((packed)); @@ -66477,17 +67796,15 @@ index feca5d9..2e7bec8 100644 #define ARCH_MIN_TASKALIGN 16 -@@ -472,6 +460,9 @@ struct thread_struct { +@@ -472,6 +479,7 @@ struct thread_struct { .io_bitmap_ptr = NULL, \ } -+#include -+ +#ifndef CONFIG_X86_NO_TSS /* * Note that the .io_bitmap member must be extra-big. This is because * the CPU will access an additional byte beyond the end of the IO -@@ -486,15 +477,25 @@ struct thread_struct { +@@ -486,15 +494,25 @@ struct thread_struct { .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \ } @@ -66507,14 +67824,14 @@ index feca5d9..2e7bec8 100644 +#define __load_esp0(tss, thread) +#endif + -+#define load_esp0(tss, thread) do { \ -+ __load_esp0(tss, thread); \ -+ mach_load_esp0(tss, thread); \ ++#define load_esp0(tss, thread) do { \ ++ __load_esp0(tss, thread); \ ++ mach_update_kernel_stack((thread)->esp0, __KERNEL_DS); \ +} while (0) #define start_thread(regs, new_eip, new_esp) do { \ __asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \ -@@ -507,33 +508,6 @@ static inline void load_esp0(struct tss_ +@@ -507,33 +525,6 @@ static inline void load_esp0(struct tss_ regs->esp = new_esp; \ } while (0) @@ -67655,10 +68972,10 @@ index 4fb4e43..b23a280 100644 #endif /* _ASM_IA64_GCC_INTRIN_H */ diff --git a/include/asm-ia64/hypercall.h b/include/asm-ia64/hypercall.h new file mode 100644 -index 0000000..fd57868 +index 0000000..b260c56 --- /dev/null +++ b/include/asm-ia64/hypercall.h -@@ -0,0 +1,253 @@ +@@ -0,0 +1,283 @@ +/****************************************************************************** + * hypercall.h + * @@ -67666,8 +68983,11 @@ index 0000000..fd57868 + * + * Copyright (c) 2002-2004, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -67693,6 +69013,8 @@ index 0000000..fd57868 + +#include +#include ++#include ++#include + +/* FIXME: temp place to hold these page related macros */ +#include @@ -67826,6 +69148,31 @@ index 0000000..fd57868 + return _hypercall2(int, sched_op, cmd, arg); +} + ++static inline int ++HYPERVISOR_sched_op_new( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, sched_op_new, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_poll( ++ evtchn_port_t *ports, unsigned int nr_ports, unsigned long timeout) ++{ ++ struct sched_poll sched_poll = { ++ .ports = ports, ++ .nr_ports = nr_ports, ++ .timeout = jiffies_to_st(timeout) ++ }; ++ ++ int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll); ++ ++ if (rc == -ENOSYS) ++ rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0); ++ ++ return rc; ++} ++ +static inline long +HYPERVISOR_set_timer_op( + u64 timeout) @@ -67914,10 +69261,10 @@ index 0000000..fd57868 +#endif /* __HYPERCALL_H__ */ diff --git a/include/asm-ia64/hypervisor.h b/include/asm-ia64/hypervisor.h new file mode 100644 -index 0000000..4771111 +index 0000000..4a5f424 --- /dev/null +++ b/include/asm-ia64/hypervisor.h -@@ -0,0 +1,70 @@ +@@ -0,0 +1,78 @@ +/****************************************************************************** + * hypervisor.h + * @@ -67925,8 +69272,11 @@ index 0000000..4771111 + * + * Copyright (c) 2002-2004, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -67964,6 +69314,11 @@ index 0000000..4771111 + +void force_evtchn_callback(void); + ++int xen_init(void); ++ ++/* Turn jiffies into Xen system time. XXX Implement me. */ ++#define jiffies_to_st(j) 0 ++ +#include + +// for drivers/xen/privcmd/privcmd.c @@ -68314,10 +69669,10 @@ index 0625387..349c8d1 100644 ({ \ diff --git a/include/asm-ia64/xen/privop.h b/include/asm-ia64/xen/privop.h new file mode 100644 -index 0000000..235197b +index 0000000..af1685b --- /dev/null +++ b/include/asm-ia64/xen/privop.h -@@ -0,0 +1,272 @@ +@@ -0,0 +1,277 @@ +#ifndef _ASM_IA64_XEN_PRIVOP_H +#define _ASM_IA64_XEN_PRIVOP_H + @@ -68353,6 +69708,11 @@ index 0000000..235197b +#define XEN_HYPER_GET_RR break 0x10 +#define XEN_HYPER_SET_RR break 0x11 +#define XEN_HYPER_SET_KR break 0x12 ++#define XEN_HYPER_FC break 0x13 ++#define XEN_HYPER_GET_CPUID break 0x14 ++#define XEN_HYPER_GET_PMD break 0x15 ++#define XEN_HYPER_GET_EFLAG break 0x16 ++#define XEN_HYPER_SET_EFLAG break 0x17 +#endif + +#ifndef __ASSEMBLY__ @@ -68982,7 +70342,7 @@ index 49a81a6..4e47ec0 100644 + #endif /* _X8664_DMA_MAPPING_H */ diff --git a/include/asm-x86_64/fixmap.h b/include/asm-x86_64/fixmap.h -index 7b286bd..beaf264 100644 +index 7b286bd..315b124 100644 --- a/include/asm-x86_64/fixmap.h +++ b/include/asm-x86_64/fixmap.h @@ -17,6 +17,10 @@ @@ -68996,7 +70356,7 @@ index 7b286bd..beaf264 100644 /* * Here we define all the compile-time 'special' virtual -@@ -45,6 +49,18 @@ enum fixed_addresses { +@@ -45,6 +49,16 @@ enum fixed_addresses { FIX_IO_APIC_BASE_0, FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, #endif @@ -69006,8 +70366,6 @@ index 7b286bd..beaf264 100644 + FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, +#endif + FIX_SHARED_INFO, -+ FIX_GNTTAB_BEGIN, -+ FIX_GNTTAB_END = FIX_GNTTAB_BEGIN + NR_GRANT_FRAMES - 1, +#define NR_FIX_ISAMAPS 256 + FIX_ISAMAP_END, + FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1, @@ -69015,7 +70373,7 @@ index 7b286bd..beaf264 100644 __end_of_fixed_addresses }; -@@ -59,6 +75,9 @@ extern void __set_fixmap (enum fixed_add +@@ -59,6 +73,9 @@ extern void __set_fixmap (enum fixed_add #define set_fixmap_nocache(idx, phys) \ __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) @@ -69214,10 +70572,10 @@ index 0df1715..d3f6028 100644 send_IPI_self(IO_APIC_VECTOR(i)); diff --git a/include/asm-x86_64/hypercall.h b/include/asm-x86_64/hypercall.h new file mode 100644 -index 0000000..87bbfb4 +index 0000000..9fb2016 --- /dev/null +++ b/include/asm-x86_64/hypercall.h -@@ -0,0 +1,323 @@ +@@ -0,0 +1,352 @@ +/****************************************************************************** + * hypercall.h + * @@ -69229,8 +70587,11 @@ index 0000000..87bbfb4 + * Benjamin Liu + * Jun Nakajima + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -69256,6 +70617,8 @@ index 0000000..87bbfb4 + +#include +#include ++#include ++#include + +#define __STR(x) #x +#define STR(x) __STR(x) @@ -69393,6 +70756,31 @@ index 0000000..87bbfb4 + return _hypercall2(int, sched_op, cmd, arg); +} + ++static inline int ++HYPERVISOR_sched_op_new( ++ int cmd, void *arg) ++{ ++ return _hypercall2(int, sched_op_new, cmd, arg); ++} ++ ++static inline int ++HYPERVISOR_poll( ++ evtchn_port_t *ports, unsigned int nr_ports, u64 timeout) ++{ ++ struct sched_poll sched_poll = { ++ .ports = ports, ++ .nr_ports = nr_ports, ++ .timeout = jiffies_to_st(timeout) ++ }; ++ ++ int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll); ++ ++ if (rc == -ENOSYS) ++ rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0); ++ ++ return rc; ++} ++ +static inline long +HYPERVISOR_set_timer_op( + u64 timeout) @@ -69524,8 +70912,7 @@ index 0000000..87bbfb4 + +static inline int +HYPERVISOR_nmi_op( -+ unsigned long op, -+ unsigned long arg) ++ unsigned long op, void *arg) +{ + return _hypercall2(int, nmi_op, op, arg); +} @@ -70018,6 +71405,73 @@ index 16e4be4..ee83836 100644 #define deactivate_mm(tsk,mm) do { \ load_gs_index(0); \ asm volatile("movl %0,%%fs"::"r"(0)); \ +diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h +index 10f8b51..cc34004 100644 +--- a/include/asm-x86_64/msr.h ++++ b/include/asm-x86_64/msr.h +@@ -79,10 +79,16 @@ + : "=a" (low), "=d" (high) \ + : "c" (counter)) + ++#ifndef CONFIG_XEN ++#define CPUID_STR "cpuid" ++#else ++#define CPUID_STR XEN_CPUID ++#endif ++ + static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) + { +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), +@@ -94,7 +100,7 @@ static inline void cpuid(int op, unsigne + static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, + int *edx) + { +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), +@@ -109,7 +115,7 @@ static inline unsigned int cpuid_eax(uns + { + unsigned int eax; + +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (eax) + : "0" (op) + : "bx", "cx", "dx"); +@@ -119,7 +125,7 @@ static inline unsigned int cpuid_ebx(uns + { + unsigned int eax, ebx; + +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (eax), "=b" (ebx) + : "0" (op) + : "cx", "dx" ); +@@ -129,7 +135,7 @@ static inline unsigned int cpuid_ecx(uns + { + unsigned int eax, ecx; + +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (eax), "=c" (ecx) + : "0" (op) + : "bx", "dx" ); +@@ -139,7 +145,7 @@ static inline unsigned int cpuid_edx(uns + { + unsigned int eax, edx; + +- __asm__("cpuid" ++ __asm__(CPUID_STR + : "=a" (eax), "=d" (edx) + : "0" (op) + : "bx", "cx"); diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h index 615e3e4..e62161d 100644 --- a/include/asm-x86_64/page.h @@ -70348,7 +71802,7 @@ index c7ab38a..64dcbc5 100644 } ____cacheline_aligned_in_smp; diff --git a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h -index 08cad24..ada72f7 100644 +index 08cad24..e838545 100644 --- a/include/asm-x86_64/pgalloc.h +++ b/include/asm-x86_64/pgalloc.h @@ -6,26 +6,90 @@ @@ -70539,12 +71993,11 @@ index 08cad24..ada72f7 100644 } /* Should really implement gc for free page table pages. This could be -@@ -89,17 +198,33 @@ static inline struct page *pte_alloc_one +@@ -89,17 +198,32 @@ static inline struct page *pte_alloc_one static inline void pte_free_kernel(pte_t *pte) { BUG_ON((unsigned long)pte & (PAGE_SIZE-1)); +#ifdef CONFIG_XEN -+ xen_pte_unpin(__pa(pte)); + make_page_writable(pte, XENFEAT_writable_page_tables); +#endif free_page((unsigned long)pte); @@ -70960,7 +72413,7 @@ index 715fd94..11dce27 100644 #define MK_IOSPACE_PFN(space, pfn) (pfn) #define GET_IOSPACE(pfn) 0 diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h -index 8c8d88c..78cd5a3 100644 +index 8c8d88c..76eafaf 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h @@ -138,27 +138,51 @@ extern unsigned int init_intel_cacheinfo @@ -71089,24 +72542,6 @@ index 8c8d88c..78cd5a3 100644 struct task_struct; struct mm_struct; -@@ -479,4 +520,17 @@ extern int bootloader_type; - - #define HAVE_ARCH_PICK_MMAP_LAYOUT 1 - -+static inline void modify_cpu_capabilities(struct cpuinfo_x86 *c) -+{ -+#ifdef CONFIG_XEN -+ clear_bit(X86_FEATURE_VME, c->x86_capability); -+ clear_bit(X86_FEATURE_DE, c->x86_capability); -+ clear_bit(X86_FEATURE_PSE, c->x86_capability); -+ clear_bit(X86_FEATURE_PGE, c->x86_capability); -+ clear_bit(X86_FEATURE_SEP, c->x86_capability); -+ if (!(xen_start_info->flags & SIF_PRIVILEGED)) -+ clear_bit(X86_FEATURE_MTRR, c->x86_capability); -+#endif -+} -+ - #endif /* __ASM_X86_64_PROCESSOR_H */ diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index 9ccbb2c..c838964 100644 --- a/include/asm-x86_64/smp.h @@ -71556,7 +72991,7 @@ index 6c5d4c8..4ffabba 100644 #ifdef CONFIG_GENERIC_HARDIRQS extern cpumask_t irq_affinity[NR_IRQS]; diff --git a/include/linux/mm.h b/include/linux/mm.h -index 498ff87..4a05b8d 100644 +index 498ff87..946f3e5 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -166,6 +166,9 @@ extern unsigned int kobjsize(const void @@ -71584,10 +73019,10 @@ index 498ff87..4a05b8d 100644 #define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */ +#ifdef CONFIG_XEN -+typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr, -+ void *data); -+extern int generic_page_range(struct mm_struct *mm, unsigned long address, -+ unsigned long size, pte_fn_t fn, void *data); ++typedef int (*pte_fn_t)(pte_t *pte, struct page *pmd_page, unsigned long addr, ++ void *data); ++extern int apply_to_page_range(struct mm_struct *mm, unsigned long address, ++ unsigned long size, pte_fn_t fn, void *data); +#endif + #ifdef CONFIG_PROC_FS @@ -71641,10 +73076,10 @@ index ad7cc22..0d20528 100644 /** diff --git a/include/xen/balloon.h b/include/xen/balloon.h new file mode 100644 -index 0000000..7f2be02 +index 0000000..d9637ef --- /dev/null +++ b/include/xen/balloon.h -@@ -0,0 +1,70 @@ +@@ -0,0 +1,73 @@ +/****************************************************************************** + * balloon.h + * @@ -71653,8 +73088,11 @@ index 0000000..7f2be02 + * Copyright (c) 2003, B Dragovic + * Copyright (c) 2003-2004, M Williamson, K Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -71749,10 +73187,10 @@ index 0000000..fe45de5 + */ diff --git a/include/xen/evtchn.h b/include/xen/evtchn.h new file mode 100644 -index 0000000..594c1a6 +index 0000000..100eb1c --- /dev/null +++ b/include/xen/evtchn.h -@@ -0,0 +1,123 @@ +@@ -0,0 +1,126 @@ +/****************************************************************************** + * evtchn.h + * @@ -71761,8 +73199,11 @@ index 0000000..594c1a6 + * + * Copyright (c) 2004-2005, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -71950,10 +73391,10 @@ index 0000000..0af4e13 + */ diff --git a/include/xen/gnttab.h b/include/xen/gnttab.h new file mode 100644 -index 0000000..58aeb49 +index 0000000..584a5db --- /dev/null +++ b/include/xen/gnttab.h -@@ -0,0 +1,120 @@ +@@ -0,0 +1,123 @@ +/****************************************************************************** + * gnttab.h + * @@ -71965,8 +73406,11 @@ index 0000000..58aeb49 + * Copyright (c) 2004-2005, K A Fraser + * Copyright (c) 2005, Christopher Clark + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -72074,6 +73518,44 @@ index 0000000..58aeb49 + * tab-width: 8 + * End: + */ +diff --git a/include/xen/hypervisor_sysfs.h b/include/xen/hypervisor_sysfs.h +new file mode 100644 +index 0000000..706fb7f +--- /dev/null ++++ b/include/xen/hypervisor_sysfs.h +@@ -0,0 +1,32 @@ ++/* ++ * copyright (c) 2006 IBM Corporation ++ * Authored by: Mike D. Day ++ * ++ * 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. ++ */ ++ ++#ifndef _HYP_SYSFS_H_ ++#define _HYP_SYSFS_H_ ++ ++#include ++#include ++ ++#define HYPERVISOR_ATTR_RO(_name) \ ++static struct hyp_sysfs_attr _name##_attr = __ATTR_RO(_name) ++ ++#define HYPERVISOR_ATTR_RW(_name) \ ++static struct hyp_sysfs_attr _name##_attr = \ ++ __ATTR(_name, 0644, _name##_show, _name##_store) ++ ++extern struct subsystem hypervisor_subsys; ++ ++struct hyp_sysfs_attr { ++ struct attribute attr; ++ ssize_t (*show)(struct hyp_sysfs_attr *, char *); ++ ssize_t (*store)(struct hyp_sysfs_attr *, const char *, size_t); ++ void *hyp_attr_data; ++}; ++ ++#endif /* _HYP_SYSFS_H_ */ diff --git a/include/xen/interface/acm.h b/include/xen/interface/acm.h new file mode 100644 index 0000000..a7a5a57 @@ -72263,10 +73745,10 @@ index 0000000..a7a5a57 + */ diff --git a/include/xen/interface/acm_ops.h b/include/xen/interface/acm_ops.h new file mode 100644 -index 0000000..76c35db +index 0000000..b4ce11f --- /dev/null +++ b/include/xen/interface/acm_ops.h -@@ -0,0 +1,96 @@ +@@ -0,0 +1,98 @@ +/* + * acm_ops.h: Xen access control module hypervisor commands + * @@ -72279,6 +73761,7 @@ index 0000000..76c35db + +#include "xen.h" +#include "sched_ctl.h" ++#include "acm.h" + +/* + * Make sure you increment the interface version whenever you modify this file! @@ -72340,7 +73823,7 @@ index 0000000..76c35db + int acm_decision; /* out */ +}; + -+struct acm_op { ++typedef struct acm_op { + uint32_t cmd; + uint32_t interface_version; /* ACM_INTERFACE_VERSION */ + union { @@ -72350,7 +73833,8 @@ index 0000000..76c35db + struct acm_getssid getssid; + struct acm_getdecision getdecision; + } u; -+}; ++} acm_op_t; ++DEFINE_GUEST_HANDLE(acm_op_t); + +#endif /* __XEN_PUBLIC_ACM_OPS_H__ */ + @@ -72365,10 +73849,10 @@ index 0000000..76c35db + */ diff --git a/include/xen/interface/arch-ia64.h b/include/xen/interface/arch-ia64.h new file mode 100644 -index 0000000..316df5c +index 0000000..ef33916 --- /dev/null +++ b/include/xen/interface/arch-ia64.h -@@ -0,0 +1,302 @@ +@@ -0,0 +1,337 @@ +/****************************************************************************** + * arch-ia64/hypervisor-if.h + * @@ -72431,6 +73915,33 @@ index 0000000..316df5c + +#define INVALID_MFN (~0UL) + ++#define MEM_G (1UL << 30) ++#define MEM_M (1UL << 20) ++ ++#define MMIO_START (3 * MEM_G) ++#define MMIO_SIZE (512 * MEM_M) ++ ++#define VGA_IO_START 0xA0000UL ++#define VGA_IO_SIZE 0x20000 ++ ++#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) ++#define LEGACY_IO_SIZE (64*MEM_M) ++ ++#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE) ++#define IO_PAGE_SIZE PAGE_SIZE ++ ++#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE) ++#define STORE_PAGE_SIZE PAGE_SIZE ++ ++#define IO_SAPIC_START 0xfec00000UL ++#define IO_SAPIC_SIZE 0x100000 ++ ++#define PIB_START 0xfee00000UL ++#define PIB_SIZE 0x100000 ++ ++#define GFW_START (4*MEM_G -16*MEM_M) ++#define GFW_SIZE (16*MEM_M) ++ +/* + * NB. This may become a 64-bit count with no shift. If this happens then the + * structure size will still be 8 bytes, so no other alignments will change. @@ -72615,7 +74126,7 @@ index 0000000..316df5c + int interrupt_delivery_enabled; // virtual psr.i + int pending_interruption; + int incomplete_regframe; // see SDM vol2 6.8 -+ unsigned long delivery_mask[4]; ++ unsigned long reserved5_1[4]; + int metaphysical_mode; // 1 = use metaphys mapping, 0 = use virtual + int banknum; // 0 or 1, which virtual register bank is active + unsigned long rrs[8]; // region registers @@ -72642,6 +74153,12 @@ index 0000000..316df5c + unsigned long start_info_pfn; +} arch_shared_info_t; + ++typedef struct { ++ unsigned long start; ++ unsigned long size; ++} arch_initrd_info_t; ++ ++#define IA64_COMMAND_LINE_SIZE 512 +typedef struct vcpu_guest_context { +#define VGCF_FPU_VALID (1<<0) +#define VGCF_VMX_GUEST (1<<1) @@ -72655,6 +74172,8 @@ index 0000000..316df5c + cpu_user_regs_t regs; + arch_vcpu_info_t vcpu; + arch_shared_info_t shared; ++ arch_initrd_info_t initrd; ++ char cmdline[IA64_COMMAND_LINE_SIZE]; +} vcpu_guest_context_t; +DEFINE_GUEST_HANDLE(vcpu_guest_context_t); + @@ -72673,10 +74192,10 @@ index 0000000..316df5c + */ diff --git a/include/xen/interface/arch-x86_32.h b/include/xen/interface/arch-x86_32.h new file mode 100644 -index 0000000..f7079eb +index 0000000..1ae2df6 --- /dev/null +++ b/include/xen/interface/arch-x86_32.h -@@ -0,0 +1,181 @@ +@@ -0,0 +1,195 @@ +/****************************************************************************** + * arch-x86_32.h + * @@ -72781,6 +74300,7 @@ index 0000000..f7079eb + uint16_t cs; /* code selector */ + unsigned long address; /* code offset */ +} trap_info_t; ++DEFINE_GUEST_HANDLE(trap_info_t); + +typedef struct cpu_user_regs { + uint32_t ebx; @@ -72804,6 +74324,7 @@ index 0000000..f7079eb + uint16_t fs, _pad4; + uint16_t gs, _pad5; +} cpu_user_regs_t; ++DEFINE_GUEST_HANDLE(cpu_user_regs_t); + +typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ + @@ -72815,7 +74336,7 @@ index 0000000..f7079eb + /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ + struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */ +#define VGCF_I387_VALID (1<<0) -+#define VGCF_VMX_GUEST (1<<1) ++#define VGCF_HVM_GUEST (1<<1) +#define VGCF_IN_KERNEL (1<<2) + unsigned long flags; /* VGCF_* flags */ + cpu_user_regs_t user_regs; /* User-level CPU registers */ @@ -72847,6 +74368,18 @@ index 0000000..f7079eb + +#endif /* !__ASSEMBLY__ */ + ++/* ++ * Prefix forces emulation of some non-trapping instructions. ++ * Currently only CPUID. ++ */ ++#ifdef __ASSEMBLY__ ++#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ; ++#define XEN_CPUID XEN_EMULATE_PREFIX cpuid ++#else ++#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; " ++#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" ++#endif ++ +#endif + +/* @@ -72860,10 +74393,10 @@ index 0000000..f7079eb + */ diff --git a/include/xen/interface/arch-x86_64.h b/include/xen/interface/arch-x86_64.h new file mode 100644 -index 0000000..f0ea2f5 +index 0000000..98948c4 --- /dev/null +++ b/include/xen/interface/arch-x86_64.h -@@ -0,0 +1,266 @@ +@@ -0,0 +1,271 @@ +/****************************************************************************** + * arch-x86_64.h + * @@ -73002,15 +74535,6 @@ index 0000000..f0ea2f5 + uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; + /* Bottom of iret stack frame. */ +}; -+/* -+ * For compatibility with HYPERVISOR_switch_to_user which is the old -+ * name for HYPERVISOR_iret. -+ */ -+struct switch_to_user { -+ /* Top of stack (%rsp at point of hypercall). */ -+ uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; -+ /* Bottom of iret stack frame. */ -+}; + +/* + * Send an array of these to HYPERVISOR_set_trap_table(). @@ -73032,6 +74556,7 @@ index 0000000..f0ea2f5 + uint16_t cs; /* code selector */ + unsigned long address; /* code offset */ +} trap_info_t; ++DEFINE_GUEST_HANDLE(trap_info_t); + +#ifdef __GNUC__ +/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ @@ -73071,6 +74596,7 @@ index 0000000..f0ea2f5 + uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */ + uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */ +} cpu_user_regs_t; ++DEFINE_GUEST_HANDLE(cpu_user_regs_t); + +#undef __DECL_REG + @@ -73084,7 +74610,7 @@ index 0000000..f0ea2f5 + /* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */ + struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */ +#define VGCF_I387_VALID (1<<0) -+#define VGCF_VMX_GUEST (1<<1) ++#define VGCF_HVM_GUEST (1<<1) +#define VGCF_IN_KERNEL (1<<2) + unsigned long flags; /* VGCF_* flags */ + cpu_user_regs_t user_regs; /* User-level CPU registers */ @@ -73119,6 +74645,18 @@ index 0000000..f0ea2f5 + +#endif /* !__ASSEMBLY__ */ + ++/* ++ * Prefix forces emulation of some non-trapping instructions. ++ * Currently only CPUID. ++ */ ++#ifdef __ASSEMBLY__ ++#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ; ++#define XEN_CPUID XEN_EMULATE_PREFIX cpuid ++#else ++#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; " ++#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" ++#endif ++ +#endif + +/* @@ -73668,10 +75206,10 @@ index 0000000..89ea35c + */ diff --git a/include/xen/interface/event_channel.h b/include/xen/interface/event_channel.h new file mode 100644 -index 0000000..03d2039 +index 0000000..c556163 --- /dev/null +++ b/include/xen/interface/event_channel.h -@@ -0,0 +1,203 @@ +@@ -0,0 +1,205 @@ +/****************************************************************************** + * event_channel.h + * @@ -73684,6 +75222,7 @@ index 0000000..03d2039 +#define __XEN_PUBLIC_EVENT_CHANNEL_H__ + +typedef uint32_t evtchn_port_t; ++DEFINE_GUEST_HANDLE(evtchn_port_t); + +/* + * EVTCHNOP_alloc_unbound: Allocate a port in domain and mark as @@ -73863,6 +75402,7 @@ index 0000000..03d2039 + evtchn_unmask_t unmask; + } u; +} evtchn_op_t; ++DEFINE_GUEST_HANDLE(evtchn_op_t); + +#endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */ + @@ -73936,10 +75476,10 @@ index 0000000..c46e3be + */ diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h new file mode 100644 -index 0000000..e137953 +index 0000000..47a033e --- /dev/null +++ b/include/xen/interface/grant_table.h -@@ -0,0 +1,306 @@ +@@ -0,0 +1,311 @@ +/****************************************************************************** + * grant_table.h + * @@ -74109,6 +75649,7 @@ index 0000000..e137953 + grant_handle_t handle; + uint64_t dev_bus_addr; +} gnttab_map_grant_ref_t; ++DEFINE_GUEST_HANDLE(gnttab_map_grant_ref_t); + +/* + * GNTTABOP_unmap_grant_ref: Destroy one or more grant-reference mappings @@ -74130,6 +75671,7 @@ index 0000000..e137953 + /* OUT parameters. */ + int16_t status; /* GNTST_* */ +} gnttab_unmap_grant_ref_t; ++DEFINE_GUEST_HANDLE(gnttab_unmap_grant_ref_t); + +/* + * GNTTABOP_setup_table: Set up a grant table for comprising at least @@ -74147,8 +75689,9 @@ index 0000000..e137953 + uint32_t nr_frames; + /* OUT parameters. */ + int16_t status; /* GNTST_* */ -+ unsigned long *frame_list; ++ GUEST_HANDLE(ulong) frame_list; +} gnttab_setup_table_t; ++DEFINE_GUEST_HANDLE(gnttab_setup_table_t); + +/* + * GNTTABOP_dump_table: Dump the contents of the grant table to the @@ -74161,6 +75704,7 @@ index 0000000..e137953 + /* OUT parameters. */ + int16_t status; /* GNTST_* */ +} gnttab_dump_table_t; ++DEFINE_GUEST_HANDLE(gnttab_dump_table_t); + +/* + * GNTTABOP_transfer_grant_ref: Transfer to a foreign domain. The @@ -74179,6 +75723,7 @@ index 0000000..e137953 + /* OUT parameters. */ + int16_t status; +} gnttab_transfer_t; ++DEFINE_GUEST_HANDLE(gnttab_transfer_t); + +/* + * Bitfield values for update_pin_status.flags. @@ -74610,10 +76155,10 @@ index 0000000..cb59b24 + */ diff --git a/include/xen/interface/io/netif.h b/include/xen/interface/io/netif.h new file mode 100644 -index 0000000..dcb9b46 +index 0000000..c9bcc77 --- /dev/null +++ b/include/xen/interface/io/netif.h -@@ -0,0 +1,76 @@ +@@ -0,0 +1,84 @@ +/****************************************************************************** + * netif.h + * @@ -74636,8 +76181,12 @@ index 0000000..dcb9b46 + */ + +/* Protocol checksum field is blank in the packet (hardware offload)? */ -+#define _NETTXF_csum_blank (0) -+#define NETTXF_csum_blank (1U<<_NETTXF_csum_blank) ++#define _NETTXF_csum_blank (0) ++#define NETTXF_csum_blank (1U<<_NETTXF_csum_blank) ++ ++/* Packet data has been validated against protocol checksum. */ ++#define _NETTXF_data_validated (1) ++#define NETTXF_data_validated (1U<<_NETTXF_data_validated) + +typedef struct netif_tx_request { + grant_ref_t gref; /* Reference to buffer page */ @@ -74657,9 +76206,13 @@ index 0000000..dcb9b46 + grant_ref_t gref; /* Reference to incoming granted frame */ +} netif_rx_request_t; + -+/* Protocol checksum already validated (e.g., performed by hardware)? */ -+#define _NETRXF_csum_valid (0) -+#define NETRXF_csum_valid (1U<<_NETRXF_csum_valid) ++/* Packet data has been validated against protocol checksum. */ ++#define _NETRXF_data_validated (0) ++#define NETRXF_data_validated (1U<<_NETRXF_data_validated) ++ ++/* Protocol checksum field is blank in the packet (hardware offload)? */ ++#define _NETRXF_csum_blank (1) ++#define NETRXF_csum_blank (1U<<_NETRXF_csum_blank) + +typedef struct { + uint16_t id; @@ -75084,161 +76637,6 @@ index 0000000..6d02f33 + * indent-tabs-mode: nil + * End: + */ -diff --git a/include/xen/interface/io/vmx_vlapic.h b/include/xen/interface/io/vmx_vlapic.h -new file mode 100644 -index 0000000..f63a9aa ---- /dev/null -+++ b/include/xen/interface/io/vmx_vlapic.h -@@ -0,0 +1,58 @@ -+#ifndef _VMX_VLAPIC_H -+#define _VMX_VLAPIC_H -+ -+/* -+ We extended one bit for PIC type -+ */ -+#define VLAPIC_DELIV_MODE_FIXED 0x0 -+#define VLAPIC_DELIV_MODE_LPRI 0x1 -+#define VLAPIC_DELIV_MODE_SMI 0x2 -+#define VLAPIC_DELIV_MODE_NMI 0x4 -+#define VLAPIC_DELIV_MODE_INIT 0x5 -+#define VLAPIC_DELIV_MODE_STARTUP 0x6 -+#define VLAPIC_DELIV_MODE_EXT 0x7 -+#define VLAPIC_DELIV_MODE_MASK 0x8 -+ -+#define VLAPIC_MSG_LEVEL 4 -+ -+#define INTR_EXT 0 -+#define INTR_APIC 1 -+#define INTR_LAPIC 2 -+ -+#define VL_STATE_EOI 1 -+#define VL_STATE_EXT_LOCK 2 -+#define VL_STATE_MSG_LOCK 3 -+#define VL_STATE_EOI_LOCK 3 -+ -+#define VLOCAL_APIC_MAX_INTS 256 -+#define VLAPIC_INT_COUNT (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(uint64_t))) -+#define VLAPIC_INT_COUNT_32 (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(uint32_t))) -+ -+typedef struct { -+ /* interrupt for PIC and ext type IOAPIC interrupt */ -+ uint64_t vl_ext_intr[VLAPIC_INT_COUNT]; -+ uint64_t vl_ext_intr_mask[VLAPIC_INT_COUNT]; -+ uint64_t vl_apic_intr[VLAPIC_INT_COUNT]; -+ uint64_t vl_apic_tmr[VLAPIC_INT_COUNT]; -+ uint64_t vl_eoi[VLAPIC_INT_COUNT]; -+ uint32_t vl_lapic_id; -+ uint32_t direct_intr; -+ uint32_t vl_apr; -+ uint32_t vl_logical_dest; -+ uint32_t vl_dest_format; -+ uint32_t vl_arb_id; -+ uint32_t vl_state; -+ uint32_t apic_msg_count; -+} vlapic_info; -+ -+#endif /* _VMX_VLAPIC_H_ */ -+ -+/* -+ * Local variables: -+ * mode: C -+ * c-set-style: "BSD" -+ * c-basic-offset: 4 -+ * tab-width: 4 -+ * indent-tabs-mode: nil -+ * End: -+ */ -diff --git a/include/xen/interface/io/vmx_vpic.h b/include/xen/interface/io/vmx_vpic.h -new file mode 100644 -index 0000000..256ac87 ---- /dev/null -+++ b/include/xen/interface/io/vmx_vpic.h -@@ -0,0 +1,85 @@ -+/* -+ * QEMU System Emulator header -+ * -+ * Copyright (c) 2003 Fabrice Bellard -+ * Copyright (c) 2005 Intel Corp -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+ -+#ifndef _VMX_VPIC_H -+#define _VMX_VPIC_H -+ -+#define hw_error(x) do {} while (0); -+ -+ -+/* i8259.c */ -+typedef struct IOAPICState IOAPICState; -+typedef struct PicState { -+ uint8_t last_irr; /* edge detection */ -+ uint8_t irr; /* interrupt request register */ -+ uint8_t imr; /* interrupt mask register */ -+ uint8_t isr; /* interrupt service register */ -+ uint8_t priority_add; /* highest irq priority */ -+ uint8_t irq_base; -+ uint8_t read_reg_select; -+ uint8_t poll; -+ uint8_t special_mask; -+ uint8_t init_state; -+ uint8_t auto_eoi; -+ uint8_t rotate_on_auto_eoi; -+ uint8_t special_fully_nested_mode; -+ uint8_t init4; /* true if 4 byte init */ -+ uint8_t elcr; /* PIIX edge/trigger selection*/ -+ uint8_t elcr_mask; -+ struct vmx_virpic *pics_state; -+} PicState; -+ -+struct vmx_virpic { -+ /* 0 is master pic, 1 is slave pic */ -+ /* XXX: better separation between the two pics */ -+ PicState pics[2]; -+ void (*irq_request)(int *opaque, int level); -+ void *irq_request_opaque; -+ /* IOAPIC callback support */ -+ void (*alt_irq_func)(void *opaque, int irq_num, int level); -+ void *alt_irq_opaque; -+}; -+ -+ -+void pic_set_irq(struct vmx_virpic *s, int irq, int level); -+void pic_set_irq_new(void *opaque, int irq, int level); -+void pic_init(struct vmx_virpic *s, -+ void (*irq_request)(), -+ void *irq_request_opaque); -+void pic_set_alt_irq_func(struct vmx_virpic *s, -+ void(*alt_irq_func)(), -+ void *alt_irq_opaque); -+int pic_read_irq(struct vmx_virpic *s); -+void pic_update_irq(struct vmx_virpic *s); -+uint32_t pic_intack_read(struct vmx_virpic *s); -+void register_pic_io_hook (void); -+int cpu_get_pic_interrupt(struct vcpu *v, int *type); -+int is_pit_irq(struct vcpu *v, int irq, int type); -+int is_irq_enabled(struct vcpu *v, int irq); -+void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs); -+void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs); -+ -+/* APIC */ -+#endif /* _VMX_VPIC_H */ diff --git a/include/xen/interface/io/xenbus.h b/include/xen/interface/io/xenbus.h new file mode 100644 index 0000000..472079c @@ -75392,10 +76790,10 @@ index 0000000..3c642fd + */ diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h new file mode 100644 -index 0000000..f3f16fe +index 0000000..f2a5c1c --- /dev/null +++ b/include/xen/interface/memory.h -@@ -0,0 +1,153 @@ +@@ -0,0 +1,155 @@ +/****************************************************************************** + * memory.h + * @@ -75495,25 +76893,27 @@ index 0000000..f3f16fe +DEFINE_GUEST_HANDLE(xen_machphys_mfn_list_t); + +/* -+ * Returns the base and size of the specified reserved 'RAM hole' in the -+ * specified guest's pseudophysical address space. -+ * arg == addr of xen_reserved_phys_area_t. ++ * Sets the GPFN at which a particular page appears in the specified guest's ++ * pseudophysical address space. ++ * arg == addr of xen_add_to_physmap_t. + */ -+#define XENMEM_reserved_phys_area 7 -+typedef struct xen_reserved_phys_area { -+ /* Which domain to report about? */ ++#define XENMEM_add_to_physmap 7 ++typedef struct xen_add_to_physmap { ++ /* Which domain to change the mapping for. */ + domid_t domid; + -+ /* -+ * Which reserved area to report? Out-of-range request reports -+ * -ESRCH. Currently no architecture will have more than one reserved area. -+ */ -+ unsigned int idx; ++ /* Source mapping space. */ ++#define XENMAPSPACE_shared_info 0 /* shared info page */ ++#define XENMAPSPACE_grant_table 1 /* grant table page */ ++ unsigned int space; + -+ /* Base and size of the specified reserved area. */ -+ unsigned long first_gpfn, nr_gpfns; -+} xen_reserved_phys_area_t; -+DEFINE_GUEST_HANDLE(xen_reserved_phys_area_t); ++ /* Index into source mapping space. */ ++ unsigned long idx; ++ ++ /* GPFN where the source mapping page should appear. */ ++ unsigned long gpfn; ++} xen_add_to_physmap_t; ++DEFINE_GUEST_HANDLE(xen_add_to_physmap_t); + +/* + * Translates a list of domain-specific GPFNs into MFNs. Returns a -ve error @@ -75551,10 +76951,10 @@ index 0000000..f3f16fe + */ diff --git a/include/xen/interface/nmi.h b/include/xen/interface/nmi.h new file mode 100644 -index 0000000..0c0c67b +index 0000000..a938ef8 --- /dev/null +++ b/include/xen/interface/nmi.h -@@ -0,0 +1,54 @@ +@@ -0,0 +1,59 @@ +/****************************************************************************** + * nmi.h + * @@ -75588,9 +76988,14 @@ index 0000000..0c0c67b +/* + * Register NMI callback for this (calling) VCPU. Currently this only makes + * sense for domain 0, vcpu 0. All other callers will be returned EINVAL. -+ * arg == address of callback function. ++ * arg == pointer to xennmi_callback structure. + */ +#define XENNMI_register_callback 0 ++typedef struct xennmi_callback { ++ unsigned long handler_address; ++ unsigned long pad; ++} xennmi_callback_t; ++DEFINE_GUEST_HANDLE(xennmi_callback_t); + +/* + * Deregister NMI callback for this (calling) VCPU. @@ -75611,10 +77016,10 @@ index 0000000..0c0c67b + */ diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h new file mode 100644 -index 0000000..2df68b4 +index 0000000..b003af7 --- /dev/null +++ b/include/xen/interface/physdev.h -@@ -0,0 +1,70 @@ +@@ -0,0 +1,71 @@ + +#ifndef __XEN_PUBLIC_PHYSDEV_H__ +#define __XEN_PUBLIC_PHYSDEV_H__ @@ -75673,6 +77078,7 @@ index 0000000..2df68b4 + physdevop_irq_t irq_op; + } u; +} physdev_op_t; ++DEFINE_GUEST_HANDLE(physdev_op_t); + +#endif /* __XEN_PUBLIC_PHYSDEV_H__ */ + @@ -75687,10 +77093,10 @@ index 0000000..2df68b4 + */ diff --git a/include/xen/interface/sched.h b/include/xen/interface/sched.h new file mode 100644 -index 0000000..a1a03de +index 0000000..bebdb1c --- /dev/null +++ b/include/xen/interface/sched.h -@@ -0,0 +1,60 @@ +@@ -0,0 +1,87 @@ +/****************************************************************************** + * sched.h + * @@ -75702,16 +77108,26 @@ index 0000000..a1a03de +#ifndef __XEN_PUBLIC_SCHED_H__ +#define __XEN_PUBLIC_SCHED_H__ + ++#include "event_channel.h" ++ +/* -+ * Prototype for this hypercall is: -+ * int sched_op(int cmd, unsigned long arg) ++ * The prototype for this hypercall is: ++ * long sched_op_new(int cmd, void *arg) + * @cmd == SCHEDOP_??? (scheduler operation). -+ * @arg == Operation-specific extra argument(s). ++ * @arg == Operation-specific extra argument(s), as described below. ++ * ++ * **NOTE**: ++ * Versions of Xen prior to 3.0.2 provide only the following legacy version ++ * of this hypercall, supporting only the commands yield, block and shutdown: ++ * long sched_op(int cmd, unsigned long arg) ++ * @cmd == SCHEDOP_??? (scheduler operation). ++ * @arg == 0 (SCHEDOP_yield and SCHEDOP_block) ++ * == SHUTDOWN_* code (SCHEDOP_shutdown) + */ + +/* + * Voluntarily yield the CPU. -+ * @arg == 0. ++ * @arg == NULL. + */ +#define SCHEDOP_yield 0 + @@ -75720,18 +77136,35 @@ index 0000000..a1a03de + * If called with event upcalls masked, this operation will atomically + * reenable event delivery and check for pending events before blocking the + * VCPU. This avoids a "wakeup waiting" race. -+ * @arg == 0. ++ * @arg == NULL. + */ +#define SCHEDOP_block 1 + +/* + * Halt execution of this domain (all VCPUs) and notify the system controller. -+ * @arg == SHUTDOWN_??? (reason for shutdown). ++ * @arg == pointer to sched_shutdown structure. + */ +#define SCHEDOP_shutdown 2 ++typedef struct sched_shutdown { ++ unsigned int reason; /* SHUTDOWN_* */ ++} sched_shutdown_t; ++DEFINE_GUEST_HANDLE(sched_shutdown_t); + +/* -+ * Reason codes for SCHEDOP_shutdown. These may be interpreted by controller ++ * Poll a set of event-channel ports. Return when one or more are pending. An ++ * optional timeout may be specified. ++ * @arg == pointer to sched_poll structure. ++ */ ++#define SCHEDOP_poll 3 ++typedef struct sched_poll { ++ GUEST_HANDLE(evtchn_port_t) ports; ++ unsigned int nr_ports; ++ uint64_t timeout; ++} sched_poll_t; ++DEFINE_GUEST_HANDLE(sched_poll_t); ++ ++/* ++ * Reason codes for SCHEDOP_shutdown. These may be interpreted by control + * software to determine the appropriate action. For the most part, Xen does + * not care about the shutdown code. + */ @@ -75823,10 +77256,10 @@ index 0000000..600c43a + */ diff --git a/include/xen/interface/trace.h b/include/xen/interface/trace.h new file mode 100644 -index 0000000..cba4b26 +index 0000000..8fc009d --- /dev/null +++ b/include/xen/interface/trace.h -@@ -0,0 +1,90 @@ +@@ -0,0 +1,86 @@ +/****************************************************************************** + * include/public/trace.h + * @@ -75853,7 +77286,6 @@ index 0000000..cba4b26 +#define TRC_VMXTIMER 0x00082000 /* VMX timer trace */ +#define TRC_VMXINT 0x00084000 /* VMX interrupt trace */ +#define TRC_VMXIO 0x00088000 /* VMX io emulation trace */ -+#define TRC_VMEXIT_HANDLER 0x00090000 /* VMX handler trace */ + +/* Trace events per class */ + @@ -75879,15 +77311,12 @@ index 0000000..cba4b26 + +/* trace events per subclass */ +#define TRC_VMX_VMEXIT (TRC_VMXEXIT + 1) -+#define TRC_VMX_VECTOR (TRC_VMXEXIT + 2) ++#define TRC_VMX_VMENTRY (TRC_VMXEXIT + 2) + +#define TRC_VMX_TIMER_INTR (TRC_VMXTIMER + 1) + +#define TRC_VMX_INT (TRC_VMXINT + 1) + -+#define TRC_VMEXIT (TRC_VMEXIT_HANDLER + 1) -+#define TRC_VMENTRY (TRC_VMEXIT_HANDLER + 2) -+ + +/* This structure represents a single trace buffer record. */ +struct t_rec { @@ -76114,10 +77543,10 @@ index 0000000..9a496f9 + */ diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h new file mode 100644 -index 0000000..6e1f366 +index 0000000..5d88c9c --- /dev/null +++ b/include/xen/interface/xen.h -@@ -0,0 +1,447 @@ +@@ -0,0 +1,449 @@ +/****************************************************************************** + * xen.h + * @@ -76174,13 +77603,12 @@ index 0000000..6e1f366 +#define __HYPERVISOR_vm_assist 21 +#define __HYPERVISOR_update_va_mapping_otherdomain 22 +#define __HYPERVISOR_iret 23 /* x86 only */ -+#define __HYPERVISOR_switch_vm86 23 /* x86/32 only (obsolete name) */ -+#define __HYPERVISOR_switch_to_user 23 /* x86/64 only (obsolete name) */ +#define __HYPERVISOR_vcpu_op 24 +#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */ +#define __HYPERVISOR_mmuext_op 26 +#define __HYPERVISOR_acm_op 27 +#define __HYPERVISOR_nmi_op 28 ++#define __HYPERVISOR_sched_op_new 29 + +/* + * VIRTUAL INTERRUPTS @@ -76282,7 +77710,7 @@ index 0000000..6e1f366 +#define MMUEXT_NEW_USER_BASEPTR 15 + +#ifndef __ASSEMBLY__ -+struct mmuext_op { ++typedef struct mmuext_op { + unsigned int cmd; + union { + /* [UN]PIN_TABLE, NEW_BASEPTR, NEW_USER_BASEPTR */ @@ -76296,7 +77724,8 @@ index 0000000..6e1f366 + /* TLB_FLUSH_MULTI, INVLPG_MULTI */ + void *vcpumask; + } arg2; -+}; ++} mmuext_op_t; ++DEFINE_GUEST_HANDLE(mmuext_op_t); +#endif + +/* These are passed as 'flags' to update_va_mapping. They can be ORed. */ @@ -76363,6 +77792,7 @@ index 0000000..6e1f366 + uint64_t ptr; /* Machine address of PTE. */ + uint64_t val; /* New contents of PTE. */ +} mmu_update_t; ++DEFINE_GUEST_HANDLE(mmu_update_t); + +/* + * Send an array of these to HYPERVISOR_multicall(). @@ -76372,6 +77802,7 @@ index 0000000..6e1f366 + unsigned long op, result; + unsigned long args[6]; +} multicall_entry_t; ++DEFINE_GUEST_HANDLE(multicall_entry_t); + +/* + * Event channel endpoints per domain: @@ -76567,19 +77998,21 @@ index 0000000..6e1f366 + */ diff --git a/include/xen/net_driver_util.h b/include/xen/net_driver_util.h new file mode 100644 -index 0000000..130b4f0 +index 0000000..9054452 --- /dev/null +++ b/include/xen/net_driver_util.h -@@ -0,0 +1,56 @@ +@@ -0,0 +1,58 @@ +/***************************************************************************** + * + * Utility functions for Xen network devices. + * + * Copyright (c) 2005 XenSource Ltd. + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following -+ * license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this source file (the "Software"), to deal in the Software without @@ -76674,10 +78107,10 @@ index 0000000..51b170a +#endif /* __XEN_ASM_PCIFRONT_H__ */ diff --git a/include/xen/public/evtchn.h b/include/xen/public/evtchn.h new file mode 100644 -index 0000000..456f246 +index 0000000..5ba554b --- /dev/null +++ b/include/xen/public/evtchn.h -@@ -0,0 +1,98 @@ +@@ -0,0 +1,101 @@ +/****************************************************************************** + * evtchn.h + * @@ -76685,8 +78118,11 @@ index 0000000..456f246 + * + * Copyright (c) 2003-2005, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -76778,10 +78214,10 @@ index 0000000..456f246 + */ diff --git a/include/xen/public/privcmd.h b/include/xen/public/privcmd.h new file mode 100644 -index 0000000..074d66c +index 0000000..a7da522 --- /dev/null +++ b/include/xen/public/privcmd.h -@@ -0,0 +1,91 @@ +@@ -0,0 +1,94 @@ +/****************************************************************************** + * privcmd.h + * @@ -76789,8 +78225,11 @@ index 0000000..074d66c + * + * Copyright (c) 2003-2005, K A Fraser + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -76950,10 +78389,10 @@ index 0000000..dc89521 + */ diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h new file mode 100644 -index 0000000..27b08d5 +index 0000000..1224805 --- /dev/null +++ b/include/xen/xenbus.h -@@ -0,0 +1,298 @@ +@@ -0,0 +1,301 @@ +/****************************************************************************** + * xenbus.h + * @@ -76962,8 +78401,11 @@ index 0000000..27b08d5 + * Copyright (C) 2005 Rusty Russell, IBM Corporation + * Copyright (C) 2005 XenSource Ltd. + * -+ * This file may be distributed separately from the Linux kernel, or -+ * incorporated into other software packages, subject to the following license: ++ * 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; or, when distributed ++ * separately from the Linux kernel or incorporated into other ++ * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without @@ -76989,7 +78431,7 @@ index 0000000..27b08d5 + +#include +#include -+#include ++#include +#include +#include +#include @@ -77272,19 +78714,6 @@ index 0000000..fa2160d +int xencons_ring_send(const char *data, unsigned len); + +#endif /* __ASM_XENCONS_H__ */ -diff --git a/init/Kconfig b/init/Kconfig -index 38416a1..2c3ece9 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -224,7 +224,7 @@ config UID16 - This enables the legacy 16-bit UID syscall wrappers. - - config VM86 -- depends X86 -+ depends on X86 - default y - bool "Enable VM86 support" if EMBEDDED - help diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt index 0b46a5d..17ab322 100644 --- a/kernel/Kconfig.preempt @@ -77496,7 +78925,7 @@ index ce2e7e8..b29bf62 100644 { unsigned long vaddr; diff --git a/mm/memory.c b/mm/memory.c -index 9abc600..351b316 100644 +index 85e80a5..f91d3ba 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -405,7 +405,8 @@ struct page *vm_normal_page(struct vm_ar @@ -77509,7 +78938,7 @@ index 9abc600..351b316 100644 return NULL; } -@@ -1019,6 +1020,23 @@ int get_user_pages(struct task_struct *t +@@ -1020,6 +1021,23 @@ int get_user_pages(struct task_struct *t continue; } @@ -77533,41 +78962,44 @@ index 9abc600..351b316 100644 if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP)) || !(vm_flags & vma->vm_flags)) return i ? : -EFAULT; -@@ -1358,6 +1376,98 @@ int remap_pfn_range(struct vm_area_struc +@@ -1359,6 +1377,102 @@ int remap_pfn_range(struct vm_area_struc } EXPORT_SYMBOL(remap_pfn_range); +#ifdef CONFIG_XEN -+static inline int generic_pte_range(struct mm_struct *mm, pmd_t *pmd, -+ unsigned long addr, unsigned long end, -+ pte_fn_t fn, void *data) ++static inline int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd, ++ unsigned long addr, unsigned long end, ++ pte_fn_t fn, void *data) +{ + pte_t *pte; + int err; -+ struct page *pte_page; ++ struct page *pmd_page; ++ spinlock_t *ptl; + + pte = (mm == &init_mm) ? + pte_alloc_kernel(pmd, addr) : -+ pte_alloc_map(mm, pmd, addr); ++ pte_alloc_map_lock(mm, pmd, addr, &ptl); + if (!pte) + return -ENOMEM; + -+ pte_page = pmd_page(*pmd); ++ BUG_ON(pmd_huge(*pmd)); ++ ++ pmd_page = pmd_page(*pmd); + + do { -+ err = fn(pte, pte_page, addr, data); ++ err = fn(pte, pmd_page, addr, data); + if (err) + break; + } while (pte++, addr += PAGE_SIZE, addr != end); + + if (mm != &init_mm) -+ pte_unmap(pte-1); ++ pte_unmap_unlock(pte-1, ptl); + return err; +} + -+static inline int generic_pmd_range(struct mm_struct *mm, pud_t *pud, -+ unsigned long addr, unsigned long end, -+ pte_fn_t fn, void *data) ++static inline int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud, ++ unsigned long addr, unsigned long end, ++ pte_fn_t fn, void *data) +{ + pmd_t *pmd; + unsigned long next; @@ -77578,16 +79010,16 @@ index 9abc600..351b316 100644 + return -ENOMEM; + do { + next = pmd_addr_end(addr, end); -+ err = generic_pte_range(mm, pmd, addr, next, fn, data); ++ err = apply_to_pte_range(mm, pmd, addr, next, fn, data); + if (err) + break; + } while (pmd++, addr = next, addr != end); + return err; +} + -+static inline int generic_pud_range(struct mm_struct *mm, pgd_t *pgd, -+ unsigned long addr, unsigned long end, -+ pte_fn_t fn, void *data) ++static inline int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd, ++ unsigned long addr, unsigned long end, ++ pte_fn_t fn, void *data) +{ + pud_t *pud; + unsigned long next; @@ -77598,7 +79030,7 @@ index 9abc600..351b316 100644 + return -ENOMEM; + do { + next = pud_addr_end(addr, end); -+ err = generic_pmd_range(mm, pud, addr, next, fn, data); ++ err = apply_to_pmd_range(mm, pud, addr, next, fn, data); + if (err) + break; + } while (pud++, addr = next, addr != end); @@ -77609,8 +79041,8 @@ index 9abc600..351b316 100644 + * Scan a region of virtual memory, filling in page tables as necessary + * and calling a provided function on each leaf page table. + */ -+int generic_page_range(struct mm_struct *mm, unsigned long addr, -+ unsigned long size, pte_fn_t fn, void *data) ++int apply_to_page_range(struct mm_struct *mm, unsigned long addr, ++ unsigned long size, pte_fn_t fn, void *data) +{ + pgd_t *pgd; + unsigned long next; @@ -77621,12 +79053,13 @@ index 9abc600..351b316 100644 + pgd = pgd_offset(mm, addr); + do { + next = pgd_addr_end(addr, end); -+ err = generic_pud_range(mm, pgd, addr, next, fn, data); ++ err = apply_to_pud_range(mm, pgd, addr, next, fn, data); + if (err) + break; + } while (pgd++, addr = next, addr != end); + return err; +} ++EXPORT_SYMBOL_GPL(apply_to_page_range); +#endif + /* @@ -77835,6 +79268,49 @@ index 2144952..dadc9cf 100644 C(pkt_type); C(ip_summed); C(priority); +diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c +index a3d1407..425c926 100644 +--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c ++++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c +@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb, + if (hdrsize < sizeof(*hdr)) + return 1; + +- hdr->check = ip_nat_cheat_check(~oldip, newip, ++ if ((*pskb)->proto_csum_blank) { ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); ++ } else { ++ hdr->check = ip_nat_cheat_check(~oldip, newip, + ip_nat_cheat_check(oldport ^ 0xFFFF, + newport, + hdr->check)); ++ } + return 1; + } + +diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c +index ec6053f..1d760fe 100644 +--- a/net/ipv4/netfilter/ip_nat_proto_udp.c ++++ b/net/ipv4/netfilter/ip_nat_proto_udp.c +@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb, + newport = tuple->dst.u.udp.port; + portptr = &hdr->dest; + } +- if (hdr->check) /* 0 is a special case meaning no checksum */ +- hdr->check = ip_nat_cheat_check(~oldip, newip, ++ if (hdr->check) { /* 0 is a special case meaning no checksum */ ++ if ((*pskb)->proto_csum_blank) { ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); ++ } else { ++ hdr->check = ip_nat_cheat_check(~oldip, newip, + ip_nat_cheat_check(*portptr ^ 0xFFFF, + newport, + hdr->check)); ++ } ++ } + *portptr = newport; + return 1; + } diff --git a/scripts/Makefile.xen b/scripts/Makefile.xen new file mode 100644 index 0000000..b3ec53a From 31e52b9370fe22c5e5e281e52489470599877990 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Mon, 3 Apr 2006 08:44:55 +0000 Subject: [PATCH 032/108] debian/arch/amd64/xen/config, debian/arch/amd64/xen-vserver/config, debian/arch/i386/xen/config, debian/arch/i386/xen-vserver/config: Adopt config changes for new xen patch. svn path=/dists/trunk/linux-2.6/; revision=6365 --- debian/arch/amd64/xen-vserver/config | 1 + debian/arch/amd64/xen/config | 1 + debian/arch/i386/xen-vserver/config | 1 + debian/arch/i386/xen/config | 1 + 4 files changed, 4 insertions(+) diff --git a/debian/arch/amd64/xen-vserver/config b/debian/arch/amd64/xen-vserver/config index 94b130318..a7a61b5c3 100644 --- a/debian/arch/amd64/xen-vserver/config +++ b/debian/arch/amd64/xen-vserver/config @@ -18,6 +18,7 @@ CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_FRONTEND is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y +CONFIG_XEN_SYSFS=y CONFIG_VSERVER=y CONFIG_VSERVER_SECURITY=y CONFIG_VSERVER_LEGACYNET=y diff --git a/debian/arch/amd64/xen/config b/debian/arch/amd64/xen/config index 388455c0b..30bbec045 100644 --- a/debian/arch/amd64/xen/config +++ b/debian/arch/amd64/xen/config @@ -18,3 +18,4 @@ CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_FRONTEND is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y +CONFIG_XEN_SYSFS=y diff --git a/debian/arch/i386/xen-vserver/config b/debian/arch/i386/xen-vserver/config index ec23b6431..7572cd4c9 100644 --- a/debian/arch/i386/xen-vserver/config +++ b/debian/arch/i386/xen-vserver/config @@ -19,6 +19,7 @@ CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_FRONTEND is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y +CONFIG_XEN_SYSFS=y # CONFIG_SMP_ALTERNATIVES is not set # CONFIG_PCI_GOXEN_FE is not set CONFIG_VSERVER=y diff --git a/debian/arch/i386/xen/config b/debian/arch/i386/xen/config index ec9e5977b..d78ec562f 100644 --- a/debian/arch/i386/xen/config +++ b/debian/arch/i386/xen/config @@ -19,5 +19,6 @@ CONFIG_XEN_NETDEV_LOOPBACK=y # CONFIG_XEN_TPMDEV_FRONTEND is not set CONFIG_XEN_SCRUB_PAGES=y CONFIG_XEN_DISABLE_SERIAL=y +CONFIG_XEN_SYSFS=y # CONFIG_SMP_ALTERNATIVES is not set # CONFIG_PCI_GOXEN_FE is not set From f906eec81f69fe591b91463ad6a1abb90e60746d Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Mon, 3 Apr 2006 17:11:06 +0000 Subject: [PATCH 033/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6368 --- debian/changelog | 5 +- debian/patches/series/5-extra | 1 + .../patches/vserver-vs2.0.2-rc15-update.patch | 679 ++++++++++++++++++ 3 files changed, 683 insertions(+), 2 deletions(-) create mode 100644 debian/patches/series/5-extra create mode 100644 debian/patches/vserver-vs2.0.2-rc15-update.patch diff --git a/debian/changelog b/debian/changelog index 65dfe7542..c50a5d084 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,7 +4,7 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- Bastian Blank Thu, 23 Mar 2006 21:40:17 +0100 -linux-2.6 (2.6.16-5) UNRELEASED; urgency=low +linux-2.6 (2.6.16-5) unstable; urgency=low [ Bastian Blank ] * Provide real dependency packages for module building. @@ -14,11 +14,12 @@ linux-2.6 (2.6.16-5) UNRELEASED; urgency=low * Fix module package output. * Include .kernelrelease in headers packages. (closes: #359813) * Disable Cumana partition support completely. (closes: #359207) + * Update vserver patch to 2.0.2-rc15. [ dann frazier ] * [ia64] initramfs-tools works now, no longer restrict initramfs-generators - -- Bastian Blank Sun, 2 Apr 2006 16:21:29 +0200 + -- Bastian Blank Mon, 3 Apr 2006 14:00:08 +0200 linux-2.6 (2.6.16-4) unstable; urgency=medium diff --git a/debian/patches/series/5-extra b/debian/patches/series/5-extra new file mode 100644 index 000000000..77e16abab --- /dev/null +++ b/debian/patches/series/5-extra @@ -0,0 +1 @@ ++ vserver-vs2.0.2-rc15-update.patch *_vserver diff --git a/debian/patches/vserver-vs2.0.2-rc15-update.patch b/debian/patches/vserver-vs2.0.2-rc15-update.patch new file mode 100644 index 000000000..8765c3746 --- /dev/null +++ b/debian/patches/vserver-vs2.0.2-rc15-update.patch @@ -0,0 +1,679 @@ +diff -u linux-2.6.16-vs2.0.2-rc14/drivers/block/vroot.c linux-2.6.16-vs2.0.2-rc15/drivers/block/vroot.c +--- linux-2.6.16-vs2.0.2-rc14/drivers/block/vroot.c 2006-03-20 17:34:49 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/drivers/block/vroot.c 2006-03-24 16:50:44 +0100 +@@ -12,7 +12,6 @@ + * + */ + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vs_context.h linux-2.6.16-vs2.0.2-rc15/include/linux/vs_context.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vs_context.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vs_context.h 2006-04-03 05:31:18 +0200 +@@ -170,7 +170,7 @@ + wake_up_interruptible(&vxi->vx_wait); + } + +-extern void exit_vx_info(struct task_struct *); ++extern void exit_vx_info(struct task_struct *, int); + + static inline + struct task_struct *vx_child_reaper(struct task_struct *p) +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vs_memory.h linux-2.6.16-vs2.0.2-rc15/include/linux/vs_memory.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vs_memory.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vs_memory.h 2006-03-24 16:50:44 +0100 +@@ -1,7 +1,6 @@ + #ifndef _VX_VS_MEMORY_H + #define _VX_VS_MEMORY_H + +-#include + #include "vserver/limit.h" + #include "vserver/debug.h" + #include "vserver/limit_int.h" +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vs_sched.h linux-2.6.16-vs2.0.2-rc15/include/linux/vs_sched.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vs_sched.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vs_sched.h 2006-03-24 16:50:44 +0100 +@@ -1,7 +1,6 @@ + #ifndef _VX_VS_SCHED_H + #define _VX_VS_SCHED_H + +-#include + #include "vserver/sched.h" + + +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/context.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/context.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/context.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/context.h 2006-04-03 05:31:18 +0200 +@@ -1,7 +1,6 @@ + #ifndef _VX_CONTEXT_H + #define _VX_CONTEXT_H + +-#include + #include + + +@@ -111,13 +110,15 @@ + struct task_struct *vx_reaper; /* guest reaper process */ + pid_t vx_initpid; /* PID of guest init */ + +- wait_queue_head_t vx_wait; /* context exit waitqueue */ +- + struct _vx_limit limit; /* vserver limits */ + struct _vx_sched sched; /* vserver scheduler */ + struct _vx_cvirt cvirt; /* virtual/bias stuff */ + struct _vx_cacct cacct; /* context accounting */ + ++ wait_queue_head_t vx_wait; /* context exit waitqueue */ ++ int reboot_cmd; /* last sys_reboot() cmd */ ++ int exit_code; /* last process exit code */ ++ + char vx_name[65]; /* vserver name */ + }; + +@@ -128,6 +129,7 @@ + #define VXS_PAUSED 0x0010 + #define VXS_ONHOLD 0x0020 + #define VXS_SHUTDOWN 0x0100 ++#define VXS_HELPER 0x1000 + #define VXS_RELEASED 0x8000 + + /* check conditions */ +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/cvirt_def.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/cvirt_def.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/cvirt_def.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/cvirt_def.h 2006-03-24 16:50:44 +0100 +@@ -1,7 +1,6 @@ + #ifndef _VX_CVIRT_DEF_H + #define _VX_CVIRT_DEF_H + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/debug.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/debug.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/debug.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/debug.h 2006-03-24 16:50:44 +0100 +@@ -1,8 +1,6 @@ + #ifndef _VX_DEBUG_H + #define _VX_DEBUG_H + +-#include +- + + #define VXD_CBIT(n,m) (vx_debug_ ## n & (1 << (m))) + #define VXD_CMIN(n,m) (vx_debug_ ## n > (m)) +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/dlimit_cmd.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/dlimit_cmd.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/dlimit_cmd.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/dlimit_cmd.h 2006-03-24 16:50:44 +0100 +@@ -1,8 +1,6 @@ + #ifndef _VX_DLIMIT_CMD_H + #define _VX_DLIMIT_CMD_H + +-#include +- + + /* dlimit vserver commands */ + +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/inode.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/inode.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/inode.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/inode.h 2006-03-24 16:50:44 +0100 +@@ -15,8 +15,6 @@ + + #ifdef __KERNEL__ + +-#include +- + + #ifdef CONFIG_VSERVER_PROC_SECURE + #define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE ) +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/inode_cmd.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/inode_cmd.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/inode_cmd.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/inode_cmd.h 2006-03-24 16:50:44 +0100 +@@ -28,8 +28,6 @@ + + #ifdef __KERNEL__ + +-#include +- + + #ifdef CONFIG_COMPAT + +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/limit_cmd.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/limit_cmd.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/limit_cmd.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/limit_cmd.h 2006-04-03 02:37:59 +0200 +@@ -28,10 +28,28 @@ + #ifdef __KERNEL__ + ++#ifdef CONFIG_IA32_EMULATION ++ ++struct vcmd_ctx_rlimit_v0_x32 { ++ uint32_t id; ++ uint64_t minimum; ++ uint64_t softlimit; ++ uint64_t maximum; ++} __attribute__ ((aligned (4))); ++ ++#endif /* CONFIG_IA32_EMULATION */ ++ + #include + + extern int vc_get_rlimit(uint32_t, void __user *); + extern int vc_set_rlimit(uint32_t, void __user *); + extern int vc_get_rlimit_mask(uint32_t, void __user *); + ++#ifdef CONFIG_IA32_EMULATION ++ ++extern int vc_get_rlimit_x32(uint32_t, void __user *); ++extern int vc_set_rlimit_x32(uint32_t, void __user *); ++ ++#endif /* CONFIG_IA32_EMULATION */ ++ + #endif /* __KERNEL__ */ + #endif /* _VX_LIMIT_CMD_H */ +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/limit_def.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/limit_def.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/limit_def.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/limit_def.h 2006-03-24 16:50:44 +0100 +@@ -1,7 +1,6 @@ + #ifndef _VX_LIMIT_DEF_H + #define _VX_LIMIT_DEF_H + +-#include + #include + #include + +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/sched_def.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/sched_def.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/sched_def.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/sched_def.h 2006-03-24 16:50:44 +0100 +@@ -1,7 +1,6 @@ + #ifndef _VX_SCHED_DEF_H + #define _VX_SCHED_DEF_H + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/signal_cmd.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/signal_cmd.h +--- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/signal_cmd.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/signal_cmd.h 2006-04-03 05:31:18 +0200 +@@ -13,8 +13,8 @@ + }; + + struct vcmd_wait_exit_v0 { +- int32_t a; +- int32_t b; ++ int32_t reboot_cmd; ++ int32_t exit_code; + }; + + #ifdef __KERNEL__ +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/exit.c linux-2.6.16-vs2.0.2-rc15/kernel/exit.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/exit.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/exit.c 2006-04-03 05:31:18 +0200 +@@ -869,7 +869,7 @@ + __exit_files(tsk); + __exit_fs(tsk); + exit_namespace(tsk); +- exit_vx_info(tsk); ++ exit_vx_info(tsk, code); + exit_nx_info(tsk); + exit_thread(); + cpuset_exit(tsk); +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/Kconfig linux-2.6.16-vs2.0.2-rc15/kernel/vserver/Kconfig +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/Kconfig 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/Kconfig 2006-03-24 16:50:44 +0100 +@@ -2,21 +2,6 @@ + # Linux VServer configuration + # + +-config VSERVER +- bool +- default y +- +-config VSERVER_SECURITY +- bool +- depends on SECURITY +- default y +- select SECURITY_CAPABILITIES +- +-config VSERVER_LEGACYNET +- bool +- depends on !VSERVER_NGNET +- default y +- + menu "Linux VServer" + + config VSERVER_LEGACY +@@ -179,0 +165,16 @@ ++ ++config VSERVER ++ bool ++ default y ++ ++config VSERVER_SECURITY ++ bool ++ depends on SECURITY ++ default y ++ select SECURITY_CAPABILITIES ++ ++config VSERVER_LEGACYNET ++ bool ++ depends on !VSERVER_NGNET ++ default y ++ +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/context.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/context.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/context.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/context.c 2006-04-03 05:31:18 +0200 +@@ -19,7 +19,6 @@ + * + */ + +-#include + #include + #include + #include +@@ -82,6 +81,9 @@ + new->vx_bcaps = CAP_INIT_EFF_SET; + new->vx_ccaps = 0; + ++ new->reboot_cmd = 0; ++ new->exit_code = 0; ++ + vxdprintk(VXD_CBIT(xid, 0), + "alloc_vx_info(%d) = %p", xid, new); + vxh_alloc_vx_info(new); +@@ -617,12 +619,13 @@ + return 0; + } + +-void vx_exit_init(struct vx_info *vxi, struct task_struct *p) ++void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code) + { + vxdprintk(VXD_CBIT(xid, 6), + "vx_exit_init(%p[#%d],%p[#%d,%d,%d])", + vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid); + ++ vxi->exit_code = code; + vxi->vx_initpid = 0; + } + +@@ -643,7 +646,7 @@ + + /* task must be current or locked */ + +-void exit_vx_info(struct task_struct *p) ++void exit_vx_info(struct task_struct *p, int code) + { + struct vx_info *vxi = p->vx_info; + +@@ -651,8 +654,9 @@ + atomic_dec(&vxi->cvirt.nr_threads); + vx_nproc_dec(p); + ++ vxi->exit_code = code; + if (vxi->vx_initpid == p->tgid) +- vx_exit_init(vxi, p); ++ vx_exit_init(vxi, p, code); + if (vxi->vx_reaper == p) + vx_set_reaper(vxi, child_reaper); + release_vx_info(vxi, p); +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/cvirt_init.h linux-2.6.16-vs2.0.2-rc15/kernel/vserver/cvirt_init.h +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/cvirt_init.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/cvirt_init.h 2006-03-24 16:50:48 +0100 +@@ -1,6 +1,4 @@ + +-#include +- + + #include + +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/dlimit.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/dlimit.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/dlimit.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/dlimit.c 2006-03-24 16:50:48 +0100 +@@ -10,7 +10,6 @@ + * + */ + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/helper.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/helper.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/helper.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/helper.c 2006-04-03 05:30:52 +0200 +@@ -9,7 +9,6 @@ + * + */ + +-#include + #include + #include + #include +@@ -64,6 +63,10 @@ + "PATH=/sbin:/usr/sbin:/bin:/usr/bin", + uid_buf, pid_buf, cmd_buf, 0}; + ++ if (vx_info_state(vxi, VXS_HELPER)) ++ return -EAGAIN; ++ vxi->vx_state |= VXS_HELPER; ++ + snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id); + + snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd); +@@ -88,6 +91,7 @@ + break; + + default: ++ vxi->vx_state &= ~VXS_HELPER; + return 0; + } + +@@ -96,6 +100,8 @@ + #else + ret = do_vshelper(vshelper_path, argv, envp, 0); + #endif ++ vxi->vx_state &= ~VXS_HELPER; ++ __wakeup_vx_info(vxi); + return (ret) ? -EPERM : 0; + } + +@@ -108,6 +114,12 @@ + vxdprintk(VXD_CBIT(misc, 5), + "vs_reboot(%p[#%d],%d)", + vxi, vxi?vxi->vx_id:0, cmd); ++ ++ ret = vs_reboot_helper(vxi, cmd, arg); ++ if (ret) ++ return ret; ++ ++ vxi->reboot_cmd = cmd; + if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) { + switch (cmd) { + case LINUX_REBOOT_CMD_RESTART: +@@ -118,10 +130,8 @@ + default: + break; + } +- } else { +- ret = vs_reboot_helper(vxi, cmd, arg); + } +- return ret; ++ return 0; + } + + +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/history.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/history.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/history.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/history.c 2006-03-24 16:50:48 +0100 +@@ -11,7 +11,6 @@ + * + */ + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/init.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/init.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/init.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/init.c 2006-03-24 16:50:44 +0100 +@@ -9,7 +9,6 @@ + * + */ + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/inode.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/inode.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/inode.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/inode.c 2006-03-24 16:50:48 +0100 +@@ -9,7 +9,6 @@ + * + */ + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/limit.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/limit.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/limit.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/limit.c 2006-04-03 01:43:40 +0200 +@@ -71,53 +71,114 @@ + return limit; + } + +-int vc_get_rlimit(uint32_t id, void __user *data) ++int do_get_rlimit(xid_t xid, uint32_t id, ++ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum) + { + struct vx_info *vxi; +- struct vcmd_ctx_rlimit_v0 vc_data; + +- if (copy_from_user (&vc_data, data, sizeof(vc_data))) +- return -EFAULT; +- if (!is_valid_rlimit(vc_data.id)) ++ if (!is_valid_rlimit(id)) + return -EINVAL; + +- vxi = lookup_vx_info(id); ++ vxi = lookup_vx_info(xid); + if (!vxi) + return -ESRCH; + +- vc_data.maximum = vc_get_rlim(vxi, vc_data.id); +- vc_data.minimum = CRLIM_UNSET; +- vc_data.softlimit = CRLIM_UNSET; ++ if (minimum) ++ *minimum = CRLIM_UNSET; ++ if (softlimit) ++ *softlimit = CRLIM_UNSET; ++ if (maximum) ++ *maximum = vc_get_rlim(vxi, id); + put_vx_info(vxi); ++ return 0; ++} ++ ++int vc_get_rlimit(uint32_t id, void __user *data) ++{ ++ struct vcmd_ctx_rlimit_v0 vc_data; ++ int ret; ++ ++ if (copy_from_user (&vc_data, data, sizeof(vc_data))) ++ return -EFAULT; ++ ++ ret = do_get_rlimit(id, vc_data.id, ++ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); ++ if (ret) ++ return ret; + + if (copy_to_user (data, &vc_data, sizeof(vc_data))) + return -EFAULT; + return 0; + } + +-int vc_set_rlimit(uint32_t id, void __user *data) ++int do_set_rlimit(xid_t xid, uint32_t id, ++ uint64_t minimum, uint64_t softlimit, uint64_t maximum) + { + struct vx_info *vxi; ++ ++ if (!is_valid_rlimit(id)) ++ return -EINVAL; ++ ++ vxi = lookup_vx_info(xid); ++ if (!vxi) ++ return -ESRCH; ++ ++ if (maximum != CRLIM_KEEP) ++ vxi->limit.rlim[id] = maximum; ++ ++ put_vx_info(vxi); ++ return 0; ++} ++ ++int vc_set_rlimit(uint32_t id, void __user *data) ++{ + struct vcmd_ctx_rlimit_v0 vc_data; + + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) + return -EPERM; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; +- if (!is_valid_rlimit(vc_data.id)) +- return -EINVAL; + +- vxi = lookup_vx_info(id); +- if (!vxi) +- return -ESRCH; ++ return do_set_rlimit(id, vc_data.id, ++ vc_data.minimum, vc_data.softlimit, vc_data.maximum); ++} + +- if (vc_data.maximum != CRLIM_KEEP) +- vxi->limit.rlim[vc_data.id] = vc_data.maximum; +- put_vx_info(vxi); ++#ifdef CONFIG_IA32_EMULATION ++ ++int vc_set_rlimit_x32(uint32_t id, void __user *data) ++{ ++ struct vcmd_ctx_rlimit_v0_x32 vc_data; ++ ++ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) ++ return -EPERM; ++ if (copy_from_user (&vc_data, data, sizeof(vc_data))) ++ return -EFAULT; ++ ++ return do_set_rlimit(id, vc_data.id, ++ vc_data.minimum, vc_data.softlimit, vc_data.maximum); ++} + ++int vc_get_rlimit_x32(uint32_t id, void __user *data) ++{ ++ struct vcmd_ctx_rlimit_v0_x32 vc_data; ++ int ret; ++ ++ if (copy_from_user (&vc_data, data, sizeof(vc_data))) ++ return -EFAULT; ++ ++ ret = do_get_rlimit(id, vc_data.id, ++ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); ++ if (ret) ++ return ret; ++ ++ if (copy_to_user (data, &vc_data, sizeof(vc_data))) ++ return -EFAULT; + return 0; + } + ++#endif /* CONFIG_IA32_EMULATION */ ++ ++ + int vc_get_rlimit_mask(uint32_t id, void __user *data) + { + static struct vcmd_ctx_rlimit_mask_v0 mask = { +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/limit_init.h linux-2.6.16-vs2.0.2-rc15/kernel/vserver/limit_init.h +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/limit_init.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/limit_init.h 2006-03-24 16:50:48 +0100 +@@ -1,6 +1,4 @@ + +-#include +- + + #include + +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/network.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/network.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/network.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/network.c 2006-03-24 16:50:48 +0100 +@@ -13,7 +13,6 @@ + * + */ + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/sched.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/sched.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/sched.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/sched.c 2006-03-24 16:50:48 +0100 +@@ -10,7 +10,6 @@ + * + */ + +-#include + #include + #include + #include +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/signal.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/signal.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/signal.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/signal.c 2006-04-03 05:31:18 +0200 +@@ -99,7 +99,8 @@ + set_current_state(TASK_INTERRUPTIBLE); + + wait: +- if (vx_info_state(vxi, VXS_SHUTDOWN|VXS_HASHED) == VXS_SHUTDOWN) ++ if (vx_info_state(vxi, ++ VXS_SHUTDOWN|VXS_HASHED|VXS_HELPER) == VXS_SHUTDOWN) + goto out; + if (signal_pending(current)) { + ret = -ERESTARTSYS; +@@ -119,6 +120,7 @@ + int vc_wait_exit(uint32_t id, void __user *data) + { + struct vx_info *vxi; ++ struct vcmd_wait_exit_v0 vc_data; + int ret; + + vxi = lookup_vx_info(id); +@@ -126,7 +128,12 @@ + return -ESRCH; + + ret = __wait_exit(vxi); ++ vc_data.reboot_cmd = vxi->reboot_cmd; ++ vc_data.exit_code = vxi->exit_code; + put_vx_info(vxi); ++ ++ if (copy_to_user (data, &vc_data, sizeof(vc_data))) ++ ret = -EFAULT; + return ret; + } + +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/switch.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/switch.c +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/switch.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/switch.c 2006-04-03 02:38:01 +0200 +@@ -14,7 +14,6 @@ + * + */ + +-#include + #include + #include + #include +@@ -131,10 +130,17 @@ + #endif + + switch (cmd) { ++#ifdef CONFIG_IA32_EMULATION ++ case VCMD_get_rlimit: ++ return __COMPAT(vc_get_rlimit, id, data, compat); ++ case VCMD_set_rlimit: ++ return __COMPAT(vc_set_rlimit, id, data, compat); ++#else + case VCMD_get_rlimit: + return vc_get_rlimit(id, data); + case VCMD_set_rlimit: + return vc_set_rlimit(id, data); ++#endif + case VCMD_get_rlimit_mask: + return vc_get_rlimit_mask(id, data); + +diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/vci_config.h linux-2.6.16-vs2.0.2-rc15/kernel/vserver/vci_config.h +--- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/vci_config.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/vci_config.h 2006-03-24 16:50:44 +0100 +@@ -1,7 +1,4 @@ + +-#include +- +- + enum { + VCI_KCBIT_LEGACY = 1, + VCI_KCBIT_LEGACYNET, From c4a0fdddf57949072d9a87d0dd485ddd1ae232c9 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 9 Apr 2006 21:17:21 +0000 Subject: [PATCH 034/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6385 --- debian/arch/amd64/config | 1 + debian/arch/amd64/config.amd64-k8-smp | 1 - debian/arch/amd64/config.em64t-p4-smp | 1 - debian/arch/amd64/vserver/config.amd64-k8 | 1 - debian/arch/amd64/vserver/config.em64t-p4 | 1 - debian/arch/amd64/xen-vserver/config.amd64-k8 | 1 - debian/arch/amd64/xen/config.amd64-k8 | 1 - debian/arch/amd64/xen/config.em64t-p4 | 1 - debian/arch/i386/config | 2 +- debian/arch/sparc/defines | 2 +- debian/bin/gencontrol.py | 5 + debian/changelog | 37 ++ debian/lib/python/debian_linux/config.py | 5 +- debian/lib/python/debian_linux/gencontrol.py | 4 +- debian/modules/gencontrol.py | 22 + debian/patches/2.6.16.2 | 588 ++++++++++++++++++ debian/patches/series/6 | 1 + debian/rules.real | 3 + 18 files changed, 665 insertions(+), 12 deletions(-) create mode 100644 debian/patches/2.6.16.2 create mode 100644 debian/patches/series/6 diff --git a/debian/arch/amd64/config b/debian/arch/amd64/config index dac97d81d..11993410a 100644 --- a/debian/arch/amd64/config +++ b/debian/arch/amd64/config @@ -1546,3 +1546,4 @@ CONFIG_EDAC_POLL=y CONFIG_EDAC_I82860=m CONFIG_EDAC_E752X=m CONFIG_EDAC_R82600=m +CONFIG_HOTPLUG_CPU=y diff --git a/debian/arch/amd64/config.amd64-k8-smp b/debian/arch/amd64/config.amd64-k8-smp index 3a1bc8296..65f6ccc63 100644 --- a/debian/arch/amd64/config.amd64-k8-smp +++ b/debian/arch/amd64/config.amd64-k8-smp @@ -20,7 +20,6 @@ CONFIG_FB_MATROX_MAVEN=m # CONFIG_SOUND_AWE32_SYNTH is not set CONFIG_FS_MBCACHE=m CONFIG_NEED_MULTIPLE_NODES=y -# CONFIG_HOTPLUG_CPU is not set CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_DIGIEPCA=m CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y diff --git a/debian/arch/amd64/config.em64t-p4-smp b/debian/arch/amd64/config.em64t-p4-smp index 3a45ed48a..b4e2aad99 100644 --- a/debian/arch/amd64/config.em64t-p4-smp +++ b/debian/arch/amd64/config.em64t-p4-smp @@ -20,7 +20,6 @@ CONFIG_R8169_VLAN=y CONFIG_SOUND_AWE32_SYNTH=m CONFIG_FS_MBCACHE=m CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_HOTPLUG_CPU is not set CONFIG_DIGIEPCA=m CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set diff --git a/debian/arch/amd64/vserver/config.amd64-k8 b/debian/arch/amd64/vserver/config.amd64-k8 index 3a1bc8296..65f6ccc63 100644 --- a/debian/arch/amd64/vserver/config.amd64-k8 +++ b/debian/arch/amd64/vserver/config.amd64-k8 @@ -20,7 +20,6 @@ CONFIG_FB_MATROX_MAVEN=m # CONFIG_SOUND_AWE32_SYNTH is not set CONFIG_FS_MBCACHE=m CONFIG_NEED_MULTIPLE_NODES=y -# CONFIG_HOTPLUG_CPU is not set CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_DIGIEPCA=m CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y diff --git a/debian/arch/amd64/vserver/config.em64t-p4 b/debian/arch/amd64/vserver/config.em64t-p4 index 3a45ed48a..b4e2aad99 100644 --- a/debian/arch/amd64/vserver/config.em64t-p4 +++ b/debian/arch/amd64/vserver/config.em64t-p4 @@ -20,7 +20,6 @@ CONFIG_R8169_VLAN=y CONFIG_SOUND_AWE32_SYNTH=m CONFIG_FS_MBCACHE=m CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_HOTPLUG_CPU is not set CONFIG_DIGIEPCA=m CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set diff --git a/debian/arch/amd64/xen-vserver/config.amd64-k8 b/debian/arch/amd64/xen-vserver/config.amd64-k8 index 3a1bc8296..65f6ccc63 100644 --- a/debian/arch/amd64/xen-vserver/config.amd64-k8 +++ b/debian/arch/amd64/xen-vserver/config.amd64-k8 @@ -20,7 +20,6 @@ CONFIG_FB_MATROX_MAVEN=m # CONFIG_SOUND_AWE32_SYNTH is not set CONFIG_FS_MBCACHE=m CONFIG_NEED_MULTIPLE_NODES=y -# CONFIG_HOTPLUG_CPU is not set CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_DIGIEPCA=m CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y diff --git a/debian/arch/amd64/xen/config.amd64-k8 b/debian/arch/amd64/xen/config.amd64-k8 index 3a1bc8296..65f6ccc63 100644 --- a/debian/arch/amd64/xen/config.amd64-k8 +++ b/debian/arch/amd64/xen/config.amd64-k8 @@ -20,7 +20,6 @@ CONFIG_FB_MATROX_MAVEN=m # CONFIG_SOUND_AWE32_SYNTH is not set CONFIG_FS_MBCACHE=m CONFIG_NEED_MULTIPLE_NODES=y -# CONFIG_HOTPLUG_CPU is not set CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_DIGIEPCA=m CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y diff --git a/debian/arch/amd64/xen/config.em64t-p4 b/debian/arch/amd64/xen/config.em64t-p4 index 3a45ed48a..b4e2aad99 100644 --- a/debian/arch/amd64/xen/config.em64t-p4 +++ b/debian/arch/amd64/xen/config.em64t-p4 @@ -20,7 +20,6 @@ CONFIG_R8169_VLAN=y CONFIG_SOUND_AWE32_SYNTH=m CONFIG_FS_MBCACHE=m CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_HOTPLUG_CPU is not set CONFIG_DIGIEPCA=m CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set diff --git a/debian/arch/i386/config b/debian/arch/i386/config index fd8014e31..d4984cb31 100644 --- a/debian/arch/i386/config +++ b/debian/arch/i386/config @@ -1764,7 +1764,7 @@ CONFIG_KEXEC=y CONFIG_HZ_1000=y CONFIG_HZ=1000 CONFIG_PHYSICAL_START=0x100000 -# CONFIG_HOTPLUG_CPU is not set +CONFIG_HOTPLUG_CPU=y CONFIG_HPET_EMULATE_RTC=y CONFIG_VIDEO_CX88_DVB=m CONFIG_VIDEO_CX88=m diff --git a/debian/arch/sparc/defines b/debian/arch/sparc/defines index 3c2b93476..ff6936f66 100644 --- a/debian/arch/sparc/defines +++ b/debian/arch/sparc/defines @@ -3,7 +3,7 @@ flavours: sparc32 sparc64 sparc64-smp -kernel-headers-dirs: sparc sparc64 +kernel-header-dirs: sparc sparc64 [image] suggests: silo, fdutils diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 454d579c3..0f60f47a0 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -5,6 +5,11 @@ import debian_linux.gencontrol from debian_linux.debian import * class gencontrol(debian_linux.gencontrol.gencontrol): + def __init__(self): + super(gencontrol, self).__init__() + self.changelog = read_changelog() + self.version, self.abiname, self.changelog_vars = self.process_changelog({}) + def do_main_setup(self, vars, makeflags): vars.update(self.config['image',]) diff --git a/debian/changelog b/debian/changelog index c50a5d084..bc37a76ab 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,43 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- Bastian Blank Thu, 23 Mar 2006 21:40:17 +0100 +linux-2.6 (2.6.16-6) UNRELEASED; urgency=low + + [ Bastian Blank ] + * Provide version infos in support package and don't longer rely on the + changelog. + * [amd64/i386] Enable cpu hotplug support. + + [ maximilian attems ] + * Add stable release 2.6.16.2: + - PCMCIA_SPECTRUM must select FW_LOADER + - drivers/net/wireless/ipw2200.c: fix an array overun + - AIRO{,_CS} <-> CRYPTO fixes + - tlclk: fix handling of device major + - fbcon: Fix big-endian bogosity in slow_imageblit() + - Fix NULL pointer dereference in node_read_numastat() + - USB: EHCI full speed ISO bugfixes + - Mark longhaul driver as broken. + - fib_trie.c node freeing fix + - USB: Fix irda-usb use after use + - sysfs: zero terminate sysfs write buffers (CVE-2006-1055) + - USB: usbcore: usb_set_configuration oops (NULL ptr dereference) + - pcmcia: permit single-character-identifiers + - hostap: Fix EAPOL frame encryption + - wrong error path in dup_fd() leading to oopses in RCU + - {ip, nf}_conntrack_netlink: fix expectation notifier unregistration + - isicom must select FW_LOADER + - knfsd: Correct reserved reply space for read requests. + - Fix module refcount leak in __set_personality() + - sbp2: fix spinlock recursion + - powerpc: make ISA floppies work again + - opti9x - Fix compile without CONFIG_PNP + - Add default entry for CTL Travel Master U553W + - Fix the p4-clockmod N60 errata workaround. + - kdump proc vmcore size oveflow fix + + -- Bastian Blank Fri, 7 Apr 2006 22:58:17 +0200 + linux-2.6 (2.6.16-5) unstable; urgency=low [ Bastian Blank ] diff --git a/debian/lib/python/debian_linux/config.py b/debian/lib/python/debian_linux/config.py index b6b02f291..fcff508e5 100644 --- a/debian/lib/python/debian_linux/config.py +++ b/debian/lib/python/debian_linux/config.py @@ -1,6 +1,9 @@ import os, os.path, re, sys, textwrap, ConfigParser -__all__ = 'config_reader', +__all__ = [ + 'config_parser', + 'config_reader', +] _marker = object() diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index 5d6ebecd8..93dac7593 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -15,10 +15,8 @@ class gencontrol(object): makefile_targets = ('binary-arch', 'build', 'setup', 'source') def __init__(self, underlay = None): - self.changelog = read_changelog() self.config = config_reader([underlay, "debian/arch"]) self.templates = templates() - self.version, self.abiname, self.changelog_vars = self.process_changelog({}) def __call__(self): packages = packages_list() @@ -43,6 +41,7 @@ class gencontrol(object): 'SOURCEVERSION': self.version['source'], 'UPSTREAMVERSION': self.version['upstream'], 'ABINAME': self.abiname, + # TODO: Don't read this here, this is linux-2.6 specific 'REVISIONS': ' '.join([i['Version']['debian'] for i in self.changelog[::-1]]), } @@ -203,6 +202,7 @@ class gencontrol(object): def do_flavour_packages(self, packages, makefile, arch, subarch, flavour, vars, makeflags, extra): pass + # TODO: Move away, linux-2.6 specific; unify with modules process_config_version def process_changelog(self, in_vars): ret = [None, None, None] ret[0] = version = self.changelog[0]['Version'] diff --git a/debian/modules/gencontrol.py b/debian/modules/gencontrol.py index 8cc05d71e..432f2f129 100755 --- a/debian/modules/gencontrol.py +++ b/debian/modules/gencontrol.py @@ -2,15 +2,27 @@ import sys sys.path.append(sys.path[0] + "/../lib/python") import debian_linux.gencontrol +from debian_linux.config import * from debian_linux.debian import * class gencontrol(debian_linux.gencontrol.gencontrol): + # TODO: workaround + changelog = [] + + def __init__(self, config): + super(gencontrol, self).__init__(config) + self.config_version = config_parser({}, [sys.path[0] + "/../version"]) + self.version, self.abiname, self.changelog_vars = self.process_config_version() + def do_main_packages(self, packages): vars = self.changelog_vars main = self.templates["control.main"] packages.extend(self.process_packages(main, vars)) + # TODO + l1 = ['linux-support-%s%s' % (self.version['upstream'], self.abiname)] + packages['source']['Build-Depends'].extend(l1) l = ['linux-headers-%s%s-all-%s [%s]' % (self.version['upstream'], self.abiname, arch, arch) for arch in self.config['base',]['arches']] packages['source']['Build-Depends'].extend(l) @@ -41,5 +53,15 @@ class gencontrol(debian_linux.gencontrol.gencontrol): makefile.append(("build-%s-%s-%s-real:" % (arch, subarch, flavour), cmds_build)) makefile.append(("setup-%s-%s-%s-real:" % (arch, subarch, flavour), cmds_setup)) + def process_config_version(self): + # TODO: unify with process_changelog + vars = self.config_version['version',] + version = parse_version(vars['source']) + vars['upstreamversion'] = version['upstream'] + vars['version'] = version['version'] + vars['source_upstream'] = version['source_upstream'] + vars['major'] = version['major'] + return version, vars['abiname'], vars + if __name__ == '__main__': gencontrol(sys.path[0] + "/../arch")() diff --git a/debian/patches/2.6.16.2 b/debian/patches/2.6.16.2 new file mode 100644 index 000000000..25fbf5781 --- /dev/null +++ b/debian/patches/2.6.16.2 @@ -0,0 +1,588 @@ +diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig +index 26892d2..16f2e35 100644 +--- a/arch/i386/kernel/cpu/cpufreq/Kconfig ++++ b/arch/i386/kernel/cpu/cpufreq/Kconfig +@@ -203,6 +203,7 @@ config X86_LONGRUN + config X86_LONGHAUL + tristate "VIA Cyrix III Longhaul" + select CPU_FREQ_TABLE ++ depends on BROKEN + help + This adds the CPUFreq driver for VIA Samuel/CyrixIII, + VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T +diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +index cc73a7a..ebe1848 100644 +--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c ++++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +@@ -244,7 +244,7 @@ static int cpufreq_p4_cpu_init(struct cp + for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { + if ((i<2) && (has_N44_O17_errata[policy->cpu])) + p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; +- else if (has_N60_errata[policy->cpu] && p4clockmod_table[i].frequency < 2000000) ++ else if (has_N60_errata[policy->cpu] && ((stock_freq * i)/8) < 2000000) + p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; + else + p4clockmod_table[i].frequency = (stock_freq * i)/8; +diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c +index ba92bab..4c4449b 100644 +--- a/arch/powerpc/kernel/pci_64.c ++++ b/arch/powerpc/kernel/pci_64.c +@@ -78,6 +78,7 @@ int global_phb_number; /* Global phb co + + /* Cached ISA bridge dev. */ + struct pci_dev *ppc64_isabridge_dev = NULL; ++EXPORT_SYMBOL_GPL(ppc64_isabridge_dev); + + static void fixup_broken_pcnet32(struct pci_dev* dev) + { +diff --git a/drivers/base/node.c b/drivers/base/node.c +index 16c513a..c80c3ae 100644 +--- a/drivers/base/node.c ++++ b/drivers/base/node.c +@@ -106,7 +106,7 @@ static ssize_t node_read_numastat(struct + other_node = 0; + for (i = 0; i < MAX_NR_ZONES; i++) { + struct zone *z = &pg->node_zones[i]; +- for (cpu = 0; cpu < NR_CPUS; cpu++) { ++ for_each_online_cpu(cpu) { + struct per_cpu_pageset *ps = zone_pcp(z,cpu); + numa_hit += ps->numa_hit; + numa_miss += ps->numa_miss; +diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig +index 05ba410..8b72a61 100644 +--- a/drivers/char/Kconfig ++++ b/drivers/char/Kconfig +@@ -187,6 +187,7 @@ config MOXA_SMARTIO + config ISI + tristate "Multi-Tech multiport card support (EXPERIMENTAL)" + depends on SERIAL_NONSTANDARD ++ select FW_LOADER + help + This is a driver for the Multi-Tech cards which provide several + serial ports. The driver is experimental and can currently only be +diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c +index 4c27218..2546637 100644 +--- a/drivers/char/tlclk.c ++++ b/drivers/char/tlclk.c +@@ -767,6 +767,7 @@ static int __init tlclk_init(void) + printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major); + return ret; + } ++ tlclk_major = ret; + alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); + if (!alarm_events) + goto out1; +diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c +index eca92eb..d83248e 100644 +--- a/drivers/ieee1394/sbp2.c ++++ b/drivers/ieee1394/sbp2.c +@@ -495,22 +495,17 @@ static struct sbp2_command_info *sbp2uti + /* + * This function finds the sbp2_command for a given outstanding SCpnt. + * Only looks at the inuse list. ++ * Must be called with scsi_id->sbp2_command_orb_lock held. + */ +-static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt) ++static struct sbp2_command_info *sbp2util_find_command_for_SCpnt( ++ struct scsi_id_instance_data *scsi_id, void *SCpnt) + { + struct sbp2_command_info *command; +- unsigned long flags; + +- spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); +- if (!list_empty(&scsi_id->sbp2_command_orb_inuse)) { +- list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) { +- if (command->Current_SCpnt == SCpnt) { +- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); ++ if (!list_empty(&scsi_id->sbp2_command_orb_inuse)) ++ list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) ++ if (command->Current_SCpnt == SCpnt) + return command; +- } +- } +- } +- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + return NULL; + } + +@@ -579,17 +574,15 @@ static void sbp2util_free_command_dma(st + + /* + * This function moves a command to the completed orb list. ++ * Must be called with scsi_id->sbp2_command_orb_lock held. + */ +-static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, +- struct sbp2_command_info *command) ++static void sbp2util_mark_command_completed( ++ struct scsi_id_instance_data *scsi_id, ++ struct sbp2_command_info *command) + { +- unsigned long flags; +- +- spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); + list_del(&command->list); + sbp2util_free_command_dma(command); + list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed); +- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + } + + /* +@@ -2177,7 +2170,9 @@ static int sbp2_handle_status_write(stru + * Matched status with command, now grab scsi command pointers and check status + */ + SCpnt = command->Current_SCpnt; ++ spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); + sbp2util_mark_command_completed(scsi_id, command); ++ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + + if (SCpnt) { + +@@ -2513,6 +2508,7 @@ static int sbp2scsi_abort(struct scsi_cm + (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; + struct sbp2scsi_host_info *hi = scsi_id->hi; + struct sbp2_command_info *command; ++ unsigned long flags; + + SBP2_ERR("aborting sbp2 command"); + scsi_print_command(SCpnt); +@@ -2523,6 +2519,7 @@ static int sbp2scsi_abort(struct scsi_cm + * Right now, just return any matching command structures + * to the free pool. + */ ++ spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); + command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt); + if (command) { + SBP2_DEBUG("Found command to abort"); +@@ -2540,6 +2537,7 @@ static int sbp2scsi_abort(struct scsi_cm + command->Current_done(command->Current_SCpnt); + } + } ++ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + + /* + * Initiate a fetch agent reset. +diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c +index 8936058..6e2ec56 100644 +--- a/drivers/net/irda/irda-usb.c ++++ b/drivers/net/irda/irda-usb.c +@@ -740,7 +740,7 @@ static void irda_usb_receive(struct urb + struct sk_buff *newskb; + struct sk_buff *dataskb; + struct urb *next_urb; +- int docopy; ++ unsigned int len, docopy; + + IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); + +@@ -851,10 +851,11 @@ static void irda_usb_receive(struct urb + dataskb->dev = self->netdev; + dataskb->mac.raw = dataskb->data; + dataskb->protocol = htons(ETH_P_IRDA); ++ len = dataskb->len; + netif_rx(dataskb); + + /* Keep stats up to date */ +- self->stats.rx_bytes += dataskb->len; ++ self->stats.rx_bytes += len; + self->stats.rx_packets++; + self->netdev->last_rx = jiffies; + +diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig +index ef85d76..8101657 100644 +--- a/drivers/net/wireless/Kconfig ++++ b/drivers/net/wireless/Kconfig +@@ -239,7 +239,8 @@ config IPW2200_DEBUG + + config AIRO + tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" +- depends on NET_RADIO && ISA_DMA_API && CRYPTO && (PCI || BROKEN) ++ depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN) ++ select CRYPTO + ---help--- + This is the standard Linux driver to support Cisco/Aironet ISA and + PCI 802.11 wireless cards. +@@ -374,6 +375,7 @@ config PCMCIA_HERMES + config PCMCIA_SPECTRUM + tristate "Symbol Spectrum24 Trilogy PCMCIA card support" + depends on NET_RADIO && PCMCIA && HERMES ++ select FW_LOADER + ---help--- + + This is a driver for 802.11b cards using RAM-loadable Symbol +@@ -387,6 +389,7 @@ config PCMCIA_SPECTRUM + config AIRO_CS + tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" + depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) ++ select CRYPTO + ---help--- + This is the standard Linux driver to support Cisco/Aironet PCMCIA + 802.11 wireless cards. This driver is the same as the Aironet +diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c +index 4a85e63..5f398bd 100644 +--- a/drivers/net/wireless/hostap/hostap_80211_tx.c ++++ b/drivers/net/wireless/hostap/hostap_80211_tx.c +@@ -469,7 +469,7 @@ int hostap_master_start_xmit(struct sk_b + } + + if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt && +- !(fc & IEEE80211_FCTL_VERS)) { ++ !(fc & IEEE80211_FCTL_PROTECTED)) { + no_encrypt = 1; + PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing " + "unencrypted EAPOL frame\n", dev->name); +diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c +index 287676a..aa6f3a4 100644 +--- a/drivers/net/wireless/ipw2200.c ++++ b/drivers/net/wireless/ipw2200.c +@@ -9956,9 +9956,8 @@ static int ipw_ethtool_set_eeprom(struct + return -EINVAL; + down(&p->sem); + memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); +- for (i = IPW_EEPROM_DATA; +- i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++) +- ipw_write8(p, i, p->eeprom[i]); ++ for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++) ++ ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]); + up(&p->sem); + return 0; + } +diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c +index bb96ce1..a4333a8 100644 +--- a/drivers/pcmcia/ds.c ++++ b/drivers/pcmcia/ds.c +@@ -546,7 +546,7 @@ static int pcmcia_device_query(struct pc + tmp = vers1->str + vers1->ofs[i]; + + length = strlen(tmp) + 1; +- if ((length < 3) || (length > 255)) ++ if ((length < 2) || (length > 255)) + continue; + + p_dev->prod_id[i] = kmalloc(sizeof(char) * length, +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index 7135e54..96cabeb 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1388,11 +1388,13 @@ free_interfaces: + if (dev->state != USB_STATE_ADDRESS) + usb_disable_device (dev, 1); // Skip ep0 + +- i = dev->bus_mA - cp->desc.bMaxPower * 2; +- if (i < 0) +- dev_warn(&dev->dev, "new config #%d exceeds power " +- "limit by %dmA\n", +- configuration, -i); ++ if (cp) { ++ i = dev->bus_mA - cp->desc.bMaxPower * 2; ++ if (i < 0) ++ dev_warn(&dev->dev, "new config #%d exceeds power " ++ "limit by %dmA\n", ++ configuration, -i); ++ } + + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_CONFIGURATION, 0, configuration, 0, +diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c +index ebcca97..88419c6 100644 +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -707,6 +707,7 @@ iso_stream_init ( + } else { + u32 addr; + int think_time; ++ int hs_transfers; + + addr = dev->ttport << 24; + if (!ehci_is_TDI(ehci) +@@ -719,6 +720,7 @@ iso_stream_init ( + think_time = dev->tt ? dev->tt->think_time : 0; + stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time ( + dev->speed, is_input, 1, maxp)); ++ hs_transfers = max (1u, (maxp + 187) / 188); + if (is_input) { + u32 tmp; + +@@ -727,12 +729,11 @@ iso_stream_init ( + stream->usecs = HS_USECS_ISO (1); + stream->raw_mask = 1; + +- /* pessimistic c-mask */ +- tmp = usb_calc_bus_time (USB_SPEED_FULL, 1, 0, maxp) +- / (125 * 1000); +- stream->raw_mask |= 3 << (tmp + 9); ++ /* c-mask as specified in USB 2.0 11.18.4 3.c */ ++ tmp = (1 << (hs_transfers + 2)) - 1; ++ stream->raw_mask |= tmp << (8 + 2); + } else +- stream->raw_mask = smask_out [maxp / 188]; ++ stream->raw_mask = smask_out [hs_transfers - 1]; + bandwidth = stream->usecs + stream->c_usecs; + bandwidth /= 1 << (interval + 2); + +diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c +index 910e233..8ba6152 100644 +--- a/drivers/video/cfbimgblt.c ++++ b/drivers/video/cfbimgblt.c +@@ -169,7 +169,7 @@ static inline void slow_imageblit(const + + while (j--) { + l--; +- color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor; ++ color = (*s & (1 << l)) ? fgcolor : bgcolor; + val |= FB_SHIFT_HIGH(color, shift); + + /* Did the bitshift spill bits to the next long? */ +diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c +index 6d2dfed..f61142a 100644 +--- a/fs/nfsd/nfs3proc.c ++++ b/fs/nfsd/nfs3proc.c +@@ -682,7 +682,7 @@ static struct svc_procedure nfsd_proced + PROC(lookup, dirop, dirop, fhandle2, RC_NOCACHE, ST+FH+pAT+pAT), + PROC(access, access, access, fhandle, RC_NOCACHE, ST+pAT+1), + PROC(readlink, readlink, readlink, fhandle, RC_NOCACHE, ST+pAT+1+NFS3_MAXPATHLEN/4), +- PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE), ++ PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE/4), + PROC(write, write, write, fhandle, RC_REPLBUFF, ST+WC+4), + PROC(create, create, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), + PROC(mkdir, mkdir, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index 6d63f1d..ca8a4c4 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -975,7 +975,7 @@ struct nfsd4_voidargs { int dummy; }; + */ + static struct svc_procedure nfsd_procedures4[2] = { + PROC(null, void, void, void, RC_NOCACHE, 1), +- PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE) ++ PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE/4) + }; + + struct svc_version nfsd_version4 = { +diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c +index 3e6b75c..06cd0db 100644 +--- a/fs/nfsd/nfsproc.c ++++ b/fs/nfsd/nfsproc.c +@@ -553,7 +553,7 @@ static struct svc_procedure nfsd_proced + PROC(none, void, void, none, RC_NOCACHE, ST), + PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT), + PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4), +- PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE), ++ PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4), + PROC(none, void, void, none, RC_NOCACHE, ST), + PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), + PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), +diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c +index 4063fb3..164a7d0 100644 +--- a/fs/proc/vmcore.c ++++ b/fs/proc/vmcore.c +@@ -103,8 +103,8 @@ static ssize_t read_vmcore(struct file * + size_t buflen, loff_t *fpos) + { + ssize_t acc = 0, tmp; +- size_t tsz, nr_bytes; +- u64 start; ++ size_t tsz; ++ u64 start, nr_bytes; + struct vmcore *curr_m = NULL; + + if (buflen == 0 || *fpos >= vmcore_size) +diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c +index d0e3d84..2ecc58c 100644 +--- a/fs/sysfs/file.c ++++ b/fs/sysfs/file.c +@@ -183,7 +183,7 @@ fill_write_buffer(struct sysfs_buffer * + return -ENOMEM; + + if (count >= PAGE_SIZE) +- count = PAGE_SIZE; ++ count = PAGE_SIZE - 1; + error = copy_from_user(buffer->page,buf,count); + buffer->needs_read_fill = 1; + return error ? -EFAULT : count; +diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h +index e258778..608164c 100644 +--- a/include/asm-powerpc/floppy.h ++++ b/include/asm-powerpc/floppy.h +@@ -35,6 +35,7 @@ + #ifdef CONFIG_PCI + + #include ++#include /* for ppc64_isabridge_dev */ + + #define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io) + +@@ -52,12 +53,12 @@ static __inline__ int powerpc_fd_dma_set + if (bus_addr + && (addr != prev_addr || size != prev_size || dir != prev_dir)) { + /* different from last time -- unmap prev */ +- pci_unmap_single(NULL, bus_addr, prev_size, prev_dir); ++ pci_unmap_single(ppc64_isabridge_dev, bus_addr, prev_size, prev_dir); + bus_addr = 0; + } + + if (!bus_addr) /* need to map it */ +- bus_addr = pci_map_single(NULL, addr, size, dir); ++ bus_addr = pci_map_single(ppc64_isabridge_dev, addr, size, dir); + + /* remember this one as prev */ + prev_addr = addr; +diff --git a/include/linux/fb.h b/include/linux/fb.h +index 2cb19e6..2fdd8ae 100644 +--- a/include/linux/fb.h ++++ b/include/linux/fb.h +@@ -839,12 +839,10 @@ struct fb_info { + #define FB_LEFT_POS(bpp) (32 - bpp) + #define FB_SHIFT_HIGH(val, bits) ((val) >> (bits)) + #define FB_SHIFT_LOW(val, bits) ((val) << (bits)) +-#define FB_BIT_NR(b) (7 - (b)) + #else + #define FB_LEFT_POS(bpp) (0) + #define FB_SHIFT_HIGH(val, bits) ((val) << (bits)) + #define FB_SHIFT_LOW(val, bits) ((val) >> (bits)) +-#define FB_BIT_NR(b) (b) + #endif + + /* +diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h +index aa6322d..6c1e347 100644 +--- a/include/linux/proc_fs.h ++++ b/include/linux/proc_fs.h +@@ -78,7 +78,7 @@ struct kcore_list { + struct vmcore { + struct list_head list; + unsigned long long paddr; +- unsigned long size; ++ unsigned long long size; + loff_t offset; + }; + +diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c +index 867d6db..c01cead 100644 +--- a/kernel/exec_domain.c ++++ b/kernel/exec_domain.c +@@ -140,6 +140,7 @@ __set_personality(u_long personality) + ep = lookup_exec_domain(personality); + if (ep == current_thread_info()->exec_domain) { + current->personality = personality; ++ module_put(ep->module); + return 0; + } + +diff --git a/kernel/fork.c b/kernel/fork.c +index b373322..9d4e0d8 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -720,7 +720,7 @@ out_release: + free_fdset (new_fdt->open_fds, new_fdt->max_fdset); + free_fd_array(new_fdt->fd, new_fdt->max_fds); + kmem_cache_free(files_cachep, newf); +- goto out; ++ return NULL; + } + + static int copy_files(unsigned long clone_flags, struct task_struct * tsk) +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index e320b32..24009be 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -314,11 +314,6 @@ static void __leaf_free_rcu(struct rcu_h + kfree(container_of(head, struct leaf, rcu)); + } + +-static inline void free_leaf(struct leaf *leaf) +-{ +- call_rcu(&leaf->rcu, __leaf_free_rcu); +-} +- + static void __leaf_info_free_rcu(struct rcu_head *head) + { + kfree(container_of(head, struct leaf_info, rcu)); +@@ -357,7 +352,12 @@ static void __tnode_free_rcu(struct rcu_ + + static inline void tnode_free(struct tnode *tn) + { +- call_rcu(&tn->rcu, __tnode_free_rcu); ++ if(IS_LEAF(tn)) { ++ struct leaf *l = (struct leaf *) tn; ++ call_rcu_bh(&l->rcu, __leaf_free_rcu); ++ } ++ else ++ call_rcu(&tn->rcu, __tnode_free_rcu); + } + + static struct leaf *leaf_new(void) +diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c +index e0b5926..d4e6d0a 100644 +--- a/net/ipv4/netfilter/ip_conntrack_netlink.c ++++ b/net/ipv4/netfilter/ip_conntrack_netlink.c +@@ -1619,7 +1619,7 @@ static void __exit ctnetlink_exit(void) + printk("ctnetlink: unregistering from nfnetlink.\n"); + + #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS +- ip_conntrack_unregister_notifier(&ctnl_notifier_exp); ++ ip_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); + ip_conntrack_unregister_notifier(&ctnl_notifier); + #endif + +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 9ff3463..40edeef 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -1641,7 +1641,7 @@ static void __exit ctnetlink_exit(void) + printk("ctnetlink: unregistering from nfnetlink.\n"); + + #ifdef CONFIG_NF_CONNTRACK_EVENTS +- nf_conntrack_unregister_notifier(&ctnl_notifier_exp); ++ nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); + nf_conntrack_unregister_notifier(&ctnl_notifier); + #endif + +diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c +index 63d96be..65b28cb 100644 +--- a/sound/isa/opti9xx/opti92x-ad1848.c ++++ b/sound/isa/opti9xx/opti92x-ad1848.c +@@ -2088,9 +2088,11 @@ static int __init alsa_card_opti9xx_init + int error; + struct platform_device *device; + ++#ifdef CONFIG_PNP + pnp_register_card_driver(&opti9xx_pnpc_driver); + if (snd_opti9xx_pnp_is_probed) + return 0; ++#endif + if (! is_isapnp_selected()) { + error = platform_driver_register(&snd_opti9xx_driver); + if (error < 0) +@@ -2102,7 +2104,9 @@ static int __init alsa_card_opti9xx_init + } + platform_driver_unregister(&snd_opti9xx_driver); + } ++#ifdef CONFIG_PNP + pnp_unregister_card_driver(&opti9xx_pnpc_driver); ++#endif + #ifdef MODULE + printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n"); + #endif +@@ -2115,7 +2119,9 @@ static void __exit alsa_card_opti9xx_exi + platform_device_unregister(snd_opti9xx_platform_device); + platform_driver_unregister(&snd_opti9xx_driver); + } ++#ifdef CONFIG_PNP + pnp_unregister_card_driver(&opti9xx_pnpc_driver); ++#endif + } + + module_init(alsa_card_opti9xx_init) +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index b767552..d5cd3a1 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -2948,6 +2948,8 @@ static struct hda_board_config alc260_cf + { .modelname = "basic", .config = ALC260_BASIC }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, + .config = ALC260_BASIC }, /* Sony VAIO */ ++ { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, ++ .config = ALC260_BASIC }, /* CTL Travel Master U553W */ + { .modelname = "hp", .config = ALC260_HP }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, diff --git a/debian/patches/series/6 b/debian/patches/series/6 new file mode 100644 index 000000000..c5667a7c9 --- /dev/null +++ b/debian/patches/series/6 @@ -0,0 +1 @@ ++ 2.6.16.2 diff --git a/debian/rules.real b/debian/rules.real index 9fce54b8f..14568eed5 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -320,12 +320,15 @@ install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR): $(STAMPS_DIR)/build-$(ARCH)-$(SUBA install-support: PACKAGE_NAME = linux-support-$(UPSTREAMVERSION)$(ABINAME) install-support: DH_OPTIONS = -p$(PACKAGE_NAME) +install-support: PACKAGE_DIR = $(CURDIR)/debian/$(PACKAGE_NAME) install-support: dh_testdir dh_testroot + dh_clean -k -d chmod a+x debian/modules/gencontrol.py dh_install debian/arch debian/lib debian/modules /usr/src/$(PACKAGE_NAME) dh_python -V 2.4 /usr/src/$(PACKAGE_NAME)/lib/python + echo -e "[version]\nsource: $(SOURCEVERSION)\nabiname: $(ABINAME)" > $(PACKAGE_DIR)/usr/src/$(PACKAGE_NAME)/version $(MAKE) -f debian/rules.real install-base install-image-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE): REAL_VERSION = $(UPSTREAMVERSION)$(ABINAME)$(LOCALVERSION) From a985a8b94cca5aa776b29a275a42e324690fda47 Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Mon, 10 Apr 2006 23:13:26 +0000 Subject: [PATCH 035/108] unset CONFIG_SECCOMP - it doesn't buy us anything - useless overhead on context-switch svn path=/dists/trunk/linux-2.6/; revision=6391 --- debian/arch/config | 2 +- debian/arch/powerpc/config.powerpc64 | 1 - debian/arch/powerpc/vserver/config.powerpc64 | 1 - debian/changelog | 6 +++++- debian/templates/control.source.in | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/debian/arch/config b/debian/arch/config index 9f9ec5977..ae0e97fe7 100644 --- a/debian/arch/config +++ b/debian/arch/config @@ -100,7 +100,7 @@ CONFIG_CRYPTO_CRC32C=m CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m -CONFIG_SECCOMP=y +# CONFIG_SECCOMP is not set # CONFIG_TCG_TPM is not set CONFIG_TCG_ATMEL=m CONFIG_TCG_NSC=m diff --git a/debian/arch/powerpc/config.powerpc64 b/debian/arch/powerpc/config.powerpc64 index c2b408e64..0a547056e 100644 --- a/debian/arch/powerpc/config.powerpc64 +++ b/debian/arch/powerpc/config.powerpc64 @@ -62,7 +62,6 @@ CONFIG_SCHED_SMT=y CONFIG_SCSI_QLOGIC_1280_1040=y CONFIG_SCSI_QLOGIC_1280=m CONFIG_SCSI_IBMVSCSI=m -CONFIG_SECCOMP=y # CONFIG_SERIAL_ICOM is not set CONFIG_SMP=y CONFIG_STOP_MACHINE=y diff --git a/debian/arch/powerpc/vserver/config.powerpc64 b/debian/arch/powerpc/vserver/config.powerpc64 index c2b408e64..0a547056e 100644 --- a/debian/arch/powerpc/vserver/config.powerpc64 +++ b/debian/arch/powerpc/vserver/config.powerpc64 @@ -62,7 +62,6 @@ CONFIG_SCHED_SMT=y CONFIG_SCSI_QLOGIC_1280_1040=y CONFIG_SCSI_QLOGIC_1280=m CONFIG_SCSI_IBMVSCSI=m -CONFIG_SECCOMP=y # CONFIG_SERIAL_ICOM is not set CONFIG_SMP=y CONFIG_STOP_MACHINE=y diff --git a/debian/changelog b/debian/changelog index bc37a76ab..12d24789b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,12 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low + [ Bastian Blank ] * - -- Bastian Blank Thu, 23 Mar 2006 21:40:17 +0100 + [ maximilian attems ] + * Unset CONFIG_SECCOMP. + + -- maximilian attems Tue, 11 Apr 2006 01:07:28 +0200 linux-2.6 (2.6.16-6) UNRELEASED; urgency=low diff --git a/debian/templates/control.source.in b/debian/templates/control.source.in index 5c8b3e5bd..337e1218f 100644 --- a/debian/templates/control.source.in +++ b/debian/templates/control.source.in @@ -2,7 +2,7 @@ Source: linux-@major@ Section: devel Priority: optional Maintainer: Debian Kernel Team -Uploaders: Andres Salomon , Bastian Blank , Simon Horman , Sven Luther , Jonas Smedegaard , Norbert Tretkowski , Frederik Schüler +Uploaders: Andres Salomon , Bastian Blank , Simon Horman , Sven Luther , Jonas Smedegaard , Norbert Tretkowski , Frederik Schüler , maximilian attems Standards-Version: 3.6.1.0 Build-Depends: debhelper (>= 4.1.0), module-init-tools, dpkg-dev (>= 1.10.23), debianutils (>= 1.6), bzip2, sparc-utils [sparc], kernel-package (>= 10.035), ocaml-interp, python, python2.4-minimal Build-Depends-Indep: docbook-utils, gs, transfig, xmlto From 29b55afc58e379b253a0aa6021681af30fa400c8 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Tue, 11 Apr 2006 10:16:23 +0000 Subject: [PATCH 036/108] Partialy revert r6391. Unrelated and not described change. svn path=/dists/trunk/linux-2.6/; revision=6392 --- debian/templates/control.source.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/templates/control.source.in b/debian/templates/control.source.in index 337e1218f..5c8b3e5bd 100644 --- a/debian/templates/control.source.in +++ b/debian/templates/control.source.in @@ -2,7 +2,7 @@ Source: linux-@major@ Section: devel Priority: optional Maintainer: Debian Kernel Team -Uploaders: Andres Salomon , Bastian Blank , Simon Horman , Sven Luther , Jonas Smedegaard , Norbert Tretkowski , Frederik Schüler , maximilian attems +Uploaders: Andres Salomon , Bastian Blank , Simon Horman , Sven Luther , Jonas Smedegaard , Norbert Tretkowski , Frederik Schüler Standards-Version: 3.6.1.0 Build-Depends: debhelper (>= 4.1.0), module-init-tools, dpkg-dev (>= 1.10.23), debianutils (>= 1.6), bzip2, sparc-utils [sparc], kernel-package (>= 10.035), ocaml-interp, python, python2.4-minimal Build-Depends-Indep: docbook-utils, gs, transfig, xmlto From 237775ced295729e5824b4e5047dbee8a2c5f4a1 Mon Sep 17 00:00:00 2001 From: "Christian T. Steigies" Date: Fri, 14 Apr 2006 13:46:07 +0000 Subject: [PATCH 037/108] 2.6.16 patch for m68k svn path=/dists/trunk/linux-2.6/; revision=6416 --- debian/patches/m68k-2.6.16.patch | 9001 ++++++++++++++++++++++++++++++ 1 file changed, 9001 insertions(+) create mode 100644 debian/patches/m68k-2.6.16.patch diff --git a/debian/patches/m68k-2.6.16.patch b/debian/patches/m68k-2.6.16.patch new file mode 100644 index 000000000..fcbb615cb --- /dev/null +++ b/debian/patches/m68k-2.6.16.patch @@ -0,0 +1,9001 @@ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/Makefile linux-m68k/Makefile +--- linux-i386/Makefile 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/Makefile 2006-04-11 16:31:06.000000000 +0200 +@@ -172,7 +172,7 @@ + # Default value for CROSS_COMPILE is not to prefix executables + # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile + +-ARCH ?= $(SUBARCH) ++ARCH ?= m68k + CROSS_COMPILE ?= + + # Architecture as present in compile.h +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/Kconfig linux-m68k/arch/m68k/Kconfig +--- linux-i386/arch/m68k/Kconfig 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/Kconfig 2006-04-11 16:32:18.000000000 +0200 +@@ -596,7 +596,7 @@ + + config SERIAL167 + bool "CD2401 support for MVME166/7 serial ports" +- depends on MVME16x && BROKEN ++ depends on MVME16x + help + This is the driver for the serial ports on the Motorola MVME166, + 167, and 172 boards. Everyone using one of these boards should say +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/amiga/amiga_ksyms.c linux-m68k/arch/m68k/amiga/amiga_ksyms.c +--- linux-i386/arch/m68k/amiga/amiga_ksyms.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/amiga/amiga_ksyms.c 2006-01-28 23:52:25.000000000 +0100 +@@ -23,8 +23,6 @@ + EXPORT_SYMBOL(amiga_chip_size); + EXPORT_SYMBOL(amiga_audio_period); + EXPORT_SYMBOL(amiga_audio_min_period); +-EXPORT_SYMBOL(amiga_do_irq); +-EXPORT_SYMBOL(amiga_do_irq_list); + + #ifdef CONFIG_AMIGA_PCMCIA + EXPORT_SYMBOL(pcmcia_reset); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/amiga/amiints.c linux-m68k/arch/m68k/amiga/amiints.c +--- linux-i386/arch/m68k/amiga/amiints.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/amiga/amiints.c 2006-04-11 16:32:18.000000000 +0200 +@@ -35,60 +35,29 @@ + * /Jes + */ + +-#include +-#include +-#include +-#include + #include ++#include + #include +-#include + +-#include + #include + #include + #include + #include + #include + +-extern int cia_request_irq(struct ciabase *base,int irq, +- irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id); +-extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id); +-extern void cia_init_IRQ(struct ciabase *base); +-extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p); +- +-/* irq node variables for amiga interrupt sources */ +-static irq_node_t *ami_irq_list[AMI_STD_IRQS]; +- +-static unsigned short amiga_intena_vals[AMI_STD_IRQS] = { +- [IRQ_AMIGA_VERTB] = IF_VERTB, +- [IRQ_AMIGA_COPPER] = IF_COPER, +- [IRQ_AMIGA_AUD0] = IF_AUD0, +- [IRQ_AMIGA_AUD1] = IF_AUD1, +- [IRQ_AMIGA_AUD2] = IF_AUD2, +- [IRQ_AMIGA_AUD3] = IF_AUD3, +- [IRQ_AMIGA_BLIT] = IF_BLIT, +- [IRQ_AMIGA_DSKSYN] = IF_DSKSYN, +- [IRQ_AMIGA_DSKBLK] = IF_DSKBLK, +- [IRQ_AMIGA_RBF] = IF_RBF, +- [IRQ_AMIGA_TBE] = IF_TBE, +- [IRQ_AMIGA_SOFT] = IF_SOFT, +- [IRQ_AMIGA_PORTS] = IF_PORTS, +- [IRQ_AMIGA_EXTER] = IF_EXTER ++static void amiga_enable_irq(unsigned int irq); ++static void amiga_disable_irq(unsigned int irq); ++static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp); ++static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp); ++static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp); ++static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp); ++ ++static struct irq_controller amiga_irq_controller = { ++ .name = "amiga", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .enable = amiga_enable_irq, ++ .disable = amiga_disable_irq, + }; +-static const unsigned char ami_servers[AMI_STD_IRQS] = { +- [IRQ_AMIGA_VERTB] = 1, +- [IRQ_AMIGA_PORTS] = 1, +- [IRQ_AMIGA_EXTER] = 1 +-}; +- +-static short ami_ablecount[AMI_IRQS]; +- +-static irqreturn_t ami_badint(int irq, void *dev_id, struct pt_regs *fp) +-{ +- num_spurious += 1; +- return IRQ_NONE; +-} + + /* + * void amiga_init_IRQ(void) +@@ -103,23 +72,12 @@ + + void __init amiga_init_IRQ(void) + { +- int i; ++ request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL); ++ request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL); ++ request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL); ++ request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL); + +- /* initialize handlers */ +- for (i = 0; i < AMI_STD_IRQS; i++) { +- if (ami_servers[i]) { +- ami_irq_list[i] = NULL; +- } else { +- ami_irq_list[i] = new_irq_node(); +- ami_irq_list[i]->handler = ami_badint; +- ami_irq_list[i]->flags = 0; +- ami_irq_list[i]->dev_id = NULL; +- ami_irq_list[i]->devname = NULL; +- ami_irq_list[i]->next = NULL; +- } +- } +- for (i = 0; i < AMI_IRQS; i++) +- ami_ablecount[i] = 0; ++ m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS); + + /* turn off PCMCIA interrupts */ + if (AMIGAHW_PRESENT(PCMCIA)) +@@ -134,249 +92,21 @@ + cia_init_IRQ(&ciab_base); + } + +-static inline int amiga_insert_irq(irq_node_t **list, irq_node_t *node) +-{ +- unsigned long flags; +- irq_node_t *cur; +- +- if (!node->dev_id) +- printk("%s: Warning: dev_id of %s is zero\n", +- __FUNCTION__, node->devname); +- +- local_irq_save(flags); +- +- cur = *list; +- +- if (node->flags & SA_INTERRUPT) { +- if (node->flags & SA_SHIRQ) +- return -EBUSY; +- /* +- * There should never be more than one +- */ +- while (cur && cur->flags & SA_INTERRUPT) { +- list = &cur->next; +- cur = cur->next; +- } +- } else { +- while (cur) { +- list = &cur->next; +- cur = cur->next; +- } +- } +- +- node->next = cur; +- *list = node; +- +- local_irq_restore(flags); +- return 0; +-} +- +-static inline void amiga_delete_irq(irq_node_t **list, void *dev_id) +-{ +- unsigned long flags; +- irq_node_t *node; +- +- local_irq_save(flags); +- +- for (node = *list; node; list = &node->next, node = *list) { +- if (node->dev_id == dev_id) { +- *list = node->next; +- /* Mark it as free. */ +- node->handler = NULL; +- local_irq_restore(flags); +- return; +- } +- } +- local_irq_restore(flags); +- printk ("%s: tried to remove invalid irq\n", __FUNCTION__); +-} +- +-/* +- * amiga_request_irq : add an interrupt service routine for a particular +- * machine specific interrupt source. +- * If the addition was successful, it returns 0. +- */ +- +-int amiga_request_irq(unsigned int irq, +- irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id) +-{ +- irq_node_t *node; +- int error = 0; +- +- if (irq >= AMI_IRQS) { +- printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, +- irq, devname); +- return -ENXIO; +- } +- +- if (irq >= IRQ_AMIGA_AUTO) +- return cpu_request_irq(irq - IRQ_AMIGA_AUTO, handler, +- flags, devname, dev_id); +- +- if (irq >= IRQ_AMIGA_CIAB) +- return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, +- handler, flags, devname, dev_id); +- +- if (irq >= IRQ_AMIGA_CIAA) +- return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, +- handler, flags, devname, dev_id); +- +- /* +- * IRQ_AMIGA_PORTS & IRQ_AMIGA_EXTER defaults to shared, +- * we could add a check here for the SA_SHIRQ flag but all drivers +- * should be aware of sharing anyway. +- */ +- if (ami_servers[irq]) { +- if (!(node = new_irq_node())) +- return -ENOMEM; +- node->handler = handler; +- node->flags = flags; +- node->dev_id = dev_id; +- node->devname = devname; +- node->next = NULL; +- error = amiga_insert_irq(&ami_irq_list[irq], node); +- } else { +- ami_irq_list[irq]->handler = handler; +- ami_irq_list[irq]->flags = flags; +- ami_irq_list[irq]->dev_id = dev_id; +- ami_irq_list[irq]->devname = devname; +- } +- +- /* enable the interrupt */ +- if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) +- amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; +- +- return error; +-} +- +-void amiga_free_irq(unsigned int irq, void *dev_id) +-{ +- if (irq >= AMI_IRQS) { +- printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq); +- return; +- } +- +- if (irq >= IRQ_AMIGA_AUTO) +- cpu_free_irq(irq - IRQ_AMIGA_AUTO, dev_id); +- +- if (irq >= IRQ_AMIGA_CIAB) { +- cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id); +- return; +- } +- +- if (irq >= IRQ_AMIGA_CIAA) { +- cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id); +- return; +- } +- +- if (ami_servers[irq]) { +- amiga_delete_irq(&ami_irq_list[irq], dev_id); +- /* if server list empty, disable the interrupt */ +- if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS) +- amiga_custom.intena = amiga_intena_vals[irq]; +- } else { +- if (ami_irq_list[irq]->dev_id != dev_id) +- printk("%s: removing probably wrong IRQ %d from %s\n", +- __FUNCTION__, irq, ami_irq_list[irq]->devname); +- ami_irq_list[irq]->handler = ami_badint; +- ami_irq_list[irq]->flags = 0; +- ami_irq_list[irq]->dev_id = NULL; +- ami_irq_list[irq]->devname = NULL; +- amiga_custom.intena = amiga_intena_vals[irq]; +- } +-} +- + /* + * Enable/disable a particular machine specific interrupt source. + * Note that this may affect other interrupts in case of a shared interrupt. + * This function should only be called for a _very_ short time to change some + * internal data, that may not be changed by the interrupt at the same time. +- * ami_(enable|disable)_irq calls may also be nested. + */ + +-void amiga_enable_irq(unsigned int irq) +-{ +- if (irq >= AMI_IRQS) { +- printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); +- return; +- } +- +- if (--ami_ablecount[irq]) +- return; +- +- /* No action for auto-vector interrupts */ +- if (irq >= IRQ_AMIGA_AUTO){ +- printk("%s: Trying to enable auto-vector IRQ %i\n", +- __FUNCTION__, irq - IRQ_AMIGA_AUTO); +- return; +- } +- +- if (irq >= IRQ_AMIGA_CIAB) { +- cia_set_irq(&ciab_base, (1 << (irq - IRQ_AMIGA_CIAB))); +- cia_able_irq(&ciab_base, CIA_ICR_SETCLR | +- (1 << (irq - IRQ_AMIGA_CIAB))); +- return; +- } +- +- if (irq >= IRQ_AMIGA_CIAA) { +- cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA))); +- cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | +- (1 << (irq - IRQ_AMIGA_CIAA))); +- return; +- } +- +- /* enable the interrupt */ +- amiga_custom.intena = IF_SETCLR | amiga_intena_vals[irq]; +-} +- +-void amiga_disable_irq(unsigned int irq) +-{ +- if (irq >= AMI_IRQS) { +- printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); +- return; +- } +- +- if (ami_ablecount[irq]++) +- return; +- +- /* No action for auto-vector interrupts */ +- if (irq >= IRQ_AMIGA_AUTO) { +- printk("%s: Trying to disable auto-vector IRQ %i\n", +- __FUNCTION__, irq - IRQ_AMIGA_AUTO); +- return; +- } +- +- if (irq >= IRQ_AMIGA_CIAB) { +- cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); +- return; +- } +- +- if (irq >= IRQ_AMIGA_CIAA) { +- cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); +- return; +- } +- +- /* disable the interrupt */ +- amiga_custom.intena = amiga_intena_vals[irq]; +-} +- +-inline void amiga_do_irq(int irq, struct pt_regs *fp) ++static void amiga_enable_irq(unsigned int irq) + { +- kstat_cpu(0).irqs[SYS_IRQS + irq]++; +- ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp); ++ amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER)); + } + +-void amiga_do_irq_list(int irq, struct pt_regs *fp) ++static void amiga_disable_irq(unsigned int irq) + { +- irq_node_t *node; +- +- kstat_cpu(0).irqs[SYS_IRQS + irq]++; +- +- amiga_custom.intreq = amiga_intena_vals[irq]; +- +- for (node = ami_irq_list[irq]; node; node = node->next) +- node->handler(irq, node->dev_id, fp); ++ amiga_custom.intena = 1 << (irq - IRQ_USER); + } + + /* +@@ -390,19 +120,19 @@ + /* if serial transmit buffer empty, interrupt */ + if (ints & IF_TBE) { + amiga_custom.intreq = IF_TBE; +- amiga_do_irq(IRQ_AMIGA_TBE, fp); ++ m68k_handle_int(IRQ_AMIGA_TBE, fp); + } + + /* if floppy disk transfer complete, interrupt */ + if (ints & IF_DSKBLK) { + amiga_custom.intreq = IF_DSKBLK; +- amiga_do_irq(IRQ_AMIGA_DSKBLK, fp); ++ m68k_handle_int(IRQ_AMIGA_DSKBLK, fp); + } + + /* if software interrupt set, interrupt */ + if (ints & IF_SOFT) { + amiga_custom.intreq = IF_SOFT; +- amiga_do_irq(IRQ_AMIGA_SOFT, fp); ++ m68k_handle_int(IRQ_AMIGA_SOFT, fp); + } + return IRQ_HANDLED; + } +@@ -414,18 +144,20 @@ + /* if a blitter interrupt */ + if (ints & IF_BLIT) { + amiga_custom.intreq = IF_BLIT; +- amiga_do_irq(IRQ_AMIGA_BLIT, fp); ++ m68k_handle_int(IRQ_AMIGA_BLIT, fp); + } + + /* if a copper interrupt */ + if (ints & IF_COPER) { + amiga_custom.intreq = IF_COPER; +- amiga_do_irq(IRQ_AMIGA_COPPER, fp); ++ m68k_handle_int(IRQ_AMIGA_COPPER, fp); + } + + /* if a vertical blank interrupt */ +- if (ints & IF_VERTB) +- amiga_do_irq_list(IRQ_AMIGA_VERTB, fp); ++ if (ints & IF_VERTB) { ++ amiga_custom.intreq = IF_VERTB; ++ m68k_handle_int(IRQ_AMIGA_VERTB, fp); ++ } + return IRQ_HANDLED; + } + +@@ -436,25 +168,25 @@ + /* if audio 0 interrupt */ + if (ints & IF_AUD0) { + amiga_custom.intreq = IF_AUD0; +- amiga_do_irq(IRQ_AMIGA_AUD0, fp); ++ m68k_handle_int(IRQ_AMIGA_AUD0, fp); + } + + /* if audio 1 interrupt */ + if (ints & IF_AUD1) { + amiga_custom.intreq = IF_AUD1; +- amiga_do_irq(IRQ_AMIGA_AUD1, fp); ++ m68k_handle_int(IRQ_AMIGA_AUD1, fp); + } + + /* if audio 2 interrupt */ + if (ints & IF_AUD2) { + amiga_custom.intreq = IF_AUD2; +- amiga_do_irq(IRQ_AMIGA_AUD2, fp); ++ m68k_handle_int(IRQ_AMIGA_AUD2, fp); + } + + /* if audio 3 interrupt */ + if (ints & IF_AUD3) { + amiga_custom.intreq = IF_AUD3; +- amiga_do_irq(IRQ_AMIGA_AUD3, fp); ++ m68k_handle_int(IRQ_AMIGA_AUD3, fp); + } + return IRQ_HANDLED; + } +@@ -466,55 +198,13 @@ + /* if serial receive buffer full interrupt */ + if (ints & IF_RBF) { + /* acknowledge of IF_RBF must be done by the serial interrupt */ +- amiga_do_irq(IRQ_AMIGA_RBF, fp); ++ m68k_handle_int(IRQ_AMIGA_RBF, fp); + } + + /* if a disk sync interrupt */ + if (ints & IF_DSKSYN) { + amiga_custom.intreq = IF_DSKSYN; +- amiga_do_irq(IRQ_AMIGA_DSKSYN, fp); ++ m68k_handle_int(IRQ_AMIGA_DSKSYN, fp); + } + return IRQ_HANDLED; + } +- +-static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp) +-{ +- panic ("level 7 interrupt received\n"); +-} +- +-irqreturn_t (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { +- [0] = ami_badint, +- [1] = ami_int1, +- [2] = ami_badint, +- [3] = ami_int3, +- [4] = ami_int4, +- [5] = ami_int5, +- [6] = ami_badint, +- [7] = ami_int7 +-}; +- +-int show_amiga_interrupts(struct seq_file *p, void *v) +-{ +- int i; +- irq_node_t *node; +- +- for (i = 0; i < AMI_STD_IRQS; i++) { +- if (!(node = ami_irq_list[i])) +- continue; +- seq_printf(p, "ami %2d: %10u ", i, +- kstat_cpu(0).irqs[SYS_IRQS + i]); +- do { +- if (node->flags & SA_INTERRUPT) +- seq_puts(p, "F "); +- else +- seq_puts(p, " "); +- seq_printf(p, "%s\n", node->devname); +- if ((node = node->next)) +- seq_puts(p, " "); +- } while (node); +- } +- +- cia_get_irq_list(&ciaa_base, p); +- cia_get_irq_list(&ciab_base, p); +- return 0; +-} +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/amiga/cia.c linux-m68k/arch/m68k/amiga/cia.c +--- linux-i386/arch/m68k/amiga/cia.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/amiga/cia.c 2006-04-11 16:32:18.000000000 +0200 +@@ -29,21 +29,18 @@ + unsigned short int_mask; + int handler_irq, cia_irq, server_irq; + char *name; +- irq_handler_t irq_list[CIA_IRQS]; + } ciaa_base = { + .cia = &ciaa, + .int_mask = IF_PORTS, +- .handler_irq = IRQ_AMIGA_AUTO_2, ++ .handler_irq = IRQ_AMIGA_PORTS, + .cia_irq = IRQ_AMIGA_CIAA, +- .server_irq = IRQ_AMIGA_PORTS, +- .name = "CIAA handler" ++ .name = "CIAA" + }, ciab_base = { + .cia = &ciab, + .int_mask = IF_EXTER, +- .handler_irq = IRQ_AMIGA_AUTO_6, ++ .handler_irq = IRQ_AMIGA_EXTER, + .cia_irq = IRQ_AMIGA_CIAB, +- .server_irq = IRQ_AMIGA_EXTER, +- .name = "CIAB handler" ++ .name = "CIAB" + }; + + /* +@@ -66,13 +63,11 @@ + + /* + * Enable or disable CIA interrupts, return old interrupt mask, +- * interrupts will only be enabled if a handler exists + */ + + unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) + { +- unsigned char old, tmp; +- int i; ++ unsigned char old; + + old = base->icr_mask; + base->icr_data |= base->cia->icr; +@@ -82,99 +77,104 @@ + else + base->icr_mask &= ~mask; + base->icr_mask &= CIA_ICR_ALL; +- for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) { +- if ((tmp & base->icr_mask) && !base->irq_list[i].handler) { +- base->icr_mask &= ~tmp; +- base->cia->icr = tmp; +- } +- } + if (base->icr_data & base->icr_mask) + amiga_custom.intreq = IF_SETCLR | base->int_mask; + return old; + } + +-int cia_request_irq(struct ciabase *base, unsigned int irq, +- irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id) +-{ +- unsigned char mask; +- +- base->irq_list[irq].handler = handler; +- base->irq_list[irq].flags = flags; +- base->irq_list[irq].dev_id = dev_id; +- base->irq_list[irq].devname = devname; +- +- /* enable the interrupt */ +- mask = 1 << irq; +- cia_set_irq(base, mask); +- cia_able_irq(base, CIA_ICR_SETCLR | mask); +- return 0; +-} +- +-void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id) +-{ +- if (base->irq_list[irq].dev_id != dev_id) +- printk("%s: removing probably wrong IRQ %i from %s\n", +- __FUNCTION__, base->cia_irq + irq, +- base->irq_list[irq].devname); +- +- base->irq_list[irq].handler = NULL; +- base->irq_list[irq].flags = 0; +- +- cia_able_irq(base, 1 << irq); +-} +- + static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp) + { + struct ciabase *base = (struct ciabase *)dev_id; +- int mach_irq, i; ++ int mach_irq; + unsigned char ints; + + mach_irq = base->cia_irq; +- irq = SYS_IRQS + mach_irq; + ints = cia_set_irq(base, CIA_ICR_ALL); + amiga_custom.intreq = base->int_mask; +- for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) { +- if (ints & 1) { +- kstat_cpu(0).irqs[irq]++; +- base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp); +- } +- ints >>= 1; ++ for (; ints; mach_irq++, ints >>= 1) { ++ if (ints & 1) ++ m68k_handle_int(mach_irq, fp); + } +- amiga_do_irq_list(base->server_irq, fp); + return IRQ_HANDLED; + } + +-void __init cia_init_IRQ(struct ciabase *base) ++static void cia_enable_irq(unsigned int irq) + { +- int i; ++ unsigned char mask; + +- /* init isr handlers */ +- for (i = 0; i < CIA_IRQS; i++) { +- base->irq_list[i].handler = NULL; +- base->irq_list[i].flags = 0; ++ if (irq >= IRQ_AMIGA_CIAB) { ++ mask = 1 << (irq - IRQ_AMIGA_CIAB); ++ cia_set_irq(&ciab_base, mask); ++ cia_able_irq(&ciab_base, CIA_ICR_SETCLR | mask); ++ } else { ++ mask = 1 << (irq - IRQ_AMIGA_CIAA); ++ cia_set_irq(&ciaa_base, mask); ++ cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | mask); + } ++} + +- /* clear any pending interrupt and turn off all interrupts */ +- cia_set_irq(base, CIA_ICR_ALL); +- cia_able_irq(base, CIA_ICR_ALL); ++static void cia_disable_irq(unsigned int irq) ++{ ++ if (irq >= IRQ_AMIGA_CIAB) ++ cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); ++ else ++ cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); ++} + +- /* install CIA handler */ +- request_irq(base->handler_irq, cia_handler, 0, base->name, base); ++static struct irq_controller cia_irq_controller = { ++ .name = "cia", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .enable = cia_enable_irq, ++ .disable = cia_disable_irq, ++}; + +- amiga_custom.intena = IF_SETCLR | base->int_mask; +-} ++/* ++ * Override auto irq 2 & 6 and use them as general chain ++ * for external interrupts, we link the CIA interrupt sources ++ * into this chain. ++ */ + +-int cia_get_irq_list(struct ciabase *base, struct seq_file *p) ++static void auto_enable_irq(unsigned int irq) + { +- int i, j; ++ switch (irq) { ++ case IRQ_AUTO_2: ++ amiga_custom.intena = IF_SETCLR | IF_PORTS; ++ break; ++ case IRQ_AUTO_6: ++ amiga_custom.intena = IF_SETCLR | IF_EXTER; ++ break; ++ } ++} + +- j = base->cia_irq; +- for (i = 0; i < CIA_IRQS; i++) { +- seq_printf(p, "cia %2d: %10d ", j + i, +- kstat_cpu(0).irqs[SYS_IRQS + j + i]); +- seq_puts(p, " "); +- seq_printf(p, "%s\n", base->irq_list[i].devname); ++static void auto_disable_irq(unsigned int irq) ++{ ++ switch (irq) { ++ case IRQ_AUTO_2: ++ amiga_custom.intena = IF_PORTS; ++ break; ++ case IRQ_AUTO_6: ++ amiga_custom.intena = IF_EXTER; ++ break; + } +- return 0; ++} ++ ++static struct irq_controller auto_irq_controller = { ++ .name = "auto", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .enable = auto_enable_irq, ++ .disable = auto_disable_irq, ++}; ++ ++void __init cia_init_IRQ(struct ciabase *base) ++{ ++ m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS); ++ ++ /* clear any pending interrupt and turn off all interrupts */ ++ cia_set_irq(base, CIA_ICR_ALL); ++ cia_able_irq(base, CIA_ICR_ALL); ++ ++ /* override auto int and install CIA handler */ ++ m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1); ++ m68k_irq_startup(base->handler_irq); ++ request_irq(base->handler_irq, cia_handler, SA_SHIRQ, base->name, base); + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/amiga/config.c linux-m68k/arch/m68k/amiga/config.c +--- linux-i386/arch/m68k/amiga/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/amiga/config.c 2006-04-11 16:32:18.000000000 +0200 +@@ -87,17 +87,8 @@ + static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); + /* amiga specific irq functions */ + extern void amiga_init_IRQ (void); +-extern irqreturn_t (*amiga_default_handler[]) (int, void *, struct pt_regs *); +-extern int amiga_request_irq (unsigned int irq, +- irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, +- void *dev_id); +-extern void amiga_free_irq (unsigned int irq, void *dev_id); +-extern void amiga_enable_irq (unsigned int); +-extern void amiga_disable_irq (unsigned int); + static void amiga_get_model(char *model); + static int amiga_get_hardware_list(char *buffer); +-extern int show_amiga_interrupts (struct seq_file *, void *); + /* amiga specific timer functions */ + static unsigned long amiga_gettimeoffset (void); + static int a3000_hwclk (int, struct rtc_time *); +@@ -392,14 +383,8 @@ + + mach_sched_init = amiga_sched_init; + mach_init_IRQ = amiga_init_IRQ; +- mach_default_handler = &amiga_default_handler; +- mach_request_irq = amiga_request_irq; +- mach_free_irq = amiga_free_irq; +- enable_irq = amiga_enable_irq; +- disable_irq = amiga_disable_irq; + mach_get_model = amiga_get_model; + mach_get_hardware_list = amiga_get_hardware_list; +- mach_get_irq_list = show_amiga_interrupts; + mach_gettimeoffset = amiga_gettimeoffset; + if (AMIGAHW_PRESENT(A3000_CLK)){ + mach_hwclk = a3000_hwclk; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/apollo/config.c linux-m68k/arch/m68k/apollo/config.c +--- linux-i386/arch/m68k/apollo/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/apollo/config.c 2006-01-28 23:52:25.000000000 +0100 +@@ -28,11 +28,6 @@ + + extern void dn_sched_init(irqreturn_t (*handler)(int,void *,struct pt_regs *)); + extern void dn_init_IRQ(void); +-extern int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); +-extern void dn_free_irq(unsigned int irq, void *dev_id); +-extern void dn_enable_irq(unsigned int); +-extern void dn_disable_irq(unsigned int); +-extern int show_dn_interrupts(struct seq_file *, void *); + extern unsigned long dn_gettimeoffset(void); + extern int dn_dummy_hwclk(int, struct rtc_time *); + extern int dn_dummy_set_clock_mmss(unsigned long); +@@ -40,13 +35,11 @@ + extern void dn_dummy_waitbut(void); + extern struct fb_info *dn_fb_init(long *); + extern void dn_dummy_debug_init(void); +-extern void dn_dummy_video_setup(char *,int *); + extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp); + #ifdef CONFIG_HEARTBEAT + static void dn_heartbeat(int on); + #endif + static irqreturn_t dn_timer_int(int irq,void *, struct pt_regs *); +-static irqreturn_t (*sched_timer_handler)(int, void *, struct pt_regs *)=NULL; + static void dn_get_model(char *model); + static const char *apollo_models[] = { + [APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)", +@@ -164,17 +157,10 @@ + + mach_sched_init=dn_sched_init; /* */ + mach_init_IRQ=dn_init_IRQ; +- mach_default_handler=NULL; +- mach_request_irq = dn_request_irq; +- mach_free_irq = dn_free_irq; +- enable_irq = dn_enable_irq; +- disable_irq = dn_disable_irq; +- mach_get_irq_list = show_dn_interrupts; + mach_gettimeoffset = dn_gettimeoffset; + mach_max_dma_address = 0xffffffff; + mach_hwclk = dn_dummy_hwclk; /* */ + mach_set_clock_mmss = dn_dummy_set_clock_mmss; /* */ +- mach_process_int = dn_process_int; + mach_reset = dn_dummy_reset; /* */ + #ifdef CONFIG_HEARTBEAT + mach_heartbeat = dn_heartbeat; +@@ -189,11 +175,13 @@ + + } + +-irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) { ++irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp) ++{ ++ irqreturn_t (*timer_handler)(int, void *, struct pt_regs *) = dev_id; + + volatile unsigned char x; + +- sched_timer_handler(irq,dev_id,fp); ++ timer_handler(irq, dev_id, fp); + + x=*(volatile unsigned char *)(timer+3); + x=*(volatile unsigned char *)(timer+5); +@@ -217,9 +205,7 @@ + printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); + #endif + +- sched_timer_handler=timer_routine; +- request_irq(0,dn_timer_int,0,NULL,NULL); +- ++ request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine); + } + + unsigned long dn_gettimeoffset(void) { +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/apollo/dn_ints.c linux-m68k/arch/m68k/apollo/dn_ints.c +--- linux-i386/arch/m68k/apollo/dn_ints.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/apollo/dn_ints.c 2006-01-28 23:52:25.000000000 +0100 +@@ -1,125 +1,44 @@ +-#include +-#include +-#include +-#include +-#include ++#include + +-#include + #include + #include +-#include +-#include + #include +-#include + +-static irq_handler_t dn_irqs[16]; +- +-irqreturn_t dn_process_int(int irq, struct pt_regs *fp) ++void dn_process_int(unsigned int irq, struct pt_regs *fp) + { +- irqreturn_t res = IRQ_NONE; +- +- if(dn_irqs[irq-160].handler) { +- res = dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp); +- } else { +- printk("spurious irq %d occurred\n",irq); +- } +- +- *(volatile unsigned char *)(pica)=0x20; +- *(volatile unsigned char *)(picb)=0x20; +- +- return res; +-} +- +-void dn_init_IRQ(void) { +- +- int i; +- +- for(i=0;i<16;i++) { +- dn_irqs[i].handler=NULL; +- dn_irqs[i].flags=IRQ_FLG_STD; +- dn_irqs[i].dev_id=NULL; +- dn_irqs[i].devname=NULL; +- } +- +-} +- +-int dn_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id) { +- +- if((irq<0) || (irq>15)) { +- printk("Trying to request invalid IRQ\n"); +- return -ENXIO; +- } +- +- if(!dn_irqs[irq].handler) { +- dn_irqs[irq].handler=handler; +- dn_irqs[irq].flags=IRQ_FLG_STD; +- dn_irqs[irq].dev_id=dev_id; +- dn_irqs[irq].devname=devname; +- if(irq<8) +- *(volatile unsigned char *)(pica+1)&=~(1<15)) { +- printk("Trying to free invalid IRQ\n"); +- return ; +- } +- +- if(irq<8) +- *(volatile unsigned char *)(pica+1)|=(1< 0 && \ +@@ -301,6 +295,14 @@ + ); + for (;;); + } ++#endif ++ ++/* ++ * Bitmap for free interrupt vector numbers ++ * (new vectors starting from 0x70 can be allocated by ++ * atari_register_vme_int()) ++ */ ++static int free_vme_vec_bitmap; + + /* GK: + * HBL IRQ handler for Falcon. Nobody needs it :-) +@@ -313,13 +315,34 @@ + "orw #0x200,%sp@\n\t" /* set saved ipl to 2 */ + "rte"); + +-/* Defined in entry.S; only increments 'num_spurious' */ +-asmlinkage void bad_interrupt(void); +- +-extern void atari_microwire_cmd( int cmd ); ++extern void atari_microwire_cmd(int cmd); + + extern int atari_SCC_reset_done; + ++static int atari_startup_irq(unsigned int irq) ++{ ++ m68k_irq_startup(irq); ++ atari_turnon_irq(irq); ++ atari_enable_irq(irq); ++ return 0; ++} ++ ++static void atari_shutdown_irq(unsigned int irq) ++{ ++ atari_disable_irq(irq); ++ atari_turnoff_irq(irq); ++ m68k_irq_shutdown(irq); ++} ++ ++static struct irq_controller atari_irq_controller = { ++ .name = "atari", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .startup = atari_startup_irq, ++ .shutdown = atari_shutdown_irq, ++ .enable = atari_enable_irq, ++ .disable = atari_disable_irq, ++}; ++ + /* + * void atari_init_IRQ (void) + * +@@ -333,12 +356,8 @@ + + void __init atari_init_IRQ(void) + { +- int i; +- +- /* initialize the vector table */ +- for (i = 0; i < NUM_INT_SOURCES; ++i) { +- vectors[IRQ_SOURCE_TO_VECTOR(i)] = bad_interrupt; +- } ++ m68k_setup_user_interrupt(VEC_USER, 192, NULL); ++ m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1); + + /* Initialize the MFP(s) */ + +@@ -378,8 +397,7 @@ + * enabled in VME mask + */ + tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */ +- } +- else { ++ } else { + /* If no SCU and no Hades, the HSYNC interrupt needs to be + * disabled this way. (Else _inthandler in kernel/sys_call.S + * gets overruns) +@@ -404,184 +422,6 @@ + } + + +-static irqreturn_t atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp ) +-{ +- irq_node_t *node; +- +- for (node = (irq_node_t *)dev_id; node; node = node->next) +- node->handler(irq, node->dev_id, fp); +- return IRQ_HANDLED; +-} +- +- +-/* +- * atari_request_irq : add an interrupt service routine for a particular +- * machine specific interrupt source. +- * If the addition was successful, it returns 0. +- */ +- +-int atari_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id) +-{ +- int vector; +- unsigned long oflags = flags; +- +- /* +- * The following is a hack to make some PCI card drivers work, +- * which set the SA_SHIRQ flag. +- */ +- +- flags &= ~SA_SHIRQ; +- +- if (flags == SA_INTERRUPT) { +- printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n", +- __FUNCTION__, devname); +- flags = IRQ_TYPE_SLOW; +- } +- if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) { +- printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n", +- __FUNCTION__, flags, oflags, devname); +- return -EINVAL; +- } +- if (!IS_VALID_INTNO(irq)) { +- printk ("%s: Unknown irq %d requested from %s\n", +- __FUNCTION__, irq, devname); +- return -ENXIO; +- } +- vector = IRQ_SOURCE_TO_VECTOR(irq); +- +- /* +- * Check type/source combination: slow ints are (currently) +- * only possible for MFP-interrupts. +- */ +- if (flags == IRQ_TYPE_SLOW && +- (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) { +- printk ("%s: Slow irq requested for non-MFP source %d from %s\n", +- __FUNCTION__, irq, devname); +- return -EINVAL; +- } +- +- if (vectors[vector] == bad_interrupt) { +- /* int has no handler yet */ +- irq_handler[irq].handler = handler; +- irq_handler[irq].dev_id = dev_id; +- irq_param[irq].flags = flags; +- irq_param[irq].devname = devname; +- vectors[vector] = +- (flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] : +- (flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler : +- atari_prio_irq_handler; +- /* If MFP int, also enable and umask it */ +- atari_turnon_irq(irq); +- atari_enable_irq(irq); +- +- return 0; +- } +- else if (irq_param[irq].flags == flags) { +- /* old handler is of same type -> handlers can be chained */ +- irq_node_t *node; +- unsigned long flags; +- +- local_irq_save(flags); +- +- if (irq_handler[irq].handler != atari_call_irq_list) { +- /* Only one handler yet, make a node for this first one */ +- if (!(node = new_irq_node())) +- return -ENOMEM; +- node->handler = irq_handler[irq].handler; +- node->dev_id = irq_handler[irq].dev_id; +- node->devname = irq_param[irq].devname; +- node->next = NULL; +- +- irq_handler[irq].handler = atari_call_irq_list; +- irq_handler[irq].dev_id = node; +- irq_param[irq].devname = "chained"; +- } +- +- if (!(node = new_irq_node())) +- return -ENOMEM; +- node->handler = handler; +- node->dev_id = dev_id; +- node->devname = devname; +- /* new handlers are put in front of the queue */ +- node->next = irq_handler[irq].dev_id; +- irq_handler[irq].dev_id = node; +- +- local_irq_restore(flags); +- return 0; +- } else { +- printk ("%s: Irq %d allocated by other type int (call from %s)\n", +- __FUNCTION__, irq, devname); +- return -EBUSY; +- } +-} +- +-void atari_free_irq(unsigned int irq, void *dev_id) +-{ +- unsigned long flags; +- int vector; +- irq_node_t **list, *node; +- +- if (!IS_VALID_INTNO(irq)) { +- printk("%s: Unknown irq %d\n", __FUNCTION__, irq); +- return; +- } +- +- vector = IRQ_SOURCE_TO_VECTOR(irq); +- if (vectors[vector] == bad_interrupt) +- goto not_found; +- +- local_irq_save(flags); +- +- if (irq_handler[irq].handler != atari_call_irq_list) { +- /* It's the only handler for the interrupt */ +- if (irq_handler[irq].dev_id != dev_id) { +- local_irq_restore(flags); +- goto not_found; +- } +- irq_handler[irq].handler = NULL; +- irq_handler[irq].dev_id = NULL; +- irq_param[irq].devname = NULL; +- vectors[vector] = bad_interrupt; +- /* If MFP int, also disable it */ +- atari_disable_irq(irq); +- atari_turnoff_irq(irq); +- +- local_irq_restore(flags); +- return; +- } +- +- /* The interrupt is chained, find the irq on the list */ +- for(list = (irq_node_t **)&irq_handler[irq].dev_id; *list; list = &(*list)->next) { +- if ((*list)->dev_id == dev_id) break; +- } +- if (!*list) { +- local_irq_restore(flags); +- goto not_found; +- } +- +- (*list)->handler = NULL; /* Mark it as free for reallocation */ +- *list = (*list)->next; +- +- /* If there's now only one handler, unchain the interrupt, i.e. plug in +- * the handler directly again and omit atari_call_irq_list */ +- node = (irq_node_t *)irq_handler[irq].dev_id; +- if (node && !node->next) { +- irq_handler[irq].handler = node->handler; +- irq_handler[irq].dev_id = node->dev_id; +- irq_param[irq].devname = node->devname; +- node->handler = NULL; /* Mark it as free for reallocation */ +- } +- +- local_irq_restore(flags); +- return; +- +-not_found: +- printk("%s: tried to remove invalid irq\n", __FUNCTION__); +- return; +-} +- +- + /* + * atari_register_vme_int() returns the number of a free interrupt vector for + * hardware with a programmable int vector (probably a VME board). +@@ -591,58 +431,24 @@ + { + int i; + +- for(i = 0; i < 32; i++) +- if((free_vme_vec_bitmap & (1 << i)) == 0) ++ for (i = 0; i < 32; i++) ++ if ((free_vme_vec_bitmap & (1 << i)) == 0) + break; + +- if(i == 16) ++ if (i == 16) + return 0; + + free_vme_vec_bitmap |= 1 << i; +- return (VME_SOURCE_BASE + i); ++ return VME_SOURCE_BASE + i; + } + + + void atari_unregister_vme_int(unsigned long irq) + { +- if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { ++ if (irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) { + irq -= VME_SOURCE_BASE; + free_vme_vec_bitmap &= ~(1 << irq); + } + } + + +-int show_atari_interrupts(struct seq_file *p, void *v) +-{ +- int i; +- +- for (i = 0; i < NUM_INT_SOURCES; ++i) { +- if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_interrupt) +- continue; +- if (i < STMFP_SOURCE_BASE) +- seq_printf(p, "auto %2d: %10u ", +- i, kstat_cpu(0).irqs[i]); +- else +- seq_printf(p, "vec $%02x: %10u ", +- IRQ_SOURCE_TO_VECTOR(i), +- kstat_cpu(0).irqs[i]); +- +- if (irq_handler[i].handler != atari_call_irq_list) { +- seq_printf(p, "%s\n", irq_param[i].devname); +- } +- else { +- irq_node_t *n; +- for( n = (irq_node_t *)irq_handler[i].dev_id; n; n = n->next ) { +- seq_printf(p, "%s\n", n->devname); +- if (n->next) +- seq_puts(p, " " ); +- } +- } +- } +- if (num_spurious) +- seq_printf(p, "spurio.: %10u\n", num_spurious); +- +- return 0; +-} +- +- +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/atari/config.c linux-m68k/arch/m68k/atari/config.c +--- linux-i386/arch/m68k/atari/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/atari/config.c 2006-04-11 16:32:18.000000000 +0200 +@@ -57,12 +57,6 @@ + + /* atari specific irq functions */ + extern void atari_init_IRQ (void); +-extern int atari_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id); +-extern void atari_free_irq (unsigned int irq, void *dev_id); +-extern void atari_enable_irq (unsigned int); +-extern void atari_disable_irq (unsigned int); +-extern int show_atari_interrupts (struct seq_file *, void *); + extern void atari_mksound( unsigned int count, unsigned int ticks ); + #ifdef CONFIG_HEARTBEAT + static void atari_heartbeat( int on ); +@@ -232,13 +226,8 @@ + + mach_sched_init = atari_sched_init; + mach_init_IRQ = atari_init_IRQ; +- mach_request_irq = atari_request_irq; +- mach_free_irq = atari_free_irq; +- enable_irq = atari_enable_irq; +- disable_irq = atari_disable_irq; + mach_get_model = atari_get_model; + mach_get_hardware_list = atari_get_hardware_list; +- mach_get_irq_list = show_atari_interrupts; + mach_gettimeoffset = atari_gettimeoffset; + mach_reset = atari_reset; + mach_max_dma_address = 0xffffff; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/bvme6000/Makefile linux-m68k/arch/m68k/bvme6000/Makefile +--- linux-i386/arch/m68k/bvme6000/Makefile 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/bvme6000/Makefile 2006-01-28 23:52:25.000000000 +0100 +@@ -2,4 +2,4 @@ + # Makefile for Linux arch/m68k/bvme6000 source directory + # + +-obj-y := config.o bvmeints.o rtc.o ++obj-y := config.o rtc.o +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/bvme6000/config.c linux-m68k/arch/m68k/bvme6000/config.c +--- linux-i386/arch/m68k/bvme6000/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/bvme6000/config.c 2006-01-28 23:52:25.000000000 +0100 +@@ -36,15 +36,8 @@ + #include + #include + +-extern irqreturn_t bvme6000_process_int (int level, struct pt_regs *regs); +-extern void bvme6000_init_IRQ (void); +-extern void bvme6000_free_irq (unsigned int, void *); +-extern int show_bvme6000_interrupts(struct seq_file *, void *); +-extern void bvme6000_enable_irq (unsigned int); +-extern void bvme6000_disable_irq (unsigned int); + static void bvme6000_get_model(char *model); + static int bvme6000_get_hardware_list(char *buffer); +-extern int bvme6000_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); + extern void bvme6000_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); + extern unsigned long bvme6000_gettimeoffset (void); + extern int bvme6000_hwclk (int, struct rtc_time *); +@@ -100,6 +93,14 @@ + return 0; + } + ++/* ++ * This function is called during kernel startup to initialize ++ * the bvme6000 IRQ handling routines. ++ */ ++static void bvme6000_init_IRQ(void) ++{ ++ m68k_setup_user_interrupt(VEC_USER, 192, NULL); ++} + + void __init config_bvme6000(void) + { +@@ -127,12 +128,6 @@ + mach_hwclk = bvme6000_hwclk; + mach_set_clock_mmss = bvme6000_set_clock_mmss; + mach_reset = bvme6000_reset; +- mach_free_irq = bvme6000_free_irq; +- mach_process_int = bvme6000_process_int; +- mach_get_irq_list = show_bvme6000_interrupts; +- mach_request_irq = bvme6000_request_irq; +- enable_irq = bvme6000_enable_irq; +- disable_irq = bvme6000_disable_irq; + mach_get_model = bvme6000_get_model; + mach_get_hardware_list = bvme6000_get_hardware_list; + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/hp300/Makefile linux-m68k/arch/m68k/hp300/Makefile +--- linux-i386/arch/m68k/hp300/Makefile 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/hp300/Makefile 2006-01-28 23:52:26.000000000 +0100 +@@ -2,4 +2,4 @@ + # Makefile for Linux arch/m68k/hp300 source directory + # + +-obj-y := ksyms.o config.o ints.o time.o reboot.o ++obj-y := ksyms.o config.o time.o reboot.o +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/hp300/config.c linux-m68k/arch/m68k/hp300/config.c +--- linux-i386/arch/m68k/hp300/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/hp300/config.c 2006-01-28 23:52:26.000000000 +0100 +@@ -21,7 +21,6 @@ + #include + #include + +-#include "ints.h" + #include "time.h" + + unsigned long hp300_model; +@@ -64,8 +63,6 @@ + static char hp300_model_name[13] = "HP9000/"; + + extern void hp300_reset(void); +-extern irqreturn_t (*hp300_default_handler[])(int, void *, struct pt_regs *); +-extern int show_hp300_interrupts(struct seq_file *, void *); + #ifdef CONFIG_SERIAL_8250_CONSOLE + extern int hp300_setup_serial_console(void) __init; + #endif +@@ -245,16 +242,16 @@ + hp300_rtc_read(RTC_REG_SEC2); + } + ++static void __init hp300_init_IRQ(void) ++{ ++} ++ + void __init config_hp300(void) + { + mach_sched_init = hp300_sched_init; + mach_init_IRQ = hp300_init_IRQ; +- mach_request_irq = hp300_request_irq; +- mach_free_irq = hp300_free_irq; + mach_get_model = hp300_get_model; +- mach_get_irq_list = show_hp300_interrupts; + mach_gettimeoffset = hp300_gettimeoffset; +- mach_default_handler = &hp300_default_handler; + mach_hwclk = hp300_hwclk; + mach_get_ss = hp300_get_ss; + mach_reset = hp300_reset; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/hp300/time.c linux-m68k/arch/m68k/hp300/time.c +--- linux-i386/arch/m68k/hp300/time.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/hp300/time.c 2006-01-28 23:52:26.000000000 +0100 +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include "ints.h" + + /* Clock hardware definitions */ + +@@ -71,7 +70,7 @@ + + asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE)); + +- cpu_request_irq(6, hp300_tick, IRQ_FLG_STD, "timer tick", vector); ++ request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector); + + out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ + out_8(CLOCKBASE + CLKCR1, 0x40); /* enable irq */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/bios32.c linux-m68k/arch/m68k/kernel/bios32.c +--- linux-i386/arch/m68k/kernel/bios32.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/kernel/bios32.c 2004-10-20 01:06:39.000000000 +0200 +@@ -285,7 +285,7 @@ + + DBG_DEVS(("layout_bus: starting bus %d\n", bus->number)); + +- if (!bus->devices && !bus->children) ++ if (list_empty(&bus->devices) && list_empty(&bus->children)) + return; + + /* +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/entry.S linux-m68k/arch/m68k/kernel/entry.S +--- linux-i386/arch/m68k/kernel/entry.S 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/kernel/entry.S 2006-02-12 16:31:29.000000000 +0100 +@@ -45,9 +45,11 @@ + #include + + .globl system_call, buserr, trap, resume +-.globl inthandler, sys_call_table ++.globl sys_call_table + .globl sys_fork, sys_clone, sys_vfork + .globl ret_from_interrupt, bad_interrupt ++.globl auto_irqhandler_fixup ++.globl user_irqvec_fixup, user_irqhandler_fixup + + .text + ENTRY(buserr) +@@ -191,65 +193,29 @@ + jbra resume_userspace + + +-#if 0 +-#ifdef CONFIG_AMIGA +-ami_inthandler: +- addql #1,irq_stat+CPUSTAT_LOCAL_IRQ_COUNT +- SAVE_ALL_INT +- GET_CURRENT(%d0) ++/* This is the main interrupt handler for autovector interrupts */ + +- bfextu %sp@(PT_VECTOR){#4,#12},%d0 +- movel %d0,%a0 +- addql #1,%a0@(kstat+STAT_IRQ-VECOFF(VEC_SPUR)) +- movel %a0@(autoirq_list-VECOFF(VEC_SPUR)),%a0 +- +-| amiga vector int handler get the req mask instead of irq vector +- lea CUSTOMBASE,%a1 +- movew %a1@(C_INTREQR),%d0 +- andw %a1@(C_INTENAR),%d0 +- +-| prepare stack (push frame pointer, dev_id & req mask) +- pea %sp@ +- movel %a0@(IRQ_DEVID),%sp@- +- movel %d0,%sp@- +- pea %pc@(ret_from_interrupt:w) +- jbra @(IRQ_HANDLER,%a0)@(0) +- +-ENTRY(nmi_handler) +- rte +-#endif +-#endif +- +-/* +-** This is the main interrupt handler, responsible for calling process_int() +-*/ +-inthandler: ++ENTRY(auto_inthandler) + SAVE_ALL_INT + GET_CURRENT(%d0) +- addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+2) ++ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) + | put exception # in d0 +- bfextu %sp@(PT_VECTOR){#4,#10},%d0 ++ bfextu %sp@(PT_VECTOR){#4,#10},%d0 ++ subw #VEC_SPUR,%d0 + + movel %sp,%sp@- + movel %d0,%sp@- | put vector # on stack +-#if defined(MACH_Q40_ONLY) && defined(CONFIG_BLK_DEV_FD) +- btstb #4,0xff000000 | Q40 floppy needs very special treatment ... +- jbeq 1f +- btstb #3,0xff000004 +- jbeq 1f +- jbsr floppy_hardint +- jbra 3f +-1: +-#endif +- jbsr process_int | process the IRQ +-3: addql #8,%sp | pop parameters off stack ++auto_irqhandler_fixup = . + 2 ++ jsr m68k_handle_int | process the IRQ ++ addql #8,%sp | pop parameters off stack + + ret_from_interrupt: +- subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+2) +- jeq 1f +-2: +- RESTORE_ALL +-1: ++ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) ++ jeq ret_from_last_interrupt ++2: RESTORE_ALL ++ ++ ALIGN ++ret_from_last_interrupt: + moveq #(~ALLOWINT>>8)&0xff,%d0 + andb %sp@(PT_SR),%d0 + jne 2b +@@ -260,12 +226,42 @@ + pea ret_from_exception + jra do_softirq + ++/* Handler for user defined interrupt vectors */ ++ ++ENTRY(user_inthandler) ++ SAVE_ALL_INT ++ GET_CURRENT(%d0) ++ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) ++ | put exception # in d0 ++ bfextu %sp@(PT_VECTOR){#4,#10},%d0 ++user_irqvec_fixup = . + 2 ++ subw #VEC_USER,%d0 ++ ++ movel %sp,%sp@- ++ movel %d0,%sp@- | put vector # on stack ++user_irqhandler_fixup = . + 2 ++ jsr m68k_handle_int | process the IRQ ++ addql #8,%sp | pop parameters off stack ++ ++ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) ++ jeq ret_from_last_interrupt ++ RESTORE_ALL + + /* Handler for uninitialized and spurious interrupts */ + +-bad_interrupt: +- addql #1,num_spurious +- rte ++ENTRY(bad_inthandler) ++ SAVE_ALL_INT ++ GET_CURRENT(%d0) ++ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) ++ ++ movel %sp,%sp@- ++ jsr handle_badint ++ addql #4,%sp ++ ++ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) ++ jeq ret_from_last_interrupt ++ RESTORE_ALL ++ + + ENTRY(sys_fork) + SAVE_SWITCH_STACK +@@ -711,4 +707,9 @@ + .long sys_add_key + .long sys_request_key /* 280 */ + .long sys_keyctl ++ .long sys_ioprio_set ++ .long sys_ioprio_get ++ .long sys_inotify_init ++ .long sys_inotify_add_watch /* 285 */ ++ .long sys_inotify_rm_watch + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/ints.c linux-m68k/arch/m68k/kernel/ints.c +--- linux-i386/arch/m68k/kernel/ints.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/kernel/ints.c 2006-01-31 16:32:01.000000000 +0100 +@@ -39,47 +39,40 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_Q40 + #include + #endif + +-/* table for system interrupt handlers */ +-static irq_handler_t irq_list[SYS_IRQS]; ++extern u32 auto_irqhandler_fixup[]; ++extern u32 user_irqhandler_fixup[]; ++extern u16 user_irqvec_fixup[]; + +-static const char *default_names[SYS_IRQS] = { +- [0] = "spurious int", +- [1] = "int1 handler", +- [2] = "int2 handler", +- [3] = "int3 handler", +- [4] = "int4 handler", +- [5] = "int5 handler", +- [6] = "int6 handler", +- [7] = "int7 handler" ++/* table for system interrupt handlers */ ++static struct irq_node *irq_list[NR_IRQS]; ++static struct irq_controller *irq_controller[NR_IRQS]; ++static int irq_depth[NR_IRQS]; ++ ++static int m68k_first_user_vec; ++ ++static struct irq_controller auto_irq_controller = { ++ .name = "auto", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .startup = m68k_irq_startup, ++ .shutdown = m68k_irq_shutdown, + }; + +-/* The number of spurious interrupts */ +-volatile unsigned int num_spurious; ++static struct irq_controller user_irq_controller = { ++ .name = "user", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .startup = m68k_irq_startup, ++ .shutdown = m68k_irq_shutdown, ++}; + + #define NUM_IRQ_NODES 100 + static irq_node_t nodes[NUM_IRQ_NODES]; + +-static void dummy_enable_irq(unsigned int irq); +-static void dummy_disable_irq(unsigned int irq); +-static int dummy_request_irq(unsigned int irq, +- irqreturn_t (*handler) (int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id); +-static void dummy_free_irq(unsigned int irq, void *dev_id); +- +-void (*enable_irq) (unsigned int) = dummy_enable_irq; +-void (*disable_irq) (unsigned int) = dummy_disable_irq; +- +-int (*mach_request_irq) (unsigned int, irqreturn_t (*)(int, void *, struct pt_regs *), +- unsigned long, const char *, void *) = dummy_request_irq; +-void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq; +- +-void init_irq_proc(void); +- + /* + * void init_IRQ(void) + * +@@ -95,18 +88,76 @@ + { + int i; + +- for (i = 0; i < SYS_IRQS; i++) { +- if (mach_default_handler) +- irq_list[i].handler = (*mach_default_handler)[i]; +- irq_list[i].flags = 0; +- irq_list[i].dev_id = NULL; +- irq_list[i].devname = default_names[i]; ++ /* assembly irq entry code relies on this... */ ++ if (HARDIRQ_MASK != 0x00ff0000) { ++ extern void hardirq_mask_is_broken(void); ++ hardirq_mask_is_broken(); + } + +- for (i = 0; i < NUM_IRQ_NODES; i++) +- nodes[i].handler = NULL; ++ for (i = IRQ_AUTO_1; i < IRQ_USER; i++) ++ irq_controller[i] = &auto_irq_controller; ++ ++ mach_init_IRQ(); ++} ++ ++/** ++ * m68k_setup_auto_interrupt ++ * @handler: called from auto vector interrupts ++ * ++ * setup the handler to be called from auto vector interrupts instead of the ++ * standard m68k_handle_int(), it will be called with irq numbers in the range ++ * from IRQ_AUTO_1 - IRQ_AUTO_7. ++ */ ++void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) ++{ ++ if (handler) ++ *auto_irqhandler_fixup = (u32)handler; ++ flush_icache(); ++} ++ ++/** ++ * m68k_setup_user_interrupt ++ * @vec: first user vector interrupt to handle ++ * @cnt: number of active user vector interrupts ++ * @handler: called from user vector interrupts ++ * ++ * setup user vector interrupts, this includes activating the specified range ++ * of interrupts, only then these interrupts can be requested (note: this is ++ * different from auto vector interrupts). An optional handler can be installed ++ * to be called instead of the default m68k_handle_int(), it will be called ++ * with irq numbers starting from IRQ_USER. ++ */ ++void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, ++ void (*handler)(unsigned int, struct pt_regs *)) ++{ ++ int i; ++ ++ m68k_first_user_vec = vec; ++ for (i = 0; i < cnt; i++) ++ irq_controller[IRQ_USER + i] = &user_irq_controller; ++ *user_irqvec_fixup = vec - IRQ_USER; ++ if (handler) ++ *user_irqhandler_fixup = (u32)handler; ++ flush_icache(); ++} ++ ++/** ++ * m68k_setup_irq_controller ++ * @contr: irq controller which controls specified irq ++ * @irq: first irq to be managed by the controller ++ * ++ * Change the controller for the specified range of irq, which will be used to ++ * manage these irq. auto/user irq already have a default controller, which can ++ * be changed as well, but the controller probably should use m68k_irq_startup/ ++ * m68k_irq_shutdown. ++ */ ++void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq, ++ unsigned int cnt) ++{ ++ int i; + +- mach_init_IRQ (); ++ for (i = 0; i < cnt; i++) ++ irq_controller[irq + i] = contr; + } + + irq_node_t *new_irq_node(void) +@@ -114,84 +165,183 @@ + irq_node_t *node; + short i; + +- for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) +- if (!node->handler) ++ for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { ++ if (!node->handler) { ++ memset(node, 0, sizeof(*node)); + return node; ++ } ++ } + + printk ("new_irq_node: out of nodes\n"); + return NULL; + } + +-/* +- * We will keep these functions until I have convinced Linus to move +- * the declaration of them from include/linux/sched.h to +- * include/asm/irq.h. +- */ ++int setup_irq(unsigned int irq, struct irq_node *node) ++{ ++ struct irq_controller *contr; ++ struct irq_node **prev; ++ unsigned long flags; ++ ++ if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { ++ printk("%s: Incorrect IRQ %d from %s\n", ++ __FUNCTION__, irq, node->devname); ++ return -ENXIO; ++ } ++ ++ spin_lock_irqsave(&contr->lock, flags); ++ ++ prev = irq_list + irq; ++ if (*prev) { ++ /* Can't share interrupts unless both agree to */ ++ if (!((*prev)->flags & node->flags & SA_SHIRQ)) { ++ spin_unlock_irqrestore(&contr->lock, flags); ++ return -EBUSY; ++ } ++ while (*prev) ++ prev = &(*prev)->next; ++ } ++ ++ if (!irq_list[irq]) { ++ if (contr->startup) ++ contr->startup(irq); ++ else ++ contr->enable(irq); ++ } ++ node->next = NULL; ++ *prev = node; ++ ++ spin_unlock_irqrestore(&contr->lock, flags); ++ ++ return 0; ++} ++ + int request_irq(unsigned int irq, + irqreturn_t (*handler) (int, void *, struct pt_regs *), + unsigned long flags, const char *devname, void *dev_id) + { +- return mach_request_irq(irq, handler, flags, devname, dev_id); ++ struct irq_node *node; ++ int res; ++ ++ node = new_irq_node(); ++ if (!node) ++ return -ENOMEM; ++ ++ node->handler = handler; ++ node->flags = flags; ++ node->dev_id = dev_id; ++ node->devname = devname; ++ ++ res = setup_irq(irq, node); ++ if (res) ++ node->handler = NULL; ++ ++ return res; + } + + EXPORT_SYMBOL(request_irq); + + void free_irq(unsigned int irq, void *dev_id) + { +- mach_free_irq(irq, dev_id); ++ struct irq_controller *contr; ++ struct irq_node **p, *node; ++ unsigned long flags; ++ ++ if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { ++ printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); ++ return; ++ } ++ ++ spin_lock_irqsave(&contr->lock, flags); ++ ++ p = irq_list + irq; ++ while ((node = *p)) { ++ if (node->dev_id == dev_id) ++ break; ++ p = &node->next; ++ } ++ ++ if (node) { ++ *p = node->next; ++ node->handler = NULL; ++ } else ++ printk("%s: Removing probably wrong IRQ %d\n", ++ __FUNCTION__, irq); ++ ++ if (!irq_list[irq]) { ++ if (contr->shutdown) ++ contr->shutdown(irq); ++ else ++ contr->disable(irq); ++ } ++ ++ spin_unlock_irqrestore(&contr->lock, flags); + } + + EXPORT_SYMBOL(free_irq); + +-int cpu_request_irq(unsigned int irq, +- irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id) ++void enable_irq(unsigned int irq) + { +- if (irq < IRQ1 || irq > IRQ7) { +- printk("%s: Incorrect IRQ %d from %s\n", +- __FUNCTION__, irq, devname); +- return -ENXIO; +- } ++ struct irq_controller *contr; ++ unsigned long flags; + +-#if 0 +- if (!(irq_list[irq].flags & IRQ_FLG_STD)) { +- if (irq_list[irq].flags & IRQ_FLG_LOCK) { +- printk("%s: IRQ %d from %s is not replaceable\n", +- __FUNCTION__, irq, irq_list[irq].devname); +- return -EBUSY; +- } +- if (!(flags & IRQ_FLG_REPLACE)) { +- printk("%s: %s can't replace IRQ %d from %s\n", +- __FUNCTION__, devname, irq, irq_list[irq].devname); +- return -EBUSY; +- } ++ if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { ++ printk("%s: Incorrect IRQ %d\n", ++ __FUNCTION__, irq); ++ return; + } +-#endif + +- irq_list[irq].handler = handler; +- irq_list[irq].flags = flags; +- irq_list[irq].dev_id = dev_id; +- irq_list[irq].devname = devname; +- return 0; ++ spin_lock_irqsave(&contr->lock, flags); ++ if (irq_depth[irq]) { ++ if (!--irq_depth[irq]) { ++ if (contr->enable) ++ contr->enable(irq); ++ } ++ } else ++ WARN_ON(1); ++ spin_unlock_irqrestore(&contr->lock, flags); + } + +-void cpu_free_irq(unsigned int irq, void *dev_id) ++EXPORT_SYMBOL(enable_irq); ++ ++void disable_irq(unsigned int irq) + { +- if (irq < IRQ1 || irq > IRQ7) { +- printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq); ++ struct irq_controller *contr; ++ unsigned long flags; ++ ++ if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { ++ printk("%s: Incorrect IRQ %d\n", ++ __FUNCTION__, irq); + return; + } + +- if (irq_list[irq].dev_id != dev_id) +- printk("%s: Removing probably wrong IRQ %d from %s\n", +- __FUNCTION__, irq, irq_list[irq].devname); +- +- irq_list[irq].handler = (*mach_default_handler)[irq]; +- irq_list[irq].flags = 0; +- irq_list[irq].dev_id = NULL; +- irq_list[irq].devname = default_names[irq]; ++ spin_lock_irqsave(&contr->lock, flags); ++ if (!irq_depth[irq]++) { ++ if (contr->disable) ++ contr->disable(irq); ++ } ++ spin_unlock_irqrestore(&contr->lock, flags); ++} ++ ++EXPORT_SYMBOL(disable_irq); ++ ++int m68k_irq_startup(unsigned int irq) ++{ ++ if (irq < IRQ_USER) ++ vectors[VEC_SPUR + irq] = auto_inthandler; ++ else ++ vectors[m68k_first_user_vec + irq - IRQ_USER] = user_inthandler; ++ return 0; + } + ++void m68k_irq_shutdown(unsigned int irq) ++{ ++ if (irq < IRQ_USER) ++ vectors[VEC_SPUR + irq] = bad_inthandler; ++ else ++ vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler; ++} ++ ++ + /* + * Do we need these probe functions on the m68k? + * +@@ -219,58 +369,50 @@ + + EXPORT_SYMBOL(probe_irq_off); + +-static void dummy_enable_irq(unsigned int irq) ++unsigned int irq_canonicalize(unsigned int irq) + { +- printk("calling uninitialized enable_irq()\n"); ++#ifdef CONFIG_Q40 ++ if (MACH_IS_Q40 && irq == 11) ++ irq = 10; ++#endif ++ return irq; + } + +-static void dummy_disable_irq(unsigned int irq) +-{ +- printk("calling uninitialized disable_irq()\n"); +-} ++EXPORT_SYMBOL(irq_canonicalize); + +-static int dummy_request_irq(unsigned int irq, +- irqreturn_t (*handler) (int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id) ++asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs) + { +- printk("calling uninitialized request_irq()\n"); +- return 0; +-} ++ struct irq_node *node; + +-static void dummy_free_irq(unsigned int irq, void *dev_id) +-{ +- printk("calling uninitialized disable_irq()\n"); ++ kstat_cpu(0).irqs[irq]++; ++ node = irq_list[irq]; ++ do { ++ node->handler(irq, node->dev_id, regs); ++ node = node->next; ++ } while (node); + } + +-asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) ++asmlinkage void handle_badint(struct pt_regs *regs) + { +- if (vec >= VEC_INT1 && vec <= VEC_INT7 && !MACH_IS_BVME6000) { +- vec -= VEC_SPUR; +- kstat_cpu(0).irqs[vec]++; +- irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); +- } else { +- if (mach_process_int) +- mach_process_int(vec, fp); +- else +- panic("Can't process interrupt vector %ld\n", vec); +- return; +- } ++ kstat_cpu(0).irqs[0]++; ++ printk("unexpected interrupt from %u\n", regs->vector); + } + + int show_interrupts(struct seq_file *p, void *v) + { ++ struct irq_controller *contr; ++ struct irq_node *node; + int i = *(loff_t *) v; + + /* autovector interrupts */ +- if (i < SYS_IRQS) { +- if (mach_default_handler) { +- seq_printf(p, "auto %2d: %10u ", i, +- i ? kstat_cpu(0).irqs[i] : num_spurious); +- seq_puts(p, " "); +- seq_printf(p, "%s\n", irq_list[i].devname); +- } +- } else if (i == SYS_IRQS) +- mach_get_irq_list(p, v); ++ if (irq_list[i]) { ++ contr = irq_controller[i]; ++ node = irq_list[i]; ++ seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); ++ while ((node = node->next)) ++ seq_printf(p, ", %s", node->devname); ++ seq_puts(p, "\n"); ++ } + return 0; + } + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/m68k_ksyms.c linux-m68k/arch/m68k/kernel/m68k_ksyms.c +--- linux-i386/arch/m68k/kernel/m68k_ksyms.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/kernel/m68k_ksyms.c 2006-04-11 16:32:22.000000000 +0200 +@@ -58,8 +58,6 @@ + EXPORT_SYMBOL(strrchr); + EXPORT_SYMBOL(strstr); + EXPORT_SYMBOL(strpbrk); +-EXPORT_SYMBOL(enable_irq); +-EXPORT_SYMBOL(disable_irq); + EXPORT_SYMBOL(kernel_thread); + #ifdef CONFIG_VME + EXPORT_SYMBOL(vme_brdtype); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/setup.c linux-m68k/arch/m68k/kernel/setup.c +--- linux-i386/arch/m68k/kernel/setup.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/kernel/setup.c 2006-04-11 16:32:22.000000000 +0200 +@@ -68,11 +68,8 @@ + void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; + /* machine dependent irq functions */ + void (*mach_init_IRQ) (void) __initdata = NULL; +-irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); + void (*mach_get_model) (char *model); + int (*mach_get_hardware_list) (char *buffer); +-int (*mach_get_irq_list) (struct seq_file *, void *); +-irqreturn_t (*mach_process_int) (int, struct pt_regs *); + /* machine dependent timer functions */ + unsigned long (*mach_gettimeoffset) (void); + int (*mach_hwclk) (int, struct rtc_time*); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/traps.c linux-m68k/arch/m68k/kernel/traps.c +--- linux-i386/arch/m68k/kernel/traps.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/kernel/traps.c 2006-04-11 16:32:22.000000000 +0200 +@@ -45,7 +45,6 @@ + asmlinkage void system_call(void); + asmlinkage void buserr(void); + asmlinkage void trap(void); +-asmlinkage void inthandler(void); + asmlinkage void nmihandler(void); + #ifdef CONFIG_M68KFPU_EMU + asmlinkage void fpu_emu(void); +@@ -53,51 +52,7 @@ + + e_vector vectors[256] = { + [VEC_BUSERR] = buserr, +- [VEC_ADDRERR] = trap, +- [VEC_ILLEGAL] = trap, +- [VEC_ZERODIV] = trap, +- [VEC_CHK] = trap, +- [VEC_TRAP] = trap, +- [VEC_PRIV] = trap, +- [VEC_TRACE] = trap, +- [VEC_LINE10] = trap, +- [VEC_LINE11] = trap, +- [VEC_RESV12] = trap, +- [VEC_COPROC] = trap, +- [VEC_FORMAT] = trap, +- [VEC_UNINT] = trap, +- [VEC_RESV16] = trap, +- [VEC_RESV17] = trap, +- [VEC_RESV18] = trap, +- [VEC_RESV19] = trap, +- [VEC_RESV20] = trap, +- [VEC_RESV21] = trap, +- [VEC_RESV22] = trap, +- [VEC_RESV23] = trap, +- [VEC_SPUR] = inthandler, +- [VEC_INT1] = inthandler, +- [VEC_INT2] = inthandler, +- [VEC_INT3] = inthandler, +- [VEC_INT4] = inthandler, +- [VEC_INT5] = inthandler, +- [VEC_INT6] = inthandler, +- [VEC_INT7] = inthandler, + [VEC_SYS] = system_call, +- [VEC_TRAP1] = trap, +- [VEC_TRAP2] = trap, +- [VEC_TRAP3] = trap, +- [VEC_TRAP4] = trap, +- [VEC_TRAP5] = trap, +- [VEC_TRAP6] = trap, +- [VEC_TRAP7] = trap, +- [VEC_TRAP8] = trap, +- [VEC_TRAP9] = trap, +- [VEC_TRAP10] = trap, +- [VEC_TRAP11] = trap, +- [VEC_TRAP12] = trap, +- [VEC_TRAP13] = trap, +- [VEC_TRAP14] = trap, +- [VEC_TRAP15] = trap, + }; + + /* nmi handler for the Amiga */ +@@ -132,12 +87,15 @@ + { + int i; + +- for (i = 48; i < 64; i++) ++ for (i = VEC_SPUR; i <= VEC_INT7; i++) ++ vectors[i] = bad_inthandler; ++ ++ for (i = 0; i < VEC_USER; i++) + if (!vectors[i]) + vectors[i] = trap; + +- for (i = 64; i < 256; i++) +- vectors[i] = inthandler; ++ for (i = VEC_USER; i < 256; i++) ++ vectors[i] = bad_inthandler; + + #ifdef CONFIG_M68KFPU_EMU + if (FPU_IS_EMU) +@@ -992,6 +950,7 @@ + + void show_stack(struct task_struct *task, unsigned long *stack) + { ++ unsigned long *p; + unsigned long *endstack; + int i; + +@@ -1004,12 +963,13 @@ + endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); + + printk("Stack from %08lx:", (unsigned long)stack); ++ p = stack; + for (i = 0; i < kstack_depth_to_print; i++) { +- if (stack + 1 > endstack) ++ if (p + 1 > endstack) + break; + if (i % 8 == 0) + printk("\n "); +- printk(" %08lx", *stack++); ++ printk(" %08lx", *p++); + } + printk("\n"); + show_trace(stack); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/baboon.c linux-m68k/arch/m68k/mac/baboon.c +--- linux-i386/arch/m68k/mac/baboon.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mac/baboon.c 2006-01-28 23:52:27.000000000 +0100 +@@ -81,7 +81,7 @@ + for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { + if (events & irq_bit/* & baboon_active*/) { + baboon_active &= ~irq_bit; +- mac_do_irq_list(IRQ_BABOON_0 + i, regs); ++ m68k_handle_int(IRQ_BABOON_0 + i, regs); + baboon_active |= irq_bit; + baboon->mb_ifr &= ~irq_bit; + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/config.c linux-m68k/arch/m68k/mac/config.c +--- linux-i386/arch/m68k/mac/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mac/config.c 2006-01-28 23:52:27.000000000 +0100 +@@ -107,20 +107,6 @@ + } + #endif + +-extern irqreturn_t mac_default_handler(int, void *, struct pt_regs *); +- +-irqreturn_t (*mac_handlers[8])(int, void *, struct pt_regs *)= +-{ +- mac_default_handler, +- mac_default_handler, +- mac_default_handler, +- mac_default_handler, +- mac_default_handler, +- mac_default_handler, +- mac_default_handler, +- mac_default_handler +-}; +- + /* + * Parse a Macintosh-specific record in the bootinfo + */ +@@ -196,13 +182,7 @@ + + mach_sched_init = mac_sched_init; + mach_init_IRQ = mac_init_IRQ; +- mach_request_irq = mac_request_irq; +- mach_free_irq = mac_free_irq; +- enable_irq = mac_enable_irq; +- disable_irq = mac_disable_irq; + mach_get_model = mac_get_model; +- mach_default_handler = &mac_handlers; +- mach_get_irq_list = show_mac_interrupts; + mach_gettimeoffset = mac_gettimeoffset; + #warning move to adb/via init + #if 0 +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/iop.c linux-m68k/arch/m68k/mac/iop.c +--- linux-i386/arch/m68k/mac/iop.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mac/iop.c 2006-04-11 16:32:23.000000000 +0200 +@@ -317,7 +317,7 @@ + { + if (iop_ism_present) { + if (oss_present) { +- cpu_request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, ++ request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, + IRQ_FLG_LOCK, "ISM IOP", + (void *) IOP_NUM_ISM); + oss_irq_enable(IRQ_MAC_ADB); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/macints.c linux-m68k/arch/m68k/mac/macints.c +--- linux-i386/arch/m68k/mac/macints.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mac/macints.c 2006-01-28 23:52:27.000000000 +0100 +@@ -137,14 +137,6 @@ + #define DEBUG_SPURIOUS + #define SHUTUP_SONIC + +-/* +- * The mac_irq_list array is an array of linked lists of irq_node_t nodes. +- * Each node contains one handler to be called whenever the interrupt +- * occurs, with fast handlers listed before slow handlers. +- */ +- +-irq_node_t *mac_irq_list[NUM_MAC_SOURCES]; +- + /* SCC interrupt mask */ + + static int scc_mask; +@@ -209,8 +201,8 @@ + * SCC interrupt routines + */ + +-static void scc_irq_enable(int); +-static void scc_irq_disable(int); ++static void scc_irq_enable(unsigned int); ++static void scc_irq_disable(unsigned int); + + /* + * console_loglevel determines NMI handler function +@@ -222,21 +214,25 @@ + + /* #define DEBUG_MACINTS */ + ++static void mac_enable_irq(unsigned int irq); ++static void mac_disable_irq(unsigned int irq); ++ ++static struct irq_controller mac_irq_controller = { ++ .name = "mac", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .enable = mac_enable_irq, ++ .disable = mac_disable_irq, ++}; ++ + void mac_init_IRQ(void) + { +- int i; +- + #ifdef DEBUG_MACINTS + printk("mac_init_IRQ(): Setting things up...\n"); + #endif +- /* Initialize the IRQ handler lists. Initially each list is empty, */ +- +- for (i = 0; i < NUM_MAC_SOURCES; i++) { +- mac_irq_list[i] = NULL; +- } +- + scc_mask = 0; + ++ m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, ++ NUM_MAC_SOURCES - IRQ_USER); + /* Make sure the SONIC interrupt is cleared or things get ugly */ + #ifdef SHUTUP_SONIC + printk("Killing onboard sonic... "); +@@ -253,15 +249,16 @@ + * at levels 1-7. Most of the work is done elsewhere. + */ + +- if (oss_present) { ++ if (oss_present) + oss_register_interrupts(); +- } else { ++ else + via_register_interrupts(); +- } +- if (psc_present) psc_register_interrupts(); +- if (baboon_present) baboon_register_interrupts(); ++ if (psc_present) ++ psc_register_interrupts(); ++ if (baboon_present) ++ baboon_register_interrupts(); + iop_register_interrupts(); +- cpu_request_irq(7, mac_nmi_handler, IRQ_FLG_LOCK, "NMI", ++ request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI", + mac_nmi_handler); + #ifdef DEBUG_MACINTS + printk("mac_init_IRQ(): Done!\n"); +@@ -269,104 +266,6 @@ + } + + /* +- * Routines to work with irq_node_t's on linked lists lifted from +- * the Amiga code written by Roman Zippel. +- */ +- +-static inline void mac_insert_irq(irq_node_t **list, irq_node_t *node) +-{ +- unsigned long flags; +- irq_node_t *cur; +- +- if (!node->dev_id) +- printk("%s: Warning: dev_id of %s is zero\n", +- __FUNCTION__, node->devname); +- +- local_irq_save(flags); +- +- cur = *list; +- +- if (node->flags & IRQ_FLG_FAST) { +- node->flags &= ~IRQ_FLG_SLOW; +- while (cur && cur->flags & IRQ_FLG_FAST) { +- list = &cur->next; +- cur = cur->next; +- } +- } else if (node->flags & IRQ_FLG_SLOW) { +- while (cur) { +- list = &cur->next; +- cur = cur->next; +- } +- } else { +- while (cur && !(cur->flags & IRQ_FLG_SLOW)) { +- list = &cur->next; +- cur = cur->next; +- } +- } +- +- node->next = cur; +- *list = node; +- +- local_irq_restore(flags); +-} +- +-static inline void mac_delete_irq(irq_node_t **list, void *dev_id) +-{ +- unsigned long flags; +- irq_node_t *node; +- +- local_irq_save(flags); +- +- for (node = *list; node; list = &node->next, node = *list) { +- if (node->dev_id == dev_id) { +- *list = node->next; +- /* Mark it as free. */ +- node->handler = NULL; +- local_irq_restore(flags); +- return; +- } +- } +- local_irq_restore(flags); +- printk ("%s: tried to remove invalid irq\n", __FUNCTION__); +-} +- +-/* +- * Call all the handlers for a given interrupt. Fast handlers are called +- * first followed by slow handlers. +- * +- * This code taken from the original Amiga code written by Roman Zippel. +- */ +- +-void mac_do_irq_list(int irq, struct pt_regs *fp) +-{ +- irq_node_t *node, *slow_nodes; +- unsigned long flags; +- +- kstat_cpu(0).irqs[irq]++; +- +-#ifdef DEBUG_SPURIOUS +- if (!mac_irq_list[irq] && (console_loglevel > 7)) { +- printk("mac_do_irq_list: spurious interrupt %d!\n", irq); +- return; +- } +-#endif +- +- /* serve first fast and normal handlers */ +- for (node = mac_irq_list[irq]; +- node && (!(node->flags & IRQ_FLG_SLOW)); +- node = node->next) +- node->handler(irq, node->dev_id, fp); +- if (!node) return; +- local_save_flags(flags); +- local_irq_restore((flags & ~0x0700) | (fp->sr & 0x0700)); +- /* if slow handlers exists, serve them now */ +- slow_nodes = node; +- for (; node; node = node->next) { +- node->handler(irq, node->dev_id, fp); +- } +-} +- +-/* + * mac_enable_irq - enable an interrupt source + * mac_disable_irq - disable an interrupt source + * mac_clear_irq - clears a pending interrupt +@@ -375,276 +274,124 @@ + * These routines are just dispatchers to the VIA/OSS/PSC routines. + */ + +-void mac_enable_irq (unsigned int irq) ++static void mac_enable_irq(unsigned int irq) + { +- int irq_src = IRQ_SRC(irq); ++ int irq_src = IRQ_SRC(irq); + + switch(irq_src) { +- case 1: via_irq_enable(irq); +- break; +- case 2: +- case 7: if (oss_present) { +- oss_irq_enable(irq); +- } else { +- via_irq_enable(irq); +- } +- break; +- case 3: +- case 4: +- case 5: +- case 6: if (psc_present) { +- psc_irq_enable(irq); +- } else if (oss_present) { +- oss_irq_enable(irq); +- } else if (irq_src == 4) { +- scc_irq_enable(irq); +- } +- break; +- case 8: if (baboon_present) { +- baboon_irq_enable(irq); +- } +- break; ++ case 1: ++ via_irq_enable(irq); ++ break; ++ case 2: ++ case 7: ++ if (oss_present) ++ oss_irq_enable(irq); ++ else ++ via_irq_enable(irq); ++ break; ++ case 3: ++ case 4: ++ case 5: ++ case 6: ++ if (psc_present) ++ psc_irq_enable(irq); ++ else if (oss_present) ++ oss_irq_enable(irq); ++ else if (irq_src == 4) ++ scc_irq_enable(irq); ++ break; ++ case 8: ++ if (baboon_present) ++ baboon_irq_enable(irq); ++ break; + } + } + +-void mac_disable_irq (unsigned int irq) ++static void mac_disable_irq(unsigned int irq) + { +- int irq_src = IRQ_SRC(irq); ++ int irq_src = IRQ_SRC(irq); + + switch(irq_src) { +- case 1: via_irq_disable(irq); +- break; +- case 2: +- case 7: if (oss_present) { +- oss_irq_disable(irq); +- } else { +- via_irq_disable(irq); +- } +- break; +- case 3: +- case 4: +- case 5: +- case 6: if (psc_present) { +- psc_irq_disable(irq); +- } else if (oss_present) { +- oss_irq_disable(irq); +- } else if (irq_src == 4) { +- scc_irq_disable(irq); +- } +- break; +- case 8: if (baboon_present) { +- baboon_irq_disable(irq); +- } +- break; ++ case 1: ++ via_irq_disable(irq); ++ break; ++ case 2: ++ case 7: ++ if (oss_present) ++ oss_irq_disable(irq); ++ else ++ via_irq_disable(irq); ++ break; ++ case 3: ++ case 4: ++ case 5: ++ case 6: ++ if (psc_present) ++ psc_irq_disable(irq); ++ else if (oss_present) ++ oss_irq_disable(irq); ++ else if (irq_src == 4) ++ scc_irq_disable(irq); ++ break; ++ case 8: ++ if (baboon_present) ++ baboon_irq_disable(irq); ++ break; + } + } + +-void mac_clear_irq( unsigned int irq ) ++void mac_clear_irq(unsigned int irq) + { + switch(IRQ_SRC(irq)) { +- case 1: via_irq_clear(irq); +- break; +- case 2: +- case 7: if (oss_present) { +- oss_irq_clear(irq); +- } else { +- via_irq_clear(irq); +- } +- break; +- case 3: +- case 4: +- case 5: +- case 6: if (psc_present) { +- psc_irq_clear(irq); +- } else if (oss_present) { +- oss_irq_clear(irq); +- } +- break; +- case 8: if (baboon_present) { +- baboon_irq_clear(irq); +- } +- break; ++ case 1: ++ via_irq_clear(irq); ++ break; ++ case 2: ++ case 7: ++ if (oss_present) ++ oss_irq_clear(irq); ++ else ++ via_irq_clear(irq); ++ break; ++ case 3: ++ case 4: ++ case 5: ++ case 6: ++ if (psc_present) ++ psc_irq_clear(irq); ++ else if (oss_present) ++ oss_irq_clear(irq); ++ break; ++ case 8: ++ if (baboon_present) ++ baboon_irq_clear(irq); ++ break; + } + } + +-int mac_irq_pending( unsigned int irq ) ++int mac_irq_pending(unsigned int irq) + { + switch(IRQ_SRC(irq)) { +- case 1: return via_irq_pending(irq); +- case 2: +- case 7: if (oss_present) { +- return oss_irq_pending(irq); +- } else { +- return via_irq_pending(irq); +- } +- case 3: +- case 4: +- case 5: +- case 6: if (psc_present) { +- return psc_irq_pending(irq); +- } else if (oss_present) { +- return oss_irq_pending(irq); +- } +- } +- return 0; +-} +- +-/* +- * Add an interrupt service routine to an interrupt source. +- * Returns 0 on success. +- * +- * FIXME: You can register interrupts on nonexistent source (ie PSC4 on a +- * non-PSC machine). We should return -EINVAL in those cases. +- */ +- +-int mac_request_irq(unsigned int irq, +- irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id) +-{ +- irq_node_t *node; +- +-#ifdef DEBUG_MACINTS +- printk ("%s: irq %d requested for %s\n", __FUNCTION__, irq, devname); +-#endif +- +- if (irq < VIA1_SOURCE_BASE) { +- return cpu_request_irq(irq, handler, flags, devname, dev_id); ++ case 1: ++ return via_irq_pending(irq); ++ case 2: ++ case 7: ++ if (oss_present) ++ return oss_irq_pending(irq); ++ else ++ return via_irq_pending(irq); ++ case 3: ++ case 4: ++ case 5: ++ case 6: ++ if (psc_present) ++ return psc_irq_pending(irq); ++ else if (oss_present) ++ return oss_irq_pending(irq); + } +- +- if (irq >= NUM_MAC_SOURCES) { +- printk ("%s: unknown irq %d requested by %s\n", +- __FUNCTION__, irq, devname); +- } +- +- /* Get a node and stick it onto the right list */ +- +- if (!(node = new_irq_node())) return -ENOMEM; +- +- node->handler = handler; +- node->flags = flags; +- node->dev_id = dev_id; +- node->devname = devname; +- node->next = NULL; +- mac_insert_irq(&mac_irq_list[irq], node); +- +- /* Now enable the IRQ source */ +- +- mac_enable_irq(irq); +- + return 0; + } + +-/* +- * Removes an interrupt service routine from an interrupt source. +- */ +- +-void mac_free_irq(unsigned int irq, void *dev_id) +-{ +-#ifdef DEBUG_MACINTS +- printk ("%s: irq %d freed by %p\n", __FUNCTION__, irq, dev_id); +-#endif +- +- if (irq < VIA1_SOURCE_BASE) { +- cpu_free_irq(irq, dev_id); +- return; +- } +- +- if (irq >= NUM_MAC_SOURCES) { +- printk ("%s: unknown irq %d freed\n", +- __FUNCTION__, irq); +- return; +- } +- +- mac_delete_irq(&mac_irq_list[irq], dev_id); +- +- /* If the list for this interrupt is */ +- /* empty then disable the source. */ +- +- if (!mac_irq_list[irq]) { +- mac_disable_irq(irq); +- } +-} +- +-/* +- * Generate a pretty listing for /proc/interrupts +- * +- * By the time we're called the autovector interrupt list has already been +- * generated, so we just need to do the machspec interrupts. +- * +- * 990506 (jmt) - rewritten to handle chained machspec interrupt handlers. +- * Also removed display of num_spurious it is already +- * displayed for us as autovector irq 0. +- */ +- +-int show_mac_interrupts(struct seq_file *p, void *v) +-{ +- int i; +- irq_node_t *node; +- char *base; +- +- /* Don't do Nubus interrupts in this loop; we do them separately */ +- /* below so that we can print slot numbers instead of IRQ numbers */ +- +- for (i = VIA1_SOURCE_BASE ; i < NUM_MAC_SOURCES ; ++i) { +- +- /* Nonexistant interrupt or nothing registered; skip it. */ +- +- if ((node = mac_irq_list[i]) == NULL) continue; +- if (node->flags & IRQ_FLG_STD) continue; +- +- base = ""; +- switch(IRQ_SRC(i)) { +- case 1: base = "via1"; +- break; +- case 2: if (oss_present) { +- base = "oss"; +- } else { +- base = "via2"; +- } +- break; +- case 3: +- case 4: +- case 5: +- case 6: if (psc_present) { +- base = "psc"; +- } else if (oss_present) { +- base = "oss"; +- } else { +- if (IRQ_SRC(i) == 4) base = "scc"; +- } +- break; +- case 7: base = "nbus"; +- break; +- case 8: base = "bbn"; +- break; +- } +- seq_printf(p, "%4s %2d: %10u ", base, i, kstat_cpu(0).irqs[i]); +- +- do { +- if (node->flags & IRQ_FLG_FAST) { +- seq_puts(p, "F "); +- } else if (node->flags & IRQ_FLG_SLOW) { +- seq_puts(p, "S "); +- } else { +- seq_puts(p, " "); +- } +- seq_printf(p, "%s\n", node->devname); +- if ((node = node->next)) { +- seq_puts(p, " "); +- } +- } while(node); +- +- } +- return 0; +-} +- +-void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs) +-{ +-#ifdef DEBUG_SPURIOUS +- printk("Unexpected IRQ %d on device %p\n", irq, dev_id); +-#endif +-} +- + static int num_debug[8]; + + irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs) +@@ -684,7 +431,7 @@ + while (nmi_hold == 1) + udelay(1000); + +- if ( console_loglevel >= 8 ) { ++ if (console_loglevel >= 8) { + #if 0 + show_state(); + printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); +@@ -713,14 +460,16 @@ + * done in hardware (only the PSC can do that.) + */ + +-static void scc_irq_enable(int irq) { +- int irq_idx = IRQ_IDX(irq); ++static void scc_irq_enable(unsigned int irq) ++{ ++ int irq_idx = IRQ_IDX(irq); + + scc_mask |= (1 << irq_idx); + } + +-static void scc_irq_disable(int irq) { +- int irq_idx = IRQ_IDX(irq); ++static void scc_irq_disable(unsigned int irq) ++{ ++ int irq_idx = IRQ_IDX(irq); + + scc_mask &= ~(1 << irq_idx); + } +@@ -755,6 +504,8 @@ + /* and since they're autovector interrupts they */ + /* pretty much kill the system. */ + +- if (reg & 0x38) mac_do_irq_list(IRQ_SCCA, regs); +- if (reg & 0x07) mac_do_irq_list(IRQ_SCCB, regs); ++ if (reg & 0x38) ++ m68k_handle_int(IRQ_SCCA, regs); ++ if (reg & 0x07) ++ m68k_handle_int(IRQ_SCCB, regs); + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/oss.c linux-m68k/arch/m68k/mac/oss.c +--- linux-i386/arch/m68k/mac/oss.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mac/oss.c 2006-01-28 23:52:27.000000000 +0100 +@@ -67,15 +67,15 @@ + + void __init oss_register_interrupts(void) + { +- cpu_request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, ++ request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, + "scsi", (void *) oss); +- cpu_request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, ++ request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK, + "scc", mac_scc_dispatch); +- cpu_request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, ++ request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, + "nubus", (void *) oss); +- cpu_request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, ++ request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, + "sound", (void *) oss); +- cpu_request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, ++ request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, + "via1", (void *) via1); + } + +@@ -113,7 +113,7 @@ + oss->irq_pending &= ~OSS_IP_SOUND; + } else if (events & OSS_IP_SCSI) { + oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; +- mac_do_irq_list(IRQ_MAC_SCSI, regs); ++ m68k_handle_int(IRQ_MAC_SCSI, regs); + oss->irq_pending &= ~OSS_IP_SCSI; + oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; + } else { +@@ -146,7 +146,7 @@ + for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { + if (events & irq_bit) { + oss->irq_level[i] = OSS_IRQLEV_DISABLED; +- mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs); ++ m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); + oss->irq_pending &= ~irq_bit; + oss->irq_level[i] = OSS_IRQLEV_NUBUS; + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/psc.c linux-m68k/arch/m68k/mac/psc.c +--- linux-i386/arch/m68k/mac/psc.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mac/psc.c 2006-01-28 23:52:27.000000000 +0100 +@@ -117,10 +117,10 @@ + + void __init psc_register_interrupts(void) + { +- cpu_request_irq(3, psc_irq, IRQ_FLG_LOCK, "psc3", (void *) 0x30); +- cpu_request_irq(4, psc_irq, IRQ_FLG_LOCK, "psc4", (void *) 0x40); +- cpu_request_irq(5, psc_irq, IRQ_FLG_LOCK, "psc5", (void *) 0x50); +- cpu_request_irq(6, psc_irq, IRQ_FLG_LOCK, "psc6", (void *) 0x60); ++ request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30); ++ request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40); ++ request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50); ++ request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60); + } + + /* +@@ -149,7 +149,7 @@ + for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) { + if (events & irq_bit) { + psc_write_byte(pIER, irq_bit); +- mac_do_irq_list(base_irq + i, regs); ++ m68k_handle_int(base_irq + i, regs); + psc_write_byte(pIFR, irq_bit); + psc_write_byte(pIER, irq_bit | 0x80); + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/via.c linux-m68k/arch/m68k/mac/via.c +--- linux-i386/arch/m68k/mac/via.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mac/via.c 2006-01-28 23:52:27.000000000 +0100 +@@ -260,27 +260,27 @@ + void __init via_register_interrupts(void) + { + if (via_alt_mapping) { +- cpu_request_irq(IRQ_AUTO_1, via1_irq, ++ request_irq(IRQ_AUTO_1, via1_irq, + IRQ_FLG_LOCK|IRQ_FLG_FAST, "software", + (void *) via1); +- cpu_request_irq(IRQ_AUTO_6, via1_irq, ++ request_irq(IRQ_AUTO_6, via1_irq, + IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", + (void *) via1); + } else { +- cpu_request_irq(IRQ_AUTO_1, via1_irq, ++ request_irq(IRQ_AUTO_1, via1_irq, + IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", + (void *) via1); + #if 0 /* interferes with serial on some machines */ + if (!psc_present) { +- cpu_request_irq(IRQ_AUTO_6, mac_bang, IRQ_FLG_LOCK, ++ request_irq(IRQ_AUTO_6, mac_bang, IRQ_FLG_LOCK, + "Off Switch", mac_bang); + } + #endif + } +- cpu_request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, ++ request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, + "via2", (void *) via2); + if (!psc_present) { +- cpu_request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK, ++ request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK, + "scc", mac_scc_dispatch); + } + request_irq(IRQ_MAC_NUBUS, via_nubus_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, +@@ -437,7 +437,7 @@ + for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) + if (events & irq_bit) { + via1[vIER] = irq_bit; +- mac_do_irq_list(VIA1_SOURCE_BASE + i, regs); ++ m68k_handle_int(VIA1_SOURCE_BASE + i, regs); + via1[vIFR] = irq_bit; + via1[vIER] = irq_bit | 0x80; + } +@@ -452,7 +452,7 @@ + /* No, it won't be set. that's why we're doing this. */ + via_irq_disable(IRQ_MAC_NUBUS); + via_irq_clear(IRQ_MAC_NUBUS); +- mac_do_irq_list(IRQ_MAC_NUBUS, regs); ++ m68k_handle_int(IRQ_MAC_NUBUS, regs); + via_irq_enable(IRQ_MAC_NUBUS); + } + #endif +@@ -471,7 +471,7 @@ + for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) + if (events & irq_bit) { + via2[gIER] = irq_bit; +- mac_do_irq_list(VIA2_SOURCE_BASE + i, regs); ++ m68k_handle_int(VIA2_SOURCE_BASE + i, regs); + via2[gIFR] = irq_bit | rbv_clear; + via2[gIER] = irq_bit | 0x80; + } +@@ -494,7 +494,7 @@ + for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) { + if (events & irq_bit) { + via_irq_disable(NUBUS_SOURCE_BASE + i); +- mac_do_irq_list(NUBUS_SOURCE_BASE + i, regs); ++ m68k_handle_int(NUBUS_SOURCE_BASE + i, regs); + via_irq_enable(NUBUS_SOURCE_BASE + i); + } + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mm/motorola.c linux-m68k/arch/m68k/mm/motorola.c +--- linux-i386/arch/m68k/mm/motorola.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mm/motorola.c 2006-01-28 23:52:28.000000000 +0100 +@@ -203,7 +203,7 @@ + { + int chunk; + unsigned long mem_avail = 0; +- unsigned long zones_size[3] = { 0, }; ++ unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + + #ifdef DEBUG + { +@@ -257,12 +257,12 @@ + #ifdef DEBUG + printk ("before free_area_init\n"); + #endif +- zones_size[0] = (mach_max_dma_address < (unsigned long)high_memory ? +- (mach_max_dma_address+1) : (unsigned long)high_memory); +- zones_size[1] = (unsigned long)high_memory - zones_size[0]; ++ zones_size[ZONE_DMA] = (mach_max_dma_address < (unsigned long)high_memory ? ++ (mach_max_dma_address+1) : (unsigned long)high_memory); ++ zones_size[ZONE_NORMAL] = (unsigned long)high_memory - zones_size[0]; + +- zones_size[0] = (zones_size[0] - PAGE_OFFSET) >> PAGE_SHIFT; +- zones_size[1] >>= PAGE_SHIFT; ++ zones_size[ZONE_DMA] = (zones_size[ZONE_DMA] - PAGE_OFFSET) >> PAGE_SHIFT; ++ zones_size[ZONE_NORMAL] >>= PAGE_SHIFT; + + free_area_init(zones_size); + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mm/sun3mmu.c linux-m68k/arch/m68k/mm/sun3mmu.c +--- linux-i386/arch/m68k/mm/sun3mmu.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mm/sun3mmu.c 2006-01-28 23:52:28.000000000 +0100 +@@ -46,7 +46,7 @@ + unsigned long address; + unsigned long next_pgtable; + unsigned long bootmem_end; +- unsigned long zones_size[3] = {0, 0, 0}; ++ unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + unsigned long size; + + +@@ -92,8 +92,7 @@ + current->mm = NULL; + + /* memory sizing is a hack stolen from motorola.c.. hope it works for us */ +- zones_size[0] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT; +- zones_size[1] = 0; ++ zones_size[ZONE_DMA] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT; + + free_area_init(zones_size); + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mvme147/Makefile linux-m68k/arch/m68k/mvme147/Makefile +--- linux-i386/arch/m68k/mvme147/Makefile 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mvme147/Makefile 2006-01-28 23:52:28.000000000 +0100 +@@ -2,4 +2,4 @@ + # Makefile for Linux arch/m68k/mvme147 source directory + # + +-obj-y := config.o 147ints.o ++obj-y := config.o +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mvme147/config.c linux-m68k/arch/m68k/mvme147/config.c +--- linux-i386/arch/m68k/mvme147/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mvme147/config.c 2006-01-28 23:52:28.000000000 +0100 +@@ -36,15 +36,8 @@ + #include + + +-extern irqreturn_t mvme147_process_int (int level, struct pt_regs *regs); +-extern void mvme147_init_IRQ (void); +-extern void mvme147_free_irq (unsigned int, void *); +-extern int show_mvme147_interrupts (struct seq_file *, void *); +-extern void mvme147_enable_irq (unsigned int); +-extern void mvme147_disable_irq (unsigned int); + static void mvme147_get_model(char *model); + static int mvme147_get_hardware_list(char *buffer); +-extern int mvme147_request_irq (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); + extern void mvme147_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); + extern unsigned long mvme147_gettimeoffset (void); + extern int mvme147_hwclk (int, struct rtc_time *); +@@ -91,6 +84,15 @@ + return 0; + } + ++/* ++ * This function is called during kernel startup to initialize ++ * the mvme147 IRQ handling routines. ++ */ ++ ++void mvme147_init_IRQ(void) ++{ ++ m68k_setup_user_interrupt(VEC_USER, 192, NULL); ++} + + void __init config_mvme147(void) + { +@@ -101,12 +103,6 @@ + mach_hwclk = mvme147_hwclk; + mach_set_clock_mmss = mvme147_set_clock_mmss; + mach_reset = mvme147_reset; +- mach_free_irq = mvme147_free_irq; +- mach_process_int = mvme147_process_int; +- mach_get_irq_list = show_mvme147_interrupts; +- mach_request_irq = mvme147_request_irq; +- enable_irq = mvme147_enable_irq; +- disable_irq = mvme147_disable_irq; + mach_get_model = mvme147_get_model; + mach_get_hardware_list = mvme147_get_hardware_list; + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mvme16x/Makefile linux-m68k/arch/m68k/mvme16x/Makefile +--- linux-i386/arch/m68k/mvme16x/Makefile 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mvme16x/Makefile 2006-01-28 23:52:28.000000000 +0100 +@@ -2,4 +2,4 @@ + # Makefile for Linux arch/m68k/mvme16x source directory + # + +-obj-y := config.o 16xints.o rtc.o mvme16x_ksyms.o ++obj-y := config.o rtc.o mvme16x_ksyms.o +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mvme16x/config.c linux-m68k/arch/m68k/mvme16x/config.c +--- linux-i386/arch/m68k/mvme16x/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/mvme16x/config.c 2006-01-28 23:52:28.000000000 +0100 +@@ -40,15 +40,8 @@ + + static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE; + +-extern irqreturn_t mvme16x_process_int (int level, struct pt_regs *regs); +-extern void mvme16x_init_IRQ (void); +-extern void mvme16x_free_irq (unsigned int, void *); +-extern int show_mvme16x_interrupts (struct seq_file *, void *); +-extern void mvme16x_enable_irq (unsigned int); +-extern void mvme16x_disable_irq (unsigned int); + static void mvme16x_get_model(char *model); + static int mvme16x_get_hardware_list(char *buffer); +-extern int mvme16x_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); + extern void mvme16x_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); + extern unsigned long mvme16x_gettimeoffset (void); + extern int mvme16x_hwclk (int, struct rtc_time *); +@@ -120,6 +113,16 @@ + return (len); + } + ++/* ++ * This function is called during kernel startup to initialize ++ * the mvme16x IRQ handling routines. Should probably ensure ++ * that the base vectors for the VMEChip2 and PCCChip2 are valid. ++ */ ++ ++static void mvme16x_init_IRQ (void) ++{ ++ m68k_setup_user_interrupt(VEC_USER, 192, NULL); ++} + + #define pcc2chip ((volatile u_char *)0xfff42000) + #define PccSCCMICR 0x1d +@@ -138,12 +141,6 @@ + mach_hwclk = mvme16x_hwclk; + mach_set_clock_mmss = mvme16x_set_clock_mmss; + mach_reset = mvme16x_reset; +- mach_free_irq = mvme16x_free_irq; +- mach_process_int = mvme16x_process_int; +- mach_get_irq_list = show_mvme16x_interrupts; +- mach_request_irq = mvme16x_request_irq; +- enable_irq = mvme16x_enable_irq; +- disable_irq = mvme16x_disable_irq; + mach_get_model = mvme16x_get_model; + mach_get_hardware_list = mvme16x_get_hardware_list; + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/q40/config.c linux-m68k/arch/m68k/q40/config.c +--- linux-i386/arch/m68k/q40/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/q40/config.c 2006-04-11 16:32:24.000000000 +0200 +@@ -37,15 +37,9 @@ + #include + + extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); +-extern irqreturn_t (*q40_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */ + extern void q40_init_IRQ (void); +-extern void q40_free_irq (unsigned int, void *); +-extern int show_q40_interrupts (struct seq_file *, void *); +-extern void q40_enable_irq (unsigned int); +-extern void q40_disable_irq (unsigned int); + static void q40_get_model(char *model); + static int q40_get_hardware_list(char *buffer); +-extern int q40_request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id); + extern void q40_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); + + extern unsigned long q40_gettimeoffset (void); +@@ -175,13 +169,6 @@ + mach_set_clock_mmss = q40_set_clock_mmss; + + mach_reset = q40_reset; +- mach_free_irq = q40_free_irq; +- mach_process_int = q40_process_int; +- mach_get_irq_list = show_q40_interrupts; +- mach_request_irq = q40_request_irq; +- enable_irq = q40_enable_irq; +- disable_irq = q40_disable_irq; +- mach_default_handler = &q40_default_handler; + mach_get_model = q40_get_model; + mach_get_hardware_list = q40_get_hardware_list; + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/q40/q40ints.c linux-m68k/arch/m68k/q40/q40ints.c +--- linux-i386/arch/m68k/q40/q40ints.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/q40/q40ints.c 2006-01-28 23:52:28.000000000 +0100 +@@ -14,13 +14,8 @@ + #include + #include + #include +-#include +-#include +-#include + #include +-#include + +-#include + #include + #include + #include +@@ -39,29 +34,37 @@ + * + */ + +-extern int ints_inited; ++static void q40_irq_handler(unsigned int, struct pt_regs *fp); ++static void q40_enable_irq(unsigned int); ++static void q40_disable_irq(unsigned int); + ++unsigned short q40_ablecount[35]; ++unsigned short q40_state[35]; + +-irqreturn_t q40_irq2_handler (int, void *, struct pt_regs *fp); +- +- +-static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp); +-static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs); +- +- +-#define DEVNAME_SIZE 24 ++static int q40_irq_startup(unsigned int irq) ++{ ++ /* test for ISA ints not implemented by HW */ ++ switch (irq) { ++ case 1: case 2: case 8: case 9: ++ case 11: case 12: case 13: ++ printk("%s: ISA IRQ %d not implemented by HW\n", __FUNCTION__, irq); ++ return -ENXIO; ++ } ++ return 0; ++} + +-static struct q40_irq_node { +- irqreturn_t (*handler)(int, void *, struct pt_regs *); +- unsigned long flags; +- void *dev_id; +- /* struct q40_irq_node *next;*/ +- char devname[DEVNAME_SIZE]; +- unsigned count; +- unsigned short state; +-} irq_tab[Q40_IRQ_MAX+1]; ++static void q40_irq_shutdown(unsigned int irq) ++{ ++} + +-short unsigned q40_ablecount[Q40_IRQ_MAX+1]; ++static struct irq_controller q40_irq_controller = { ++ .name = "q40", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .startup = q40_irq_startup, ++ .shutdown = q40_irq_shutdown, ++ .enable = q40_enable_irq, ++ .disable = q40_disable_irq, ++}; + + /* + * void q40_init_IRQ (void) +@@ -74,139 +77,29 @@ + * the q40 IRQ handling routines. + */ + +-static int disabled=0; ++static int disabled; + +-void q40_init_IRQ (void) ++void q40_init_IRQ(void) + { +- int i; +- +- disabled=0; +- for (i = 0; i <= Q40_IRQ_MAX; i++) { +- irq_tab[i].handler = q40_defhand; +- irq_tab[i].flags = 0; +- irq_tab[i].dev_id = NULL; +- /* irq_tab[i].next = NULL;*/ +- irq_tab[i].devname[0] = 0; +- irq_tab[i].count = 0; +- irq_tab[i].state =0; +- q40_ablecount[i]=0; /* all enabled */ +- } ++ m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); + + /* setup handler for ISA ints */ +- cpu_request_irq(IRQ2, q40_irq2_handler, 0, "q40 ISA and master chip", +- NULL); ++ m68k_setup_auto_interrupt(q40_irq_handler); ++ ++ m68k_irq_startup(IRQ_AUTO_2); ++ m68k_irq_startup(IRQ_AUTO_4); + + /* now enable some ints.. */ +- master_outb(1,EXT_ENABLE_REG); /* ISA IRQ 5-15 */ ++ master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ + + /* make sure keyboard IRQ is disabled */ +- master_outb(0,KEY_IRQ_ENABLE_REG); ++ master_outb(0, KEY_IRQ_ENABLE_REG); + } + +-int q40_request_irq(unsigned int irq, +- irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id) +-{ +- /*printk("q40_request_irq %d, %s\n",irq,devname);*/ +- +- if (irq > Q40_IRQ_MAX || (irq>15 && irq<32)) { +- printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname); +- return -ENXIO; +- } +- +- /* test for ISA ints not implemented by HW */ +- switch (irq) +- { +- case 1: case 2: case 8: case 9: +- case 12: case 13: +- printk("%s: ISA IRQ %d from %s not implemented by HW\n", __FUNCTION__, irq, devname); +- return -ENXIO; +- case 11: +- printk("warning IRQ 10 and 11 not distinguishable\n"); +- irq=10; +- default: +- ; +- } +- +- if (irq Q40_IRQ_MAX || (irq>15 && irq<32)) { +- printk("%s: Incorrect IRQ %d, dev_id %x \n", __FUNCTION__, irq, (unsigned)dev_id); +- return; +- } +- +- /* test for ISA ints not implemented by HW */ +- switch (irq) +- { +- case 1: case 2: case 8: case 9: +- case 12: case 13: +- printk("%s: ISA IRQ %d from %x invalid\n", __FUNCTION__, irq, (unsigned)dev_id); +- return; +- case 11: irq=10; +- default: +- ; +- } +- +- if (irqpc, fp->d0, fp->orig_d0, fp->d1, fp->d2); +- printk("\tIIRQ_REG = %x, EIRQ_REG = %x\n",master_inb(IIRQ_REG),master_inb(EIRQ_REG)); +- return IRQ_HANDLED; +-} + + /* + * this stuff doesn't really belong here.. +-*/ ++ */ + + int ql_ticks; /* 200Hz ticks since last jiffie */ + static int sound_ticks; +@@ -215,54 +108,53 @@ + + void q40_mksound(unsigned int hz, unsigned int ticks) + { +- /* for now ignore hz, except that hz==0 switches off sound */ +- /* simply alternate the ampl (128-SVOL)-(128+SVOL)-..-.. at 200Hz */ +- if (hz==0) +- { +- if (sound_ticks) +- sound_ticks=1; +- +- *DAC_LEFT=128; +- *DAC_RIGHT=128; +- +- return; +- } +- /* sound itself is done in q40_timer_int */ +- if (sound_ticks == 0) sound_ticks=1000; /* pretty long beep */ +- sound_ticks=ticks<<1; ++ /* for now ignore hz, except that hz==0 switches off sound */ ++ /* simply alternate the ampl (128-SVOL)-(128+SVOL)-..-.. at 200Hz */ ++ if (hz == 0) { ++ if (sound_ticks) ++ sound_ticks = 1; ++ ++ *DAC_LEFT = 128; ++ *DAC_RIGHT = 128; ++ ++ return; ++ } ++ /* sound itself is done in q40_timer_int */ ++ if (sound_ticks == 0) ++ sound_ticks = 1000; /* pretty long beep */ ++ sound_ticks = ticks << 1; + } + + static irqreturn_t (*q40_timer_routine)(int, void *, struct pt_regs *); + + static irqreturn_t q40_timer_int (int irq, void * dev, struct pt_regs * regs) + { +- ql_ticks = ql_ticks ? 0 : 1; +- if (sound_ticks) +- { +- unsigned char sval=(sound_ticks & 1) ? 128-SVOL : 128+SVOL; +- sound_ticks--; +- *DAC_LEFT=sval; +- *DAC_RIGHT=sval; +- } +- +- if (!ql_ticks) +- q40_timer_routine(irq, dev, regs); +- return IRQ_HANDLED; ++ ql_ticks = ql_ticks ? 0 : 1; ++ if (sound_ticks) { ++ unsigned char sval=(sound_ticks & 1) ? 128-SVOL : 128+SVOL; ++ sound_ticks--; ++ *DAC_LEFT=sval; ++ *DAC_RIGHT=sval; ++ } ++ ++ if (!ql_ticks) ++ q40_timer_routine(irq, dev, regs); ++ return IRQ_HANDLED; + } + + void q40_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) + { +- int timer_irq; ++ int timer_irq; + +- q40_timer_routine = timer_routine; +- timer_irq=Q40_IRQ_FRAME; ++ q40_timer_routine = timer_routine; ++ timer_irq = Q40_IRQ_FRAME; + +- if (request_irq(timer_irq, q40_timer_int, 0, ++ if (request_irq(timer_irq, q40_timer_int, 0, + "timer", q40_timer_int)) +- panic ("Couldn't register timer int"); ++ panic("Couldn't register timer int"); + +- master_outb(-1,FRAME_CLEAR_REG); +- master_outb( 1,FRAME_RATE_REG); ++ master_outb(-1, FRAME_CLEAR_REG); ++ master_outb( 1, FRAME_RATE_REG); + } + + +@@ -308,169 +200,132 @@ + static int aliased_irq=0; /* how many times inside handler ?*/ + + +-/* got level 2 interrupt, dispatch to ISA or keyboard/timer IRQs */ +-irqreturn_t q40_irq2_handler (int vec, void *devname, struct pt_regs *fp) ++/* got interrupt, dispatch to ISA or keyboard/timer IRQs */ ++static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) + { +- unsigned mir, mer; +- int irq,i; ++ unsigned mir, mer; ++ int i; + + //repeat: +- mir=master_inb(IIRQ_REG); +- if (mir&Q40_IRQ_FRAME_MASK) { +- irq_tab[Q40_IRQ_FRAME].count++; +- irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp); +- master_outb(-1,FRAME_CLEAR_REG); +- } +- if ((mir&Q40_IRQ_SER_MASK) || (mir&Q40_IRQ_EXT_MASK)) { +- mer=master_inb(EIRQ_REG); +- for (i=0; eirqs[i].mask; i++) { +- if (mer&(eirqs[i].mask)) { +- irq=eirqs[i].irq; ++ mir = master_inb(IIRQ_REG); ++#ifdef CONFIG_BLK_DEV_FD ++ if ((mir & Q40_IRQ_EXT_MASK) && ++ (master_inb(EIRQ_REG) & Q40_IRQ6_MASK)) { ++ floppy_hardint(); ++ return; ++ } ++#endif ++ switch (irq) { ++ case 4: ++ case 6: ++ m68k_handle_int(Q40_IRQ_SAMPLE, fp); ++ return; ++ } ++ if (mir & Q40_IRQ_FRAME_MASK) { ++ m68k_handle_int(Q40_IRQ_FRAME, fp); ++ master_outb(-1, FRAME_CLEAR_REG); ++ } ++ if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { ++ mer = master_inb(EIRQ_REG); ++ for (i = 0; eirqs[i].mask; i++) { ++ if (mer & eirqs[i].mask) { ++ irq = eirqs[i].irq; + /* + * There is a little mess wrt which IRQ really caused this irq request. The + * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they + * are read - which is long after the request came in. In theory IRQs should + * not just go away but they occassionally do + */ +- if (irq>4 && irq<=15 && mext_disabled) { +- /*aliased_irq++;*/ +- goto iirq; +- } +- if (irq_tab[irq].handler == q40_defhand ) { +- printk("handler for IRQ %d not defined\n",irq); +- continue; /* ignore uninited INTs :-( */ +- } +- if ( irq_tab[irq].state & IRQ_INPROGRESS ) { +- /* some handlers do local_irq_enable() for irq latency reasons, */ +- /* however reentering an active irq handler is not permitted */ ++ if (irq > 4 && irq <= 15 && mext_disabled) { ++ /*aliased_irq++;*/ ++ goto iirq; ++ } ++ if (q40_state[irq] & IRQ_INPROGRESS) { ++ /* some handlers do local_irq_enable() for irq latency reasons, */ ++ /* however reentering an active irq handler is not permitted */ + #ifdef IP_USE_DISABLE +- /* in theory this is the better way to do it because it still */ +- /* lets through eg the serial irqs, unfortunately it crashes */ +- disable_irq(irq); +- disabled=1; ++ /* in theory this is the better way to do it because it still */ ++ /* lets through eg the serial irqs, unfortunately it crashes */ ++ disable_irq(irq); ++ disabled = 1; + #else +- /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */ +- fp->sr = (((fp->sr) & (~0x700))+0x200); +- disabled=1; ++ /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n", ++ irq, disabled ? "already" : "not yet"); */ ++ fp->sr = (((fp->sr) & (~0x700))+0x200); ++ disabled = 1; + #endif +- goto iirq; +- } +- irq_tab[irq].count++; +- irq_tab[irq].state |= IRQ_INPROGRESS; +- irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp); +- irq_tab[irq].state &= ~IRQ_INPROGRESS; +- +- /* naively enable everything, if that fails than */ +- /* this function will be reentered immediately thus */ +- /* getting another chance to disable the IRQ */ ++ goto iirq; ++ } ++ q40_state[irq] |= IRQ_INPROGRESS; ++ m68k_handle_int(irq, fp); ++ q40_state[irq] &= ~IRQ_INPROGRESS; ++ ++ /* naively enable everything, if that fails than */ ++ /* this function will be reentered immediately thus */ ++ /* getting another chance to disable the IRQ */ + +- if ( disabled ) { ++ if (disabled) { + #ifdef IP_USE_DISABLE +- if (irq>4){ +- disabled=0; +- enable_irq(irq);} ++ if (irq > 4) { ++ disabled = 0; ++ enable_irq(irq); ++ } + #else +- disabled=0; +- /*printk("reenabling irq %d\n",irq); */ ++ disabled = 0; ++ /*printk("reenabling irq %d\n", irq); */ + #endif +- } ++ } + // used to do 'goto repeat;' here, this delayed bh processing too long +- return IRQ_HANDLED; +- } +- } +- if (mer && ccleirq>0 && !aliased_irq) +- printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--; +- } ++ return; ++ } ++ } ++ if (mer && ccleirq > 0 && !aliased_irq) { ++ printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer); ++ ccleirq--; ++ } ++ } + iirq: +- mir=master_inb(IIRQ_REG); +- /* should test whether keyboard irq is really enabled, doing it in defhand */ +- if (mir&Q40_IRQ_KEYB_MASK) { +- irq_tab[Q40_IRQ_KEYBOARD].count++; +- irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp); +- } +- return IRQ_HANDLED; +-} +- +-int show_q40_interrupts (struct seq_file *p, void *v) +-{ +- int i; +- +- for (i = 0; i <= Q40_IRQ_MAX; i++) { +- if (irq_tab[i].count) +- seq_printf(p, "%sIRQ %02d: %8d %s%s\n", +- (i<=15) ? "ISA-" : " " , +- i, irq_tab[i].count, +- irq_tab[i].devname[0] ? irq_tab[i].devname : "?", +- irq_tab[i].handler == q40_defhand ? +- " (now unassigned)" : ""); ++ mir = master_inb(IIRQ_REG); ++ /* should test whether keyboard irq is really enabled, doing it in defhand */ ++ if (mir & Q40_IRQ_KEYB_MASK) ++ m68k_handle_int(Q40_IRQ_KEYBOARD, fp); ++ ++ return; ++} ++ ++void q40_enable_irq(unsigned int irq) ++{ ++ if (irq >= 5 && irq <= 15) { ++ mext_disabled--; ++ if (mext_disabled > 0) ++ printk("q40_enable_irq : nested disable/enable\n"); ++ if (mext_disabled == 0) ++ master_outb(1, EXT_ENABLE_REG); + } +- return 0; + } + + +-static irqreturn_t q40_defhand (int irq, void *dev_id, struct pt_regs *fp) +-{ +- if (irq!=Q40_IRQ_KEYBOARD) +- printk ("Unknown q40 interrupt %d\n", irq); +- else master_outb(-1,KEYBOARD_UNLOCK_REG); +- return IRQ_NONE; +-} +-static irqreturn_t default_handler(int lev, void *dev_id, struct pt_regs *regs) +-{ +- printk ("Uninitialised interrupt level %d\n", lev); +- return IRQ_NONE; +-} +- +-irqreturn_t (*q40_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { +- [0] = default_handler, +- [1] = default_handler, +- [2] = default_handler, +- [3] = default_handler, +- [4] = default_handler, +- [5] = default_handler, +- [6] = default_handler, +- [7] = default_handler +-}; +- +- +-void q40_enable_irq (unsigned int irq) ++void q40_disable_irq(unsigned int irq) + { +- if ( irq>=5 && irq<=15 ) +- { +- mext_disabled--; +- if (mext_disabled>0) +- printk("q40_enable_irq : nested disable/enable\n"); +- if (mext_disabled==0) +- master_outb(1,EXT_ENABLE_REG); +- } +-} +- +- +-void q40_disable_irq (unsigned int irq) +-{ +- /* disable ISA iqs : only do something if the driver has been +- * verified to be Q40 "compatible" - right now IDE, NE2K +- * Any driver should not attempt to sleep across disable_irq !! +- */ +- +- if ( irq>=5 && irq<=15 ) { +- master_outb(0,EXT_ENABLE_REG); +- mext_disabled++; +- if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled); +- } ++ /* disable ISA iqs : only do something if the driver has been ++ * verified to be Q40 "compatible" - right now IDE, NE2K ++ * Any driver should not attempt to sleep across disable_irq !! ++ */ ++ ++ if (irq >= 5 && irq <= 15) { ++ master_outb(0, EXT_ENABLE_REG); ++ mext_disabled++; ++ if (mext_disabled > 1) ++ printk("disable_irq nesting count %d\n",mext_disabled); ++ } + } + +-unsigned long q40_probe_irq_on (void) ++unsigned long q40_probe_irq_on(void) + { +- printk("irq probing not working - reconfigure the driver to avoid this\n"); +- return -1; ++ printk("irq probing not working - reconfigure the driver to avoid this\n"); ++ return -1; + } +-int q40_probe_irq_off (unsigned long irqs) ++int q40_probe_irq_off(unsigned long irqs) + { +- return -1; ++ return -1; + } +-/* +- * Local variables: +- * compile-command: "m68k-linux-gcc -D__KERNEL__ -I/home/rz/lx/linux-2.2.6/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -ffixed-a2 -m68040 -c -o q40ints.o q40ints.c" +- * End: +- */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/sun3/config.c linux-m68k/arch/m68k/sun3/config.c +--- linux-i386/arch/m68k/sun3/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/sun3/config.c 2006-01-28 23:52:28.000000000 +0100 +@@ -36,7 +36,6 @@ + char sun3_reserved_pmeg[SUN3_PMEGS_NUM]; + + extern unsigned long sun3_gettimeoffset(void); +-extern int show_sun3_interrupts (struct seq_file *, void *); + extern void sun3_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); + extern void sun3_get_model (char* model); + extern void idprom_init (void); +@@ -147,13 +146,6 @@ + + mach_sched_init = sun3_sched_init; + mach_init_IRQ = sun3_init_IRQ; +- mach_default_handler = &sun3_default_handler; +- mach_request_irq = sun3_request_irq; +- mach_free_irq = sun3_free_irq; +- enable_irq = sun3_enable_irq; +- disable_irq = sun3_disable_irq; +- mach_process_int = sun3_process_int; +- mach_get_irq_list = show_sun3_interrupts; + mach_reset = sun3_reboot; + mach_gettimeoffset = sun3_gettimeoffset; + mach_get_model = sun3_get_model; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/sun3/sun3ints.c linux-m68k/arch/m68k/sun3/sun3ints.c +--- linux-i386/arch/m68k/sun3/sun3ints.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/sun3/sun3ints.c 2006-01-28 23:52:28.000000000 +0100 +@@ -19,7 +19,6 @@ + #include + + extern void sun3_leds (unsigned char); +-static irqreturn_t sun3_inthandle(int irq, void *dev_id, struct pt_regs *fp); + + void sun3_disable_interrupts(void) + { +@@ -40,48 +39,30 @@ + + volatile unsigned char* sun3_intreg; + +-void sun3_insert_irq(irq_node_t **list, irq_node_t *node) +-{ +-} +- +-void sun3_delete_irq(irq_node_t **list, void *dev_id) +-{ +-} +- + void sun3_enable_irq(unsigned int irq) + { +- *sun3_intreg |= (1<= 64) && (irq <= 255)) { +- int vec; +- +- vec = irq - 64; +- if(sun3_vechandler[vec] != NULL) { +- printk("sun3_request_irq: request for vec %d -- already taken!\n", irq); +- return 1; +- } +- +- sun3_vechandler[vec] = handler; +- vec_ids[vec] = dev_id; +- vec_names[vec] = devname; +- vec_ints[vec] = 0; +- +- return 0; +- } +- } +- +- printk("sun3_request_irq: invalid irq %d\n", irq); +- return 1; +- ++ m68k_handle_int(irq, fp); + } + +-void sun3_free_irq(unsigned int irq, void *dev_id) +-{ +- +- if(irq < SYS_IRQS) { +- if(sun3_inthandler[irq] == NULL) +- panic("sun3_free_int: attempt to free unused irq %d\n", irq); +- if(dev_ids[irq] != dev_id) +- panic("sun3_free_int: incorrect dev_id for irq %d\n", irq); +- +- sun3_inthandler[irq] = NULL; +- return; +- } else if((irq >= 64) && (irq <= 255)) { +- int vec; +- +- vec = irq - 64; +- if(sun3_vechandler[vec] == NULL) +- panic("sun3_free_int: attempt to free unused vector %d\n", irq); +- if(vec_ids[irq] != dev_id) +- panic("sun3_free_int: incorrect dev_id for vec %d\n", irq); +- +- sun3_vechandler[vec] = NULL; +- return; +- } else { +- panic("sun3_free_irq: invalid irq %d\n", irq); +- } +-} ++static struct irq_controller sun3_irq_controller = { ++ .name = "sun3", ++ .lock = SPIN_LOCK_UNLOCKED, ++ .startup = m68k_irq_startup, ++ .shutdown = m68k_irq_shutdown, ++ .enable = sun3_enable_irq, ++ .disable = sun3_disable_irq, ++}; + +-irqreturn_t sun3_process_int(int irq, struct pt_regs *regs) ++void sun3_init_IRQ(void) + { ++ *sun3_intreg = 1; + +- if((irq >= 64) && (irq <= 255)) { +- int vec; +- +- vec = irq - 64; +- if(sun3_vechandler[vec] == NULL) +- panic ("bad interrupt vector %d received\n",irq); +- +- vec_ints[vec]++; +- return sun3_vechandler[vec](irq, vec_ids[vec], regs); +- } else { +- panic("sun3_process_int: unable to handle interrupt vector %d\n", +- irq); +- } ++ m68k_setup_auto_interrupt(sun3_inthandle); ++ m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7); ++ m68k_setup_user_interrupt(VEC_USER, 192, NULL); ++ ++ request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL); ++ request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL); ++ request_irq(IRQ_USER+127, sun3_vec255, 0, "vec255", NULL); + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/sun3x/config.c linux-m68k/arch/m68k/sun3x/config.c +--- linux-i386/arch/m68k/sun3x/config.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/arch/m68k/sun3x/config.c 2006-01-28 23:52:29.000000000 +0100 +@@ -52,17 +52,10 @@ + + sun3x_prom_init(); + +- mach_get_irq_list = show_sun3_interrupts; + mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */ + +- mach_default_handler = &sun3_default_handler; + mach_sched_init = sun3x_sched_init; + mach_init_IRQ = sun3_init_IRQ; +- enable_irq = sun3_enable_irq; +- disable_irq = sun3_disable_irq; +- mach_request_irq = sun3_request_irq; +- mach_free_irq = sun3_free_irq; +- mach_process_int = sun3_process_int; + + mach_gettimeoffset = sun3x_gettimeoffset; + mach_reset = sun3x_reboot; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/block/amiflop.c linux-m68k/drivers/block/amiflop.c +--- linux-i386/drivers/block/amiflop.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/block/amiflop.c 2006-04-11 16:34:39.000000000 +0200 +@@ -64,6 +64,7 @@ + #include + #include + #include ++#include + + #include + #include +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/16c552.h linux-m68k/drivers/char/16c552.h +--- linux-i386/drivers/char/16c552.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-m68k/drivers/char/16c552.h 2001-10-22 11:34:32.000000000 +0200 +@@ -0,0 +1,165 @@ ++/* ++ * Definitions for the 16c552 DACE ++ * (dual-asynchronous-communications-element) used on the GVP ++ * IO-Extender. ++ * ++ * Basically this is two 16c550 uarts's and a parallel port, which is ++ * why the serial definitions should be valid for the 16c550 uart ++ * aswell. ++ * ++ * Data was taken from National Semiconductors duart 16c552 ++ * data-sheets and the Texas Instruments DACE 16c552 data-sheets (the ++ * NS version of the chip is _non_ standard and their data-sheets did ++ * cost me several wasted hours of work). ++ * ++ * This file is (C) 1995 Jes Sorensen (jds@kom.auc.dk) ++ * ++ * Moved from drivers/char/ to include/linux/, because it's useful ++ * on more than just the one card. I'm using it on the hp300 DCA ++ * serial driver, for example. ++ * -- Peter Maydell 05/1998 ++ */ ++ ++#ifndef _16C552_H_ ++#define _16C552_H_ ++ ++/* Serial stuff */ ++ ++struct uart_16c550 { ++ volatile u_char skip0; ++ volatile u_char RBR; ++ volatile u_char skip1; ++ volatile u_char IER; ++ volatile u_char skip2; ++ volatile u_char IIR; ++ volatile u_char skip3; ++ volatile u_char LCR; ++ volatile u_char skip4; ++ volatile u_char MCR; ++ volatile u_char skip5; ++ volatile u_char LSR; ++ volatile u_char skip6; ++ volatile u_char MSR; ++ volatile u_char skip7; ++ volatile u_char SCR; ++}; ++ ++#define THR RBR ++#define FCR IIR ++#define DLL RBR ++#define DLM IER ++#define AFR IIR ++ ++/* ++ * Bit-defines for the various registers. ++ */ ++ ++ ++/* IER */ ++ ++#define ERDAI (1<<0) ++#define ETHREI (1<<1) ++#define ELSI (1<<2) ++#define EMSI (1<<3) ++ ++/* IIR - Interrupt Ident. Register */ ++ ++#define IRQ_PEND (1<<0) /* NOTE: IRQ_PEND=0 implies irq pending */ ++#define IRQ_ID1 (1<<1) ++#define IRQ_ID2 (1<<2) ++#define IRQ_ID3 (1<<3) ++#define FIFO_ENA0 (1<<6) /* Both these are set when FCR(1<<0)=1 */ ++#define FIFO_ENA1 (1<<7) ++ ++#define IRQ_RLS (IRQ_ID1 | IRQ_ID2) ++#define IRQ_RDA (IRQ_ID2) ++#define IRQ_CTI (IRQ_ID2 | IRQ_ID3) ++#define IRQ_THRE (IRQ_ID1) ++#define IRQ_MS 0 ++ ++/* FCR - FIFO Control Register */ ++ ++#define FIFO_ENA (1<<0) ++#define RCVR_FIFO_RES (1<<1) ++#define XMIT_FIFO_RES (1<<2) ++#define DMA_MODE_SEL (1<<3) ++#define RCVR_TRIG_LSB (1<<6) ++#define RCVR_TRIG_MSB (1<<7) ++ ++#define FIFO_TRIG_1 0x00 ++#define FIFO_TRIG_4 RCVR_TRIG_LSB ++#define FIFO_TRIG_8 RCVR_TRIG_MSB ++#define FIFO_TRIG_14 RCVR_TRIG_LSB|RCVR_TRIG_MSB ++ ++/* LCR - Line Control Register */ ++ ++#define WLS0 (1<<0) ++#define WLS1 (1<<1) ++#define STB (1<<2) ++#define PEN (1<<3) ++#define EPS (1<<4) ++#define STICK_PARITY (1<<5) ++#define SET_BREAK (1<<6) ++#define DLAB (1<<7) ++ ++#define data_5bit 0x00 ++#define data_6bit 0x01 ++#define data_7bit 0x02 ++#define data_8bit 0x03 ++ ++ ++/* MCR - Modem Control Register */ ++ ++#define DTR (1<<0) ++#define RTS (1<<1) ++#define OUT1 (1<<2) ++#define OUT2 (1<<3) ++#define LOOP (1<<4) ++ ++/* LSR - Line Status Register */ ++ ++#define DR (1<<0) ++#define OE (1<<1) ++#define PE (1<<2) ++#define FE (1<<3) ++#define BI (1<<4) ++#define THRE (1<<5) ++#define TEMT (1<<6) ++#define RCVR_FIFO_ERR (1<<7) ++ ++/* MSR - Modem Status Register */ ++ ++#define DCTS (1<<0) ++#define DDSR (1<<1) ++#define TERI (1<<2) ++#define DDCD (1<<3) ++#define CTS (1<<4) ++#define DSR (1<<5) ++#define RING_I (1<<6) ++#define DCD (1<<7) ++ ++/* AFR - Alternate Function Register */ ++ ++#define CONCUR_WRITE (1<<0) ++#define BAUDOUT (1<<1) ++#define RXRDY (1<<2) ++ ++/* Parallel stuff */ ++ ++/* ++ * Unfortunately National Semiconductors did not supply the ++ * specifications for the parallel port in the chip :-( ++ * TI succed though, so here they are :-) ++ * ++ * Defines for the bits can be found by including ++ */ ++struct IOEXT_par { ++ volatile u_char skip0; ++ volatile u_char DATA; ++ volatile u_char skip1; ++ volatile u_char STATUS; ++ volatile u_char skip2; ++ volatile u_char CTRL; ++}; ++ ++#endif +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/ioext.h linux-m68k/drivers/char/ioext.h +--- linux-i386/drivers/char/ioext.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-m68k/drivers/char/ioext.h 2001-10-22 11:34:32.000000000 +0200 +@@ -0,0 +1,108 @@ ++/* ++ * Shared data structure for GVP IO-Extender support. ++ * ++ * Merge of ioext.h and ser_ioext.h ++ */ ++#ifndef _IOEXT_H_ ++#define _IOEXT_H_ ++ ++#include ++#include ++ ++#include "16c552.h" ++ ++#define MAX_IOEXT 5 /* ++ * The maximum number of io-extenders is 5, as you ++ * can't have more than 5 ZII boards in any Amiga. ++ */ ++ ++#define UART_CLK 7372800 ++ ++#define IOEXT_BAUD_BASE (UART_CLK / 16) ++ ++#define IOEXT_MAX_LINES 2 ++ ++#define IOEXT_PAR_PLIP 0x0001 ++#define IOEXT_PAR_LP 0x0002 ++ ++ ++/* ++ * Macros for the serial driver. ++ */ ++#define curruart(info) ((struct uart_16c550 *)(info->port)) ++ ++#define ser_DTRon(info) curruart(info)->MCR |= DTR ++#define ser_RTSon(info) curruart(info)->MCR |= RTS ++#define ser_DTRoff(info) curruart(info)->MCR &= ~DTR ++#define ser_RTSoff(info) curruart(info)->MCR &= ~RTS ++ ++ ++/* ++ * CNTR defines (copied from the GVP SCSI-driver file gvp11.h ++ */ ++#define GVP_BUSY (1<<0) ++#define GVP_IRQ_PEND (1<<1) ++#define GVP_IRQ_ENA (1<<3) ++#define GVP_DIR_WRITE (1<<4) ++ ++ ++/* ++ * CTRL defines ++ */ ++#define PORT0_MIDI (1<<0) /* CLR = DRIVERS SET = MIDI */ ++#define PORT1_MIDI (1<<1) /* CLR = DRIVERS SET = MIDI */ ++#define PORT0_DRIVER (1<<2) /* CLR = RS232, SET = MIDI */ ++#define PORT1_DRIVER (1<<3) /* CLR = RS232, SET = MIDI */ ++#define IRQ_SEL (1<<4) /* CLR = INT2, SET = INT6 */ ++#define ROM_BANK_SEL (1<<5) /* CLR = LOW 32K, SET = HIGH 32K */ ++#define PORT0_CTRL (1<<6) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */ ++#define PORT1_CTRL (1<<7) /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */ ++ ++ ++/* ++ * This is the struct describing the registers on the IO-Extender. ++ * NOTE: The board uses a dual uart (16c552), which should be equal to ++ * two 16c550 uarts. ++ */ ++typedef struct { ++ char gap0[0x41]; ++ volatile unsigned char CNTR; /* GVP DMAC CNTR (status register) */ ++ char gap1[0x11e]; ++ struct uart_16c550 uart0; /* The first uart */ ++ char gap2[0xf0]; ++ struct uart_16c550 uart1; /* The second uart */ ++ char gap3[0xf0]; ++ struct IOEXT_par par; /* The parallel port */ ++ char gap4[0xfb]; ++ volatile unsigned char CTRL; /* The control-register on the board */ ++} IOEXT_struct; ++ ++ ++typedef struct { ++ int num_uarts; ++ int line[IOEXT_MAX_LINES]; ++ volatile struct uart_16c550 *uart[IOEXT_MAX_LINES]; ++ IOEXT_struct *board; ++ int spurious_count; ++ unsigned char par_use; /* IOEXT_PAR_xxx */ ++#if defined(CONFIG_GVPIOEXT_PLIP) || defined(CONFIG_GVPIOEXT_PLIP_MODULE) ++ struct nt_device *dev; ++#endif ++#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE) ++ struct lp_struct *lp_table; ++ int lp_dev; ++ int lp_interrupt; ++#endif ++} IOExtInfoType; ++ ++/* Number of detected boards. */ ++extern int ioext_num; ++extern IOExtInfoType ioext_info[MAX_IOEXT]; ++ ++void ioext_plip_interrupt(struct net_device *dev, int *spurious_count); ++void ioext_lp_interrupt(int dev, int *spurious_count); ++ ++extern struct net_device ioext_dev_plip[3]; ++extern struct lp_struct ioext_lp_table[1]; ++ ++#endif +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/mc68681.h linux-m68k/drivers/char/mc68681.h +--- linux-i386/drivers/char/mc68681.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-m68k/drivers/char/mc68681.h 2001-10-22 11:34:32.000000000 +0200 +@@ -0,0 +1,131 @@ ++#ifndef _MC68681_H_ ++#define _MC68681_H_ ++ ++/* ++ * This describes an MC68681 DUART. It has almost only overlayed registers, which ++ * the structure very ugly. ++ * Note that the ri-register isn't really a register of the duart but a kludge of bsc ++ * to make the ring indicator available. ++ * ++ * The data came from the MFC-31-Developer Kit (from Ralph Seidel, ++ * zodiac@darkness.gun.de) and the data sheet of Phillip's clone device (SCN68681) ++ * (from Richard Hirst, srh@gpt.co.uk) ++ * ++ * 11.11.95 copyright Joerg Dorchain (dorchain@mpi-sb.mpg.de) ++ * ++ */ ++ ++struct duarthalf { ++union { ++volatile u_char mr1; /* rw */ ++volatile u_char mr2; /* rw */ ++} mr; ++volatile u_char ri; /* special, read */ ++union { ++volatile u_char sr; /* read */ ++volatile u_char csr; /* write */ ++} sr_csr; ++u_char pad1; ++volatile u_char cr; /* write */ ++u_char pad2; ++union { ++volatile u_char rhr; /* read */ ++volatile u_char thr; /* write */ ++} hr; ++u_char pad3; ++}; ++ ++struct duart { ++struct duarthalf pa; ++union { ++volatile u_char ipcr; /* read */ ++volatile u_char acr; /* write */ ++} ipcr_acr; ++u_char pad1; ++union { ++volatile u_char isr; /* read */ ++volatile u_char imr; /* write */ ++} ir; ++u_char pad2; ++volatile u_char ctu; ++u_char pad3; ++volatile u_char ctl; ++u_char pad4; ++struct duarthalf pb; ++volatile u_char ivr; ++u_char pad5; ++union { ++volatile u_char ipr; /* read */ ++volatile u_char opcr; /* write */ ++} ipr_opcr; ++u_char pad6; ++union { ++volatile u_char start; /* read */ ++volatile u_char sopc; /* write */ ++} start_sopc; ++u_char pad7; ++union { ++volatile u_char stop; /* read */ ++volatile u_char ropc; /* write */ ++} stop_ropc; ++u_char pad8; ++}; ++ ++#define MR1_BITS 3 ++#define MR1_5BITS 0 ++#define MR1_6BITS 1 ++#define MR1_7BITS 2 ++#define MR1_8BITS 3 ++ ++#define MR1_PARITY_ODD 4 ++ ++#define MR1_PARITY 24 ++#define MR1_PARITY_WITH 0 ++#define MR1_PARITY_FORCE 8 ++#define MR1_PARITY_NO 16 ++#define MR1_PARITY_MULTIDROP 24 ++ ++#define MR1_ERROR_BLOCK 32 ++#define MR1_FFULL_IRQ 64 ++#define MR1_RxRTS_ON 128 ++ ++#define MR2_STOPS 15 ++#define MR2_1STOP 7 ++#define MR2_2STOP 15 ++ ++#define MR2_CTS_ON 16 ++#define MR2_TxRTS_ON 32 ++ ++#define MR2_MODE 192 ++#define MR2_NORMAL 0 ++#define MR2_ECHO 64 ++#define MR2_LOCALLOOP 128 ++#define MR2_REMOTELOOP 192 ++ ++#define CR_RXCOMMAND 3 ++#define CR_NONE 0 ++#define CR_RX_ON 1 ++#define CR_RX_OFF 2 ++#define CR_TXCOMMAND 12 ++#define CR_TX_ON 4 ++#define CR_TX_OFF 8 ++#define CR_MISC 112 ++#define CR_RESET_MR 16 ++#define CR_RESET_RX 32 ++#define CR_RESET_TX 48 ++#define CR_RESET_ERR 64 ++#define CR_RESET_BREAK 80 ++#define CR_START_BREAK 96 ++#define CR_STOP_BREAK 112 ++ ++#define SR_RXRDY 1 ++#define SR_FFULL 2 ++#define SR_TXRDY 4 ++#define SR_TXEMPT 8 ++#define SR_OVERRUN 16 ++#define SR_PARITY 32 ++#define SR_FRAMING 64 ++#define SR_BREAK 128 ++ ++ ++#endif +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/plip_ioext.c linux-m68k/drivers/char/plip_ioext.c +--- linux-i386/drivers/char/plip_ioext.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-m68k/drivers/char/plip_ioext.c 2004-10-24 22:59:56.000000000 +0200 +@@ -0,0 +1,1058 @@ ++/* ++ * plip_ioext: A parallel port "network" driver for GVP IO-Extender. ++ * ++ * Authors: See drivers/net/plip.c ++ * IO-Extender version by Steve Bennett, ++ * ++ * This driver is for use with a 5-bit cable (LapLink (R) cable). ++ */ ++ ++static const char *version = "NET3 PLIP version 2.2/m68k"; ++ ++#define __NO_VERSION__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++/*#include */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "ioext.h" ++ ++#define DEBUG 0 ++ ++/* Map 'struct device *' to our control structure */ ++#define PLIP_DEV(DEV) (&ioext_info[(DEV)->irq]) ++ ++/************************************************************************ ++** ++** PLIP definitions ++** ++************************************************************************* ++*/ ++ ++/* Use 0 for production, 1 for verification, >2 for debug */ ++#ifndef NET_DEBUG ++#define NET_DEBUG 2 ++#endif ++static unsigned int net_debug = NET_DEBUG; ++ ++/* In micro second */ ++#define PLIP_DELAY_UNIT 1 ++ ++/* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */ ++#define PLIP_TRIGGER_WAIT 500 ++ ++/* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */ ++#define PLIP_NIBBLE_WAIT 3000 ++ ++#define PAR_DATA(dev) ((dev)->base_addr+0) ++#define PAR_STATUS(dev) ((dev)->base_addr+2) ++#define PAR_CONTROL(dev) ((dev)->base_addr+4) ++ ++static void enable_par_irq(struct device *dev, int on); ++static int plip_init(struct device *dev); ++ ++/* Bottom halfs */ ++static void plip_kick_bh(struct device *dev); ++static void plip_bh(struct device *dev); ++ ++/* Functions for DEV methods */ ++static int plip_rebuild_header(struct sk_buff *skb); ++static int plip_tx_packet(struct sk_buff *skb, struct device *dev); ++static int plip_open(struct device *dev); ++static int plip_close(struct device *dev); ++static struct enet_statistics *plip_get_stats(struct device *dev); ++static int plip_config(struct device *dev, struct ifmap *map); ++static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd); ++ ++enum plip_connection_state { ++ PLIP_CN_NONE=0, ++ PLIP_CN_RECEIVE, ++ PLIP_CN_SEND, ++ PLIP_CN_CLOSING, ++ PLIP_CN_ERROR ++}; ++ ++enum plip_packet_state { ++ PLIP_PK_DONE=0, ++ PLIP_PK_TRIGGER, ++ PLIP_PK_LENGTH_LSB, ++ PLIP_PK_LENGTH_MSB, ++ PLIP_PK_DATA, ++ PLIP_PK_CHECKSUM ++}; ++ ++enum plip_nibble_state { ++ PLIP_NB_BEGIN, ++ PLIP_NB_1, ++ PLIP_NB_2, ++}; ++ ++struct plip_local { ++ enum plip_packet_state state; ++ enum plip_nibble_state nibble; ++ union { ++ struct { ++#if defined(__LITTLE_ENDIAN) ++ unsigned char lsb; ++ unsigned char msb; ++#elif defined(__BIG_ENDIAN) ++ unsigned char msb; ++ unsigned char lsb; ++#else ++#error "Please fix the endianness defines in " ++#endif ++ } b; ++ unsigned short h; ++ } length; ++ unsigned short byte; ++ unsigned char checksum; ++ unsigned char data; ++ struct sk_buff *skb; ++}; ++ ++struct net_local { ++ struct enet_statistics enet_stats; ++ struct tq_struct immediate; ++ struct tq_struct deferred; ++ struct plip_local snd_data; ++ struct plip_local rcv_data; ++ unsigned long trigger; ++ unsigned long nibble; ++ enum plip_connection_state connection; ++ unsigned short timeout_count; ++ char is_deferred; ++ int (*orig_rebuild_header)(struct sk_buff *skb); ++}; ++ ++struct device ioext_dev_plip[] = { ++ { ++ "plip0", ++ 0, 0, 0, 0, /* memory */ ++ 0, 0, /* base, irq */ ++ 0, 0, 0, NULL, plip_init ++ }, ++ { ++ "plip1", ++ 0, 0, 0, 0, /* memory */ ++ 0, 0, /* base, irq */ ++ 0, 0, 0, NULL, plip_init ++ }, ++ { ++ "plip2", ++ 0, 0, 0, 0, /* memory */ ++ 0, 0, /* base, irq */ ++ 0, 0, 0, NULL, plip_init ++ } ++}; ++ ++/* ++ * Check for and handle an interrupt for this PLIP device. ++ * ++ */ ++void ioext_plip_interrupt(struct device *dev, int *spurious_count) ++{ ++ struct net_local *nl; ++ struct plip_local *rcv; ++ unsigned char c0; ++ unsigned long flags; ++ ++ nl = (struct net_local *)dev->priv; ++ rcv = &nl->rcv_data; ++ ++ c0 = z_readb(PAR_STATUS(dev)); ++ ++ if (dev->interrupt) { ++ return; ++ } ++ ++ if ((c0 & 0xf8) != 0xc0) { ++ /* Not for us */ ++ ++*spurious_count; ++ return; ++ } ++ ++ *spurious_count = 0; ++ dev->interrupt = 1; ++ ++ local_irq_save(flags); ++ ++ switch (nl->connection) { ++ case PLIP_CN_CLOSING: ++ dev->tbusy = 0; ++ case PLIP_CN_NONE: ++ case PLIP_CN_SEND: ++ dev->last_rx = jiffies; ++ rcv->state = PLIP_PK_TRIGGER; ++ nl->connection = PLIP_CN_RECEIVE; ++ nl->timeout_count = 0; ++ queue_task(&nl->immediate, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++ local_irq_restore(flags); ++#if 0 ++ printk("%s: receive irq in SEND/NONE/CLOSING (%d) ok\n", ++ dev->name, nl->connection); ++#endif ++ break; ++ ++ case PLIP_CN_RECEIVE: ++ local_irq_restore(flags); ++ printk("%s: receive interrupt when receiving packet\n", ++ dev->name); ++ break; ++ ++ case PLIP_CN_ERROR: ++ local_irq_restore(flags); ++ printk("%s: receive interrupt in error state\n", dev->name); ++ break; ++ } ++} ++ ++ ++/* Bottom half handler for the delayed request. ++ This routine is kicked by do_timer(). ++ Request `plip_bh' to be invoked. */ ++static void ++plip_kick_bh(struct device *dev) ++{ ++ struct net_local *nl = (struct net_local *)dev->priv; ++ ++ if (nl->is_deferred) { ++ queue_task(&nl->immediate, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++ } ++} ++ ++/* Forward declarations of internal routines */ ++static int plip_none(struct device *, struct net_local *, ++ struct plip_local *, struct plip_local *); ++static int plip_receive_packet(struct device *, struct net_local *, ++ struct plip_local *, struct plip_local *); ++static int plip_send_packet(struct device *, struct net_local *, ++ struct plip_local *, struct plip_local *); ++static int plip_connection_close(struct device *, struct net_local *, ++ struct plip_local *, struct plip_local *); ++static int plip_error(struct device *, struct net_local *, ++ struct plip_local *, struct plip_local *); ++static int plip_bh_timeout_error(struct device *dev, struct net_local *nl, ++ struct plip_local *snd, ++ struct plip_local *rcv, ++ int error); ++ ++#define OK 0 ++#define TIMEOUT 1 ++#define ERROR 2 ++ ++typedef int (*plip_func)(struct device *dev, struct net_local *nl, ++ struct plip_local *snd, struct plip_local *rcv); ++ ++static plip_func connection_state_table[] = ++{ ++ plip_none, ++ plip_receive_packet, ++ plip_send_packet, ++ plip_connection_close, ++ plip_error ++}; ++ ++/* ++** enable_par_irq() ++** ++** Enable or disable parallel irq for 'dev' according to 'on'. ++** ++** It is NOT possible to disable only the parallel irq. ++** So we disable the board interrupt instead. This means that ++** during reception of a PLIP packet, no serial interrupts can ++** happen. Sorry. ++*/ ++static void enable_par_irq(struct device *dev, int on) ++{ ++ if (on) { ++ PLIP_DEV(dev)->board->CNTR |= GVP_IRQ_ENA; ++ } ++ else { ++ PLIP_DEV(dev)->board->CNTR &= ~GVP_IRQ_ENA; ++ } ++} ++ ++/* Bottom half handler of PLIP. */ ++static void ++plip_bh(struct device *dev) ++{ ++ struct net_local *nl = (struct net_local *)dev->priv; ++ struct plip_local *snd = &nl->snd_data; ++ struct plip_local *rcv = &nl->rcv_data; ++ plip_func f; ++ int r; ++ ++ nl->is_deferred = 0; ++ f = connection_state_table[nl->connection]; ++ if ((r = (*f)(dev, nl, snd, rcv)) != OK ++ && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) { ++ nl->is_deferred = 1; ++ queue_task(&nl->deferred, &tq_timer); ++ } ++} ++ ++static int ++plip_bh_timeout_error(struct device *dev, struct net_local *nl, ++ struct plip_local *snd, struct plip_local *rcv, ++ int error) ++{ ++ unsigned char c0; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ if (nl->connection == PLIP_CN_SEND) { ++ ++ if (error != ERROR) { /* Timeout */ ++ nl->timeout_count++; ++ if ((snd->state == PLIP_PK_TRIGGER ++ && nl->timeout_count <= 10) ++ || nl->timeout_count <= 3) { ++ local_irq_restore(flags); ++ /* Try again later */ ++ return TIMEOUT; ++ } ++ c0 = z_readb(PAR_STATUS(dev)); ++ printk(KERN_INFO "%s: transmit timeout(%d,%02x)\n", ++ dev->name, snd->state, c0); ++ } ++ nl->enet_stats.tx_errors++; ++ nl->enet_stats.tx_aborted_errors++; ++ } else if (nl->connection == PLIP_CN_RECEIVE) { ++ if (rcv->state == PLIP_PK_TRIGGER) { ++ /* Transmission was interrupted. */ ++ local_irq_restore(flags); ++ return OK; ++ } ++ if (error != ERROR) { /* Timeout */ ++ if (++nl->timeout_count <= 3) { ++ local_irq_restore(flags); ++ /* Try again later */ ++ return TIMEOUT; ++ } ++ c0 = z_readb(PAR_STATUS(dev)); ++ printk(KERN_INFO "%s: receive timeout(%d,%02x)\n", ++ dev->name, rcv->state, c0); ++ } ++ nl->enet_stats.rx_dropped++; ++ } ++ rcv->state = PLIP_PK_DONE; ++ if (rcv->skb) { ++ kfree_skb(rcv->skb); ++ rcv->skb = NULL; ++ } ++ snd->state = PLIP_PK_DONE; ++ if (snd->skb) { ++ dev_kfree_skb(snd->skb); ++ snd->skb = NULL; ++ } ++ enable_par_irq(dev, 0); ++ dev->tbusy = 1; ++ nl->connection = PLIP_CN_ERROR; ++ z_writeb(0x00, PAR_DATA(dev)); ++ local_irq_restore(flags); ++ ++ return TIMEOUT; ++} ++ ++static int ++plip_none(struct device *dev, struct net_local *nl, ++ struct plip_local *snd, struct plip_local *rcv) ++{ ++ return OK; ++} ++ ++/* PLIP_RECEIVE --- receive a byte(two nibbles) ++ Returns OK on success, TIMEOUT on timeout */ ++inline static int ++plip_receive(struct device *dev, unsigned short nibble_timeout, ++ enum plip_nibble_state *ns_p, unsigned char *data_p) ++{ ++ unsigned char c0, c1; ++ unsigned int cx; ++ ++ switch (*ns_p) { ++ case PLIP_NB_BEGIN: ++ cx = nibble_timeout; ++ while (1) { ++ c0 = z_readb(PAR_STATUS(dev)); ++ udelay(PLIP_DELAY_UNIT); ++ if ((c0 & 0x80) == 0) { ++ c1 = z_readb(PAR_STATUS(dev)); ++ if (c0 == c1) ++ break; ++ } ++ if (--cx == 0) ++ return TIMEOUT; ++ } ++#if 0 ++ printk("received first nybble: %02X -> %02X\n", ++ c0, (c0 >> 3) & 0x0F); ++#endif ++ *data_p = (c0 >> 3) & 0x0f; ++ z_writeb(0x10, PAR_DATA(dev)); /* send ACK */ ++ *ns_p = PLIP_NB_1; ++ ++ case PLIP_NB_1: ++ cx = nibble_timeout; ++ while (1) { ++ c0 = z_readb(PAR_STATUS(dev)); ++ udelay(PLIP_DELAY_UNIT); ++ if (c0 & 0x80) { ++ c1 = z_readb(PAR_STATUS(dev)); ++ if (c0 == c1) ++ break; ++ } ++ if (--cx == 0) ++ return TIMEOUT; ++ } ++#if 0 ++ printk("received second nybble: %02X -> %02X\n", ++ c0, (c0 << 1) & 0xF0); ++#endif ++ *data_p |= (c0 << 1) & 0xf0; ++ z_writeb(0x00, PAR_DATA(dev)); /* send ACK */ ++ *ns_p = PLIP_NB_BEGIN; ++ case PLIP_NB_2: ++ break; ++ } ++ return OK; ++} ++ ++/* PLIP_RECEIVE_PACKET --- receive a packet */ ++static int ++plip_receive_packet(struct device *dev, struct net_local *nl, ++ struct plip_local *snd, struct plip_local *rcv) ++{ ++ unsigned short nibble_timeout = nl->nibble; ++ unsigned char *lbuf; ++ unsigned long flags; ++ ++ switch (rcv->state) { ++ case PLIP_PK_TRIGGER: ++ enable_par_irq(dev, 0); ++ dev->interrupt = 0; ++ z_writeb(0x01, PAR_DATA(dev)); /* send ACK */ ++ if (net_debug > 2) ++ printk(KERN_DEBUG "%s: receive start\n", dev->name); ++ rcv->state = PLIP_PK_LENGTH_LSB; ++ rcv->nibble = PLIP_NB_BEGIN; ++ ++ case PLIP_PK_LENGTH_LSB: ++ if (snd->state != PLIP_PK_DONE) { ++ if (plip_receive(dev, nl->trigger, ++ &rcv->nibble, &rcv->length.b.lsb)) { ++ /* collision, here dev->tbusy == 1 */ ++ rcv->state = PLIP_PK_DONE; ++ nl->is_deferred = 1; ++ nl->connection = PLIP_CN_SEND; ++ queue_task(&nl->deferred, &tq_timer); ++ enable_par_irq(dev, 1); ++ return OK; ++ } ++ } else { ++ if (plip_receive(dev, nibble_timeout, ++ &rcv->nibble, &rcv->length.b.lsb)) ++ return TIMEOUT; ++ } ++ rcv->state = PLIP_PK_LENGTH_MSB; ++ ++ case PLIP_PK_LENGTH_MSB: ++ if (plip_receive(dev, nibble_timeout, ++ &rcv->nibble, &rcv->length.b.msb)) ++ return TIMEOUT; ++ if (rcv->length.h > dev->mtu + dev->hard_header_len ++ || rcv->length.h < 8) { ++ printk(KERN_INFO "%s: bogus packet size %d.\n", ++ dev->name, rcv->length.h); ++ return ERROR; ++ } ++ /* Malloc up new buffer. */ ++ rcv->skb = dev_alloc_skb(rcv->length.h); ++ if (rcv->skb == NULL) { ++ printk(KERN_INFO "%s: Memory squeeze.\n", dev->name); ++ return ERROR; ++ } ++ skb_put(rcv->skb,rcv->length.h); ++ rcv->skb->dev = dev; ++ rcv->state = PLIP_PK_DATA; ++ rcv->byte = 0; ++ rcv->checksum = 0; ++ ++ case PLIP_PK_DATA: ++ lbuf = rcv->skb->data; ++ do ++ if (plip_receive(dev, nibble_timeout, ++ &rcv->nibble, &lbuf[rcv->byte])) ++ return TIMEOUT; ++ while (++rcv->byte < rcv->length.h); ++ do ++ rcv->checksum += lbuf[--rcv->byte]; ++ while (rcv->byte); ++ rcv->state = PLIP_PK_CHECKSUM; ++ ++ case PLIP_PK_CHECKSUM: ++ if (plip_receive(dev, nibble_timeout, ++ &rcv->nibble, &rcv->data)) ++ return TIMEOUT; ++ if (rcv->data != rcv->checksum) { ++ nl->enet_stats.rx_crc_errors++; ++ if (net_debug) ++ printk(KERN_INFO "%s: checksum error\n", ++ dev->name); ++ return ERROR; ++ } ++ rcv->state = PLIP_PK_DONE; ++ ++ case PLIP_PK_DONE: ++ /* Inform the upper layer for the arrival of a packet. */ ++ rcv->skb->protocol=eth_type_trans(rcv->skb, dev); ++ netif_rx(rcv->skb); ++ nl->enet_stats.rx_packets++; ++ rcv->skb = NULL; ++ if (net_debug > 2) ++ printk(KERN_DEBUG "%s: receive end\n", dev->name); ++ ++ /* Close the connection. */ ++ z_writeb (0x00, PAR_DATA(dev)); ++ ++ local_irq_save(flags); ++ if (snd->state != PLIP_PK_DONE) { ++ nl->connection = PLIP_CN_SEND; ++ local_irq_restore(flags); ++ queue_task(&nl->immediate, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++ enable_par_irq(dev, 1); ++ return OK; ++ } else { ++ nl->connection = PLIP_CN_NONE; ++ local_irq_restore(flags); ++ enable_par_irq(dev, 1); ++ return OK; ++ } ++ } ++ return OK; ++} ++ ++/* PLIP_SEND --- send a byte (two nibbles) ++ Returns OK on success, TIMEOUT when timeout */ ++inline static int ++plip_send(struct device *dev, unsigned short nibble_timeout, ++ enum plip_nibble_state *ns_p, unsigned char data) ++{ ++ unsigned char c0; ++ unsigned int cx; ++ ++ switch (*ns_p) { ++ case PLIP_NB_BEGIN: ++ z_writeb((data & 0x0f), PAR_DATA(dev)); ++ *ns_p = PLIP_NB_1; ++ ++ case PLIP_NB_1: ++ z_writeb(0x10 | (data & 0x0f), PAR_DATA(dev)); ++ cx = nibble_timeout; ++ while (1) { ++ c0 = z_readb(PAR_STATUS(dev)); ++ if ((c0 & 0x80) == 0) ++ break; ++ if (--cx == 0) ++ return TIMEOUT; ++ udelay(PLIP_DELAY_UNIT); ++ } ++ z_writeb(0x10 | (data >> 4), PAR_DATA(dev)); ++ *ns_p = PLIP_NB_2; ++ ++ case PLIP_NB_2: ++ z_writeb((data >> 4), PAR_DATA(dev)); ++ cx = nibble_timeout; ++ while (1) { ++ c0 = z_readb(PAR_STATUS(dev)); ++ if (c0 & 0x80) ++ break; ++ if (--cx == 0) ++ return TIMEOUT; ++ udelay(PLIP_DELAY_UNIT); ++ } ++ *ns_p = PLIP_NB_BEGIN; ++ return OK; ++ } ++ return OK; ++} ++ ++/* PLIP_SEND_PACKET --- send a packet */ ++static int ++plip_send_packet(struct device *dev, struct net_local *nl, ++ struct plip_local *snd, struct plip_local *rcv) ++{ ++ unsigned short nibble_timeout = nl->nibble; ++ unsigned char *lbuf; ++ unsigned char c0; ++ unsigned int cx; ++ unsigned long flags; ++ ++ if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) { ++ printk(KERN_INFO "%s: send skb lost\n", dev->name); ++ snd->state = PLIP_PK_DONE; ++ snd->skb = NULL; ++ return ERROR; ++ } ++ ++ if (snd->length.h == 0) { ++ return OK; ++ } ++ ++ switch (snd->state) { ++ case PLIP_PK_TRIGGER: ++ if ((z_readb(PAR_STATUS(dev)) & 0xf8) != 0x80) ++ return TIMEOUT; ++ ++ /* Trigger remote rx interrupt. */ ++ z_writeb(0x08, PAR_DATA(dev)); ++ cx = nl->trigger; ++ while (1) { ++ udelay(PLIP_DELAY_UNIT); ++ local_irq_save(flags); ++ if (nl->connection == PLIP_CN_RECEIVE) { ++ local_irq_restore(flags); ++ /* interrupted */ ++ nl->enet_stats.collisions++; ++ if (net_debug > 1) ++ printk(KERN_INFO "%s: collision.\n", ++ dev->name); ++ return OK; ++ } ++ c0 = z_readb(PAR_STATUS(dev)); ++ if (c0 & 0x08) { ++ enable_par_irq(dev, 0); ++ if (net_debug > 2) ++ printk(KERN_DEBUG "%s: send start\n", ++ dev->name); ++ snd->state = PLIP_PK_LENGTH_LSB; ++ snd->nibble = PLIP_NB_BEGIN; ++ nl->timeout_count = 0; ++ local_irq_restore(flags); ++ break; ++ } ++ local_irq_restore(flags); ++ if (--cx == 0) { ++ z_writeb(0x00, PAR_DATA(dev)); ++ return TIMEOUT; ++ } ++ } ++ ++ case PLIP_PK_LENGTH_LSB: ++ if (plip_send(dev, nibble_timeout, ++ &snd->nibble, snd->length.b.lsb)) ++ return TIMEOUT; ++ snd->state = PLIP_PK_LENGTH_MSB; ++ ++ case PLIP_PK_LENGTH_MSB: ++ if (plip_send(dev, nibble_timeout, ++ &snd->nibble, snd->length.b.msb)) ++ return TIMEOUT; ++ snd->state = PLIP_PK_DATA; ++ snd->byte = 0; ++ snd->checksum = 0; ++ ++ case PLIP_PK_DATA: ++ do ++ if (plip_send(dev, nibble_timeout, ++ &snd->nibble, lbuf[snd->byte])) ++ return TIMEOUT; ++ while (++snd->byte < snd->length.h); ++ do ++ snd->checksum += lbuf[--snd->byte]; ++ while (snd->byte); ++ snd->state = PLIP_PK_CHECKSUM; ++ ++ case PLIP_PK_CHECKSUM: ++ if (plip_send(dev, nibble_timeout, ++ &snd->nibble, snd->checksum)) ++ return TIMEOUT; ++ ++ dev_kfree_skb(snd->skb); ++ nl->enet_stats.tx_packets++; ++ snd->state = PLIP_PK_DONE; ++ ++ case PLIP_PK_DONE: ++ /* Close the connection */ ++ z_writeb (0x00, PAR_DATA(dev)); ++ snd->skb = NULL; ++ if (net_debug > 2) ++ printk(KERN_DEBUG "%s: send end\n", dev->name); ++ nl->connection = PLIP_CN_CLOSING; ++ nl->is_deferred = 1; ++ queue_task(&nl->deferred, &tq_timer); ++ enable_par_irq(dev, 1); ++ return OK; ++ } ++ return OK; ++} ++ ++static int ++plip_connection_close(struct device *dev, struct net_local *nl, ++ struct plip_local *snd, struct plip_local *rcv) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ if (nl->connection == PLIP_CN_CLOSING) { ++ nl->connection = PLIP_CN_NONE; ++ dev->tbusy = 0; ++ mark_bh(NET_BH); ++ } ++ local_irq_restore(flags); ++ return OK; ++} ++ ++/* PLIP_ERROR --- wait till other end settled */ ++static int ++plip_error(struct device *dev, struct net_local *nl, ++ struct plip_local *snd, struct plip_local *rcv) ++{ ++ unsigned char status; ++ ++ status = z_readb(PAR_STATUS(dev)); ++ if ((status & 0xf8) == 0x80) { ++ if (net_debug > 2) ++ printk(KERN_DEBUG "%s: reset interface.\n", dev->name); ++ nl->connection = PLIP_CN_NONE; ++ dev->tbusy = 0; ++ dev->interrupt = 0; ++ enable_par_irq(dev, 1); ++ mark_bh(NET_BH); ++ } else { ++ nl->is_deferred = 1; ++ queue_task(&nl->deferred, &tq_timer); ++ } ++ ++ return OK; ++} ++ ++/* We don't need to send arp, for plip is point-to-point. */ ++static int ++plip_rebuild_header(struct sk_buff *skb) ++{ ++ struct device *dev = skb->dev; ++ struct net_local *nl = (struct net_local *)dev->priv; ++ struct ethhdr *eth = (struct ethhdr *)skb->data; ++ int i; ++ ++ if ((dev->flags & IFF_NOARP)==0) ++ return nl->orig_rebuild_header(skb); ++ ++ if (eth->h_proto != __constant_htons(ETH_P_IP) ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ && eth->h_proto != __constant_htons(ETH_P_IPV6) ++#endif ++ ) { ++ printk(KERN_ERR "plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto); ++ memcpy(eth->h_source, dev->dev_addr, dev->addr_len); ++ return 0; ++ } ++ ++ for (i=0; i < ETH_ALEN - sizeof(u32); i++) ++ eth->h_dest[i] = 0xfc; ++#if 0 ++ *(u32 *)(eth->h_dest+i) = dst; ++#else ++ /* Do not want to include net/route.h here. ++ * In any case, it is TOP of silliness to emulate ++ * hardware addresses on PtP link. --ANK ++ */ ++ *(u32 *)(eth->h_dest+i) = 0; ++#endif ++ return 0; ++} ++ ++static int ++plip_tx_packet(struct sk_buff *skb, struct device *dev) ++{ ++ struct net_local *nl = (struct net_local *)dev->priv; ++ struct plip_local *snd = &nl->snd_data; ++ unsigned long flags; ++ ++ if (dev->tbusy) ++ return 1; ++ ++ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { ++ printk(KERN_ERR "%s: Transmitter access conflict.\n", ++ dev->name); ++ return 1; ++ } ++ ++ if (skb->len > dev->mtu + dev->hard_header_len) { ++ printk(KERN_ERR "%s: packet too big, %d.\n", ++ dev->name, (int)skb->len); ++ dev->tbusy = 0; ++ return 0; ++ } ++ ++ if (net_debug > 2) ++ printk(KERN_DEBUG "%s: send request\n", dev->name); ++ ++ local_irq_save(flags); ++ dev->trans_start = jiffies; ++ snd->skb = skb; ++ snd->length.h = skb->len; ++ snd->state = PLIP_PK_TRIGGER; ++ if (nl->connection == PLIP_CN_NONE) { ++ nl->connection = PLIP_CN_SEND; ++ nl->timeout_count = 0; ++ } ++ queue_task(&nl->immediate, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++ local_irq_restore(flags); ++ ++ return 0; ++} ++ ++/* Open/initialize the board. This is called (in the current kernel) ++ sometime after booting when the 'ifconfig' program is run. ++ ++ */ ++static int ++plip_open(struct device *dev) ++{ ++ struct net_local *nl = (struct net_local *)dev->priv; ++ struct in_device *in_dev; ++ ++#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE) ++ /* Yes, there is a race condition here. Fix it later */ ++ if (PLIP_DEV(dev)->par_use & IOEXT_PAR_LP) { ++ /* Can't open if lp is in use */ ++#if DEBUG ++ printk("par is in use by lp\n"); ++#endif ++ return(-EBUSY); ++ } ++#endif ++ PLIP_DEV(dev)->par_use |= IOEXT_PAR_PLIP; ++ ++#if DEBUG ++ printk("plip_open(): sending 00 to data port\n"); ++#endif ++ ++ /* Clear the data port. */ ++ z_writeb (0x00, PAR_DATA(dev)); ++ ++#if DEBUG ++ printk("plip_open(): sent\n"); ++#endif ++ ++ /* Initialize the state machine. */ ++ nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE; ++ nl->rcv_data.skb = nl->snd_data.skb = NULL; ++ nl->connection = PLIP_CN_NONE; ++ nl->is_deferred = 0; ++ ++ /* Fill in the MAC-level header. ++ (ab)Use "dev->broadcast" to store point-to-point MAC address. ++ ++ PLIP doesn't have a real mac address, but we need to create one ++ to be DOS compatible. */ ++ memset(dev->dev_addr, 0xfc, ETH_ALEN); ++ memset(dev->broadcast, 0xfc, ETH_ALEN); ++ ++ if ((in_dev=dev->ip_ptr) != NULL) { ++ /* ++ * Any address will do - we take the first ++ */ ++ struct in_ifaddr *ifa=in_dev->ifa_list; ++ if (ifa != NULL) { ++ memcpy(dev->dev_addr+2, &ifa->ifa_local, 4); ++ memcpy(dev->broadcast+2, &ifa->ifa_address, 4); ++ } ++ } ++ ++ dev->interrupt = 0; ++ dev->start = 1; ++ dev->tbusy = 0; ++ ++ MOD_INC_USE_COUNT; ++ ++ /* Enable rx interrupt. */ ++ enable_par_irq(dev, 1); ++ ++ return 0; ++} ++ ++/* The inverse routine to plip_open (). */ ++static int ++plip_close(struct device *dev) ++{ ++ struct net_local *nl = (struct net_local *)dev->priv; ++ struct plip_local *snd = &nl->snd_data; ++ struct plip_local *rcv = &nl->rcv_data; ++ unsigned long flags; ++ ++ dev->tbusy = 1; ++ dev->start = 0; ++ local_irq_save(flags); ++ nl->is_deferred = 0; ++ nl->connection = PLIP_CN_NONE; ++ local_irq_restore(flags); ++ z_writeb(0x00, PAR_DATA(dev)); ++ ++ snd->state = PLIP_PK_DONE; ++ if (snd->skb) { ++ dev_kfree_skb(snd->skb); ++ snd->skb = NULL; ++ } ++ rcv->state = PLIP_PK_DONE; ++ if (rcv->skb) { ++ kfree_skb(rcv->skb); ++ rcv->skb = NULL; ++ } ++ ++ PLIP_DEV(dev)->par_use &= ~IOEXT_PAR_PLIP; ++ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static struct enet_statistics * ++plip_get_stats(struct device *dev) ++{ ++ struct net_local *nl = (struct net_local *)dev->priv; ++ struct enet_statistics *r = &nl->enet_stats; ++ ++ return r; ++} ++ ++static int ++plip_config(struct device *dev, struct ifmap *map) ++{ ++ if (dev->flags & IFF_UP) ++ return -EBUSY; ++ ++ printk(KERN_INFO "%s: This interface is autodetected (ignored).\n", ++ dev->name); ++ ++ return 0; ++} ++ ++static int ++plip_ioctl(struct device *dev, struct ifreq *rq, int cmd) ++{ ++ struct net_local *nl = (struct net_local *) dev->priv; ++ struct plipconf *pc = (struct plipconf *) &rq->ifr_data; ++ ++ switch(pc->pcmd) { ++ case PLIP_GET_TIMEOUT: ++ pc->trigger = nl->trigger; ++ pc->nibble = nl->nibble; ++ break; ++ case PLIP_SET_TIMEOUT: ++ nl->trigger = pc->trigger; ++ nl->nibble = pc->nibble; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ return 0; ++} ++ ++/* ++ * Detect and initialize all IO-Extenders in this system. ++ * ++ * Both PLIP and serial devices are configured. ++ */ ++int plip_init(struct device *dev) ++{ ++ IOEXT_struct *board; ++ struct net_local *nl; ++ ++ if (ioext_num == 0) { ++ printk(KERN_INFO "%s\n", version); ++ } ++ ++ board = PLIP_DEV(dev)->board; ++ dev->base_addr = (unsigned long)&board->par.DATA; ++ ++ /* Cheat and use irq to index into our table */ ++ dev->irq = ioext_num; ++ ++ printk(KERN_INFO "%s: IO-Extender parallel port at 0x%08lX\n", dev->name, dev->base_addr); ++ ++ /* Fill in the generic fields of the device structure. */ ++ ether_setup(dev); ++ ++ /* Then, override parts of it */ ++ dev->hard_start_xmit = plip_tx_packet; ++ dev->open = plip_open; ++ dev->stop = plip_close; ++ dev->get_stats = plip_get_stats; ++ dev->set_config = plip_config; ++ dev->do_ioctl = plip_ioctl; ++ dev->tx_queue_len = 10; ++ dev->flags = IFF_POINTOPOINT|IFF_NOARP; ++ ++ /* Set the private structure */ ++ dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL); ++ if (dev->priv == NULL) { ++ printk(KERN_ERR "%s: out of memory\n", dev->name); ++ return -ENOMEM; ++ } ++ memset(dev->priv, 0, sizeof(struct net_local)); ++ nl = (struct net_local *) dev->priv; ++ ++ nl->orig_rebuild_header = dev->rebuild_header; ++ dev->rebuild_header = plip_rebuild_header; ++ ++ /* Initialize constants */ ++ nl->trigger = PLIP_TRIGGER_WAIT; ++ nl->nibble = PLIP_NIBBLE_WAIT; ++ ++ /* Initialize task queue structures */ ++ nl->immediate.next = NULL; ++ nl->immediate.sync = 0; ++ nl->immediate.routine = (void *)(void *)plip_bh; ++ nl->immediate.data = dev; ++ ++ nl->deferred.next = NULL; ++ nl->deferred.sync = 0; ++ nl->deferred.routine = (void *)(void *)plip_kick_bh; ++ nl->deferred.data = dev; ++ ++ /* Don't enable interrupts yet */ ++ ++ return 0; ++} +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/serial167.c linux-m68k/drivers/char/serial167.c +--- linux-i386/drivers/char/serial167.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/char/serial167.c 2006-04-11 16:34:45.000000000 +0200 +@@ -1434,7 +1434,6 @@ + volatile unsigned char *base_addr = (u_char *)BASE_ADDR; + unsigned long flags; + unsigned char status; +- unsigned int result; + + channel = info->line; + +@@ -1458,7 +1457,6 @@ + int channel; + volatile unsigned char *base_addr = (u_char *)BASE_ADDR; + unsigned long flags; +- unsigned int arg; + + channel = info->line; + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/ide/ide-iops.c linux-m68k/drivers/ide/ide-iops.c +--- linux-i386/drivers/ide/ide-iops.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/ide/ide-iops.c 2006-04-11 16:35:25.000000000 +0200 +@@ -337,6 +337,23 @@ + int i; + u16 *stringcast; + ++#ifdef __mc68000__ ++ if (!MACH_IS_AMIGA && !MACH_IS_MAC && !MACH_IS_Q40 && !MACH_IS_ATARI) ++ return; ++ ++#ifdef M68K_IDE_SWAPW ++ if (M68K_IDE_SWAPW) { /* fix bus byteorder first */ ++ u_char *p = (u_char *)id; ++ u_char t; ++ for (i = 0; i < 512; i += 2) { ++ t = p[i]; ++ p[i] = p[i+1]; ++ p[i+1] = t; ++ } ++ } ++#endif ++#endif /* __mc68000__ */ ++ + id->config = __le16_to_cpu(id->config); + id->cyls = __le16_to_cpu(id->cyls); + id->reserved2 = __le16_to_cpu(id->reserved2); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/ide/legacy/gayle.c linux-m68k/drivers/ide/legacy/gayle.c +--- linux-i386/drivers/ide/legacy/gayle.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/ide/legacy/gayle.c 2005-09-02 00:29:58.000000000 +0200 +@@ -161,6 +161,7 @@ + base = (unsigned long)ZTWO_VADDR(phys_base); + ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; + ++ memset(&hw, 0, sizeof(hw)); + ide_setup_ports(&hw, base, gayle_offsets, + ctrlport, irqport, ack_intr, + // &gayle_iops, +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/keyboard/Kconfig linux-m68k/drivers/input/keyboard/Kconfig +--- linux-i386/drivers/input/keyboard/Kconfig 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/input/keyboard/Kconfig 2006-04-11 16:35:35.000000000 +0200 +@@ -155,7 +155,7 @@ + + config KEYBOARD_HIL_OLD + tristate "HP HIL keyboard support (simple driver)" +- depends on GSC ++ depends on GSC || HP300 + default y + help + The "Human Interface Loop" is a older, 8-channel USB-like +@@ -172,7 +172,7 @@ + + config KEYBOARD_HIL + tristate "HP HIL keyboard support" +- depends on GSC ++ depends on GSC || HP300 + default y + select HP_SDC + select HIL_MLC +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/keyboard/amikbd.c linux-m68k/drivers/input/keyboard/amikbd.c +--- linux-i386/drivers/input/keyboard/amikbd.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/input/keyboard/amikbd.c 2006-01-28 23:53:40.000000000 +0100 +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -45,7 +46,7 @@ + MODULE_DESCRIPTION("Amiga keyboard driver"); + MODULE_LICENSE("GPL"); + +-static unsigned char amikbd_keycode[0x78] = { ++static unsigned char amikbd_keycode[0x78] __initdata = { + [0] = KEY_GRAVE, + [1] = KEY_1, + [2] = KEY_2, +@@ -170,12 +171,9 @@ + scancode >>= 1; + + if (scancode < 0x78) { /* scancodes < 0x78 are keys */ +- +- scancode = amikbd_keycode[scancode]; +- + input_regs(amikbd_dev, fp); + +- if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ ++ if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ + input_report_key(amikbd_dev, scancode, 1); + input_report_key(amikbd_dev, scancode, 0); + } else { +@@ -191,7 +189,7 @@ + + static int __init amikbd_init(void) + { +- int i; ++ int i, j; + + if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) + return -EIO; +@@ -214,14 +212,26 @@ + amikbd_dev->id.version = 0x0100; + + amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); +- amikbd_dev->keycode = amikbd_keycode; +- amikbd_dev->keycodesize = sizeof(unsigned char); +- amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode); + + for (i = 0; i < 0x78; i++) +- if (amikbd_keycode[i]) +- set_bit(amikbd_keycode[i], amikbd_dev->keybit); ++ set_bit(i, amikbd_dev->keybit); + ++ for (i = 0; i < MAX_NR_KEYMAPS; i++) { ++ static u_short temp_map[NR_KEYS] __initdata; ++ if (!key_maps[i]) ++ continue; ++ memset(temp_map, 0, sizeof(temp_map)); ++ for (j = 0; j < 0x78; j++) { ++ if (!amikbd_keycode[j]) ++ continue; ++ temp_map[j] = key_maps[i][amikbd_keycode[j]]; ++ } ++ for (j = 0; j < NR_KEYS; j++) { ++ if (!temp_map[j]) ++ temp_map[j] = 0xf200; ++ } ++ memcpy(key_maps[i], temp_map, sizeof(temp_map)); ++ } + ciaa.cra &= ~0x41; /* serial data in, turn off TA */ + request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt); + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/misc/Kconfig linux-m68k/drivers/input/misc/Kconfig +--- linux-i386/drivers/input/misc/Kconfig 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/input/misc/Kconfig 2006-04-11 16:35:36.000000000 +0200 +@@ -73,7 +73,7 @@ + + config HP_SDC_RTC + tristate "HP SDC Real Time Clock" +- depends on GSC ++ depends on GSC || HP300 + select HP_SDC + help + Say Y here if you want to support the built-in real time clock +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/mouse/Kconfig linux-m68k/drivers/input/mouse/Kconfig +--- linux-i386/drivers/input/mouse/Kconfig 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/input/mouse/Kconfig 2006-04-11 16:35:36.000000000 +0200 +@@ -119,7 +119,7 @@ + + config MOUSE_HIL + tristate "HIL pointers (mice etc)." +- depends on GSC ++ depends on GSC || HP300 + select HP_SDC + select HIL_MLC + help +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/serio/Kconfig linux-m68k/drivers/input/serio/Kconfig +--- linux-i386/drivers/input/serio/Kconfig 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/input/serio/Kconfig 2005-08-29 21:17:45.000000000 +0200 +@@ -112,7 +112,7 @@ + + config HP_SDC + tristate "HP System Device Controller i8042 Support" +- depends on GSC && SERIO ++ depends on (GSC || HP300) && SERIO + default y + ---help--- + This option enables supports for the the "System Device +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/macintosh/adb.c linux-m68k/drivers/macintosh/adb.c +--- linux-i386/drivers/macintosh/adb.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/macintosh/adb.c 2006-01-19 22:07:24.000000000 +0100 +@@ -476,13 +476,15 @@ + use_sreq = 1; + } else + use_sreq = 0; +- req->nbytes = nbytes+1; ++ i = (flags & ADBREQ_RAW) ? 0 : 1; ++ req->nbytes = nbytes+i; + req->done = done; + req->reply_expected = flags & ADBREQ_REPLY; + req->data[0] = ADB_PACKET; + va_start(list, nbytes); +- for (i = 0; i < nbytes; ++i) +- req->data[i+1] = va_arg(list, int); ++ while (i < req->nbytes) { ++ req->data[i++] = va_arg(list, int); ++ } + va_end(list); + + if (flags & ADBREQ_NOSEND) +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/7990.c linux-m68k/drivers/net/7990.c +--- linux-i386/drivers/net/7990.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/net/7990.c 2005-10-11 22:57:19.000000000 +0200 +@@ -500,7 +500,7 @@ + int res; + + /* Install the Interrupt handler. Or we could shunt this out to specific drivers? */ +- if (request_irq(lp->irq, lance_interrupt, 0, lp->name, dev)) ++ if (request_irq(lp->irq, lance_interrupt, SA_SHIRQ, lp->name, dev)) + return -EAGAIN; + + res = lance_reset(dev); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/Kconfig linux-m68k/drivers/net/Kconfig +--- linux-i386/drivers/net/Kconfig 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/net/Kconfig 2006-04-11 16:36:26.000000000 +0200 +@@ -307,7 +307,7 @@ + + config MAC89x0 + tristate "Macintosh CS89x0 based ethernet cards" +- depends on NET_ETHERNET && MAC && BROKEN ++ depends on NET_ETHERNET && MAC + ---help--- + Support for CS89x0 chipset based Ethernet cards. If you have a + Nubus or LC-PDS network (Ethernet) card of this type, say Y and +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/hplance.c linux-m68k/drivers/net/hplance.c +--- linux-i386/drivers/net/hplance.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/net/hplance.c 2006-04-11 16:36:30.000000000 +0200 +@@ -77,6 +77,7 @@ + { + struct net_device *dev; + int err = -ENOMEM; ++ int i; + + dev = alloc_etherdev(sizeof(struct hplance_private)); + if (!dev) +@@ -93,6 +94,15 @@ + goto out_release_mem_region; + + dio_set_drvdata(d, dev); ++ ++ printk(KERN_INFO "%s: %s; select code %d, addr %2.2x", dev->name, d->name, d->scode, dev->dev_addr[0]); ++ ++ for (i=1; i<6; i++) { ++ printk(":%2.2x", dev->dev_addr[i]); ++ } ++ ++ printk(", irq %d\n", d->ipl); ++ + return 0; + + out_release_mem_region: +@@ -118,9 +128,7 @@ + unsigned long va = (d->resource.start + DIO_VIRADDRBASE); + struct hplance_private *lp; + int i; +- +- printk(KERN_INFO "%s: %s; select code %d, addr", dev->name, d->name, d->scode); +- ++ + /* reset the board */ + out_8(va+DIO_IDOFF, 0xff); + udelay(100); /* ariba! ariba! udelay! udelay! */ +@@ -143,7 +151,6 @@ + */ + dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4) + | (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF); +- printk("%c%2.2x", i == 0 ? ' ' : ':', dev->dev_addr[i]); + } + + lp = netdev_priv(dev); +@@ -160,7 +167,6 @@ + lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS; + lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK; + lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK; +- printk(", irq %d\n", lp->lance.irq); + } + + /* This is disgusting. We have to check the DIO status register for ack every +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/mac89x0.c linux-m68k/drivers/net/mac89x0.c +--- linux-i386/drivers/net/mac89x0.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/net/mac89x0.c 2004-12-30 01:59:08.000000000 +0100 +@@ -128,7 +128,7 @@ + extern void reset_chip(struct net_device *dev); + #endif + static int net_open(struct net_device *dev); +-static int net_send_packet(struct sk_buff *skb, struct net_device *dev); ++static int net_send_packet(struct sk_buff *skb, struct net_device *dev); + static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs); + static void set_multicast_list(struct net_device *dev); + static void net_rx(struct net_device *dev); +@@ -374,56 +374,37 @@ + static int + net_send_packet(struct sk_buff *skb, struct net_device *dev) + { +- if (dev->tbusy) { +- /* If we get here, some higher level has decided we are broken. +- There should really be a "kick me" function call instead. */ +- int tickssofar = jiffies - dev->trans_start; +- if (tickssofar < 5) +- return 1; +- if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name, +- tx_done(dev) ? "IRQ conflict" : "network cable problem"); +- /* Try to restart the adaptor. */ +- dev->tbusy=0; +- dev->trans_start = jiffies; +- } +- +- /* Block a timer-based transmit from overlapping. This could better be +- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ +- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) +- printk("%s: Transmitter access conflict.\n", dev->name); +- else { +- struct net_local *lp = netdev_priv(dev); +- unsigned long flags; +- +- if (net_debug > 3) +- printk("%s: sent %d byte packet of type %x\n", +- dev->name, skb->len, +- (skb->data[ETH_ALEN+ETH_ALEN] << 8) +- | skb->data[ETH_ALEN+ETH_ALEN+1]); +- +- /* keep the upload from being interrupted, since we +- ask the chip to start transmitting before the +- whole packet has been completely uploaded. */ +- local_irq_save(flags); +- +- /* initiate a transmit sequence */ +- writereg(dev, PP_TxCMD, lp->send_cmd); +- writereg(dev, PP_TxLength, skb->len); +- +- /* Test to see if the chip has allocated memory for the packet */ +- if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { +- /* Gasp! It hasn't. But that shouldn't happen since +- we're waiting for TxOk, so return 1 and requeue this packet. */ +- local_irq_restore(flags); +- return 1; +- } ++ struct net_local *lp = netdev_priv(dev); ++ unsigned long flags; + +- /* Write the contents of the packet */ +- memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1); ++ if (net_debug > 3) ++ printk("%s: sent %d byte packet of type %x\n", ++ dev->name, skb->len, ++ (skb->data[ETH_ALEN+ETH_ALEN] << 8) ++ | skb->data[ETH_ALEN+ETH_ALEN+1]); ++ ++ /* keep the upload from being interrupted, since we ++ ask the chip to start transmitting before the ++ whole packet has been completely uploaded. */ ++ local_irq_save(flags); + ++ /* initiate a transmit sequence */ ++ writereg(dev, PP_TxCMD, lp->send_cmd); ++ writereg(dev, PP_TxLength, skb->len); ++ ++ /* Test to see if the chip has allocated memory for the packet */ ++ if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { ++ /* Gasp! It hasn't. But that shouldn't happen since ++ we're waiting for TxOk, so return 1 and requeue this packet. */ + local_irq_restore(flags); +- dev->trans_start = jiffies; ++ return 1; + } ++ ++ /* Write the contents of the packet */ ++ memcpy((void *)(dev->mem_start + PP_TxFrame), skb->data, skb->len+1); ++ ++ local_irq_restore(flags); ++ dev->trans_start = jiffies; + dev_kfree_skb (skb); + + return 0; +@@ -441,9 +422,6 @@ + printk ("net_interrupt(): irq %d for unknown device.\n", irq); + return IRQ_NONE; + } +- if (dev->interrupt) +- printk("%s: Re-entering the interrupt handler.\n", dev->name); +- dev->interrupt = 1; + + ioaddr = dev->base_addr; + lp = netdev_priv(dev); +@@ -464,8 +442,7 @@ + break; + case ISQ_TRANSMITTER_EVENT: + lp->stats.tx_packets++; +- dev->tbusy = 0; +- mark_bh(NET_BH); /* Inform upper layers. */ ++ netif_wake_queue(dev); + if ((status & TX_OK) == 0) lp->stats.tx_errors++; + if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++; + if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++; +@@ -479,8 +456,7 @@ + That shouldn't happen since we only ever + load one packet. Shrug. Do the right + thing anyway. */ +- dev->tbusy = 0; +- mark_bh(NET_BH); /* Inform upper layers. */ ++ netif_wake_queue(dev); + } + if (status & TX_UNDERRUN) { + if (net_debug > 0) printk("%s: transmit underrun\n", dev->name); +@@ -497,7 +473,6 @@ + break; + } + } +- dev->interrupt = 0; + return IRQ_HANDLED; + } + +@@ -532,7 +507,7 @@ + skb_put(skb, length); + skb->dev = dev; + +- memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length); ++ memcpy(skb->data, (void *)(dev->mem_start + PP_RxFrame), length); + + if (net_debug > 3)printk("%s: received %d byte packet of type %x\n", + dev->name, length, +@@ -611,8 +586,6 @@ + static int set_mac_address(struct net_device *dev, void *addr) + { + int i; +- if (dev->start) +- return -EBUSY; + printk("%s: Setting MAC address to ", dev->name); + for (i = 0; i < 6; i++) + printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/sun3lance.c linux-m68k/drivers/net/sun3lance.c +--- linux-i386/drivers/net/sun3lance.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/net/sun3lance.c 2006-04-11 16:36:42.000000000 +0200 +@@ -55,7 +55,7 @@ + /* sun3/60 addr/irq for the lance chip. If your sun is different, + change this. */ + #define LANCE_OBIO 0x120000 +-#define LANCE_IRQ IRQ3 ++#define LANCE_IRQ IRQ_AUTO_3 + + /* Debug level: + * 0 = silent, print only serious errors +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/53c7xx.c linux-m68k/drivers/scsi/53c7xx.c +--- linux-i386/drivers/scsi/53c7xx.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/53c7xx.c 2006-04-11 16:37:15.000000000 +0200 +@@ -308,7 +308,7 @@ + + static int check_address (unsigned long addr, int size); + static void dump_events (struct Scsi_Host *host, int count); +-static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host, ++static struct scsi_cmnd * return_outstanding_commands (struct Scsi_Host *host, + int free, int issue); + static void hard_reset (struct Scsi_Host *host); + static void ncr_scsi_reset (struct Scsi_Host *host); +@@ -317,7 +317,7 @@ + int scntl3, int now_connected); + static int datapath_residual (struct Scsi_Host *host); + static const char * sbcl_to_phase (int sbcl); +-static void print_progress (Scsi_Cmnd *cmd); ++static void print_progress (struct scsi_cmnd *cmd); + static void print_queues (struct Scsi_Host *host); + static void process_issue_queue (unsigned long flags); + static int shutdown (struct Scsi_Host *host); +@@ -342,9 +342,8 @@ + static void NCR53c7x0_soft_reset (struct Scsi_Host *host); + + /* Size of event list (per host adapter) */ +-static int track_events = 0; +-static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */ +-static struct scsi_host_template *the_template = NULL; ++static int track_events; ++static struct scsi_host_template *the_template; + + /* NCR53c710 script handling code */ + +@@ -667,8 +666,11 @@ + + static struct Scsi_Host * + find_host (int host) { +- struct Scsi_Host *h; +- for (h = first_host; h && h->host_no != host; h = h->next); ++ struct Scsi_Host *h, *s; ++ list_for_each_entry_safe(h, s, &the_template->legacy_hosts, sht_legacy_list) { ++ if (h->host_no == host) ++ break; ++ } + if (!h) { + printk (KERN_ALERT "scsi%d not found\n", host); + return NULL; +@@ -716,14 +718,14 @@ + } + hostdata = (struct NCR53c7x0_hostdata *)h->hostdata[0]; + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + if (hostdata->initiate_sdtr & (1 << target)) { +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + printk (KERN_ALERT "target %d already doing SDTR\n", target); + return -1; + } + hostdata->initiate_sdtr |= (1 << target); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return 0; + } + #endif +@@ -1034,9 +1036,6 @@ + + ccf = clock_to_ccf_710 (expected_clock); + +- for (i = 0; i < 16; ++i) +- hostdata->cmd_allocated[i] = 0; +- + if (hostdata->init_save_regs) + hostdata->init_save_regs (host); + if (hostdata->init_fixup) +@@ -1044,7 +1043,6 @@ + + if (!the_template) { + the_template = host->hostt; +- first_host = host; + } + + /* +@@ -1307,7 +1305,6 @@ + hostdata->free->size = max_cmd_size; + hostdata->free->free = NULL; + hostdata->free->next = NULL; +- hostdata->extra_allocate = 0; + + /* Allocate command start code space */ + hostdata->schedule = (chip == 700 || chip == 70066) ? +@@ -1590,10 +1587,10 @@ + + /* The NCR chip _must_ be idle to run the test scripts */ + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + if (!hostdata->idle) { + printk ("scsi%d : chip not idle, aborting tests\n", host->host_no); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return -1; + } + +@@ -1617,7 +1614,7 @@ + NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM | + DCNTL_STD); + printk (" started\n"); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + + /* + * This is currently a .5 second timeout, since (in theory) no slow +@@ -1656,7 +1653,7 @@ + hostdata->script, start); + printk ("scsi%d : DSPS = 0x%x\n", host->host_no, + NCR53c7x0_read32(DSPS_REG)); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return -1; + } + hostdata->test_running = 0; +@@ -1694,7 +1691,7 @@ + local_irq_disable(); + if (!hostdata->idle) { + printk ("scsi%d : chip not idle, aborting tests\n", host->host_no); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return -1; + } + +@@ -1710,7 +1707,7 @@ + if (hostdata->options & OPTION_DEBUG_TRACE) + NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | + DCNTL_SSM | DCNTL_STD); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + + timeout = jiffies + 5 * HZ; /* arbitrary */ + while ((hostdata->test_completed == -1) && time_before(jiffies, timeout)) +@@ -1732,19 +1729,19 @@ + host->host_no, i); + if (!hostdata->idle) { + printk("scsi%d : not idle\n", host->host_no); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return -1; + } + } else if (hostdata->test_completed == -1) { + printk ("scsi%d : test 2 timed out\n", host->host_no); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return -1; + } + hostdata->test_running = 0; + } + } + +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return 0; + } + +@@ -1760,7 +1757,7 @@ + + static void + NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) { +- Scsi_Cmnd *c = cmd->cmd; ++ struct scsi_cmnd *c = cmd->cmd; + struct Scsi_Host *host = c->device->host; + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) + host->hostdata[0]; +@@ -1846,7 +1843,7 @@ + * + * Purpose : mark SCSI command as finished, OR'ing the host portion + * of the result word into the result field of the corresponding +- * Scsi_Cmnd structure, and removing it from the internal queues. ++ * scsi_cmnd structure, and removing it from the internal queues. + * + * Inputs : cmd - command, result - entire result field + * +@@ -1857,7 +1854,7 @@ + + static void + abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) { +- Scsi_Cmnd *c = cmd->cmd; ++ struct scsi_cmnd *c = cmd->cmd; + struct Scsi_Host *host = c->device->host; + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) + host->hostdata[0]; +@@ -1871,7 +1868,7 @@ + printk ("scsi%d: abnormal finished\n", host->host_no); + #endif + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + found = 0; + /* + * Traverse the NCR issue array until we find a match or run out +@@ -1954,7 +1951,7 @@ + c->result = result; + c->scsi_done(c); + +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + run_process_issue_queue(); + } + +@@ -1976,7 +1973,7 @@ + NCR53c7x0_local_declare(); + struct NCR53c7x0_break *bp; + #if 0 +- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL; ++ struct scsi_cmnd *c = cmd ? cmd->cmd : NULL; + #endif + u32 *dsp; + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) +@@ -1989,7 +1986,7 @@ + * dump the appropriate debugging information to standard + * output. + */ +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG)); + for (bp = hostdata->breakpoints; bp && bp->address != dsp; + bp = bp->next); +@@ -2011,7 +2008,7 @@ + * instruction in bytes. + */ + +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } + /* + * Function : static void print_synchronous (const char *prefix, +@@ -2253,7 +2250,7 @@ + NCR53c7x0_cmd *cmd) { + NCR53c7x0_local_declare(); + int print; +- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL; ++ struct scsi_cmnd *c = cmd ? cmd->cmd : NULL; + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) + host->hostdata[0]; + u32 dsps,*dsp; /* Argument of the INT instruction */ +@@ -2917,7 +2914,7 @@ + host->hostdata[0]; + NCR53c7x0_local_setup(host); + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + + /* Disable scsi chip and s/w level 7 ints */ + +@@ -3018,12 +3015,12 @@ + } + #endif + /* Anything needed for your hardware? */ +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } + + + /* +- * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd) ++ * Function static struct NCR53c7x0_cmd *allocate_cmd (struct scsi_cmnd *cmd) + * + * Purpose : Return the first free NCR53c7x0_cmd structure (which are + * reused in a LIFO manner to minimize cache thrashing). +@@ -3050,86 +3047,25 @@ + } + + static struct NCR53c7x0_cmd * +-allocate_cmd (Scsi_Cmnd *cmd) { ++allocate_cmd (struct scsi_cmnd *cmd) { + struct Scsi_Host *host = cmd->device->host; + struct NCR53c7x0_hostdata *hostdata = + (struct NCR53c7x0_hostdata *) host->hostdata[0]; +- u32 real; /* Real address */ +- int size; /* Size of *tmp */ + struct NCR53c7x0_cmd *tmp; + unsigned long flags; + + if (hostdata->options & OPTION_DEBUG_ALLOCATION) + printk ("scsi%d : num_cmds = %d, can_queue = %d\n" +- " target = %d, lun = %d, %s\n", ++ " target = %d, lun = %d\n", + host->host_no, hostdata->num_cmds, host->can_queue, +- cmd->device->id, cmd->device->lun, (hostdata->cmd_allocated[cmd->device->id] & +- (1 << cmd->device->lun)) ? "already allocated" : "not allocated"); +- +-/* +- * If we have not yet reserved commands for this I_T_L nexus, and +- * the device exists (as indicated by permanent Scsi_Cmnd structures +- * being allocated under 1.3.x, or being outside of scan_scsis in +- * 1.2.x), do so now. +- */ +- if (!(hostdata->cmd_allocated[cmd->device->id] & (1 << cmd->device->lun)) && +- cmd->device && cmd->device->has_cmdblocks) { +- if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue) +- hostdata->extra_allocate += host->cmd_per_lun; +- hostdata->cmd_allocated[cmd->device->id] |= (1 << cmd->device->lun); +- } +- +- for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate, +- ++hostdata->num_cmds) { +- /* historically, kmalloc has returned unaligned addresses; pad so we +- have enough room to ROUNDUP */ +- size = hostdata->max_cmd_size + sizeof (void *); +-#ifdef FORCE_DSA_ALIGNMENT +- /* +- * 53c710 rev.0 doesn't have an add-with-carry instruction. +- * Ensure we allocate enough memory to force alignment. +- */ +- size += 256; +-#endif +-/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */ ++ cmd->device->id, cmd->device->lun); + +- if (size > 4096) { +- printk (KERN_ERR "53c7xx: allocate_cmd size > 4K\n"); +- return NULL; +- } +- real = get_zeroed_page(GFP_ATOMIC); +- if (real == 0) +- return NULL; +- memset((void *)real, 0, 4096); +- cache_push(virt_to_phys((void *)real), 4096); +- cache_clear(virt_to_phys((void *)real), 4096); +- kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER); +- tmp = ROUNDUP(real, void *); +-#ifdef FORCE_DSA_ALIGNMENT +- { +- if (((u32)tmp & 0xff) > CmdPageStart) +- tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255); +- tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart); +-#if 0 +- printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n", +- size, real, (u32)tmp); +-#endif +- } +-#endif +- tmp->real = (void *)real; +- tmp->size = size; +- tmp->free = ((void (*)(void *, int)) my_free_page); +- local_irq_save(flags); +- tmp->next = hostdata->free; +- hostdata->free = tmp; +- local_irq_restore(flags); +- } +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + tmp = (struct NCR53c7x0_cmd *) hostdata->free; + if (tmp) { + hostdata->free = tmp->next; + } +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + if (!tmp) + printk ("scsi%d : can't allocate command for target %d lun %d\n", + host->host_no, cmd->device->id, cmd->device->lun); +@@ -3137,11 +3073,11 @@ + } + + /* +- * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) ++ * Function static struct NCR53c7x0_cmd *create_cmd (struct scsi_cmnd *cmd) + * + * + * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the +- * Scsi_Cmnd structure passed in cmd, including dsa and Linux field ++ * scsi_cmnd structure passed in cmd, including dsa and Linux field + * initialization, and dsa code relocation. + * + * Inputs : cmd - SCSI command +@@ -3150,7 +3086,7 @@ + * NULL on failure. + */ + static struct NCR53c7x0_cmd * +-create_cmd (Scsi_Cmnd *cmd) { ++create_cmd (struct scsi_cmnd *cmd) { + NCR53c7x0_local_declare(); + struct Scsi_Host *host = cmd->device->host; + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) +@@ -3174,7 +3110,7 @@ + return NULL; + + /* +- * Copy CDB and initialised result fields from Scsi_Cmnd to NCR53c7x0_cmd. ++ * Copy CDB and initialised result fields from scsi_cmnd to NCR53c7x0_cmd. + * We do this because NCR53c7x0_cmd may have a special cache mode + * selected to cope with lack of bus snooping, etc. + */ +@@ -3317,7 +3253,7 @@ + + patch_dsa_32(tmp->dsa, dsa_next, 0, 0); + /* +- * XXX is this giving 53c710 access to the Scsi_Cmnd in some way? ++ * XXX is this giving 53c710 access to the scsi_cmnd in some way? + * Do we need to change it for caching reasons? + */ + patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd)); +@@ -3348,17 +3284,17 @@ + memcpy ((void *) (tmp->select + 1), (void *) wdtr_message, + sizeof(wdtr_message)); + patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message)); +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + hostdata->initiate_wdtr &= ~(1 << cmd->device->id); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } else if (hostdata->initiate_sdtr & (1 << cmd->device->id)) { + memcpy ((void *) (tmp->select + 1), (void *) sdtr_message, + sizeof(sdtr_message)); + patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message)); + tmp->flags |= CMD_FLAG_SDTR; +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + hostdata->initiate_sdtr &= ~(1 << cmd->device->id); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + + } + #if 1 +@@ -3571,8 +3507,8 @@ + } + + /* +- * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, +- * void (*done)(Scsi_Cmnd *)) ++ * Function : int NCR53c7xx_queue_command (struct scsi_cmnd *cmd, ++ * void (*done)(struct scsi_cmnd *)) + * + * Purpose : enqueues a SCSI command + * +@@ -3586,18 +3522,18 @@ + * twiddling done to the host specific fields of cmd. If the + * process_issue_queue coroutine isn't running, it is restarted. + * +- * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to ++ * NOTE : we use the host_scribble field of the scsi_cmnd structure to + * hold our own data, and pervert the ptr field of the SCp field + * to create a linked list. + */ + + int +-NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { ++NCR53c7xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) { + struct Scsi_Host *host = cmd->device->host; + struct NCR53c7x0_hostdata *hostdata = + (struct NCR53c7x0_hostdata *) host->hostdata[0]; + unsigned long flags; +- Scsi_Cmnd *tmp; ++ struct scsi_cmnd *tmp; + + cmd->scsi_done = done; + cmd->host_scribble = NULL; +@@ -3615,7 +3551,7 @@ + } + #endif + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) + || ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) && + !(hostdata->debug_lun_limit[cmd->device->id] & (1 << cmd->device->lun))) +@@ -3630,7 +3566,7 @@ + cmd->device->id, cmd->device->lun); + cmd->result = (DID_BAD_TARGET << 16); + done(cmd); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return 0; + } + +@@ -3639,7 +3575,7 @@ + printk("scsi%d : maximum commands exceeded\n", host->host_no); + cmd->result = (DID_BAD_TARGET << 16); + done(cmd); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return 0; + } + +@@ -3651,7 +3587,7 @@ + host->host_no); + cmd->result = (DID_BAD_TARGET << 16); + done(cmd); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return 0; + } + } +@@ -3674,18 +3610,18 @@ + cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue; + hostdata->issue_queue = cmd; + } else { +- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr; +- tmp = (Scsi_Cmnd *) tmp->SCp.ptr); ++ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->SCp.ptr; ++ tmp = (struct scsi_cmnd *) tmp->SCp.ptr); + tmp->SCp.ptr = (unsigned char *) cmd; + } +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + run_process_issue_queue(); + return 0; + } + + /* + * Function : void to_schedule_list (struct Scsi_Host *host, +- * struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd) ++ * struct NCR53c7x0_hostdata * hostdata, struct scsi_cmnd *cmd) + * + * Purpose : takes a SCSI command which was just removed from the + * issue queue, and deals with it by inserting it in the first +@@ -3706,7 +3642,7 @@ + to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata, + struct NCR53c7x0_cmd *cmd) { + NCR53c7x0_local_declare(); +- Scsi_Cmnd *tmp = cmd->cmd; ++ struct scsi_cmnd *tmp = cmd->cmd; + unsigned long flags; + /* dsa start is negative, so subtraction is used */ + volatile u32 *ncrcurrent; +@@ -3718,7 +3654,7 @@ + virt_to_bus(hostdata->dsa), hostdata->dsa); + #endif + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + + /* + * Work around race condition : if an interrupt fired and we +@@ -3731,7 +3667,7 @@ + cmd->next = (struct NCR53c7x0_cmd *) hostdata->free; + hostdata->free = cmd; + tmp->scsi_done(tmp); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return; + } + +@@ -3761,7 +3697,7 @@ + cmd->next = (struct NCR53c7x0_cmd *) hostdata->free; + hostdata->free = cmd; + tmp->scsi_done(tmp); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return; + } + +@@ -3782,12 +3718,12 @@ + NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP); + } + +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } + + /* + * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata +- * *hostdata, Scsi_Cmnd *cmd) ++ * *hostdata, struct scsi_cmnd *cmd) + * + * Purpose : decide if we can pass the given SCSI command on to the + * device in question or not. +@@ -3797,7 +3733,7 @@ + + static __inline__ int + busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata, +- Scsi_Cmnd *cmd) { ++ struct scsi_cmnd *cmd) { + /* FIXME : in the future, this needs to accommodate SCSI-II tagged + queuing, and we may be able to play with fairness here a bit. + */ +@@ -3823,8 +3759,8 @@ + + static void + process_issue_queue (unsigned long flags) { +- Scsi_Cmnd *tmp, *prev; +- struct Scsi_Host *host; ++ struct scsi_cmnd *tmp, *prev; ++ struct Scsi_Host *host, *s; + struct NCR53c7x0_hostdata *hostdata; + int done; + +@@ -3842,14 +3778,13 @@ + do { + local_irq_disable(); /* Freeze request queues */ + done = 1; +- for (host = first_host; host && host->hostt == the_template; +- host = host->next) { ++ list_for_each_entry_safe(host, s, &the_template->legacy_hosts, sht_legacy_list) { + hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0]; +- local_irq_disable(); ++ spin_lock_irq(host->host_lock); + if (hostdata->issue_queue) { + if (hostdata->state == STATE_DISABLED) { +- tmp = (Scsi_Cmnd *) hostdata->issue_queue; +- hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr; ++ tmp = (struct scsi_cmnd *) hostdata->issue_queue; ++ hostdata->issue_queue = (struct scsi_cmnd *) tmp->SCp.ptr; + tmp->result = (DID_BAD_TARGET << 16); + if (tmp->host_scribble) { + ((struct NCR53c7x0_cmd *)tmp->host_scribble)->next = +@@ -3861,15 +3796,15 @@ + tmp->scsi_done (tmp); + done = 0; + } else +- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, +- prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) ++ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, ++ prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) + tmp->SCp.ptr) + if (!tmp->host_scribble || + !busyp (host, hostdata, tmp)) { + if (prev) + prev->SCp.ptr = tmp->SCp.ptr; + else +- hostdata->issue_queue = (Scsi_Cmnd *) ++ hostdata->issue_queue = (struct scsi_cmnd *) + tmp->SCp.ptr; + tmp->SCp.ptr = NULL; + if (tmp->host_scribble) { +@@ -3894,6 +3829,7 @@ + done = 0; + } /* if target/lun is not busy */ + } /* if hostdata->issue_queue */ ++ spin_unlock(host->host_lock); + if (!done) + local_irq_restore(flags); + } /* for host */ +@@ -4104,7 +4040,7 @@ + int cnt = 0; + int i = insn_log_index; + int size; +- struct Scsi_Host *host = first_host; ++ struct Scsi_Host *host = (struct Scsi_Host *)the_template->legacy_hosts->next; + + while (cnt < 4096) { + printk ("%08x (+%6x): ", insn_log[i], (insn_log[i] - (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4); +@@ -4162,14 +4098,14 @@ + * completion. + */ + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + restart: + for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)&(hostdata->running_list), + cmd = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ; + cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), + cmd = (struct NCR53c7x0_cmd *) cmd->next) + { +- Scsi_Cmnd *tmp; ++ struct scsi_cmnd *tmp; + + if (!cmd) { + printk("scsi%d : very weird.\n", host->host_no); +@@ -4177,7 +4113,7 @@ + } + + if (!(tmp = cmd->cmd)) { +- printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n", ++ printk("scsi%d : weird. NCR53c7x0_cmd has no scsi_cmnd\n", + host->host_no); + continue; + } +@@ -4216,7 +4152,7 @@ + tmp->scsi_done(tmp); + goto restart; + } +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + + if (!search_found) { + printk ("scsi%d : WARNING : INTFLY with no completed commands.\n", +@@ -4251,7 +4187,7 @@ + struct NCR53c7x0_cmd *cmd; /* command which halted */ + u32 *dsa; /* DSA */ + int handled = 0; +- ++ unsigned long flags; + #ifdef NCR_DEBUG + char buf[80]; /* Debugging sprintf buffer */ + size_t buflen; /* Length of same */ +@@ -4260,6 +4196,7 @@ + host = (struct Scsi_Host *)dev_id; + hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0]; + NCR53c7x0_local_setup(host); ++ spin_lock_irqsave(host->host_lock, flags); + + /* + * Only read istat once per loop, since reading it again will unstack +@@ -4352,7 +4289,8 @@ + } + } + } +- return IRQ_HANDLED; ++ spin_unlock_irqrestore(host->host_lock, flags); ++ return IRQ_RETVAL(handled); + } + + +@@ -4361,7 +4299,7 @@ + * + * Purpose : Assuming that the NCR SCSI processor is currently + * halted, break the currently established nexus. Clean +- * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should ++ * up of the NCR53c7x0_cmd and scsi_cmnd structures should + * be done on receipt of the abort interrupt. + * + * Inputs : host - SCSI host +@@ -4900,12 +4838,12 @@ + /* Don't print instr. until we write DSP at end of intr function */ + } else if (hostdata->options & OPTION_DEBUG_SINGLE) { + print_insn (host, dsp, "s ", 0); +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + /* XXX - should we do this, or can we get away with writing dsp? */ + + NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & + ~DCNTL_SSM) | DCNTL_STD); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } else { + printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n" + " ", host->host_no); +@@ -5128,7 +5066,7 @@ + } + + /* +- * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd) ++ * Function : int NCR53c7xx_abort (struct scsi_cmnd *cmd) + * + * Purpose : Abort an errant SCSI command, doing all necessary + * cleanup of the issue_queue, running_list, shared Linux/NCR +@@ -5140,14 +5078,14 @@ + */ + + int +-NCR53c7xx_abort (Scsi_Cmnd *cmd) { ++NCR53c7xx_abort (struct scsi_cmnd *cmd) { + NCR53c7x0_local_declare(); + struct Scsi_Host *host = cmd->device->host; + struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *) + host->hostdata[0] : NULL; + unsigned long flags; + struct NCR53c7x0_cmd *curr, **prev; +- Scsi_Cmnd *me, **last; ++ struct scsi_cmnd *me, **last; + #if 0 + static long cache_pid = -1; + #endif +@@ -5156,10 +5094,10 @@ + if (!host) { + printk ("Bogus SCSI command pid %ld; no host structure\n", + cmd->pid); +- return SCSI_ABORT_ERROR; ++ return FAILED; + } else if (!hostdata) { + printk ("Bogus SCSI host %d; no hostdata\n", host->host_no); +- return SCSI_ABORT_ERROR; ++ return FAILED; + } + NCR53c7x0_local_setup(host); + +@@ -5180,10 +5118,10 @@ + printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no, + cmd->pid); + NCR53c7x0_intr (host->irq, NULL, NULL); +- return SCSI_ABORT_BUSY; ++ return FAILED; + } + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + #if 0 + if (cache_pid == cmd->pid) + panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid); +@@ -5202,13 +5140,13 @@ + * pull the command out of the old queue, and call it aborted. + */ + +- for (me = (Scsi_Cmnd *) hostdata->issue_queue, +- last = (Scsi_Cmnd **) &(hostdata->issue_queue); +- me && me != cmd; last = (Scsi_Cmnd **)&(me->SCp.ptr), +- me = (Scsi_Cmnd *)me->SCp.ptr); ++ for (me = (struct scsi_cmnd *) hostdata->issue_queue, ++ last = (struct scsi_cmnd **) &(hostdata->issue_queue); ++ me && me != cmd; last = (struct scsi_cmnd **)&(me->SCp.ptr), ++ me = (struct scsi_cmnd *)me->SCp.ptr); + + if (me) { +- *last = (Scsi_Cmnd *) me->SCp.ptr; ++ *last = (struct scsi_cmnd *) me->SCp.ptr; + if (me->host_scribble) { + ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free; + hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble; +@@ -5218,9 +5156,9 @@ + cmd->scsi_done(cmd); + printk ("scsi%d : found command %ld in Linux issue queue\n", + host->host_no, me->pid); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + run_process_issue_queue(); +- return SCSI_ABORT_SUCCESS; ++ return SUCCESS; + } + + /* +@@ -5244,13 +5182,13 @@ + cmd->scsi_done(cmd); + printk ("scsi%d : found finished command %ld in running list\n", + host->host_no, cmd->pid); +- local_irq_restore(flags); +- return SCSI_ABORT_NOT_RUNNING; ++ spin_unlock_irqrestore(host->host_lock, flags); ++ return SUCCESS; + } else { + printk ("scsi%d : DANGER : command running, can not abort.\n", + cmd->device->host->host_no); +- local_irq_restore(flags); +- return SCSI_ABORT_BUSY; ++ spin_unlock_irqrestore(host->host_lock, flags); ++ return FAILED; + } + } + +@@ -5281,21 +5219,20 @@ + */ + --hostdata->busy[cmd->device->id][cmd->device->lun]; + } +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + cmd->scsi_done(cmd); + + /* + * We need to run process_issue_queue since termination of this command + * may allow another queued command to execute first? + */ +- return SCSI_ABORT_NOT_RUNNING; ++ return SUCCESS; + } + + /* +- * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd) ++ * Function : int NCR53c7xx_reset (struct scsi_cmnd *cmd) + * +- * Purpose : perform a hard reset of the SCSI bus and NCR +- * chip. ++ * Purpose : perform a hard reset of the SCSI bus. + * + * Inputs : cmd - command which caused the SCSI RESET + * +@@ -5303,12 +5240,12 @@ + */ + + int +-NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) { ++NCR53c7xx_reset (struct scsi_cmnd *cmd) { + NCR53c7x0_local_declare(); + unsigned long flags; + int found = 0; + struct NCR53c7x0_cmd * c; +- Scsi_Cmnd *tmp; ++ struct scsi_cmnd *tmp; + /* + * When we call scsi_done(), it's going to wake up anything sleeping on the + * resources which were in use by the aborted commands, and we'll start to +@@ -5323,19 +5260,19 @@ + * pointer), do our reinitialization, and then call the done function for + * each command. + */ +- Scsi_Cmnd *nuke_list = NULL; ++ struct scsi_cmnd *nuke_list = NULL; + struct Scsi_Host *host = cmd->device->host; + struct NCR53c7x0_hostdata *hostdata = + (struct NCR53c7x0_hostdata *) host->hostdata[0]; + + NCR53c7x0_local_setup(host); +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + ncr_halt (host); + print_lots (host); + dump_events (host, 30); + ncr_scsi_reset (host); + for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */, +- 0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer) ++ 0 /* issue */ ); tmp; tmp = (struct scsi_cmnd *) tmp->SCp.buffer) + if (tmp == cmd) { + found = 1; + break; +@@ -5358,19 +5295,21 @@ + } + + NCR53c7x0_driver_init (host); ++#if 0 + hostdata->soft_reset (host); ++#endif + if (hostdata->resets == 0) + disable(host); + else if (hostdata->resets != -1) + --hostdata->resets; +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + for (; nuke_list; nuke_list = tmp) { +- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer; ++ tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer; + nuke_list->result = DID_RESET << 16; + nuke_list->scsi_done (nuke_list); + } +- local_irq_restore(flags); +- return SCSI_RESET_SUCCESS; ++ spin_unlock_irqrestore(host->host_lock, flags); ++ return SUCCESS; + } + + /* +@@ -5379,7 +5318,7 @@ + */ + + /* +- * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) ++ * Function : int insn_to_offset (struct scsi_cmnd *cmd, u32 *insn) + * + * Purpose : convert instructions stored at NCR pointer into data + * pointer offset. +@@ -5392,7 +5331,7 @@ + + + static int +-insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) { ++insn_to_offset (struct scsi_cmnd *cmd, u32 *insn) { + struct NCR53c7x0_hostdata *hostdata = + (struct NCR53c7x0_hostdata *) cmd->device->host->hostdata[0]; + struct NCR53c7x0_cmd *ncmd = +@@ -5446,7 +5385,7 @@ + + + /* +- * Function : void print_progress (Scsi_Cmnd *cmd) ++ * Function : void print_progress (struct scsi_cmnd *cmd) + * + * Purpose : print the current location of the saved data pointer + * +@@ -5455,7 +5394,7 @@ + */ + + static void +-print_progress (Scsi_Cmnd *cmd) { ++print_progress (struct scsi_cmnd *cmd) { + NCR53c7x0_local_declare(); + struct NCR53c7x0_cmd *ncmd = + (struct NCR53c7x0_cmd *) cmd->host_scribble; +@@ -5513,7 +5452,7 @@ + host->hostdata[0]; + int i, len; + char *ptr; +- Scsi_Cmnd *cmd; ++ struct scsi_cmnd *cmd; + + if (check_address ((unsigned long) dsa, hostdata->dsa_end - + hostdata->dsa_start) == -1) { +@@ -5549,7 +5488,7 @@ + + printk(" + %d : select_indirect = 0x%x\n", + hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]); +- cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]); ++ cmd = (struct scsi_cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]); + printk(" + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd, + (u32) virt_to_bus(cmd)); + /* XXX Maybe we should access cmd->host_scribble->result here. RGH */ +@@ -5589,16 +5528,16 @@ + u32 *dsa, *next_dsa; + volatile u32 *ncrcurrent; + int left; +- Scsi_Cmnd *cmd, *next_cmd; ++ struct scsi_cmnd *cmd, *next_cmd; + unsigned long flags; + + printk ("scsi%d : issue queue\n", host->host_no); + +- for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue; ++ for (left = host->can_queue, cmd = (struct scsi_cmnd *) hostdata->issue_queue; + left >= 0 && cmd; + cmd = next_cmd) { +- next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr; +- local_irq_save(flags); ++ next_cmd = (struct scsi_cmnd *) cmd->SCp.ptr; ++ spin_lock_irqsave(host->host_lock, flags); + if (cmd->host_scribble) { + if (check_address ((unsigned long) (cmd->host_scribble), + sizeof (cmd->host_scribble)) == -1) +@@ -5611,7 +5550,7 @@ + } else + printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n", + host->host_no, cmd->pid, cmd->device->id, cmd->device->lun); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } + + if (left <= 0) { +@@ -5643,7 +5582,7 @@ + dsa = bus_to_virt (hostdata->reconnect_dsa_head); + left >= 0 && dsa; + dsa = next_dsa) { +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) { + printk ("scsi%d: bad DSA pointer 0x%p", host->host_no, + dsa); +@@ -5654,7 +5593,7 @@ + next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]); + print_dsa (host, dsa, ""); + } +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } + printk ("scsi%d : end reconnect_dsa_head\n", host->host_no); + if (left < 0) +@@ -5744,14 +5683,14 @@ + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) + host->hostdata[0]; + NCR53c7x0_local_setup(host); +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + /* Get in a state where we can reset the SCSI bus */ + ncr_halt (host); + ncr_scsi_reset (host); + hostdata->soft_reset(host); + + disable (host); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + return 0; + } + +@@ -5766,11 +5705,11 @@ + NCR53c7x0_local_declare(); + unsigned long flags; + NCR53c7x0_local_setup(host); +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST); + udelay(25); /* Minimum amount of time to assert RST */ + NCR53c7x0_write8(SCNTL1_REG, 0); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } + + /* +@@ -5783,26 +5722,26 @@ + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) + host->hostdata[0]; + unsigned long flags; +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + ncr_scsi_reset(host); + NCR53c7x0_driver_init (host); + if (hostdata->soft_reset) + hostdata->soft_reset (host); +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + } + + + /* +- * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host, ++ * Function : struct scsi_cmnd *return_outstanding_commands (struct Scsi_Host *host, + * int free, int issue) + * + * Purpose : return a linked list (using the SCp.buffer field as next, + * so we don't perturb hostdata. We don't use a field of the + * NCR53c7x0_cmd structure since we may not have allocated one +- * for the command causing the reset.) of Scsi_Cmnd structures that ++ * for the command causing the reset.) of scsi_cmnd structures that + * had propagated below the Linux issue queue level. If free is set, + * free the NCR53c7x0_cmd structures which are associated with +- * the Scsi_Cmnd structures, and clean up any internal ++ * the scsi_cmnd structures, and clean up any internal + * NCR lists that the commands were on. If issue is set, + * also return commands in the issue queue. + * +@@ -5812,14 +5751,14 @@ + * if the free flag is set. + */ + +-static Scsi_Cmnd * ++static struct scsi_cmnd * + return_outstanding_commands (struct Scsi_Host *host, int free, int issue) { + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) + host->hostdata[0]; + struct NCR53c7x0_cmd *c; + int i; + u32 *ncrcurrent; +- Scsi_Cmnd *list = NULL, *tmp; ++ struct scsi_cmnd *list = NULL, *tmp, *next_cmd; + for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c; + c = (struct NCR53c7x0_cmd *) c->next) { + if (c->cmd->SCp.buffer) { +@@ -5848,7 +5787,9 @@ + } + + if (issue) { +- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) { ++ for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; tmp = next_cmd) { ++ next_cmd = (struct scsi_cmnd *) tmp->SCp.ptr; ++ + if (tmp->SCp.buffer) { + printk ("scsi%d : loop detected in issue queue!\n", + host->host_no); +@@ -5883,17 +5824,17 @@ + struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) + host->hostdata[0]; + unsigned long flags; +- Scsi_Cmnd *nuke_list, *tmp; +- local_irq_save(flags); ++ struct scsi_cmnd *nuke_list, *tmp; ++ spin_lock_irqsave(host->host_lock, flags); + if (hostdata->state != STATE_HALTED) + ncr_halt (host); + nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */); + hard_reset (host); + hostdata->state = STATE_DISABLED; +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + printk ("scsi%d : nuking commands\n", host->host_no); + for (; nuke_list; nuke_list = tmp) { +- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer; ++ tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer; + nuke_list->result = DID_ERROR << 16; + nuke_list->scsi_done(nuke_list); + } +@@ -5923,7 +5864,7 @@ + int stage; + NCR53c7x0_local_setup(host); + +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + /* Stage 0 : eat all interrupts + Stage 1 : set ABORT + Stage 2 : eat all but abort interrupts +@@ -5958,7 +5899,7 @@ + } + } + hostdata->state = STATE_HALTED; +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + #if 0 + print_lots (host); + #endif +@@ -6012,7 +5953,7 @@ + * still be guaranteed that they're happening on the same + * event structure. + */ +- local_irq_save(flags); ++ spin_lock_irqsave(host->host_lock, flags); + #if 0 + event = hostdata->events[i]; + #else +@@ -6020,7 +5961,7 @@ + sizeof(event)); + #endif + +- local_irq_restore(flags); ++ spin_unlock_irqrestore(host->host_lock, flags); + printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n", + host->host_no, event_name (event.event), count, + (long) event.time.tv_sec, (long) event.time.tv_usec, +@@ -6055,6 +5996,72 @@ + return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ? -1 : 0); + } + ++int ++NCR53c7xx_slave_configure(struct scsi_device *sdev) { ++ struct Scsi_Host *host = sdev->host; ++ struct NCR53c7x0_hostdata *hostdata = ++ (struct NCR53c7x0_hostdata *) host->hostdata[0]; ++ struct NCR53c7x0_cmd *tmp; ++ u32 real; /* Real address */ ++ int size; /* Size of *tmp */ ++ unsigned long flags; ++ int extra_allocate = 0; ++ ++/* ++ * Reserve commands for this I_T_L nexus. ++ */ ++ if (hostdata->num_cmds < host->can_queue) ++ extra_allocate = host->cmd_per_lun; ++ ++ for (; extra_allocate > 0 ; --extra_allocate, ++ ++hostdata->num_cmds) { ++ /* historically, kmalloc has returned unaligned addresses; pad so we ++ have enough room to ROUNDUP */ ++ size = hostdata->max_cmd_size + sizeof (void *); ++#ifdef FORCE_DSA_ALIGNMENT ++ /* ++ * 53c710 rev.0 doesn't have an add-with-carry instruction. ++ * Ensure we allocate enough memory to force alignment. ++ */ ++ size += 256; ++#endif ++/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */ ++ ++ if (size > 4096) { ++ printk (KERN_ERR "53c7xx: slave_configure size > 4K\n"); ++ return -ENOMEM; ++ } ++ real = get_zeroed_page(GFP_ATOMIC); ++ if (real == 0) ++ return -ENOMEM; ++ memset((void *)real, 0, 4096); ++ cache_push(virt_to_phys((void *)real), 4096); ++ cache_clear(virt_to_phys((void *)real), 4096); ++ kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER); ++ tmp = ROUNDUP(real, void *); ++#ifdef FORCE_DSA_ALIGNMENT ++ { ++ if (((u32)tmp & 0xff) > CmdPageStart) ++ tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255); ++ tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart); ++#if 0 ++ printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n", ++ size, real, (u32)tmp); ++#endif ++ } ++#endif ++ tmp->real = (void *)real; ++ tmp->size = size; ++ tmp->free = ((void (*)(void *, int)) my_free_page); ++ spin_lock_irqsave(host->host_lock, flags); ++ tmp->next = hostdata->free; ++ hostdata->free = tmp; ++ spin_unlock_irqrestore(host->host_lock, flags); ++ } ++ ++ return 0; ++} ++ + #ifdef MODULE + int + NCR53c7x0_release(struct Scsi_Host *host) { +@@ -6064,19 +6071,22 @@ + shutdown (host); + if (host->irq != SCSI_IRQ_NONE) + { +- int irq_count; +- struct Scsi_Host *tmp; +- for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next) +- if (tmp->hostt == the_template && tmp->irq == host->irq) ++ int irq_count = 0; ++ struct Scsi_Host *tmp, *s; ++ list_for_each_entry_safe(tmp, s, &the_template->legacy_hosts, sht_legacy_list) { ++ if (tmp->irq == host->irq) + ++irq_count; ++ } + if (irq_count == 1) + free_irq(host->irq, NULL); + } ++#ifdef CONFIG_ISA + if (host->dma_channel != DMA_NONE) + free_dma(host->dma_channel); ++#endif + if (host->io_port) + release_region(host->io_port, host->n_io_port); +- ++ + for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp, + --hostdata->num_cmds) { + tmp = (struct NCR53c7x0_cmd *) cmd->next; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/53c7xx.h linux-m68k/drivers/scsi/53c7xx.h +--- linux-i386/drivers/scsi/53c7xx.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/53c7xx.h 2004-10-30 14:41:36.000000000 +0200 +@@ -997,7 +997,7 @@ + u32 *dsa; /* What's in the DSA register now (virt) */ + /* + * A few things from that SCSI pid so we know what happened after +- * the Scsi_Cmnd structure in question may have disappeared. ++ * the scsi_cmnd structure in question may have disappeared. + */ + unsigned long pid; /* The SCSI PID which caused this + event */ +@@ -1029,8 +1029,8 @@ + void (* free)(void *, int); /* Command to deallocate; NULL + for structures allocated with + scsi_register, etc. */ +- Scsi_Cmnd *cmd; /* Associated Scsi_Cmnd +- structure, Scsi_Cmnd points ++ struct scsi_cmnd *cmd; /* Associated scsi_cmnd ++ structure, scsi_cmnd points + at NCR53c7x0_cmd using + host_scribble structure */ + +@@ -1039,8 +1039,8 @@ + + int flags; /* CMD_* flags */ + +- unsigned char cmnd[12]; /* CDB, copied from Scsi_Cmnd */ +- int result; /* Copy to Scsi_Cmnd when done */ ++ unsigned char cmnd[12]; /* CDB, copied from scsi_cmnd */ ++ int result; /* Copy to scsi_cmnd when done */ + + struct { /* Private non-cached bounce buffer */ + unsigned char buf[256]; +@@ -1339,7 +1339,7 @@ + volatile struct NCR53c7x0_synchronous sync[16] + __attribute__ ((aligned (4))); + +- volatile Scsi_Cmnd *issue_queue ++ volatile struct scsi_cmnd *issue_queue + __attribute__ ((aligned (4))); + /* waiting to be issued by + Linux driver */ +@@ -1363,10 +1363,6 @@ + */ + volatile int num_cmds; /* Number of commands + allocated */ +- volatile int extra_allocate; +- volatile unsigned char cmd_allocated[16]; /* Have we allocated commands +- for this target yet? If not, +- do so ASAP */ + volatile unsigned char busy[16][8]; /* number of commands + executing on each target + */ +@@ -1589,11 +1585,11 @@ + /* Patch field in dsa structure (assignment should be +=?) */ + #define patch_dsa_32(dsa, symbol, word, value) \ + { \ +- (dsa)[(hostdata->##symbol - hostdata->dsa_start) / sizeof(u32) \ ++ (dsa)[(hostdata->symbol - hostdata->dsa_start) / sizeof(u32) \ + + (word)] = (value); \ + if (hostdata->options & OPTION_DEBUG_DSA) \ + printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n", \ +- #dsa, #symbol, hostdata->##symbol, \ ++ #dsa, #symbol, hostdata->symbol, \ + (word), (u32) (value)); \ + } + +@@ -1603,6 +1599,12 @@ + extern int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip, + unsigned long base, int io_port, int irq, int dma, + long long options, int clock); ++extern const char *NCR53c7x0_info(void); ++extern int NCR53c7xx_queue_command(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); ++extern int NCR53c7xx_abort(struct scsi_cmnd *); ++extern int NCR53c7x0_release (struct Scsi_Host *); ++extern int NCR53c7xx_reset(struct scsi_cmnd *); ++extern int NCR53c7xx_slave_configure(struct scsi_device *); + + #endif /* NCR53c710_C */ + #endif /* NCR53c710_H */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/Kconfig linux-m68k/drivers/scsi/Kconfig +--- linux-i386/drivers/scsi/Kconfig 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/Kconfig 2006-04-11 16:37:15.000000000 +0200 +@@ -1659,7 +1659,7 @@ + + config SCSI_AMIGA7XX + bool "Amiga NCR53c710 SCSI support (EXPERIMENTAL)" +- depends on AMIGA && SCSI && EXPERIMENTAL && BROKEN ++ depends on AMIGA && SCSI && EXPERIMENTAL + help + Support for various NCR53c710-based SCSI controllers on the Amiga. + This includes: +@@ -1759,7 +1759,7 @@ + + config MVME16x_SCSI + bool "NCR53C710 SCSI driver for MVME16x" +- depends on MVME16x && SCSI && BROKEN ++ depends on MVME16x && SCSI + select SCSI_SPI_ATTRS + help + The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710 +@@ -1768,7 +1768,7 @@ + + config BVME6000_SCSI + bool "NCR53C710 SCSI driver for BVME6000" +- depends on BVME6000 && SCSI && BROKEN ++ depends on BVME6000 && SCSI + select SCSI_SPI_ATTRS + help + The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710 +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/NCR5380.c linux-m68k/drivers/scsi/NCR5380.c +--- linux-i386/drivers/scsi/NCR5380.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/NCR5380.c 2006-04-11 16:37:15.000000000 +0200 +@@ -354,6 +354,7 @@ + return -ETIMEDOUT; + } + ++#if NDEBUG + static struct { + unsigned char value; + const char *name; +@@ -367,7 +368,6 @@ + {PHASE_UNKNOWN, "UNKNOWN"} + }; + +-#if NDEBUG + static struct { + unsigned char mask; + const char *name; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/amiga7xx.c linux-m68k/drivers/scsi/amiga7xx.c +--- linux-i386/drivers/scsi/amiga7xx.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/amiga7xx.c 2006-01-19 22:08:23.000000000 +0100 +@@ -26,8 +26,14 @@ + #include "scsi.h" + #include + #include "53c7xx.h" +-#include "amiga7xx.h" + ++#ifndef CMD_PER_LUN ++#define CMD_PER_LUN 3 ++#endif ++ ++#ifndef CAN_QUEUE ++#define CAN_QUEUE 24 ++#endif + + static int amiga7xx_register_one(struct scsi_host_template *tpnt, + unsigned long address) +@@ -114,8 +120,10 @@ + { + if (shost->irq) + free_irq(shost->irq, NULL); ++#ifdef CONFIG_ISA + if (shost->dma_channel != 0xff) + free_dma(shost->dma_channel); ++#endif + if (shost->io_port && shost->n_io_port) + release_region(shost->io_port, shost->n_io_port); + scsi_unregister(shost); +@@ -127,8 +135,9 @@ + .detect = amiga7xx_detect, + .release = amiga7xx_release, + .queuecommand = NCR53c7xx_queue_command, +- .abort = NCR53c7xx_abort, +- .reset = NCR53c7xx_reset, ++ .eh_abort_handler = NCR53c7xx_abort, ++ .eh_bus_reset_handler = NCR53c7xx_reset, ++ .slave_configure = NCR53c7xx_slave_configure, + .can_queue = 24, + .this_id = 7, + .sg_tablesize = 63, +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/amiga7xx.h linux-m68k/drivers/scsi/amiga7xx.h +--- linux-i386/drivers/scsi/amiga7xx.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/amiga7xx.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,23 +0,0 @@ +-#ifndef AMIGA7XX_H +- +-#include +- +-int amiga7xx_detect(struct scsi_host_template *); +-const char *NCR53c7x0_info(void); +-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +-int NCR53c7xx_abort(Scsi_Cmnd *); +-int NCR53c7x0_release (struct Scsi_Host *); +-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); +-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); +- +-#ifndef CMD_PER_LUN +-#define CMD_PER_LUN 3 +-#endif +- +-#ifndef CAN_QUEUE +-#define CAN_QUEUE 24 +-#endif +- +-#include +- +-#endif /* AMIGA7XX_H */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/bvme6000.c linux-m68k/drivers/scsi/bvme6000.c +--- linux-i386/drivers/scsi/bvme6000.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/bvme6000.c 2006-01-19 22:08:23.000000000 +0100 +@@ -18,10 +18,16 @@ + #include "scsi.h" + #include + #include "53c7xx.h" +-#include "bvme6000.h" + + #include + ++#ifndef CMD_PER_LUN ++#define CMD_PER_LUN 3 ++#endif ++ ++#ifndef CAN_QUEUE ++#define CAN_QUEUE 24 ++#endif + + int bvme6000_scsi_detect(struct scsi_host_template *tpnt) + { +@@ -51,8 +57,10 @@ + { + if (shost->irq) + free_irq(shost->irq, NULL); ++#ifdef CONFIG_ISA + if (shost->dma_channel != 0xff) + free_dma(shost->dma_channel); ++#endif + if (shost->io_port && shost->n_io_port) + release_region(shost->io_port, shost->n_io_port); + scsi_unregister(shost); +@@ -64,8 +72,9 @@ + .detect = bvme6000_scsi_detect, + .release = bvme6000_scsi_release, + .queuecommand = NCR53c7xx_queue_command, +- .abort = NCR53c7xx_abort, +- .reset = NCR53c7xx_reset, ++ .eh_abort_handler = NCR53c7xx_abort, ++ .eh_bus_reset_handler = NCR53c7xx_reset, ++ .slave_configure = NCR53c7xx_slave_configure, + .can_queue = 24, + .this_id = 7, + .sg_tablesize = 63, +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/bvme6000.h linux-m68k/drivers/scsi/bvme6000.h +--- linux-i386/drivers/scsi/bvme6000.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/bvme6000.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,24 +0,0 @@ +-#ifndef BVME6000_SCSI_H +-#define BVME6000_SCSI_H +- +-#include +- +-int bvme6000_scsi_detect(struct scsi_host_template *); +-const char *NCR53c7x0_info(void); +-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +-int NCR53c7xx_abort(Scsi_Cmnd *); +-int NCR53c7x0_release (struct Scsi_Host *); +-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); +-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); +- +-#ifndef CMD_PER_LUN +-#define CMD_PER_LUN 3 +-#endif +- +-#ifndef CAN_QUEUE +-#define CAN_QUEUE 24 +-#endif +- +-#include +- +-#endif /* BVME6000_SCSI_H */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mac_esp.c linux-m68k/drivers/scsi/mac_esp.c +--- linux-i386/drivers/scsi/mac_esp.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/mac_esp.c 2006-01-31 16:33:52.000000000 +0100 +@@ -43,9 +43,6 @@ + + /* #define DEBUG_MAC_ESP */ + +-#define mac_turnon_irq(x) mac_enable_irq(x) +-#define mac_turnoff_irq(x) mac_disable_irq(x) +- + extern void esp_handle(struct NCR_ESP *esp); + extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs); + +@@ -639,13 +636,13 @@ + + static void dma_ints_off(struct NCR_ESP * esp) + { +- mac_turnoff_irq(esp->irq); ++ disable_irq(esp->irq); + } + + + static void dma_ints_on(struct NCR_ESP * esp) + { +- mac_turnon_irq(esp->irq); ++ enable_irq(esp->irq); + } + + /* +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mac_scsi.c linux-m68k/drivers/scsi/mac_scsi.c +--- linux-i386/drivers/scsi/mac_scsi.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/mac_scsi.c 2006-01-31 16:33:52.000000000 +0100 +@@ -65,9 +65,6 @@ + #define RESET_BOOT + #define DRIVER_SETUP + +-#define ENABLE_IRQ() mac_enable_irq( IRQ_MAC_SCSI ); +-#define DISABLE_IRQ() mac_disable_irq( IRQ_MAC_SCSI ); +- + extern void via_scsi_clear(void); + + #ifdef RESET_BOOT +@@ -351,7 +348,7 @@ + printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." ); + + /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ +- mac_disable_irq(IRQ_MAC_SCSI); ++ disable_irq(IRQ_MAC_SCSI); + + /* get in phase */ + NCR5380_write( TARGET_COMMAND_REG, +@@ -369,7 +366,7 @@ + barrier(); + + /* switch on SCSI IRQ again */ +- mac_enable_irq(IRQ_MAC_SCSI); ++ enable_irq(IRQ_MAC_SCSI); + + printk(KERN_INFO " done\n" ); + } +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mvme16x.c linux-m68k/drivers/scsi/mvme16x.c +--- linux-i386/drivers/scsi/mvme16x.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/mvme16x.c 2006-01-19 22:08:29.000000000 +0100 +@@ -16,10 +16,16 @@ + #include "scsi.h" + #include + #include "53c7xx.h" +-#include "mvme16x.h" + + #include + ++#ifndef CMD_PER_LUN ++#define CMD_PER_LUN 3 ++#endif ++ ++#ifndef CAN_QUEUE ++#define CAN_QUEUE 24 ++#endif + + int mvme16x_scsi_detect(struct scsi_host_template *tpnt) + { +@@ -53,8 +59,10 @@ + { + if (shost->irq) + free_irq(shost->irq, NULL); ++#ifdef CONFIG_ISA + if (shost->dma_channel != 0xff) + free_dma(shost->dma_channel); ++#endif + if (shost->io_port && shost->n_io_port) + release_region(shost->io_port, shost->n_io_port); + scsi_unregister(shost); +@@ -66,8 +74,9 @@ + .detect = mvme16x_scsi_detect, + .release = mvme16x_scsi_release, + .queuecommand = NCR53c7xx_queue_command, +- .abort = NCR53c7xx_abort, +- .reset = NCR53c7xx_reset, ++ .eh_abort_handler = NCR53c7xx_abort, ++ .eh_bus_reset_handler = NCR53c7xx_reset, ++ .slave_configure = NCR53c7xx_slave_configure, + .can_queue = 24, + .this_id = 7, + .sg_tablesize = 63, +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mvme16x.h linux-m68k/drivers/scsi/mvme16x.h +--- linux-i386/drivers/scsi/mvme16x.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/mvme16x.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,24 +0,0 @@ +-#ifndef MVME16x_SCSI_H +-#define MVME16x_SCSI_H +- +-#include +- +-int mvme16x_scsi_detect(struct scsi_host_template *); +-const char *NCR53c7x0_info(void); +-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +-int NCR53c7xx_abort(Scsi_Cmnd *); +-int NCR53c7x0_release (struct Scsi_Host *); +-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); +-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); +- +-#ifndef CMD_PER_LUN +-#define CMD_PER_LUN 3 +-#endif +- +-#ifndef CAN_QUEUE +-#define CAN_QUEUE 24 +-#endif +- +-#include +- +-#endif /* MVME16x_SCSI_H */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/wd33c93.c linux-m68k/drivers/scsi/wd33c93.c +--- linux-i386/drivers/scsi/wd33c93.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/drivers/scsi/wd33c93.c 2006-04-11 16:37:26.000000000 +0200 +@@ -939,6 +939,7 @@ + DB(DB_INTR, printk("%02x", cmd->SCp.Status)) + if (hostdata->level2 >= L2_BASIC) { + sr = read_wd33c93(regs, WD_SCSI_STATUS); /* clear interrupt */ ++ udelay(7); + hostdata->state = S_RUNNING_LEVEL2; + write_wd33c93(regs, WD_COMMAND_PHASE, 0x50); + write_wd33c93_cmd(regs, WD_CMD_SEL_ATN_XFER); +@@ -955,6 +956,7 @@ + + msg = read_1_byte(regs); + sr = read_wd33c93(regs, WD_SCSI_STATUS); /* clear interrupt */ ++ udelay(7); + + hostdata->incoming_msg[hostdata->incoming_ptr] = msg; + if (hostdata->incoming_msg[0] == EXTENDED_MESSAGE) +@@ -1358,6 +1360,7 @@ + } else { + /* Verify this is a change to MSG_IN and read the message */ + sr = read_wd33c93(regs, WD_SCSI_STATUS); ++ udelay(7); + if (sr == (CSR_ABORT | PHS_MESS_IN) || + sr == (CSR_UNEXP | PHS_MESS_IN) || + sr == (CSR_SRV_REQ | PHS_MESS_IN)) { +@@ -1374,6 +1377,7 @@ + asr); + } + sr = read_wd33c93(regs, WD_SCSI_STATUS); ++ udelay(7); + if (sr != CSR_MSGIN) + printk + ("wd33c93: Not paused with ACK on RESEL (%02x)\n", +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/fs/fat/inode.c linux-m68k/fs/fat/inode.c +--- linux-i386/fs/fat/inode.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/fs/fat/inode.c 2006-04-11 16:39:04.000000000 +0200 +@@ -11,12 +11,14 @@ + */ + + #include ++#include + #include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -856,7 +858,7 @@ + Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid, + Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase, + Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable, +- Opt_dots, Opt_nodots, ++ Opt_dots, Opt_nodots, Opt_atari_no, Opt_atari_yes, + Opt_charset, Opt_shortname_lower, Opt_shortname_win95, + Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, + Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, +@@ -881,6 +883,9 @@ + {Opt_showexec, "showexec"}, + {Opt_debug, "debug"}, + {Opt_immutable, "sys_immutable"}, ++ {Opt_atari_yes, "atari=yes"}, ++ {Opt_atari_yes, "atari"}, ++ {Opt_atari_no, "atari=no"}, + {Opt_obsolate, "conv=binary"}, + {Opt_obsolate, "conv=text"}, + {Opt_obsolate, "conv=auto"}, +@@ -955,6 +960,13 @@ + opts->utf8 = opts->unicode_xlate = 0; + opts->numtail = 1; + opts->nocase = 0; ++ opts->atari = 0; ++ ++#ifdef CONFIG_ATARI ++ if(MACH_IS_ATARI) ++ /* make Atari GEMDOS format the default if machine is an Atari */ ++ opts->atari = 1; ++#endif + *debug = 0; + + if (!options) +@@ -1003,6 +1015,12 @@ + case Opt_immutable: + opts->sys_immutable = 1; + break; ++ case Opt_atari_yes: ++ opts->atari = 1; ++ break; ++ case Opt_atari_no: ++ opts->atari = 0; ++ break; + case Opt_uid: + if (match_int(&args[0], &option)) + return 0; +@@ -1338,8 +1356,31 @@ + + total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus; + +- if (sbi->fat_bits != 32) +- sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12; ++ if (!sbi->options.atari) { ++ if (sbi->fat_bits != 32) ++ sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12; ++ } else { ++ int sectors; ++ /* Atari GEMDOS partitions always have 16-bit fat */ ++ if (sbi->fat_bits != 32) ++ sbi->fat_bits = 16; ++ /* If more clusters than fat entries in 16-bit fat, we assume ++ * it's a real MSDOS partition with 12-bit fat. ++ */ ++ if (sbi->fat_bits != 32 && total_clusters+2 > sbi-> ++ fat_length*SECTOR_SIZE*8/sbi->fat_bits) ++ sbi->fat_bits = 12; ++ /* if it's a floppy disk --> 12bit fat */ ++ if (sbi->fat_bits != 32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR) ++ sbi->fat_bits = 12; ++ /* if it's a ramdisk or loopback device and has one of the usual ++ * floppy sizes -> 12bit FAT */ ++ sectors = total_sectors + sbi->data_start; ++ if (sbi->fat_bits != 32 && (MAJOR(sb->s_dev) == RAMDISK_MAJOR || ++ MAJOR(sb->s_dev) == LOOP_MAJOR) && ++ (sectors == 720 || sectors == 1440 || sectors == 2880)) ++ sbi->fat_bits = 12; ++ } + + /* check that FAT table does not overflow */ + fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/amigaints.h linux-m68k/include/asm-m68k/amigaints.h +--- linux-i386/include/asm-m68k/amigaints.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/amigaints.h 2006-01-28 23:55:19.000000000 +0100 +@@ -13,6 +13,8 @@ + #ifndef _ASMm68k_AMIGAINTS_H_ + #define _ASMm68k_AMIGAINTS_H_ + ++#include ++ + /* + ** Amiga Interrupt sources. + ** +@@ -23,72 +25,52 @@ + #define CIA_IRQS (5) + #define AMI_IRQS (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */ + +-/* vertical blanking interrupt */ +-#define IRQ_AMIGA_VERTB 0 ++/* builtin serial port interrupts */ ++#define IRQ_AMIGA_TBE (IRQ_USER+0) ++#define IRQ_AMIGA_RBF (IRQ_USER+11) + +-/* copper interrupt */ +-#define IRQ_AMIGA_COPPER 1 ++/* floppy disk interrupts */ ++#define IRQ_AMIGA_DSKBLK (IRQ_USER+1) ++#define IRQ_AMIGA_DSKSYN (IRQ_USER+12) + +-/* Audio interrupts */ +-#define IRQ_AMIGA_AUD0 2 +-#define IRQ_AMIGA_AUD1 3 +-#define IRQ_AMIGA_AUD2 4 +-#define IRQ_AMIGA_AUD3 5 ++/* software interrupts */ ++#define IRQ_AMIGA_SOFT (IRQ_USER+2) + +-/* Blitter done interrupt */ +-#define IRQ_AMIGA_BLIT 6 ++/* interrupts from external hardware */ ++#define IRQ_AMIGA_PORTS IRQ_AUTO_2 ++#define IRQ_AMIGA_EXTER IRQ_AUTO_6 + +-/* floppy disk interrupts */ +-#define IRQ_AMIGA_DSKSYN 7 +-#define IRQ_AMIGA_DSKBLK 8 ++/* copper interrupt */ ++#define IRQ_AMIGA_COPPER (IRQ_USER+4) + +-/* builtin serial port interrupts */ +-#define IRQ_AMIGA_RBF 9 +-#define IRQ_AMIGA_TBE 10 ++/* vertical blanking interrupt */ ++#define IRQ_AMIGA_VERTB (IRQ_USER+5) + +-/* software interrupts */ +-#define IRQ_AMIGA_SOFT 11 ++/* Blitter done interrupt */ ++#define IRQ_AMIGA_BLIT (IRQ_USER+6) + +-/* interrupts from external hardware */ +-#define IRQ_AMIGA_PORTS 12 +-#define IRQ_AMIGA_EXTER 13 ++/* Audio interrupts */ ++#define IRQ_AMIGA_AUD0 (IRQ_USER+7) ++#define IRQ_AMIGA_AUD1 (IRQ_USER+8) ++#define IRQ_AMIGA_AUD2 (IRQ_USER+9) ++#define IRQ_AMIGA_AUD3 (IRQ_USER+10) + + /* CIA interrupt sources */ +-#define IRQ_AMIGA_CIAA 14 +-#define IRQ_AMIGA_CIAA_TA 14 +-#define IRQ_AMIGA_CIAA_TB 15 +-#define IRQ_AMIGA_CIAA_ALRM 16 +-#define IRQ_AMIGA_CIAA_SP 17 +-#define IRQ_AMIGA_CIAA_FLG 18 +-#define IRQ_AMIGA_CIAB 19 +-#define IRQ_AMIGA_CIAB_TA 19 +-#define IRQ_AMIGA_CIAB_TB 20 +-#define IRQ_AMIGA_CIAB_ALRM 21 +-#define IRQ_AMIGA_CIAB_SP 22 +-#define IRQ_AMIGA_CIAB_FLG 23 +- +-/* auto-vector interrupts */ +-#define IRQ_AMIGA_AUTO 24 +-#define IRQ_AMIGA_AUTO_0 24 /* This is just a dummy */ +-#define IRQ_AMIGA_AUTO_1 25 +-#define IRQ_AMIGA_AUTO_2 26 +-#define IRQ_AMIGA_AUTO_3 27 +-#define IRQ_AMIGA_AUTO_4 28 +-#define IRQ_AMIGA_AUTO_5 29 +-#define IRQ_AMIGA_AUTO_6 30 +-#define IRQ_AMIGA_AUTO_7 31 ++#define IRQ_AMIGA_CIAA (IRQ_USER+14) ++#define IRQ_AMIGA_CIAA_TA (IRQ_USER+14) ++#define IRQ_AMIGA_CIAA_TB (IRQ_USER+15) ++#define IRQ_AMIGA_CIAA_ALRM (IRQ_USER+16) ++#define IRQ_AMIGA_CIAA_SP (IRQ_USER+17) ++#define IRQ_AMIGA_CIAA_FLG (IRQ_USER+18) ++#define IRQ_AMIGA_CIAB (IRQ_USER+19) ++#define IRQ_AMIGA_CIAB_TA (IRQ_USER+19) ++#define IRQ_AMIGA_CIAB_TB (IRQ_USER+20) ++#define IRQ_AMIGA_CIAB_ALRM (IRQ_USER+21) ++#define IRQ_AMIGA_CIAB_SP (IRQ_USER+22) ++#define IRQ_AMIGA_CIAB_FLG (IRQ_USER+23) + +-#define IRQ_FLOPPY IRQ_AMIGA_DSKBLK + + /* INTREQR masks */ +-#define IRQ1_MASK 0x0007 /* INTREQR mask for IRQ 1 */ +-#define IRQ2_MASK 0x0008 /* INTREQR mask for IRQ 2 */ +-#define IRQ3_MASK 0x0070 /* INTREQR mask for IRQ 3 */ +-#define IRQ4_MASK 0x0780 /* INTREQR mask for IRQ 4 */ +-#define IRQ5_MASK 0x1800 /* INTREQR mask for IRQ 5 */ +-#define IRQ6_MASK 0x2000 /* INTREQR mask for IRQ 6 */ +-#define IRQ7_MASK 0x4000 /* INTREQR mask for IRQ 7 */ +- + #define IF_SETCLR 0x8000 /* set/clr bit */ + #define IF_INTEN 0x4000 /* master interrupt bit in INT* registers */ + #define IF_EXTER 0x2000 /* external level 6 and CIA B interrupt */ +@@ -106,9 +88,6 @@ + #define IF_DSKBLK 0x0002 /* diskblock DMA finished */ + #define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ + +-extern void amiga_do_irq(int irq, struct pt_regs *fp); +-extern void amiga_do_irq_list(int irq, struct pt_regs *fp); +- + /* CIA interrupt control register bits */ + + #define CIA_ICR_TA 0x01 +@@ -125,6 +104,7 @@ + + extern struct ciabase ciaa_base, ciab_base; + ++extern void cia_init_IRQ(struct ciabase *base); + extern unsigned char cia_set_irq(struct ciabase *base, unsigned char mask); + extern unsigned char cia_able_irq(struct ciabase *base, unsigned char mask); + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/apollohw.h linux-m68k/include/asm-m68k/apollohw.h +--- linux-i386/include/asm-m68k/apollohw.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/apollohw.h 2006-01-28 23:55:19.000000000 +0100 +@@ -3,6 +3,8 @@ + #ifndef _ASMm68k_APOLLOHW_H_ + #define _ASMm68k_APOLLOHW_H_ + ++#include ++ + /* + apollo models + */ +@@ -101,4 +103,6 @@ + + #define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE) + ++#define IRQ_APOLLO IRQ_USER ++ + #endif +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/atariints.h linux-m68k/include/asm-m68k/atariints.h +--- linux-i386/include/asm-m68k/atariints.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/atariints.h 2006-01-28 23:55:19.000000000 +0100 +@@ -45,17 +45,6 @@ + #define IRQ_TYPE_FAST 1 + #define IRQ_TYPE_PRIO 2 + +-#define IRQ_SPURIOUS (0) +- +-/* auto-vector interrupts */ +-#define IRQ_AUTO_1 (1) +-#define IRQ_AUTO_2 (2) +-#define IRQ_AUTO_3 (3) +-#define IRQ_AUTO_4 (4) +-#define IRQ_AUTO_5 (5) +-#define IRQ_AUTO_6 (6) +-#define IRQ_AUTO_7 (7) +- + /* ST-MFP interrupts */ + #define IRQ_MFP_BUSY (8) + #define IRQ_MFP_DCD (9) +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/bvme6000hw.h linux-m68k/include/asm-m68k/bvme6000hw.h +--- linux-i386/include/asm-m68k/bvme6000hw.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/bvme6000hw.h 2006-01-28 23:55:19.000000000 +0100 +@@ -109,23 +109,23 @@ + + #define BVME_IRQ_TYPE_PRIO 0 + +-#define BVME_IRQ_PRN 0x54 +-#define BVME_IRQ_I596 0x1a +-#define BVME_IRQ_SCSI 0x1b +-#define BVME_IRQ_TIMER 0x59 +-#define BVME_IRQ_RTC 0x1e +-#define BVME_IRQ_ABORT 0x1f ++#define BVME_IRQ_PRN (IRQ_USER+20) ++#define BVME_IRQ_TIMER (IRQ_USER+25) ++#define BVME_IRQ_I596 IRQ_AUTO_2 ++#define BVME_IRQ_SCSI IRQ_AUTO_3 ++#define BVME_IRQ_RTC IRQ_AUTO_6 ++#define BVME_IRQ_ABORT IRQ_AUTO_7 + + /* SCC interrupts */ +-#define BVME_IRQ_SCC_BASE 0x40 +-#define BVME_IRQ_SCCB_TX 0x40 +-#define BVME_IRQ_SCCB_STAT 0x42 +-#define BVME_IRQ_SCCB_RX 0x44 +-#define BVME_IRQ_SCCB_SPCOND 0x46 +-#define BVME_IRQ_SCCA_TX 0x48 +-#define BVME_IRQ_SCCA_STAT 0x4a +-#define BVME_IRQ_SCCA_RX 0x4c +-#define BVME_IRQ_SCCA_SPCOND 0x4e ++#define BVME_IRQ_SCC_BASE IRQ_USER ++#define BVME_IRQ_SCCB_TX IRQ_USER ++#define BVME_IRQ_SCCB_STAT (IRQ_USER+2) ++#define BVME_IRQ_SCCB_RX (IRQ_USER+4) ++#define BVME_IRQ_SCCB_SPCOND (IRQ_USER+6) ++#define BVME_IRQ_SCCA_TX (IRQ_USER+8) ++#define BVME_IRQ_SCCA_STAT (IRQ_USER+10) ++#define BVME_IRQ_SCCA_RX (IRQ_USER+12) ++#define BVME_IRQ_SCCA_SPCOND (IRQ_USER+14) + + /* Address control registers */ + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/io.h linux-m68k/include/asm-m68k/io.h +--- linux-i386/include/asm-m68k/io.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/io.h 2006-04-11 16:41:20.000000000 +0200 +@@ -325,8 +325,6 @@ + #define writel(val,addr) out_le32((addr),(val)) + #endif + +-#define mmiowb() +- + static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) + { + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/irq.h linux-m68k/include/asm-m68k/irq.h +--- linux-i386/include/asm-m68k/irq.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/irq.h 2006-04-11 16:41:20.000000000 +0200 +@@ -2,13 +2,8 @@ + #define _M68K_IRQ_H_ + + #include +-#include +- +-/* +- * # of m68k interrupts +- */ +- +-#define SYS_IRQS 8 ++#include ++#include + + /* + * This should be the same as the max(NUM_X_SOURCES) for all the +@@ -16,10 +11,20 @@ + * Currently the Atari has 72 and the Amiga 24, but if both are + * supported in the kernel it is better to make room for 72. + */ +-#if defined(CONFIG_ATARI) || defined(CONFIG_MAC) +-#define NR_IRQS (72+SYS_IRQS) ++#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X) ++#define NR_IRQS 200 ++#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) ++#define NR_IRQS 72 ++#elif defined(CONFIG_Q40) ++#define NR_IRQS 43 ++#elif defined(CONFIG_AMIGA) ++#define NR_IRQS 32 ++#elif defined(CONFIG_APOLLO) ++#define NR_IRQS 24 ++#elif defined(CONFIG_HP300) ++#define NR_IRQS 8 + #else +-#define NR_IRQS (24+SYS_IRQS) ++#error unknown nr of irqs + #endif + + /* +@@ -41,53 +46,26 @@ + * that routine requires service. + */ + +-#define IRQ1 (1) /* level 1 interrupt */ +-#define IRQ2 (2) /* level 2 interrupt */ +-#define IRQ3 (3) /* level 3 interrupt */ +-#define IRQ4 (4) /* level 4 interrupt */ +-#define IRQ5 (5) /* level 5 interrupt */ +-#define IRQ6 (6) /* level 6 interrupt */ +-#define IRQ7 (7) /* level 7 interrupt (non-maskable) */ +- +-/* +- * "Generic" interrupt sources +- */ +- +-#define IRQ_SCHED_TIMER (8) /* interrupt source for scheduling timer */ +- +-static __inline__ int irq_canonicalize(int irq) +-{ +- return irq; +-} +- +-/* +- * Machine specific interrupt sources. +- * +- * Adding an interrupt service routine for a source with this bit +- * set indicates a special machine specific interrupt source. +- * The machine specific files define these sources. +- * +- * The IRQ_MACHSPEC bit is now gone - the only thing it did was to +- * introduce unnecessary overhead. +- * +- * All interrupt handling is actually machine specific so it is better +- * to use function pointers, as used by the Sparc port, and select the +- * interrupt handling functions when initializing the kernel. This way +- * we save some unnecessary overhead at run-time. +- * 01/11/97 - Jes +- */ ++#define IRQ_SPURIOUS 0 ++ ++#define IRQ_AUTO_1 1 /* level 1 interrupt */ ++#define IRQ_AUTO_2 2 /* level 2 interrupt */ ++#define IRQ_AUTO_3 3 /* level 3 interrupt */ ++#define IRQ_AUTO_4 4 /* level 4 interrupt */ ++#define IRQ_AUTO_5 5 /* level 5 interrupt */ ++#define IRQ_AUTO_6 6 /* level 6 interrupt */ ++#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */ ++ ++#define IRQ_USER 8 ++ ++extern unsigned int irq_canonicalize(unsigned int irq); ++extern void enable_irq(unsigned int); ++extern void disable_irq(unsigned int); + +-extern void (*enable_irq)(unsigned int); +-extern void (*disable_irq)(unsigned int); + #define disable_irq_nosync disable_irq + + struct pt_regs; + +-extern int cpu_request_irq(unsigned int, +- irqreturn_t (*)(int, void *, struct pt_regs *), +- unsigned long, const char *, void *); +-extern void cpu_free_irq(unsigned int, void *); +- + /* + * various flags for request_irq() - the Amiga now uses the standard + * mechanism like all other architectures - SA_INTERRUPT and SA_SHIRQ +@@ -106,33 +84,45 @@ + * interrupt source (if it supports chaining). + */ + typedef struct irq_node { +- irqreturn_t (*handler)(int, void *, struct pt_regs *); +- unsigned long flags; ++ int (*handler)(int, void *, struct pt_regs *); + void *dev_id; +- const char *devname; + struct irq_node *next; ++ unsigned long flags; ++ const char *devname; + } irq_node_t; + + /* + * This structure has only 4 elements for speed reasons + */ + typedef struct irq_handler { +- irqreturn_t (*handler)(int, void *, struct pt_regs *); ++ int (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + void *dev_id; + const char *devname; + } irq_handler_t; + +-/* count of spurious interrupts */ +-extern volatile unsigned int num_spurious; ++struct irq_controller { ++ const char *name; ++ spinlock_t lock; ++ int (*startup)(unsigned int irq); ++ void (*shutdown)(unsigned int irq); ++ void (*enable)(unsigned int irq); ++ void (*disable)(unsigned int irq); ++}; ++ ++extern int m68k_irq_startup(unsigned int); ++extern void m68k_irq_shutdown(unsigned int); + + /* + * This function returns a new irq_node_t + */ + extern irq_node_t *new_irq_node(void); + +-struct irqaction; +-struct pt_regs; +-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); ++extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); ++extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, ++ void (*handler)(unsigned int, struct pt_regs *)); ++extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); ++ ++asmlinkage void m68k_handle_int(unsigned int, struct pt_regs *); + + #endif /* _M68K_IRQ_H_ */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/mac_oss.h linux-m68k/include/asm-m68k/mac_oss.h +--- linux-i386/include/asm-m68k/mac_oss.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/mac_oss.h 2006-01-28 23:55:20.000000000 +0100 +@@ -69,12 +69,12 @@ + + #define OSS_IRQLEV_DISABLED 0 + #define OSS_IRQLEV_IOPISM 1 /* ADB? */ +-#define OSS_IRQLEV_SCSI 2 +-#define OSS_IRQLEV_NUBUS 3 /* keep this on its own level */ +-#define OSS_IRQLEV_IOPSCC 4 /* matches VIA alternate mapping */ +-#define OSS_IRQLEV_SOUND 5 /* matches VIA alternate mapping */ ++#define OSS_IRQLEV_SCSI IRQ_AUTO_2 ++#define OSS_IRQLEV_NUBUS IRQ_AUTO_3 /* keep this on its own level */ ++#define OSS_IRQLEV_IOPSCC IRQ_AUTO_4 /* matches VIA alternate mapping */ ++#define OSS_IRQLEV_SOUND IRQ_AUTO_5 /* matches VIA alternate mapping */ + #define OSS_IRQLEV_60HZ 6 /* matches VIA alternate mapping */ +-#define OSS_IRQLEV_VIA1 6 /* matches VIA alternate mapping */ ++#define OSS_IRQLEV_VIA1 IRQ_AUTO_6 /* matches VIA alternate mapping */ + #define OSS_IRQLEV_PARITY 7 /* matches VIA alternate mapping */ + + #ifndef __ASSEMBLY__ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/machdep.h linux-m68k/include/asm-m68k/machdep.h +--- linux-i386/include/asm-m68k/machdep.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/machdep.h 2006-04-11 16:41:20.000000000 +0200 +@@ -13,14 +13,8 @@ + extern void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)); + /* machine dependent irq functions */ + extern void (*mach_init_IRQ) (void); +-extern irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); +-extern int (*mach_request_irq) (unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id); +-extern void (*mach_free_irq) (unsigned int irq, void *dev_id); + extern void (*mach_get_model) (char *model); + extern int (*mach_get_hardware_list) (char *buffer); +-extern int (*mach_get_irq_list) (struct seq_file *p, void *v); +-extern irqreturn_t (*mach_process_int) (int irq, struct pt_regs *fp); + /* machine dependent timer functions */ + extern unsigned long (*mach_gettimeoffset)(void); + extern int (*mach_hwclk)(int, struct rtc_time*); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/macintosh.h linux-m68k/include/asm-m68k/macintosh.h +--- linux-i386/include/asm-m68k/macintosh.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/macintosh.h 2006-01-28 23:55:20.000000000 +0100 +@@ -11,17 +11,7 @@ + extern void mac_reset(void); + extern void mac_poweroff(void); + extern void mac_init_IRQ(void); +-extern int mac_request_irq (unsigned int, irqreturn_t (*)(int, void *, +- struct pt_regs *), +- unsigned long, const char *, void *); +-extern void mac_free_irq(unsigned int, void *); +-extern void mac_enable_irq(unsigned int); +-extern void mac_disable_irq(unsigned int); + extern int mac_irq_pending(unsigned int); +-extern int show_mac_interrupts(struct seq_file *, void *); +-#if 0 +-extern void mac_default_handler(int irq); +-#endif + extern void mac_identify(void); + extern void mac_report_hardware(void); + extern void mac_debugging_penguin(int); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/macints.h linux-m68k/include/asm-m68k/macints.h +--- linux-i386/include/asm-m68k/macints.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/macints.h 2006-01-28 23:55:20.000000000 +0100 +@@ -59,17 +59,6 @@ + #define IRQ_SRC(irq) (irq >> 3) + #define IRQ_IDX(irq) (irq & 7) + +-#define IRQ_SPURIOUS (0) +- +-/* auto-vector interrupts */ +-#define IRQ_AUTO_1 (1) +-#define IRQ_AUTO_2 (2) +-#define IRQ_AUTO_3 (3) +-#define IRQ_AUTO_4 (4) +-#define IRQ_AUTO_5 (5) +-#define IRQ_AUTO_6 (6) +-#define IRQ_AUTO_7 (7) +- + /* VIA1 interrupts */ + #define IRQ_VIA1_0 (8) /* one second int. */ + #define IRQ_VIA1_1 (9) /* VBlank int. */ +@@ -163,7 +152,4 @@ + #define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */ + #define INT_TICKS 246 /* to make sched_time = 99.902... HZ */ + +-extern irq_node_t *mac_irq_list[NUM_MAC_SOURCES]; +-extern void mac_do_irq_list(int irq, struct pt_regs *); +- + #endif /* asm/macints.h */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/mvme147hw.h linux-m68k/include/asm-m68k/mvme147hw.h +--- linux-i386/include/asm-m68k/mvme147hw.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/mvme147hw.h 2006-01-28 23:55:20.000000000 +0100 +@@ -1,6 +1,8 @@ + #ifndef _MVME147HW_H_ + #define _MVME147HW_H_ + ++#include ++ + typedef struct { + unsigned char + ctrl, +@@ -72,39 +74,39 @@ + #define PCC_LEVEL_SCSI_PORT 0x04 + #define PCC_LEVEL_SCSI_DMA 0x04 + +-#define PCC_IRQ_AC_FAIL 0x40 +-#define PCC_IRQ_BERR 0x41 +-#define PCC_IRQ_ABORT 0x42 +-/* #define PCC_IRQ_SERIAL 0x43 */ +-#define PCC_IRQ_PRINTER 0x47 +-#define PCC_IRQ_TIMER1 0x48 +-#define PCC_IRQ_TIMER2 0x49 +-#define PCC_IRQ_SOFTWARE1 0x4a +-#define PCC_IRQ_SOFTWARE2 0x4b ++#define PCC_IRQ_AC_FAIL (IRQ_USER+0) ++#define PCC_IRQ_BERR (IRQ_USER+1) ++#define PCC_IRQ_ABORT (IRQ_USER+2) ++/* #define PCC_IRQ_SERIAL (IRQ_USER+3) */ ++#define PCC_IRQ_PRINTER (IRQ_USER+7) ++#define PCC_IRQ_TIMER1 (IRQ_USER+8) ++#define PCC_IRQ_TIMER2 (IRQ_USER+9) ++#define PCC_IRQ_SOFTWARE1 (IRQ_USER+10) ++#define PCC_IRQ_SOFTWARE2 (IRQ_USER+11) + + + #define M147_SCC_A_ADDR 0xfffe3002 + #define M147_SCC_B_ADDR 0xfffe3000 + #define M147_SCC_PCLK 5000000 + +-#define MVME147_IRQ_SCSI_PORT 0x45 +-#define MVME147_IRQ_SCSI_DMA 0x46 ++#define MVME147_IRQ_SCSI_PORT (IRQ_USER+0x45) ++#define MVME147_IRQ_SCSI_DMA (IRQ_USER+0x46) + + /* SCC interrupts, for MVME147 */ + + #define MVME147_IRQ_TYPE_PRIO 0 +-#define MVME147_IRQ_SCC_BASE 0x60 +-#define MVME147_IRQ_SCCB_TX 0x60 +-#define MVME147_IRQ_SCCB_STAT 0x62 +-#define MVME147_IRQ_SCCB_RX 0x64 +-#define MVME147_IRQ_SCCB_SPCOND 0x66 +-#define MVME147_IRQ_SCCA_TX 0x68 +-#define MVME147_IRQ_SCCA_STAT 0x6a +-#define MVME147_IRQ_SCCA_RX 0x6c +-#define MVME147_IRQ_SCCA_SPCOND 0x6e ++#define MVME147_IRQ_SCC_BASE (IRQ_USER+32) ++#define MVME147_IRQ_SCCB_TX (IRQ_USER+32) ++#define MVME147_IRQ_SCCB_STAT (IRQ_USER+34) ++#define MVME147_IRQ_SCCB_RX (IRQ_USER+36) ++#define MVME147_IRQ_SCCB_SPCOND (IRQ_USER+38) ++#define MVME147_IRQ_SCCA_TX (IRQ_USER+40) ++#define MVME147_IRQ_SCCA_STAT (IRQ_USER+42) ++#define MVME147_IRQ_SCCA_RX (IRQ_USER+44) ++#define MVME147_IRQ_SCCA_SPCOND (IRQ_USER+46) + + #define MVME147_LANCE_BASE 0xfffe1800 +-#define MVME147_LANCE_IRQ 0x44 ++#define MVME147_LANCE_IRQ (IRQ_USER+4) + + #define ETHERNET_ADDRESS 0xfffe0778 + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/mvme16xhw.h linux-m68k/include/asm-m68k/mvme16xhw.h +--- linux-i386/include/asm-m68k/mvme16xhw.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/mvme16xhw.h 2006-01-28 23:55:20.000000000 +0100 +@@ -66,28 +66,28 @@ + + #define MVME162_IRQ_TYPE_PRIO 0 + +-#define MVME167_IRQ_PRN 0x54 +-#define MVME16x_IRQ_I596 0x57 +-#define MVME16x_IRQ_SCSI 0x55 +-#define MVME16x_IRQ_FLY 0x7f +-#define MVME167_IRQ_SER_ERR 0x5c +-#define MVME167_IRQ_SER_MODEM 0x5d +-#define MVME167_IRQ_SER_TX 0x5e +-#define MVME167_IRQ_SER_RX 0x5f +-#define MVME16x_IRQ_TIMER 0x59 +-#define MVME167_IRQ_ABORT 0x6e +-#define MVME162_IRQ_ABORT 0x5e ++#define MVME167_IRQ_PRN (IRQ_USER+20) ++#define MVME16x_IRQ_I596 (IRQ_USER+23) ++#define MVME16x_IRQ_SCSI (IRQ_USER+21) ++#define MVME16x_IRQ_FLY (IRQ_USER+63) ++#define MVME167_IRQ_SER_ERR (IRQ_USER+28) ++#define MVME167_IRQ_SER_MODEM (IRQ_USER+29) ++#define MVME167_IRQ_SER_TX (IRQ_USER+30) ++#define MVME167_IRQ_SER_RX (IRQ_USER+31) ++#define MVME16x_IRQ_TIMER (IRQ_USER+25) ++#define MVME167_IRQ_ABORT (IRQ_USER+46) ++#define MVME162_IRQ_ABORT (IRQ_USER+30) + + /* SCC interrupts, for MVME162 */ +-#define MVME162_IRQ_SCC_BASE 0x40 +-#define MVME162_IRQ_SCCB_TX 0x40 +-#define MVME162_IRQ_SCCB_STAT 0x42 +-#define MVME162_IRQ_SCCB_RX 0x44 +-#define MVME162_IRQ_SCCB_SPCOND 0x46 +-#define MVME162_IRQ_SCCA_TX 0x48 +-#define MVME162_IRQ_SCCA_STAT 0x4a +-#define MVME162_IRQ_SCCA_RX 0x4c +-#define MVME162_IRQ_SCCA_SPCOND 0x4e ++#define MVME162_IRQ_SCC_BASE (IRQ_USER+0) ++#define MVME162_IRQ_SCCB_TX (IRQ_USER+0) ++#define MVME162_IRQ_SCCB_STAT (IRQ_USER+2) ++#define MVME162_IRQ_SCCB_RX (IRQ_USER+4) ++#define MVME162_IRQ_SCCB_SPCOND (IRQ_USER+6) ++#define MVME162_IRQ_SCCA_TX (IRQ_USER+8) ++#define MVME162_IRQ_SCCA_STAT (IRQ_USER+10) ++#define MVME162_IRQ_SCCA_RX (IRQ_USER+12) ++#define MVME162_IRQ_SCCA_SPCOND (IRQ_USER+14) + + /* MVME162 version register */ + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/processor.h linux-m68k/include/asm-m68k/processor.h +--- linux-i386/include/asm-m68k/processor.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/processor.h 2006-01-28 23:55:20.000000000 +0100 +@@ -72,10 +72,10 @@ + }; + + #define INIT_THREAD { \ +- ksp: sizeof(init_stack) + (unsigned long) init_stack, \ +- sr: PS_S, \ +- fs: __KERNEL_DS, \ +- info: INIT_THREAD_INFO(init_task) \ ++ .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ ++ .sr = PS_S, \ ++ .fs = __KERNEL_DS, \ ++ .info = INIT_THREAD_INFO(init_task), \ + } + + /* +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/serial.h linux-m68k/include/asm-m68k/serial.h +--- linux-i386/include/asm-m68k/serial.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/serial.h 2005-08-29 17:37:10.000000000 +0200 +@@ -26,9 +26,11 @@ + #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF + #endif + ++#ifdef CONFIG_ISA + #define SERIAL_PORT_DFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ ++#endif +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/sun3ints.h linux-m68k/include/asm-m68k/sun3ints.h +--- linux-i386/include/asm-m68k/sun3ints.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/sun3ints.h 2006-01-28 23:55:20.000000000 +0100 +@@ -12,37 +12,25 @@ + #define SUN3INTS_H + + #include +-#include +-#include +-#include + #include +-#include +-#include + #include + #include ++#include + + #define SUN3_INT_VECS 192 + + void sun3_enable_irq(unsigned int irq); + void sun3_disable_irq(unsigned int irq); +-int sun3_request_irq(unsigned int irq, +- irqreturn_t (*handler)(int, void *, struct pt_regs *), +- unsigned long flags, const char *devname, void *dev_id +- ); + extern void sun3_init_IRQ (void); +-extern irqreturn_t (*sun3_default_handler[]) (int, void *, struct pt_regs *); +-extern void sun3_free_irq (unsigned int irq, void *dev_id); + extern void sun3_enable_interrupts (void); + extern void sun3_disable_interrupts (void); +-extern int show_sun3_interrupts(struct seq_file *, void *); +-extern irqreturn_t sun3_process_int(int, struct pt_regs *); + extern volatile unsigned char* sun3_intreg; + + /* master list of VME vectors -- don't fuck with this */ +-#define SUN3_VEC_FLOPPY 0x40 +-#define SUN3_VEC_VMESCSI0 0x40 +-#define SUN3_VEC_VMESCSI1 0x41 +-#define SUN3_VEC_CG 0xA8 ++#define SUN3_VEC_FLOPPY (IRQ_USER+0) ++#define SUN3_VEC_VMESCSI0 (IRQ_USER+0) ++#define SUN3_VEC_VMESCSI1 (IRQ_USER+1) ++#define SUN3_VEC_CG (IRQ_USER+104) + + + #endif /* SUN3INTS_H */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/thread_info.h linux-m68k/include/asm-m68k/thread_info.h +--- linux-i386/include/asm-m68k/thread_info.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/thread_info.h 2006-04-11 16:41:20.000000000 +0200 +@@ -26,24 +26,24 @@ + + /* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */ + #if PAGE_SHIFT == 13 /* 8k machines */ +-#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,0)) +-#define free_thread_info(ti) free_pages((unsigned long)(ti),0) ++#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,0)) ++#define free_thread_stack(ti) free_pages((unsigned long)(ti),0) + #else /* otherwise assume 4k pages */ +-#define alloc_thread_info(tsk) ((struct thread_info *)__get_free_pages(GFP_KERNEL,1)) +-#define free_thread_info(ti) free_pages((unsigned long)(ti),1) ++#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,1)) ++#define free_thread_stack(ti) free_pages((unsigned long)(ti),1) + #endif /* PAGE_SHIFT == 13 */ + + #define init_thread_info (init_task.thread.info) + #define init_stack (init_thread_union.stack) + + #define task_thread_info(tsk) (&(tsk)->thread.info) +-#define task_stack_page(tsk) ((void *)(tsk)->thread_info) ++#define task_stack_page(tsk) ((void *)(tsk)->stack) + #define current_thread_info() task_thread_info(current) + + #define __HAVE_THREAD_FUNCTIONS + + #define setup_thread_stack(p, org) ({ \ +- *(struct task_struct **)(p)->thread_info = (p); \ ++ *(struct task_struct **)(p)->stack = (p); \ + task_thread_info(p)->task = (p); \ + }) + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/traps.h linux-m68k/include/asm-m68k/traps.h +--- linux-i386/include/asm-m68k/traps.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/traps.h 2006-01-28 23:55:20.000000000 +0100 +@@ -15,6 +15,10 @@ + + typedef void (*e_vector)(void); + ++asmlinkage void auto_inthandler(void); ++asmlinkage void user_inthandler(void); ++asmlinkage void bad_inthandler(void); ++ + extern e_vector vectors[]; + + #endif +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/unistd.h linux-m68k/include/asm-m68k/unistd.h +--- linux-i386/include/asm-m68k/unistd.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/asm-m68k/unistd.h 2006-02-12 16:33:52.000000000 +0100 +@@ -284,8 +284,13 @@ + #define __NR_add_key 279 + #define __NR_request_key 280 + #define __NR_keyctl 281 ++#define __NR_ioprio_set 282 ++#define __NR_ioprio_get 283 ++#define __NR_inotify_init 284 ++#define __NR_inotify_add_watch 285 ++#define __NR_inotify_rm_watch 286 + +-#define NR_syscalls 282 ++#define NR_syscalls 287 + + /* user-visible error numbers are in the range -1 - -124: see + */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/adb.h linux-m68k/include/linux/adb.h +--- linux-i386/include/linux/adb.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/adb.h 2003-03-25 20:25:16.000000000 +0100 +@@ -76,6 +76,7 @@ + #define ADBREQ_REPLY 1 /* expect reply */ + #define ADBREQ_SYNC 2 /* poll until done */ + #define ADBREQ_NOSEND 4 /* build the request, but don't send it */ ++#define ADBREQ_RAW 8 /* send raw packet (don't prepend ADB_PACKET) */ + + /* Messages sent thru the client_list notifier. You should NOT stop + the operation, at least not with this version */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/bootmem.h linux-m68k/include/linux/bootmem.h +--- linux-i386/include/linux/bootmem.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/bootmem.h 2006-04-11 16:41:45.000000000 +0200 +@@ -56,11 +56,11 @@ + #define alloc_bootmem(x) \ + __alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) + #define alloc_bootmem_low(x) \ +- __alloc_bootmem_low((x), SMP_CACHE_BYTES, 0) ++ __alloc_bootmem_low((x), SMP_CACHE_BYTES, __pa(PAGE_OFFSET)) + #define alloc_bootmem_pages(x) \ + __alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS)) + #define alloc_bootmem_low_pages(x) \ +- __alloc_bootmem_low((x), PAGE_SIZE, 0) ++ __alloc_bootmem_low((x), PAGE_SIZE, __pa(PAGE_OFFSET)) + #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ + extern unsigned long __init free_all_bootmem (void); + extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/file.h linux-m68k/include/linux/file.h +--- linux-i386/include/linux/file.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/file.h 2006-04-11 16:41:47.000000000 +0200 +@@ -5,7 +5,6 @@ + #ifndef __LINUX_FILE_H + #define __LINUX_FILE_H + +-#include + #include + #include + #include +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/ide.h linux-m68k/include/linux/ide.h +--- linux-i386/include/linux/ide.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/ide.h 2006-04-11 16:41:50.000000000 +0200 +@@ -510,7 +510,7 @@ + * sense_key : Sense key of the last failed packet command + */ + typedef union { +- unsigned all :8; ++ u8 all; + struct { + #if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned ili :1; +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/init_task.h linux-m68k/include/linux/init_task.h +--- linux-i386/include/linux/init_task.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/init_task.h 2006-01-19 22:10:55.000000000 +0100 +@@ -79,7 +79,7 @@ + #define INIT_TASK(tsk) \ + { \ + .state = 0, \ +- .thread_info = &init_thread_info, \ ++ .stack = &init_stack, \ + .usage = ATOMIC_INIT(2), \ + .flags = 0, \ + .lock_depth = -1, \ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/kernel_stat.h linux-m68k/include/linux/kernel_stat.h +--- linux-i386/include/linux/kernel_stat.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/kernel_stat.h 2006-04-11 16:41:51.000000000 +0200 +@@ -2,12 +2,12 @@ + #define _LINUX_KERNEL_STAT_H + + #include +-#include + #include + #include + #include + #include + #include ++#include + + /* + * 'kernel_stat.h' contains the definitions needed for doing +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/module.h linux-m68k/include/linux/module.h +--- linux-i386/include/linux/module.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/module.h 2006-01-28 23:55:42.000000000 +0100 +@@ -314,6 +314,9 @@ + keeping pointers to this stuff */ + char *args; + }; ++#ifndef MODULE_ARCH_INIT ++#define MODULE_ARCH_INIT {} ++#endif + + /* FIXME: It'd be nice to isolate modules during init, too, so they + aren't used before they (may) fail. But presently too much code +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/sched.h linux-m68k/include/linux/sched.h +--- linux-i386/include/linux/sched.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/sched.h 2006-04-11 16:41:54.000000000 +0200 +@@ -691,7 +691,8 @@ + + struct task_struct { + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ +- struct thread_info *thread_info; ++ //struct thread_info *thread_info; ++ void *stack; + atomic_t usage; + unsigned long flags; /* per process flags, defined below */ + unsigned long ptrace; +@@ -1257,6 +1258,7 @@ + /* set thread flags in other task's structures + * - see asm/thread_info.h for TIF_xxxx flags available + */ ++ + static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag) + { + set_ti_thread_flag(task_thread_info(tsk), flag); +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/thread_info.h linux-m68k/include/linux/thread_info.h +--- linux-i386/include/linux/thread_info.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/thread_info.h 2005-05-30 02:26:01.000000000 +0200 +@@ -66,6 +66,6 @@ + #define set_need_resched() set_thread_flag(TIF_NEED_RESCHED) + #define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED) + +-#endif ++#endif /* __KERNEL__ */ + + #endif /* _LINUX_THREAD_INFO_H */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/zorro.h linux-m68k/include/linux/zorro.h +--- linux-i386/include/linux/zorro.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/include/linux/zorro.h 2006-01-28 23:55:43.000000000 +0100 +@@ -11,8 +11,6 @@ + #ifndef _LINUX_ZORRO_H + #define _LINUX_ZORRO_H + +-#ifndef __ASSEMBLY__ +- + #include + + +@@ -112,45 +110,6 @@ + __u32 cd_Unused[4]; /* for whatever the driver wants */ + } __attribute__ ((packed)); + +-#else /* __ASSEMBLY__ */ +- +-LN_Succ = 0 +-LN_Pred = LN_Succ+4 +-LN_Type = LN_Pred+4 +-LN_Pri = LN_Type+1 +-LN_Name = LN_Pri+1 +-LN_sizeof = LN_Name+4 +- +-ER_Type = 0 +-ER_Product = ER_Type+1 +-ER_Flags = ER_Product+1 +-ER_Reserved03 = ER_Flags+1 +-ER_Manufacturer = ER_Reserved03+1 +-ER_SerialNumber = ER_Manufacturer+2 +-ER_InitDiagVec = ER_SerialNumber+4 +-ER_Reserved0c = ER_InitDiagVec+2 +-ER_Reserved0d = ER_Reserved0c+1 +-ER_Reserved0e = ER_Reserved0d+1 +-ER_Reserved0f = ER_Reserved0e+1 +-ER_sizeof = ER_Reserved0f+1 +- +-CD_Node = 0 +-CD_Flags = CD_Node+LN_sizeof +-CD_Pad = CD_Flags+1 +-CD_Rom = CD_Pad+1 +-CD_BoardAddr = CD_Rom+ER_sizeof +-CD_BoardSize = CD_BoardAddr+4 +-CD_SlotAddr = CD_BoardSize+4 +-CD_SlotSize = CD_SlotAddr+2 +-CD_Driver = CD_SlotSize+2 +-CD_NextCD = CD_Driver+4 +-CD_Unused = CD_NextCD+4 +-CD_sizeof = CD_Unused+(4*4) +- +-#endif /* __ASSEMBLY__ */ +- +-#ifndef __ASSEMBLY__ +- + #define ZORRO_NUM_AUTO 16 + + #ifdef __KERNEL__ +@@ -323,7 +282,6 @@ + #define Z2RAM_CHUNKSHIFT (16) + + +-#endif /* !__ASSEMBLY__ */ + #endif /* __KERNEL__ */ + + #endif /* _LINUX_ZORRO_H */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/kernel/fork.c linux-m68k/kernel/fork.c +--- linux-i386/kernel/fork.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/kernel/fork.c 2006-04-11 16:42:19.000000000 +0200 +@@ -103,7 +103,7 @@ + + void free_task(struct task_struct *tsk) + { +- free_thread_info(tsk->thread_info); ++ free_thread_stack(tsk->stack); + free_task_struct(tsk); + } + EXPORT_SYMBOL(free_task); +@@ -160,7 +160,7 @@ + static struct task_struct *dup_task_struct(struct task_struct *orig) + { + struct task_struct *tsk; +- struct thread_info *ti; ++ void *stack; + + prepare_to_copy(orig); + +@@ -168,14 +168,14 @@ + if (!tsk) + return NULL; + +- ti = alloc_thread_info(tsk); +- if (!ti) { ++ stack = alloc_thread_stack(tsk); ++ if (!stack) { + free_task_struct(tsk); + return NULL; + } + + *tsk = *orig; +- tsk->thread_info = ti; ++ tsk->stack = stack; + setup_thread_stack(tsk, orig); + + /* One for us, one for whoever does the "release_task()" (usually parent) */ +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/lib/kref.c linux-m68k/lib/kref.c +--- linux-i386/lib/kref.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/lib/kref.c 2005-11-01 02:17:02.000000000 +0100 +@@ -11,8 +11,8 @@ + * + */ + +-#include + #include ++#include + + /** + * kref_init - initialize object. +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/mm/bootmem.c linux-m68k/mm/bootmem.c +--- linux-i386/mm/bootmem.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/mm/bootmem.c 2006-04-11 16:42:33.000000000 +0200 +@@ -285,7 +285,6 @@ + + count = 0; + /* first extant page of the node */ +- pfn = bdata->node_boot_start >> PAGE_SHIFT; + idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT); + map = bdata->node_bootmem_map; + /* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */ +@@ -298,26 +297,24 @@ + if (gofast && v == ~0UL) { + int order; + +- page = pfn_to_page(pfn); ++ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) + ++ bdata->node_boot_start)); + count += BITS_PER_LONG; + order = ffs(BITS_PER_LONG) - 1; + __free_pages_bootmem(page, order); + i += BITS_PER_LONG; +- page += BITS_PER_LONG; + } else if (v) { + unsigned long m; +- +- page = pfn_to_page(pfn); +- for (m = 1; m && i < idx; m<<=1, page++, i++) { ++ for (m = 1; m && i < idx; m<<=1, i++) { + if (v & m) { ++ page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) + ++ bdata->node_boot_start)); + count++; + __free_pages_bootmem(page, 0); + } + } +- } else { ++ } else + i+=BITS_PER_LONG; +- } +- pfn += BITS_PER_LONG; + } + total += count; + +diff -urN --exclude-from=/usr/src/exclude-file linux-i386/scripts/mod/modpost.c linux-m68k/scripts/mod/modpost.c +--- linux-i386/scripts/mod/modpost.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-m68k/scripts/mod/modpost.c 2006-04-11 16:44:12.000000000 +0200 +@@ -543,6 +543,7 @@ + buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n" + " .exit = cleanup_module,\n" + "#endif\n"); ++ buf_printf(b, " .arch = MODULE_ARCH_INIT,\n"); + buf_printf(b, "};\n"); + } + From 57f29d1e7358a33bf16abebd0989139ef6dd3d37 Mon Sep 17 00:00:00 2001 From: "Christian T. Steigies" Date: Fri, 14 Apr 2006 14:31:00 +0000 Subject: [PATCH 038/108] update m68k config, temporarily disable atari svn path=/dists/trunk/linux-2.6/; revision=6417 --- debian/arch/m68k/config | 4 ++++ debian/arch/m68k/config.amiga | 3 +++ debian/arch/m68k/config.mac | 1 - debian/arch/m68k/config.q40 | 1 - debian/arch/m68k/defines | 2 +- 5 files changed, 8 insertions(+), 3 deletions(-) diff --git a/debian/arch/m68k/config b/debian/arch/m68k/config index 148bec5d2..ac227859a 100644 --- a/debian/arch/m68k/config +++ b/debian/arch/m68k/config @@ -228,3 +228,7 @@ CONFIG_ZLIB_DEFLATE=m # CONFIG_IEEE80211_CRYPT_WEP is not set # CONFIG_IEEE80211 is not set # CONFIG_IPW2100 is not set +# new for 2.6.16: +CONFIG_DM_MULTIPATH_EMC=m +# CONFIG_SENSORS_F71805F is not set +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 diff --git a/debian/arch/m68k/config.amiga b/debian/arch/m68k/config.amiga index fa2745217..388caf8ba 100644 --- a/debian/arch/m68k/config.amiga +++ b/debian/arch/m68k/config.amiga @@ -196,3 +196,6 @@ CONFIG_NCPFS_OS2_NS=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_AMIGA_PARTITION=y CONFIG_CRC32=y +# 2.6.16 +# temporary workaround for old/buggy(?) 53c7xx.c driver +CONFIG_SCSI_SPI_ATTRS=y diff --git a/debian/arch/m68k/config.mac b/debian/arch/m68k/config.mac index 2b167ec33..b7c0edf3d 100644 --- a/debian/arch/m68k/config.mac +++ b/debian/arch/m68k/config.mac @@ -38,7 +38,6 @@ CONFIG_BLK_DEV_MAC_IDE=y # CONFIG_BLK_DEV_HD is not set CONFIG_MAC_SCSI=y CONFIG_SCSI_MAC_ESP=y -CONFIG_DM_MULTIPATH_EMC=m CONFIG_ADB=y CONFIG_ADB_MACII=y CONFIG_ADB_MACIISI=y diff --git a/debian/arch/m68k/config.q40 b/debian/arch/m68k/config.q40 index b79043eeb..d01449b35 100644 --- a/debian/arch/m68k/config.q40 +++ b/debian/arch/m68k/config.q40 @@ -50,7 +50,6 @@ CONFIG_BLK_DEV_Q40IDE=y # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set # CONFIG_CD_NO_IDESCSI is not set -CONFIG_DM_MULTIPATH_EMC=m CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y diff --git a/debian/arch/m68k/defines b/debian/arch/m68k/defines index 2c418e979..3d452fca4 100644 --- a/debian/arch/m68k/defines +++ b/debian/arch/m68k/defines @@ -2,7 +2,7 @@ compiler: gcc-3.3 flavours: amiga - atari +# does not build currently: atari bvme6000 hp mac From f7a57d4ce41c3620fda4bcead99c55e0b4fccc52 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 14 Apr 2006 15:53:22 +0000 Subject: [PATCH 039/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6419 --- debian/arch/powerpc/defines | 10 ++- debian/changelog | 32 ++++++++-- debian/patches/2.6.16.3 | 27 ++++++++ debian/patches/2.6.16.4 | 12 ++++ debian/patches/2.6.16.5 | 63 +++++++++++++++++++ .../patches/powerpc-mkvmlinuz-support-2.patch | 57 +++++++++++++++++ debian/patches/series/7 | 4 ++ debian/patches/series/7-extra | 1 + 8 files changed, 195 insertions(+), 11 deletions(-) create mode 100644 debian/patches/2.6.16.3 create mode 100644 debian/patches/2.6.16.4 create mode 100644 debian/patches/2.6.16.5 create mode 100644 debian/patches/powerpc-mkvmlinuz-support-2.patch create mode 100644 debian/patches/series/7 create mode 100644 debian/patches/series/7-extra diff --git a/debian/arch/powerpc/defines b/debian/arch/powerpc/defines index af2b50230..1db4d721d 100644 --- a/debian/arch/powerpc/defines +++ b/debian/arch/powerpc/defines @@ -10,19 +10,17 @@ kpkg-subarch: ppc subarches: vserver -[image] - [apus] -depends: mkvmlinuz (>= 18) +depends: mkvmlinuz (>= 19) [powerpc] -depends: mkvmlinuz (>= 18) +depends: mkvmlinuz (>= 19) [powerpc-smp] -depends: mkvmlinuz (>= 18) +depends: mkvmlinuz (>= 19) [powerpc-miboot] -depends: mkvmlinuz (>= 18) +depends: mkvmlinuz (>= 19) [powerpc64] kpkg-subarch: powerpc64 diff --git a/debian/changelog b/debian/changelog index 12d24789b..3f8f1b297 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,14 +1,36 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low - [ Bastian Blank ] * + -- Bastian Blank Fri, 14 Apr 2006 17:52:48 +0200 + +linux-2.6 (2.6.16-7) UNRELEASED; urgency=low + + [ Frederik Schüler ] + * Add stable release 2.6.16.3: + - Keys: Fix oops when adding key to non-keyring (CVE-2006-1522) + + [ Bastian Blank ] + * Add stable release 2.6.16.4: + - RCU signal handling (CVE-2006-1523) + + [ Sven Luther ] + * [powerpc] Transitioned mkvmlinuz support patch to the 2.6.16 ARCH=powerpc + tree. PReP is broken in 2.6.16 though. + [ maximilian attems ] - * Unset CONFIG_SECCOMP. + * Add stable release 2.6.16.5: + - x86_64: Clean up execve + - x86_64: When user could have changed RIP always force IRET (CVE-2006-0744) + * Disable CONFIG_SECCOMP (adds useless overhead on context-switch) - + thanks to fs for checking abi. - -- maximilian attems Tue, 11 Apr 2006 01:07:28 +0200 + [ Christian T. Steigies ] + * [m68k] update m68k patch and config to 2.6.16, temporarily disable atari -linux-2.6 (2.6.16-6) UNRELEASED; urgency=low + -- maximilian attems Thu, 13 Apr 2006 11:16:42 +0200 + +linux-2.6 (2.6.16-6) unstable; urgency=medium [ Bastian Blank ] * Provide version infos in support package and don't longer rely on the @@ -43,7 +65,7 @@ linux-2.6 (2.6.16-6) UNRELEASED; urgency=low - Fix the p4-clockmod N60 errata workaround. - kdump proc vmcore size oveflow fix - -- Bastian Blank Fri, 7 Apr 2006 22:58:17 +0200 + -- Bastian Blank Mon, 10 Apr 2006 16:09:51 +0200 linux-2.6 (2.6.16-5) unstable; urgency=low diff --git a/debian/patches/2.6.16.3 b/debian/patches/2.6.16.3 new file mode 100644 index 000000000..438766b15 --- /dev/null +++ b/debian/patches/2.6.16.3 @@ -0,0 +1,27 @@ +diff --git a/security/keys/key.c b/security/keys/key.c +index 99781b7..0e2584e 100644 +--- a/security/keys/key.c ++++ b/security/keys/key.c +@@ -785,6 +785,10 @@ key_ref_t key_create_or_update(key_ref_t + + key_check(keyring); + ++ key_ref = ERR_PTR(-ENOTDIR); ++ if (keyring->type != &key_type_keyring) ++ goto error_2; ++ + down_write(&keyring->sem); + + /* if we're going to allocate a new key, we're going to have +diff --git a/security/keys/keyring.c b/security/keys/keyring.c +index d65a180..bffa924 100644 +--- a/security/keys/keyring.c ++++ b/security/keys/keyring.c +@@ -437,6 +437,7 @@ EXPORT_SYMBOL(keyring_search); + /* + * search the given keyring only (no recursion) + * - keyring must be locked by caller ++ * - caller must guarantee that the keyring is a keyring + */ + key_ref_t __keyring_search_one(key_ref_t keyring_ref, + const struct key_type *ktype, diff --git a/debian/patches/2.6.16.4 b/debian/patches/2.6.16.4 new file mode 100644 index 000000000..d134fbe5a --- /dev/null +++ b/debian/patches/2.6.16.4 @@ -0,0 +1,12 @@ +diff --git a/kernel/signal.c b/kernel/signal.c +index ea15410..bc8f80b 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -975,7 +975,6 @@ __group_complete_signal(int sig, struct + if (t == NULL) + /* restart balancing at this thread */ + t = p->signal->curr_target = p; +- BUG_ON(t->tgid != p->tgid); + + while (!wants_signal(sig, t)) { + t = next_thread(t); diff --git a/debian/patches/2.6.16.5 b/debian/patches/2.6.16.5 new file mode 100644 index 000000000..78d0633c0 --- /dev/null +++ b/debian/patches/2.6.16.5 @@ -0,0 +1,63 @@ +diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S +index 7c10e90..ab6e44d 100644 +--- a/arch/x86_64/kernel/entry.S ++++ b/arch/x86_64/kernel/entry.S +@@ -180,6 +180,10 @@ rff_trace: + * + * XXX if we had a free scratch register we could save the RSP into the stack frame + * and report it properly in ps. Unfortunately we haven't. ++ * ++ * When user can change the frames always force IRET. That is because ++ * it deals with uncanonical addresses better. SYSRET has trouble ++ * with them due to bugs in both AMD and Intel CPUs. + */ + + ENTRY(system_call) +@@ -254,7 +258,10 @@ sysret_signal: + xorl %esi,%esi # oldset -> arg2 + call ptregscall_common + 1: movl $_TIF_NEED_RESCHED,%edi +- jmp sysret_check ++ /* Use IRET because user could have changed frame. This ++ works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ ++ cli ++ jmp int_with_check + + badsys: + movq $-ENOSYS,RAX-ARGOFFSET(%rsp) +@@ -280,7 +287,8 @@ tracesys: + call syscall_trace_leave + RESTORE_TOP_OF_STACK %rbx + RESTORE_REST +- jmp ret_from_sys_call ++ /* Use IRET because user could have changed frame */ ++ jmp int_ret_from_sys_call + CFI_ENDPROC + + /* +@@ -408,25 +416,9 @@ ENTRY(stub_execve) + CFI_ADJUST_CFA_OFFSET -8 + CFI_REGISTER rip, r11 + SAVE_REST +- movq %r11, %r15 +- CFI_REGISTER rip, r15 + FIXUP_TOP_OF_STACK %r11 + call sys_execve +- GET_THREAD_INFO(%rcx) +- bt $TIF_IA32,threadinfo_flags(%rcx) +- CFI_REMEMBER_STATE +- jc exec_32bit + RESTORE_TOP_OF_STACK %r11 +- movq %r15, %r11 +- CFI_REGISTER rip, r11 +- RESTORE_REST +- pushq %r11 +- CFI_ADJUST_CFA_OFFSET 8 +- CFI_REL_OFFSET rip, 0 +- ret +- +-exec_32bit: +- CFI_RESTORE_STATE + movq %rax,RAX(%rsp) + RESTORE_REST + jmp int_ret_from_sys_call diff --git a/debian/patches/powerpc-mkvmlinuz-support-2.patch b/debian/patches/powerpc-mkvmlinuz-support-2.patch new file mode 100644 index 000000000..5c9cc2a9e --- /dev/null +++ b/debian/patches/powerpc-mkvmlinuz-support-2.patch @@ -0,0 +1,57 @@ +# +# Mkvmlinuz support patch, called by debian's kernel-package to generate +# the files needed by mkvmlinuz to generate the bootable images from vmlinux. +# Author: Sven Luther +# Based on work from: Jens Schmalzing +# Original comment from Jens : +# This shell script is intended to be put into the debian subdirectory +# of a Linux kernel tree, where make-kpkg will find and execute it +# while building a kernel-image package. The purpose of this script +# is to add glue (object code, libraries, utilities and so on) from +# the kernel tree to the kernel-image package. Later, the mkvmlinuz +# utility, which is available as a separate Debian package, can use +# this glue to create a bootable compressed kernel from the +# uncompressed kernel in the kernel-image package and optionally a +# ramdisk. This is especially important on PowerPC subarchitectures +# that don't have a boot loader, but also comes handy for rescue +# systems and the like. +# Upstream status: This patch stays a debian specific patch for now, +# but it is not in a form where it could go upstream. +# +--- linux-2.6.16/arch/powerpc/Makefile.orig 2006-04-12 16:57:16.000000000 +0000 ++++ linux-2.6.16/arch/powerpc/Makefile 2006-04-12 16:58:53.000000000 +0000 +@@ -148,7 +148,7 @@ + + CPPFLAGS_vmlinux.lds := -Upowerpc + +-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage ++BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage mkvmlinuz_support_install + + .PHONY: $(BOOT_TARGETS) + +--- linux-2.6.16/arch/powerpc/boot/Makefile.orig 2006-04-12 16:40:11.000000000 +0000 ++++ linux-2.6.16/arch/powerpc/boot/Makefile 2006-04-12 19:23:06.000000000 +0000 +@@ -213,3 +213,23 @@ + sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" + + clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip) ++ ++#----------------------------------------------------------- ++# install mkvmlinuz support files ++#----------------------------------------------------------- ++quiet_cmd_mkvmlinuz = INSTALL mkvmlinuz support files ++ cmd_mkvmlinuz = cp -f $? $(INSTALL_MKVMLINUZ) ++ ++mkvmlinuz-obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/mkvmlinuz-kernel-%.o, $(section))) ++mkvmlinuz-src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/mkvmlinuz-kernel-%.c, $(section))) ++ ++$(call mkvmlinuz-src-sec, $(required) $(initrd)): $(obj)/mkvmlinuz-kernel-%.c: ++ @touch $@ ++$(call mkvmlinuz-obj-sec, $(required) $(initrd)): $(obj)/mkvmlinuz-kernel-%.o: $(obj)/mkvmlinuz-kernel-%.c ++ $(call if_changed_dep,bootcc) ++ ++$(obj)/mkvmlinuz_support_install: $(obj)/addRamDisk $(obj)/addnote $(obj-boot) $(call mkvmlinuz-obj-sec, $(required) $(initrd)) $(srctree)/$(src)/zImage.lds ++ mkdir -p $(INSTALL_MKVMLINUZ) ++ $(call cmd,mkvmlinuz) ++targets += mkvmlinuz_support_install ++ diff --git a/debian/patches/series/7 b/debian/patches/series/7 new file mode 100644 index 000000000..ee82a76a5 --- /dev/null +++ b/debian/patches/series/7 @@ -0,0 +1,4 @@ ++ 2.6.16.3 ++ 2.6.16.4 ++ powerpc-mkvmlinuz-support-2.patch ++ 2.6.16.5 diff --git a/debian/patches/series/7-extra b/debian/patches/series/7-extra new file mode 100644 index 000000000..9dfd712f5 --- /dev/null +++ b/debian/patches/series/7-extra @@ -0,0 +1 @@ ++ m68k-2.6.16.patch m68k From 7ba864e429ed66d9d511ee689bf287cf8fc2c8bf Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 14 Apr 2006 16:07:56 +0000 Subject: [PATCH 040/108] * debian/bin/gencontrol.py: Move changelog processing. * debian/lib/python/debian_linux/gencontrol.py: Add generic version processing. svn path=/dists/trunk/linux-2.6/; revision=6420 --- debian/bin/gencontrol.py | 10 ++++++- debian/lib/python/debian_linux/gencontrol.py | 29 +++++++++----------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 0f60f47a0..1aa836963 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -8,7 +8,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): def __init__(self): super(gencontrol, self).__init__() self.changelog = read_changelog() - self.version, self.abiname, self.changelog_vars = self.process_changelog({}) + self.version, self.abiname, self.changelog_vars = self.process_changelog() def do_main_setup(self, vars, makeflags): vars.update(self.config['image',]) @@ -165,6 +165,14 @@ class gencontrol(debian_linux.gencontrol.gencontrol): makefile.append(("setup-%s-%s-%s-real:" % (arch, subarch, flavour), cmds_setup)) makefile.append(("source-%s-%s-%s-real:" % (arch, subarch, flavour))) + def process_changelog(self): + ret = [None, None, None] + ret[0] = version = self.changelog[0]['Version'] + vars = self.process_version(version) + ret[1] = vars['abiname'] + ret[2] = vars + return ret + def process_real_image(self, in_entry, depends, vars): entry = self.process_package(in_entry, vars) if vars.has_key('desc'): diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index 93dac7593..2f2078a2e 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -202,22 +202,6 @@ class gencontrol(object): def do_flavour_packages(self, packages, makefile, arch, subarch, flavour, vars, makeflags, extra): pass - # TODO: Move away, linux-2.6 specific; unify with modules process_config_version - def process_changelog(self, in_vars): - ret = [None, None, None] - ret[0] = version = self.changelog[0]['Version'] - vars = in_vars.copy() - if version['modifier'] is not None: - ret[1] = vars['abiname'] = '' - else: - ret[1] = vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] - vars['upstreamversion'] = version['upstream'] - vars['version'] = version['version'] - vars['source_upstream'] = version['source_upstream'] - vars['major'] = version['major'] - ret[2] = vars - return ret - def process_relation(self, key, e, in_e, vars): in_dep = in_e[key] dep = package_relation_list() @@ -260,6 +244,19 @@ class gencontrol(object): entries.append(self.process_package(i, vars)) return entries + def process_version(self, version): + vars = { + 'upstreamversion': version['upstream'], + 'version': version['version'], + 'source_upstream': version['source_upstream'], + 'major': version['major'], + } + if version['modifier'] is not None: + vars['abiname'] = '' + else: + vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] + return vars + def substitute(self, s, vars): if isinstance(s, (list, tuple)): for i in xrange(len(s)): From 063add398314dabc59dbfa25e11f200e64f57abe Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 14 Apr 2006 16:12:41 +0000 Subject: [PATCH 041/108] debian/bin/gencontrol.py, debian/lib/python/debian_linux/gencontrol.py: Set variables directly. svn path=/dists/trunk/linux-2.6/; revision=6421 --- debian/bin/gencontrol.py | 10 +++------- debian/lib/python/debian_linux/gencontrol.py | 5 +++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 1aa836963..7d708dd5e 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -8,7 +8,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): def __init__(self): super(gencontrol, self).__init__() self.changelog = read_changelog() - self.version, self.abiname, self.changelog_vars = self.process_changelog() + self.process_changelog() def do_main_setup(self, vars, makeflags): vars.update(self.config['image',]) @@ -166,12 +166,8 @@ class gencontrol(debian_linux.gencontrol.gencontrol): makefile.append(("source-%s-%s-%s-real:" % (arch, subarch, flavour))) def process_changelog(self): - ret = [None, None, None] - ret[0] = version = self.changelog[0]['Version'] - vars = self.process_version(version) - ret[1] = vars['abiname'] - ret[2] = vars - return ret + version = self.changelog[0]['Version'] + self.changelog_vars = self.process_version(version) def process_real_image(self, in_entry, depends, vars): entry = self.process_package(in_entry, vars) diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index 2f2078a2e..8d3b35d2f 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -245,6 +245,7 @@ class gencontrol(object): return entries def process_version(self, version): + self.version = version vars = { 'upstreamversion': version['upstream'], 'version': version['version'], @@ -252,9 +253,9 @@ class gencontrol(object): 'major': version['major'], } if version['modifier'] is not None: - vars['abiname'] = '' + self.abiname = vars['abiname'] = '' else: - vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] + self.abiname = vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] return vars def substitute(self, s, vars): From 287444d150bf026cb23ea504b541aed307f6db98 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 14 Apr 2006 16:17:39 +0000 Subject: [PATCH 042/108] debian/bin/gencontrol.py, debian/lib/python/debian_linux/gencontrol.py: Move initial abiname handling into special code. svn path=/dists/trunk/linux-2.6/; revision=6422 --- debian/bin/gencontrol.py | 4 ++++ debian/lib/python/debian_linux/gencontrol.py | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 7d708dd5e..549141d2d 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -168,6 +168,10 @@ class gencontrol(debian_linux.gencontrol.gencontrol): def process_changelog(self): version = self.changelog[0]['Version'] self.changelog_vars = self.process_version(version) + if version['modifier'] is not None: + self.abiname = self.changelog_vars['abiname'] = '' + else: + self.abiname = self.changelog_vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] def process_real_image(self, in_entry, depends, vars): entry = self.process_package(in_entry, vars) diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index 8d3b35d2f..0aa30de99 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -252,10 +252,6 @@ class gencontrol(object): 'source_upstream': version['source_upstream'], 'major': version['major'], } - if version['modifier'] is not None: - self.abiname = vars['abiname'] = '' - else: - self.abiname = vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] return vars def substitute(self, s, vars): From 345264d09b272916c3762a75b4c10204723918c3 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 14 Apr 2006 16:45:34 +0000 Subject: [PATCH 043/108] debian/rules.real: Specify each target in its own spec. svn path=/dists/trunk/linux-2.6/; revision=6423 --- debian/rules.real | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/debian/rules.real b/debian/rules.real index 14568eed5..dea6fd0b3 100644 --- a/debian/rules.real +++ b/debian/rules.real @@ -73,8 +73,11 @@ ifeq ($(MODULES),True) binary-arch-flavour: install-header-$(ARCH)-$(SUBARCH)-$(FLAVOUR) endif -binary-indep: install-doc install-patch install-source install-tree +binary-indep: install-doc +binary-indep: install-patch +binary-indep: install-source binary-indep: install-support +binary-indep: install-tree build: $(STAMPS_DIR)/build-$(ARCH)-$(SUBARCH)-$(FLAVOUR)-$(TYPE) From 66ce664b9d74a3d05e281278122a800031c129e0 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 14 Apr 2006 16:52:33 +0000 Subject: [PATCH 044/108] debian/bin/gencontrol.py, debian/lib/python/debian_linux/gencontrol.py, debian/modules/gencontrol.py - Fix variable name. - Use new version code in modules scripts. svn path=/dists/trunk/linux-2.6/; revision=6424 --- debian/bin/gencontrol.py | 8 ++++---- debian/lib/python/debian_linux/gencontrol.py | 7 +++---- debian/modules/gencontrol.py | 18 ++++++------------ 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 549141d2d..7a0d401bb 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -14,7 +14,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): vars.update(self.config['image',]) def do_main_packages(self, packages): - vars = self.changelog_vars + vars = self.vars main = self.templates["control.main"] packages.extend(self.process_packages(main, vars)) @@ -167,11 +167,11 @@ class gencontrol(debian_linux.gencontrol.gencontrol): def process_changelog(self): version = self.changelog[0]['Version'] - self.changelog_vars = self.process_version(version) + self.process_version(version) if version['modifier'] is not None: - self.abiname = self.changelog_vars['abiname'] = '' + self.abiname = self.vars['abiname'] = '' else: - self.abiname = self.changelog_vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] + self.abiname = self.vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] def process_real_image(self, in_entry, depends, vars): entry = self.process_package(in_entry, vars) diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index 0aa30de99..1e8669680 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -31,7 +31,7 @@ class gencontrol(object): def do_source(self, packages): source = self.templates["control.source"] - packages['source'] = self.process_package(source[0], self.changelog_vars) + packages['source'] = self.process_package(source[0], self.vars) def do_main(self, packages, makefile): makeflags = { @@ -45,7 +45,7 @@ class gencontrol(object): 'REVISIONS': ' '.join([i['Version']['debian'] for i in self.changelog[::-1]]), } - vars = self.changelog_vars.copy() + vars = self.vars.copy() self.do_main_setup(vars, makeflags) self.do_main_packages(packages) @@ -246,13 +246,12 @@ class gencontrol(object): def process_version(self, version): self.version = version - vars = { + self.vars = { 'upstreamversion': version['upstream'], 'version': version['version'], 'source_upstream': version['source_upstream'], 'major': version['major'], } - return vars def substitute(self, s, vars): if isinstance(s, (list, tuple)): diff --git a/debian/modules/gencontrol.py b/debian/modules/gencontrol.py index 432f2f129..b2efcb3c3 100755 --- a/debian/modules/gencontrol.py +++ b/debian/modules/gencontrol.py @@ -11,11 +11,10 @@ class gencontrol(debian_linux.gencontrol.gencontrol): def __init__(self, config): super(gencontrol, self).__init__(config) - self.config_version = config_parser({}, [sys.path[0] + "/../version"]) - self.version, self.abiname, self.changelog_vars = self.process_config_version() + self.process_config_version(config_parser({}, [sys.path[0] + "/../version"])) def do_main_packages(self, packages): - vars = self.changelog_vars + vars = self.vars main = self.templates["control.main"] packages.extend(self.process_packages(main, vars)) @@ -53,15 +52,10 @@ class gencontrol(debian_linux.gencontrol.gencontrol): makefile.append(("build-%s-%s-%s-real:" % (arch, subarch, flavour), cmds_build)) makefile.append(("setup-%s-%s-%s-real:" % (arch, subarch, flavour), cmds_setup)) - def process_config_version(self): - # TODO: unify with process_changelog - vars = self.config_version['version',] - version = parse_version(vars['source']) - vars['upstreamversion'] = version['upstream'] - vars['version'] = version['version'] - vars['source_upstream'] = version['source_upstream'] - vars['major'] = version['major'] - return version, vars['abiname'], vars + def process_config_version(self, config): + entry = config['version',] + self.process_version(parse_version(entry['source'])) + self.vars['abiname'] = self.abiname = entry['abiname'] if __name__ == '__main__': gencontrol(sys.path[0] + "/../arch")() From 94d4d84b696376c3ab439de070114dbf63936faf Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 14 Apr 2006 16:56:10 +0000 Subject: [PATCH 045/108] * debian/bin/gencontrol.py, debian/lib/python/debian_linux/gencontrol.py, debian/modules/gencontrol.py: Move handling of revisions to special code. svn path=/dists/trunk/linux-2.6/; revision=6425 --- debian/bin/gencontrol.py | 1 + debian/lib/python/debian_linux/gencontrol.py | 2 -- debian/modules/gencontrol.py | 3 --- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 7a0d401bb..7e2f590b7 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -26,6 +26,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): def do_arch_setup(self, vars, makeflags, arch): vars.update(self.config.get(('image', arch), {})) + makeflags['REVISIONS'] = ' '.join([i['Version']['debian'] for i in self.changelog[::-1]]), def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra): headers_arch = self.templates["control.headers.arch"] diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index 1e8669680..4ea28a25c 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -41,8 +41,6 @@ class gencontrol(object): 'SOURCEVERSION': self.version['source'], 'UPSTREAMVERSION': self.version['upstream'], 'ABINAME': self.abiname, - # TODO: Don't read this here, this is linux-2.6 specific - 'REVISIONS': ' '.join([i['Version']['debian'] for i in self.changelog[::-1]]), } vars = self.vars.copy() diff --git a/debian/modules/gencontrol.py b/debian/modules/gencontrol.py index b2efcb3c3..ab5e776c7 100755 --- a/debian/modules/gencontrol.py +++ b/debian/modules/gencontrol.py @@ -6,9 +6,6 @@ from debian_linux.config import * from debian_linux.debian import * class gencontrol(debian_linux.gencontrol.gencontrol): - # TODO: workaround - changelog = [] - def __init__(self, config): super(gencontrol, self).__init__(config) self.process_config_version(config_parser({}, [sys.path[0] + "/../version"])) From a4be86b472ef3c4764f65a4861d491eda1cff1cc Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 14 Apr 2006 16:59:36 +0000 Subject: [PATCH 046/108] debian/modules/gencontrol.py: Redo build dep generation. svn path=/dists/trunk/linux-2.6/; revision=6426 --- debian/modules/gencontrol.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/debian/modules/gencontrol.py b/debian/modules/gencontrol.py index ab5e776c7..6bec51029 100755 --- a/debian/modules/gencontrol.py +++ b/debian/modules/gencontrol.py @@ -16,11 +16,13 @@ class gencontrol(debian_linux.gencontrol.gencontrol): main = self.templates["control.main"] packages.extend(self.process_packages(main, vars)) - # TODO - l1 = ['linux-support-%s%s' % (self.version['upstream'], self.abiname)] - packages['source']['Build-Depends'].extend(l1) - l = ['linux-headers-%s%s-all-%s [%s]' % (self.version['upstream'], self.abiname, arch, arch) for arch in self.config['base',]['arches']] - packages['source']['Build-Depends'].extend(l) + packages['source']['Build-Depends'].extend( + ['linux-support-%s%s' % (self.version['upstream'], self.abiname)] + ) + packages['source']['Build-Depends'].extend( + ['linux-headers-%s%s-all-%s [%s]' % (self.version['upstream'], self.abiname, arch, arch) + for arch in self.config['base',]['arches']], + ) def do_flavour_packages(self, packages, makefile, arch, subarch, flavour, vars, makeflags, extra): modules = self.templates["control.modules"] From b2b25ed7c8188ea4c047c8d7250a8d68aa7f06ad Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 16 Apr 2006 16:54:04 +0000 Subject: [PATCH 047/108] debian/bin/gencontrol.py: Fix revisions list. svn path=/dists/trunk/linux-2.6/; revision=6433 --- debian/bin/gencontrol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 7e2f590b7..55e1e679d 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -26,7 +26,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): def do_arch_setup(self, vars, makeflags, arch): vars.update(self.config.get(('image', arch), {})) - makeflags['REVISIONS'] = ' '.join([i['Version']['debian'] for i in self.changelog[::-1]]), + makeflags['REVISIONS'] = ' '.join([i['Version']['debian'] for i in self.changelog[::-1]]) def do_arch_packages(self, packages, makefile, arch, vars, makeflags, extra): headers_arch = self.templates["control.headers.arch"] From 8e7fde74f4ee99ebdf8dd31d81e441d4c006b117 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 16 Apr 2006 23:53:58 +0000 Subject: [PATCH 048/108] * debian/arch/amd64/vserver/defines, debian/arch/i386/vserver/defines, debian/arch/powerpc/vserver/defines: Add util-vserver to Recommends. * debian/bin/gencontrol.py: Fix dependency generation of image packages. * debian/lib/python/debian_linux/debian.py - Make type checks in relation classes more strict. - Support checking of each entry against the config. svn path=/dists/trunk/linux-2.6/; revision=6434 --- debian/arch/amd64/vserver/defines | 3 + debian/arch/i386/vserver/defines | 5 +- debian/arch/powerpc/vserver/defines | 3 + debian/bin/gencontrol.py | 17 ++--- debian/lib/python/debian_linux/debian.py | 88 ++++++++++++++++-------- 5 files changed, 79 insertions(+), 37 deletions(-) diff --git a/debian/arch/amd64/vserver/defines b/debian/arch/amd64/vserver/defines index 6bcede465..180936fc4 100644 --- a/debian/arch/amd64/vserver/defines +++ b/debian/arch/amd64/vserver/defines @@ -3,6 +3,9 @@ flavours: amd64-k8 em64t-p4 +[image] +recommends: util-vserver + [amd64-k8] class: AMD64 K8 longclass: 64bit AMD Athlon64, AthlonFX, Opteron and Turion64 diff --git a/debian/arch/i386/vserver/defines b/debian/arch/i386/vserver/defines index 2843ce0df..b779db83f 100644 --- a/debian/arch/i386/vserver/defines +++ b/debian/arch/i386/vserver/defines @@ -3,13 +3,14 @@ flavours: 686 k7 +[image] +recommends: util-vserver, libc6-i686 + [686] class: PPro/Celeron/PII/PIII/P4 longclass: Pentium Pro/Celeron/Pentium II/Pentium III/Pentium 4 -recommends: libc6-i686 [k7] class: AMD K7 longclass: 32bit AMD Duron/Athlon/AthlonXP -recommends: libc6-i686 diff --git a/debian/arch/powerpc/vserver/defines b/debian/arch/powerpc/vserver/defines index 489172848..59b128772 100644 --- a/debian/arch/powerpc/vserver/defines +++ b/debian/arch/powerpc/vserver/defines @@ -3,6 +3,9 @@ flavours: powerpc powerpc64 +[image] +recommends: util-vserver + [powerpc] depends: mkvmlinuz (>= 18) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 55e1e679d..e64312a74 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -111,16 +111,16 @@ class gencontrol(debian_linux.gencontrol.gencontrol): image_latest = self.templates["control.image.latest"] headers_latest = self.templates["control.headers.latest"] + config_entry_relations = self.config.merge('relations', arch, subarch, flavour) + image_depends = package_relation_list() if vars.get('initramfs', True): generators = vars['initramfs-generators'] config_entry_commands_initramfs = self.config.merge('commands-image-initramfs-generators', arch, subarch, flavour) - config_entry_relations = self.config.merge('relations', arch, subarch, flavour) commands = [config_entry_commands_initramfs[i] for i in generators if config_entry_commands_initramfs.has_key(i)] makeflags['INITRD_CMD'] = ' '.join(commands) l = package_relation_group() - l.extend([package_relation(config_entry_relations[i]) for i in generators]) - l.append(package_relation(config_entry_relations['initramfs-fallback'])) + l.extend(generators + ['initramfs-fallback']) image_depends.append(l) packages_own = [] @@ -133,8 +133,8 @@ class gencontrol(debian_linux.gencontrol.gencontrol): else: image = image_type_modulesinline - packages_own.append(self.process_real_image(image[0], image_depends, vars)) - packages_own.extend(self.process_packages(image[1:], vars)) + for i in image: + packages_own.append(self.process_real_image(i, {'depends': image_depends}, config_entry_relations, vars)) packages_dummy.extend(self.process_packages(image_latest, vars)) if image in (image_type_modulesextra, image_type_modulesinline): @@ -174,7 +174,7 @@ class gencontrol(debian_linux.gencontrol.gencontrol): else: self.abiname = self.vars['abiname'] = '-%s' % self.config['abiname',]['abiname'] - def process_real_image(self, in_entry, depends, vars): + def process_real_image(self, in_entry, relations, config, vars): entry = self.process_package(in_entry, vars) if vars.has_key('desc'): entry['Description'].long[1:1] = [vars['desc']] @@ -182,8 +182,9 @@ class gencontrol(debian_linux.gencontrol.gencontrol): value = entry.get(field, package_relation_list()) t = vars.get(field.lower(), []) value.extend(t) - if depends and field == 'Depends': - value.append(depends) + t = relations.get(field.lower(), []) + value.extend(t) + value.config(config) entry[field] = value return entry diff --git a/debian/lib/python/debian_linux/debian.py b/debian/lib/python/debian_linux/debian.py index 9e41e0c83..ce1e287b9 100644 --- a/debian/lib/python/debian_linux/debian.py +++ b/debian/lib/python/debian_linux/debian.py @@ -107,16 +107,7 @@ class package_relation(object): def __init__(self, value = None): if value is not None: - match = self._re.match(value) - if match is None: - raise RuntimeError, "Can't parse dependency %s" % value - match = match.groups() - self.name = match[0] - self.version = match[1] - if match[2] is not None: - self.arches = re.split('\s+', match[2]) - else: - self.arches = [] + self.parse(value) else: self.name = None self.version = None @@ -130,11 +121,29 @@ class package_relation(object): ret.extend([' [', ' '.join(self.arches), ']']) return ''.join(ret) + def config(self, entry): + if self.version is not None or self.arches: + return + value = entry.get(self.name, None) + if value is None: + return + self.parse(value) + + def parse(self, value): + match = self._re.match(value) + if match is None: + raise RuntimeError, "Can't parse dependency %s" % value + match = match.groups() + self.name = match[0] + self.version = match[1] + if match[2] is not None: + self.arches = re.split('\s+', match[2]) + else: + self.arches = [] + class package_relation_list(list): def __init__(self, value = None): - if isinstance(value, (list, tuple)): - self.extend(value) - elif value is not None: + if value is not None: self.extend(value) def __str__(self): @@ -146,31 +155,37 @@ class package_relation_list(list): return i return None + def append(self, value): + if isinstance(value, basestring): + value = package_relation_group(value) + elif not isinstance(value, package_relation_group): + raise ValueError, "got %s" % type(value) + j = self._match(value) + if j: + j._update_arches(value) + else: + super(package_relation_list, self).append(value) + + def config(self, entry): + for i in self: + i.config(entry) + def extend(self, value): if isinstance(value, basestring): - value = [package_relation_group(j.strip()) for j in re.split(',', value.strip())] + value = [j.strip() for j in re.split(',', value.strip())] + elif not isinstance(value, (list, tuple)): + raise ValueError, "got %s" % type(value) for i in value: - if isinstance(i, basestring): - i = package_relation_group(i) - j = self._match(i) - if j: - j._update_arches(i) - else: - self.append(i) + self.append(i) class package_relation_group(list): def __init__(self, value = None): - if isinstance(value, package_relation_list): + if value is not None: self.extend(value) - elif value is not None: - self._extend(value) def __str__(self): return ' | '.join([str(i) for i in self]) - def _extend(self, value): - self.extend([package_relation(j.strip()) for j in re.split('\|', value.strip())]) - def _match(self, value): for i, j in itertools.izip(self, value): if i.name != j.name or i.version != j.version: @@ -184,6 +199,25 @@ class package_relation_group(list): if arch not in i.arches: i.arches.append(arch) + def append(self, value): + if isinstance(value, basestring): + value = package_relation(value) + elif not isinstance(value, package_relation): + raise ValueError + super(package_relation_group, self).append(value) + + def config(self, entry): + for i in self: + i.config(entry) + + def extend(self, value): + if isinstance(value, basestring): + value = [j.strip() for j in re.split('\|', value.strip())] + elif not isinstance(value, (list, tuple)): + raise ValueError + for i in value: + self.append(i) + class package(dict): _fields = utils.sorted_dict(( ('Package', str), From 416228d3e4ad948aed1af87ed252a6159659d933 Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Tue, 18 Apr 2006 00:13:02 +0000 Subject: [PATCH 049/108] disable b0rked lsm modules svn path=/dists/trunk/linux-2.6/; revision=6439 --- debian/arch/arm/config.footbridge | 2 -- debian/arch/arm/config.ixp4xx | 1 - debian/arch/arm/config.nslu2 | 2 -- debian/arch/arm/config.rpc | 1 - debian/arch/arm/config.s3c2410 | 1 - debian/arch/armeb/config.nslu2 | 2 -- debian/arch/config | 4 ++-- debian/arch/mips/config.r4k-ip22 | 1 - debian/arch/mips/config.r5k-ip32 | 1 - debian/arch/mips/config.sb1-bcm91250a | 2 -- debian/arch/mips/config.sb1a-bcm91480b | 2 -- debian/arch/mipsel/config.r5k-cobalt | 2 -- debian/arch/mipsel/config.sb1-bcm91250a | 2 -- debian/arch/mipsel/config.sb1a-bcm91480b | 2 -- debian/changelog | 7 ++++++- 15 files changed, 8 insertions(+), 24 deletions(-) diff --git a/debian/arch/arm/config.footbridge b/debian/arch/arm/config.footbridge index 87a0f530b..8bfbe72d4 100644 --- a/debian/arch/arm/config.footbridge +++ b/debian/arch/arm/config.footbridge @@ -1487,8 +1487,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/arm/config.ixp4xx b/debian/arch/arm/config.ixp4xx index e049e26ab..528f35a2a 100644 --- a/debian/arch/arm/config.ixp4xx +++ b/debian/arch/arm/config.ixp4xx @@ -1251,7 +1251,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/arm/config.nslu2 b/debian/arch/arm/config.nslu2 index fdf5c0d1b..03752d8eb 100644 --- a/debian/arch/arm/config.nslu2 +++ b/debian/arch/arm/config.nslu2 @@ -1486,8 +1486,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/arm/config.rpc b/debian/arch/arm/config.rpc index f0bb08ef7..5376b1ce4 100644 --- a/debian/arch/arm/config.rpc +++ b/debian/arch/arm/config.rpc @@ -973,7 +973,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/arm/config.s3c2410 b/debian/arch/arm/config.s3c2410 index 8101bb9ac..91059209b 100644 --- a/debian/arch/arm/config.s3c2410 +++ b/debian/arch/arm/config.s3c2410 @@ -1037,7 +1037,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/armeb/config.nslu2 b/debian/arch/armeb/config.nslu2 index 7e84de814..a5472eb97 100644 --- a/debian/arch/armeb/config.nslu2 +++ b/debian/arch/armeb/config.nslu2 @@ -1486,8 +1486,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/config b/debian/arch/config index ae0e97fe7..faa83db76 100644 --- a/debian/arch/config +++ b/debian/arch/config @@ -318,8 +318,8 @@ CONFIG_KEYS=y # CONFIG_KEYS_DEBUG_PROC_KEYS is not set CONFIG_SECURITY=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m +# CONFIG_SECURITY_ROOTPLUG is not set +# CONFIG_SECURITY_SECLVL is not set CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/mips/config.r4k-ip22 b/debian/arch/mips/config.r4k-ip22 index d12fd04e4..cd8b9c869 100644 --- a/debian/arch/mips/config.r4k-ip22 +++ b/debian/arch/mips/config.r4k-ip22 @@ -1341,7 +1341,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/mips/config.r5k-ip32 b/debian/arch/mips/config.r5k-ip32 index 4bc55ed4a..cb08a8a69 100644 --- a/debian/arch/mips/config.r5k-ip32 +++ b/debian/arch/mips/config.r5k-ip32 @@ -1461,7 +1461,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/mips/config.sb1-bcm91250a b/debian/arch/mips/config.sb1-bcm91250a index ea3567c88..f9ade0304 100644 --- a/debian/arch/mips/config.sb1-bcm91250a +++ b/debian/arch/mips/config.sb1-bcm91250a @@ -1794,8 +1794,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/mips/config.sb1a-bcm91480b b/debian/arch/mips/config.sb1a-bcm91480b index 15badc17d..973b5d03c 100644 --- a/debian/arch/mips/config.sb1a-bcm91480b +++ b/debian/arch/mips/config.sb1a-bcm91480b @@ -1794,8 +1794,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/mipsel/config.r5k-cobalt b/debian/arch/mipsel/config.r5k-cobalt index b722a7654..809f8840b 100644 --- a/debian/arch/mipsel/config.r5k-cobalt +++ b/debian/arch/mipsel/config.r5k-cobalt @@ -1574,8 +1574,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/mipsel/config.sb1-bcm91250a b/debian/arch/mipsel/config.sb1-bcm91250a index 18f182a74..32cbb63e5 100644 --- a/debian/arch/mipsel/config.sb1-bcm91250a +++ b/debian/arch/mipsel/config.sb1-bcm91250a @@ -1794,8 +1794,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/arch/mipsel/config.sb1a-bcm91480b b/debian/arch/mipsel/config.sb1a-bcm91480b index ac228384c..47c644a67 100644 --- a/debian/arch/mipsel/config.sb1a-bcm91480b +++ b/debian/arch/mipsel/config.sb1a-bcm91480b @@ -1794,8 +1794,6 @@ CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_CAPABILITIES=y -CONFIG_SECURITY_ROOTPLUG=m -CONFIG_SECURITY_SECLVL=m CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 diff --git a/debian/changelog b/debian/changelog index 3f8f1b297..8098d35f8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,13 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low + [ Bastian Blank ] * - -- Bastian Blank Fri, 14 Apr 2006 17:52:48 +0200 + [ maximilian attems ] + * Disable broken and known unsecure LSM modules: CONFIG_SECURITY_SECLVL, + CONFIG_SECURITY_ROOTPLUG. Upstream plans to remove them for 2.6.18 + + -- maximilian attems Tue, 18 Apr 2006 02:09:27 +0200 linux-2.6 (2.6.16-7) UNRELEASED; urgency=low From eb9e0c5274fa69d24201376d231ca2806ccc88e3 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 21 Apr 2006 18:01:23 +0000 Subject: [PATCH 050/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6472 --- debian/arch/powerpc/defines | 8 +- debian/arch/powerpc/vserver/defines | 2 +- debian/changelog | 49 +- debian/patches/2.6.16.6 | 1753 +++++++++++++++++ debian/patches/2.6.16.7 | 14 + debian/patches/2.6.16.8 | 16 + debian/patches/2.6.16.9 | 178 ++ .../include-linux-seccomp-abifix.patch | 18 + debian/patches/series/8 | 3 + debian/patches/series/9 | 2 + debian/patches/series/9-extra | 1 + .../patches/vserver-vs2.0.2-rc17-update.patch | 75 + 12 files changed, 2112 insertions(+), 7 deletions(-) create mode 100644 debian/patches/2.6.16.6 create mode 100644 debian/patches/2.6.16.7 create mode 100644 debian/patches/2.6.16.8 create mode 100644 debian/patches/2.6.16.9 create mode 100644 debian/patches/include-linux-seccomp-abifix.patch create mode 100644 debian/patches/series/8 create mode 100644 debian/patches/series/9 create mode 100644 debian/patches/series/9-extra create mode 100644 debian/patches/vserver-vs2.0.2-rc17-update.patch diff --git a/debian/arch/powerpc/defines b/debian/arch/powerpc/defines index 1db4d721d..be2c30f24 100644 --- a/debian/arch/powerpc/defines +++ b/debian/arch/powerpc/defines @@ -11,16 +11,16 @@ subarches: vserver [apus] -depends: mkvmlinuz (>= 19) +depends: mkvmlinuz (>= 20) [powerpc] -depends: mkvmlinuz (>= 19) +depends: mkvmlinuz (>= 20) [powerpc-smp] -depends: mkvmlinuz (>= 19) +depends: mkvmlinuz (>= 20) [powerpc-miboot] -depends: mkvmlinuz (>= 19) +depends: mkvmlinuz (>= 20) [powerpc64] kpkg-subarch: powerpc64 diff --git a/debian/arch/powerpc/vserver/defines b/debian/arch/powerpc/vserver/defines index 59b128772..350150641 100644 --- a/debian/arch/powerpc/vserver/defines +++ b/debian/arch/powerpc/vserver/defines @@ -7,7 +7,7 @@ flavours: recommends: util-vserver [powerpc] -depends: mkvmlinuz (>= 18) +depends: mkvmlinuz (>= 20) [powerpc64] kpkg-subarch: powerpc64 diff --git a/debian/changelog b/debian/changelog index 8098d35f8..48956e236 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,7 +9,52 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- maximilian attems Tue, 18 Apr 2006 02:09:27 +0200 -linux-2.6 (2.6.16-7) UNRELEASED; urgency=low +linux-2.6 (2.6.16-9) unstable; urgency=low + + [ maximilian attems ] + * Add stable release 2.6.16.8: + - ip_route_input panic fix (CVE-2006-1525) + * Add stable release 2.6.16.9: + - i386/x86-64: Fix x87 information leak between processes (CVE-2006-1056) + + [ Bastian Blank ] + * Update vserver patch to 2.0.2-rc17. + + -- Bastian Blank Thu, 20 Apr 2006 15:37:28 +0200 + +linux-2.6 (2.6.16-8) unstable; urgency=low + + * Fix ABI-breakage introduced in -7. (closes: #363032) + * Add stable release 2.6.16.6: + - ext3: Fix missed mutex unlock + - RLIMIT_CPU: fix handling of a zero limit + - alpha: SMP boot fixes + - m32r: security fix of {get, put}_user macros + - m32r: Fix cpu_possible_map and cpu_present_map initialization for SMP kernel + - shmat: stop mprotect from giving write permission to a readonly attachment (CVE-2006-1524) + - powerpc: fix incorrect SA_ONSTACK behaviour for 64-bit processes + - MPBL0010 driver sysfs permissions wide open + - cciss: bug fix for crash when running hpacucli + - fuse: fix oops in fuse_send_readpages() + - Fix utime(2) in the case that no times parameter was passed in. + - Fix buddy list race that could lead to page lru list corruptions + - NETFILTER: Fix fragmentation issues with bridge netfilter + - USB: remove __init from usb_console_setup + - Fix suspend with traced tasks + - isd200: limit to BLK_DEV_IDE + - edac_752x needs CONFIG_HOTPLUG + - fix non-leader exec under ptrace + - sky2: bad memory reference on dual port cards + - atm: clip causes unregister hang + - powerpc: iSeries needs slb_initialize to be called + - Fix block device symlink name + - Incorrect signature sent on SMB Read + * Add stable release 2.6.16.7: + - fix MADV_REMOVE vulnerability (CVE-2006-1524 for real this time) + + -- Bastian Blank Tue, 18 Apr 2006 16:22:31 +0200 + +linux-2.6 (2.6.16-7) unstable; urgency=low [ Frederik Schüler ] * Add stable release 2.6.16.3: @@ -33,7 +78,7 @@ linux-2.6 (2.6.16-7) UNRELEASED; urgency=low [ Christian T. Steigies ] * [m68k] update m68k patch and config to 2.6.16, temporarily disable atari - -- maximilian attems Thu, 13 Apr 2006 11:16:42 +0200 + -- Bastian Blank Sat, 15 Apr 2006 13:56:05 +0200 linux-2.6 (2.6.16-6) unstable; urgency=medium diff --git a/debian/patches/2.6.16.6 b/debian/patches/2.6.16.6 new file mode 100644 index 000000000..87748bdbe --- /dev/null +++ b/debian/patches/2.6.16.6 @@ -0,0 +1,1753 @@ +diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c +index b4e5f8f..45308bd 100644 +--- a/arch/alpha/kernel/setup.c ++++ b/arch/alpha/kernel/setup.c +@@ -24,6 +24,7 @@ + #include /* CONFIG_ALPHA_LCA etc */ + #include + #include ++#include + #include + #include + #include +@@ -477,6 +478,22 @@ page_is_ram(unsigned long pfn) + #undef PFN_PHYS + #undef PFN_MAX + ++static int __init ++register_cpus(void) ++{ ++ int i; ++ ++ for_each_possible_cpu(i) { ++ struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); ++ if (!p) ++ return -ENOMEM; ++ register_cpu(p, i, NULL); ++ } ++ return 0; ++} ++ ++arch_initcall(register_cpus); ++ + void __init + setup_arch(char **cmdline_p) + { +diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c +index 02c2db0..1852554 100644 +--- a/arch/alpha/kernel/smp.c ++++ b/arch/alpha/kernel/smp.c +@@ -439,7 +439,7 @@ setup_smp(void) + if ((cpu->flags & 0x1cc) == 0x1cc) { + smp_num_probed++; + /* Assume here that "whami" == index */ +- cpu_set(i, cpu_possible_map); ++ cpu_set(i, cpu_present_mask); + cpu->pal_revision = boot_cpu_palrev; + } + +@@ -450,9 +450,8 @@ setup_smp(void) + } + } else { + smp_num_probed = 1; +- cpu_set(boot_cpuid, cpu_possible_map); ++ cpu_set(boot_cpuid, cpu_present_mask); + } +- cpu_present_mask = cpumask_of_cpu(boot_cpuid); + + printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", + smp_num_probed, cpu_possible_map.bits[0]); +@@ -488,9 +487,8 @@ void __devinit + smp_prepare_boot_cpu(void) + { + /* +- * Mark the boot cpu (current cpu) as both present and online ++ * Mark the boot cpu (current cpu) as online + */ +- cpu_set(smp_processor_id(), cpu_present_mask); + cpu_set(smp_processor_id(), cpu_online_map); + } + +diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c +index be8b711..6000950 100644 +--- a/arch/m32r/kernel/m32r_ksyms.c ++++ b/arch/m32r/kernel/m32r_ksyms.c +@@ -38,10 +38,6 @@ EXPORT_SYMBOL(__udelay); + EXPORT_SYMBOL(__delay); + EXPORT_SYMBOL(__const_udelay); + +-EXPORT_SYMBOL(__get_user_1); +-EXPORT_SYMBOL(__get_user_2); +-EXPORT_SYMBOL(__get_user_4); +- + EXPORT_SYMBOL(strpbrk); + EXPORT_SYMBOL(strstr); + +diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c +index d742037..542ed93 100644 +--- a/arch/m32r/kernel/setup.c ++++ b/arch/m32r/kernel/setup.c +@@ -9,6 +9,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -218,8 +219,6 @@ static unsigned long __init setup_memory + extern unsigned long setup_memory(void); + #endif /* CONFIG_DISCONTIGMEM */ + +-#define M32R_PCC_PCATCR 0x00ef7014 /* will move to m32r.h */ +- + void __init setup_arch(char **cmdline_p) + { + ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); +@@ -268,15 +267,14 @@ void __init setup_arch(char **cmdline_p) + paging_init(); + } + +-static struct cpu cpu[NR_CPUS]; ++static struct cpu cpu_devices[NR_CPUS]; + + static int __init topology_init(void) + { +- int cpu_id; ++ int i; + +- for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++) +- if (cpu_possible(cpu_id)) +- register_cpu(&cpu[cpu_id], cpu_id, NULL); ++ for_each_present_cpu(i) ++ register_cpu(&cpu_devices[i], i, NULL); + + return 0; + } +diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c +index d7ec16e..840b434 100644 +--- a/arch/m32r/kernel/smpboot.c ++++ b/arch/m32r/kernel/smpboot.c +@@ -39,8 +39,10 @@ + * Martin J. Bligh : Added support for multi-quad systems + */ + ++#include + #include + #include ++#include + #include + #include + #include +@@ -72,11 +74,15 @@ physid_mask_t phys_cpu_present_map; + + /* Bitmask of currently online CPUs */ + cpumask_t cpu_online_map; ++EXPORT_SYMBOL(cpu_online_map); + + cpumask_t cpu_bootout_map; + cpumask_t cpu_bootin_map; +-cpumask_t cpu_callout_map; + static cpumask_t cpu_callin_map; ++cpumask_t cpu_callout_map; ++EXPORT_SYMBOL(cpu_callout_map); ++cpumask_t cpu_possible_map = CPU_MASK_ALL; ++EXPORT_SYMBOL(cpu_possible_map); + + /* Per CPU bogomips and other parameters */ + struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned; +@@ -110,7 +116,6 @@ static unsigned int calibration_result; + + void smp_prepare_boot_cpu(void); + void smp_prepare_cpus(unsigned int); +-static void smp_tune_scheduling(void); + static void init_ipi_lock(void); + static void do_boot_cpu(int); + int __cpu_up(unsigned int); +@@ -177,6 +182,9 @@ void __init smp_prepare_cpus(unsigned in + } + for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++) + physid_set(phys_id, phys_cpu_present_map); ++#ifndef CONFIG_HOTPLUG_CPU ++ cpu_present_map = cpu_possible_map; ++#endif + + show_mp_info(nr_cpu); + +@@ -186,7 +194,6 @@ void __init smp_prepare_cpus(unsigned in + * Setup boot CPU information + */ + smp_store_cpu_info(0); /* Final full version of the data */ +- smp_tune_scheduling(); + + /* + * If SMP should be disabled, then really disable it! +@@ -230,11 +237,6 @@ smp_done: + Dprintk("Boot done.\n"); + } + +-static void __init smp_tune_scheduling(void) +-{ +- /* Nothing to do. */ +-} +- + /* + * init_ipi_lock : Initialize IPI locks. + */ +@@ -629,4 +631,3 @@ static void __init unmap_cpu_to_physid(i + physid_2_cpu[phys_id] = -1; + cpu_2_physid[cpu_id] = -1; + } +- +diff --git a/arch/m32r/lib/Makefile b/arch/m32r/lib/Makefile +index e632d10..d16b4e4 100644 +--- a/arch/m32r/lib/Makefile ++++ b/arch/m32r/lib/Makefile +@@ -2,6 +2,6 @@ + # Makefile for M32R-specific library files.. + # + +-lib-y := checksum.o ashxdi3.o memset.o memcpy.o getuser.o \ +- putuser.o delay.o strlen.o usercopy.o csum_partial_copy.o ++lib-y := checksum.o ashxdi3.o memset.o memcpy.o \ ++ delay.o strlen.o usercopy.o csum_partial_copy.o + +diff --git a/arch/m32r/lib/getuser.S b/arch/m32r/lib/getuser.S +deleted file mode 100644 +index 58a0db0..0000000 +--- a/arch/m32r/lib/getuser.S ++++ /dev/null +@@ -1,88 +0,0 @@ +-/* +- * __get_user functions. +- * +- * (C) Copyright 2001 Hirokazu Takata +- * +- * These functions have a non-standard call interface +- * to make them more efficient, especially as they +- * return an error value in addition to the "real" +- * return value. +- */ +- +-#include +- +-/* +- * __get_user_X +- * +- * Inputs: r0 contains the address +- * +- * Outputs: r0 is error code (0 or -EFAULT) +- * r1 contains zero-extended value +- * +- * These functions should not modify any other registers, +- * as they get called from within inline assembly. +- */ +- +-#ifdef CONFIG_ISA_DUAL_ISSUE +- +- .text +- .balign 4 +- .globl __get_user_1 +-__get_user_1: +-1: ldub r1, @r0 || ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __get_user_2 +-__get_user_2: +-2: lduh r1, @r0 || ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __get_user_4 +-__get_user_4: +-3: ld r1, @r0 || ldi r0, #0 +- jmp r14 +- +-bad_get_user: +- ldi r1, #0 || ldi r0, #-14 +- jmp r14 +- +-#else /* not CONFIG_ISA_DUAL_ISSUE */ +- +- .text +- .balign 4 +- .globl __get_user_1 +-__get_user_1: +-1: ldub r1, @r0 +- ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __get_user_2 +-__get_user_2: +-2: lduh r1, @r0 +- ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __get_user_4 +-__get_user_4: +-3: ld r1, @r0 +- ldi r0, #0 +- jmp r14 +- +-bad_get_user: +- ldi r1, #0 +- ldi r0, #-14 +- jmp r14 +- +-#endif /* not CONFIG_ISA_DUAL_ISSUE */ +- +-.section __ex_table,"a" +- .long 1b,bad_get_user +- .long 2b,bad_get_user +- .long 3b,bad_get_user +-.previous +- +- .end +diff --git a/arch/m32r/lib/putuser.S b/arch/m32r/lib/putuser.S +deleted file mode 100644 +index 218154c..0000000 +--- a/arch/m32r/lib/putuser.S ++++ /dev/null +@@ -1,84 +0,0 @@ +-/* +- * __put_user functions. +- * +- * (C) Copyright 1998 Linus Torvalds +- * (C) Copyright 2001 Hirokazu Takata +- * +- * These functions have a non-standard call interface +- * to make them more efficient. +- */ +- +-#include +- +-/* +- * __put_user_X +- * +- * Inputs: r0 contains the address +- * r1 contains the value +- * +- * Outputs: r0 is error code (0 or -EFAULT) +- * r1 is corrupted (will contain "current_task"). +- * +- * These functions should not modify any other registers, +- * as they get called from within inline assembly. +- */ +- +-#ifdef CONFIG_ISA_DUAL_ISSUE +- +- .text +- .balign 4 +- .globl __put_user_1 +-__put_user_1: +-1: stb r1, @r0 || ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __put_user_2 +-__put_user_2: +-2: sth r1, @r0 || ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __put_user_4 +-__put_user_4: +-3: st r1, @r0 || ldi r0, #0 +- jmp r14 +- +-bad_put_user: +- ldi r0, #-14 || jmp r14 +- +-#else /* not CONFIG_ISA_DUAL_ISSUE */ +- +- .text +- .balign 4 +- .globl __put_user_1 +-__put_user_1: +-1: stb r1, @r0 +- ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __put_user_2 +-__put_user_2: +-2: sth r1, @r0 +- ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __put_user_4 +-__put_user_4: +-3: st r1, @r0 +- ldi r0, #0 +- jmp r14 +- +-bad_put_user: +- ldi r0, #-14 +- jmp r14 +- +-#endif /* not CONFIG_ISA_DUAL_ISSUE */ +- +-.section __ex_table,"a" +- .long 1b,bad_put_user +- .long 2b,bad_put_user +- .long 3b,bad_put_user +-.previous +diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c +index f96c49b..abd758f 100644 +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -256,12 +256,10 @@ void __init early_setup(unsigned long dt + /* + * Initialize stab / SLB management except on iSeries + */ +- if (!firmware_has_feature(FW_FEATURE_ISERIES)) { +- if (cpu_has_feature(CPU_FTR_SLB)) +- slb_initialize(); +- else +- stab_initialize(lpaca->stab_real); +- } ++ if (cpu_has_feature(CPU_FTR_SLB)) ++ slb_initialize(); ++ else if (!firmware_has_feature(FW_FEATURE_ISERIES)) ++ stab_initialize(lpaca->stab_real); + + DBG(" <- early_setup()\n"); + } +diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c +index 4324f8a..096dfdc 100644 +--- a/arch/powerpc/kernel/signal_64.c ++++ b/arch/powerpc/kernel/signal_64.c +@@ -213,7 +213,7 @@ static inline void __user * get_sigframe + /* Default to using normal stack */ + newsp = regs->gpr[1]; + +- if (ka->sa.sa_flags & SA_ONSTACK) { ++ if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) { + if (! on_sig_stack(regs->gpr[1])) + newsp = (current->sas_ss_sp + current->sas_ss_size); + } +diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c +index c149d57..71552e1 100644 +--- a/drivers/block/cciss.c ++++ b/drivers/block/cciss.c +@@ -1181,6 +1181,53 @@ static int revalidate_allvol(ctlr_info_t + return 0; + } + ++static inline void complete_buffers(struct bio *bio, int status) ++{ ++ while (bio) { ++ struct bio *xbh = bio->bi_next; ++ int nr_sectors = bio_sectors(bio); ++ ++ bio->bi_next = NULL; ++ blk_finished_io(len); ++ bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); ++ bio = xbh; ++ } ++ ++} ++ ++static void cciss_softirq_done(struct request *rq) ++{ ++ CommandList_struct *cmd = rq->completion_data; ++ ctlr_info_t *h = hba[cmd->ctlr]; ++ unsigned long flags; ++ u64bit temp64; ++ int i, ddir; ++ ++ if (cmd->Request.Type.Direction == XFER_READ) ++ ddir = PCI_DMA_FROMDEVICE; ++ else ++ ddir = PCI_DMA_TODEVICE; ++ ++ /* command did not need to be retried */ ++ /* unmap the DMA mapping for all the scatter gather elements */ ++ for(i=0; iHeader.SGList; i++) { ++ temp64.val32.lower = cmd->SG[i].Addr.lower; ++ temp64.val32.upper = cmd->SG[i].Addr.upper; ++ pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); ++ } ++ ++ complete_buffers(rq->bio, rq->errors); ++ ++#ifdef CCISS_DEBUG ++ printk("Done with %p\n", rq); ++#endif /* CCISS_DEBUG */ ++ ++ spin_lock_irqsave(&h->lock, flags); ++ end_that_request_last(rq, rq->errors); ++ cmd_free(h, cmd,1); ++ spin_unlock_irqrestore(&h->lock, flags); ++} ++ + /* This function will check the usage_count of the drive to be updated/added. + * If the usage_count is zero then the drive information will be updated and + * the disk will be re-registered with the kernel. If not then it will be +@@ -1249,6 +1296,8 @@ static void cciss_update_drive_info(int + + blk_queue_max_sectors(disk->queue, 512); + ++ blk_queue_softirq_done(disk->queue, cciss_softirq_done); ++ + disk->queue->queuedata = hba[ctlr]; + + blk_queue_hardsect_size(disk->queue, +@@ -2148,20 +2197,6 @@ static void start_io( ctlr_info_t *h) + addQ (&(h->cmpQ), c); + } + } +- +-static inline void complete_buffers(struct bio *bio, int status) +-{ +- while (bio) { +- struct bio *xbh = bio->bi_next; +- int nr_sectors = bio_sectors(bio); +- +- bio->bi_next = NULL; +- blk_finished_io(len); +- bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); +- bio = xbh; +- } +- +-} + /* Assumes that CCISS_LOCK(h->ctlr) is held. */ + /* Zeros out the error record and then resends the command back */ + /* to the controller */ +@@ -2179,39 +2214,6 @@ static inline void resend_cciss_cmd( ctl + start_io(h); + } + +-static void cciss_softirq_done(struct request *rq) +-{ +- CommandList_struct *cmd = rq->completion_data; +- ctlr_info_t *h = hba[cmd->ctlr]; +- unsigned long flags; +- u64bit temp64; +- int i, ddir; +- +- if (cmd->Request.Type.Direction == XFER_READ) +- ddir = PCI_DMA_FROMDEVICE; +- else +- ddir = PCI_DMA_TODEVICE; +- +- /* command did not need to be retried */ +- /* unmap the DMA mapping for all the scatter gather elements */ +- for(i=0; iHeader.SGList; i++) { +- temp64.val32.lower = cmd->SG[i].Addr.lower; +- temp64.val32.upper = cmd->SG[i].Addr.upper; +- pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); +- } +- +- complete_buffers(rq->bio, rq->errors); +- +-#ifdef CCISS_DEBUG +- printk("Done with %p\n", rq); +-#endif /* CCISS_DEBUG */ +- +- spin_lock_irqsave(&h->lock, flags); +- end_that_request_last(rq, rq->errors); +- cmd_free(h, cmd,1); +- spin_unlock_irqrestore(&h->lock, flags); +-} +- + /* checks the status of the job and calls complete buffers to mark all + * buffers for the completed job. Note that this function does not need + * to hold the hba/queue lock. +diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c +index 2546637..f58ad7f 100644 +--- a/drivers/char/tlclk.c ++++ b/drivers/char/tlclk.c +@@ -327,7 +327,7 @@ static ssize_t store_received_ref_clk3a( + return strnlen(buf, count); + } + +-static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL, ++static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL, + store_received_ref_clk3a); + + +@@ -349,7 +349,7 @@ static ssize_t store_received_ref_clk3b( + return strnlen(buf, count); + } + +-static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL, ++static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL, + store_received_ref_clk3b); + + +@@ -371,7 +371,7 @@ static ssize_t store_enable_clk3b_output + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clk3b_output); + + static ssize_t store_enable_clk3a_output(struct device *d, +@@ -392,7 +392,7 @@ static ssize_t store_enable_clk3a_output + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clk3a_output); + + static ssize_t store_enable_clkb1_output(struct device *d, +@@ -413,7 +413,7 @@ static ssize_t store_enable_clkb1_output + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clkb1_output); + + +@@ -435,7 +435,7 @@ static ssize_t store_enable_clka1_output + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clka1_output); + + static ssize_t store_enable_clkb0_output(struct device *d, +@@ -456,7 +456,7 @@ static ssize_t store_enable_clkb0_output + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clkb0_output); + + static ssize_t store_enable_clka0_output(struct device *d, +@@ -477,7 +477,7 @@ static ssize_t store_enable_clka0_output + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clka0_output); + + static ssize_t store_select_amcb2_transmit_clock(struct device *d, +@@ -519,7 +519,7 @@ static ssize_t store_select_amcb2_transm + return strnlen(buf, count); + } + +-static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL, ++static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL, + store_select_amcb2_transmit_clock); + + static ssize_t store_select_amcb1_transmit_clock(struct device *d, +@@ -560,7 +560,7 @@ static ssize_t store_select_amcb1_transm + return strnlen(buf, count); + } + +-static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL, ++static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL, + store_select_amcb1_transmit_clock); + + static ssize_t store_select_redundant_clock(struct device *d, +@@ -581,7 +581,7 @@ static ssize_t store_select_redundant_cl + return strnlen(buf, count); + } + +-static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL, ++static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL, + store_select_redundant_clock); + + static ssize_t store_select_ref_frequency(struct device *d, +@@ -602,7 +602,7 @@ static ssize_t store_select_ref_frequenc + return strnlen(buf, count); + } + +-static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL, ++static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL, + store_select_ref_frequency); + + static ssize_t store_filter_select(struct device *d, +@@ -623,7 +623,7 @@ static ssize_t store_filter_select(struc + return strnlen(buf, count); + } + +-static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select); ++static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select); + + static ssize_t store_hardware_switching_mode(struct device *d, + struct device_attribute *attr, const char *buf, size_t count) +@@ -643,7 +643,7 @@ static ssize_t store_hardware_switching_ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL, ++static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL, + store_hardware_switching_mode); + + static ssize_t store_hardware_switching(struct device *d, +@@ -664,7 +664,7 @@ static ssize_t store_hardware_switching( + return strnlen(buf, count); + } + +-static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL, ++static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL, + store_hardware_switching); + + static ssize_t store_refalign (struct device *d, +@@ -684,7 +684,7 @@ static ssize_t store_refalign (struct de + return strnlen(buf, count); + } + +-static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign); ++static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign); + + static ssize_t store_mode_select (struct device *d, + struct device_attribute *attr, const char *buf, size_t count) +@@ -704,7 +704,7 @@ static ssize_t store_mode_select (struct + return strnlen(buf, count); + } + +-static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select); ++static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select); + + static ssize_t store_reset (struct device *d, + struct device_attribute *attr, const char *buf, size_t count) +@@ -724,7 +724,7 @@ static ssize_t store_reset (struct devic + return strnlen(buf, count); + } + +-static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset); ++static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset); + + static struct attribute *tlclk_sysfs_entries[] = { + &dev_attr_current_ref.attr, +diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig +index 52f3eb4..7ecdb1e 100644 +--- a/drivers/edac/Kconfig ++++ b/drivers/edac/Kconfig +@@ -71,7 +71,7 @@ config EDAC_E7XXX + + config EDAC_E752X + tristate "Intel e752x (e7520, e7525, e7320)" +- depends on EDAC_MM_EDAC && PCI ++ depends on EDAC_MM_EDAC && PCI && HOTPLUG + help + Support for error detection and correction on the Intel + E7520, E7525, E7320 server chipsets. +diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c +index 7326036..0618cd5 100644 +--- a/drivers/net/sky2.c ++++ b/drivers/net/sky2.c +@@ -579,8 +579,8 @@ static void sky2_mac_init(struct sky2_hw + reg = gma_read16(hw, port, GM_PHY_ADDR); + gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); + +- for (i = 0; i < GM_MIB_CNT_SIZE; i++) +- gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i); ++ for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4) ++ gma_read16(hw, port, i); + gma_write16(hw, port, GM_PHY_ADDR, reg); + + /* transmit control */ +diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h +index dce955c..c91e0a4 100644 +--- a/drivers/net/sky2.h ++++ b/drivers/net/sky2.h +@@ -1380,6 +1380,7 @@ enum { + /* MIB Counters */ + #define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */ + #define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */ ++#define GM_MIB_CNT_END 0x025C /* Last MIB counter */ + + /* + * MIB Counters base address definitions (low word) - +diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c +index 167f8ec..8023bb7 100644 +--- a/drivers/usb/serial/console.c ++++ b/drivers/usb/serial/console.c +@@ -54,7 +54,7 @@ static struct console usbcons; + * serial.c code, except that the specifier is "ttyUSB" instead + * of "ttyS". + */ +-static int __init usb_console_setup(struct console *co, char *options) ++static int usb_console_setup(struct console *co, char *options) + { + struct usbcons_info *info = &usbcons_info; + int baud = 9600; +diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig +index 92be101..be9eec2 100644 +--- a/drivers/usb/storage/Kconfig ++++ b/drivers/usb/storage/Kconfig +@@ -48,7 +48,8 @@ config USB_STORAGE_FREECOM + + config USB_STORAGE_ISD200 + bool "ISD-200 USB/ATA Bridge support" +- depends on USB_STORAGE && BLK_DEV_IDE ++ depends on USB_STORAGE ++ depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE + ---help--- + Say Y here if you want to use USB Mass Store devices based + on the In-Systems Design ISD-200 USB/ATA bridge. +diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c +index a2c2485..3f5e38c 100644 +--- a/fs/cifs/cifsencrypt.c ++++ b/fs/cifs/cifsencrypt.c +@@ -56,9 +56,6 @@ int cifs_sign_smb(struct smb_hdr * cifs_ + int rc = 0; + char smb_signature[20]; + +- /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */ +- /* BB remember to add code to save expected sequence number in midQ entry BB */ +- + if((cifs_pdu == NULL) || (server == NULL)) + return -EINVAL; + +@@ -85,20 +82,33 @@ int cifs_sign_smb(struct smb_hdr * cifs_ + static int cifs_calc_signature2(const struct kvec * iov, int n_vec, + const char * key, char * signature) + { +- struct MD5Context context; +- +- if((iov == NULL) || (signature == NULL)) +- return -EINVAL; ++ struct MD5Context context; ++ int i; + +- MD5Init(&context); +- MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); ++ if((iov == NULL) || (signature == NULL)) ++ return -EINVAL; + +-/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */ ++ MD5Init(&context); ++ MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); ++ for(i=0;is_blocks_count)) { + ext3_warning(sb, __FUNCTION__, + "multiple resizers run on filesystem!"); ++ unlock_super(sb); + err = -EBUSY; + goto exit_put; + } +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index 6f05379..ce93cf9 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -397,8 +397,12 @@ static int fuse_readpages(struct file *f + return -EINTR; + + err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); +- if (!err) +- fuse_send_readpages(data.req, file, inode); ++ if (!err) { ++ if (data.req->num_pages) ++ fuse_send_readpages(data.req, file, inode); ++ else ++ fuse_put_request(fc, data.req); ++ } + return err; + } + +diff --git a/fs/partitions/check.c b/fs/partitions/check.c +index f924f45..2ef03aa 100644 +--- a/fs/partitions/check.c ++++ b/fs/partitions/check.c +@@ -345,6 +345,7 @@ static char *make_block_name(struct gend + char *name; + static char *block_str = "block:"; + int size; ++ char *s; + + size = strlen(block_str) + strlen(disk->disk_name) + 1; + name = kmalloc(size, GFP_KERNEL); +@@ -352,6 +353,10 @@ static char *make_block_name(struct gend + return NULL; + strcpy(name, block_str); + strcat(name, disk->disk_name); ++ /* ewww... some of these buggers have / in name... */ ++ s = strchr(name, '/'); ++ if (s) ++ *s = '!'; + return name; + } + +diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c +index d7f6f2d..43808e2 100644 +--- a/fs/xfs/linux-2.6/xfs_iops.c ++++ b/fs/xfs/linux-2.6/xfs_iops.c +@@ -673,8 +673,7 @@ linvfs_setattr( + if (ia_valid & ATTR_ATIME) { + vattr.va_mask |= XFS_AT_ATIME; + vattr.va_atime = attr->ia_atime; +- if (ia_valid & ATTR_ATIME_SET) +- inode->i_atime = attr->ia_atime; ++ inode->i_atime = attr->ia_atime; + } + if (ia_valid & ATTR_MTIME) { + vattr.va_mask |= XFS_AT_MTIME; +diff --git a/include/asm-m32r/smp.h b/include/asm-m32r/smp.h +index 7885b7d..1184293 100644 +--- a/include/asm-m32r/smp.h ++++ b/include/asm-m32r/smp.h +@@ -67,7 +67,8 @@ extern volatile int cpu_2_physid[NR_CPUS + #define raw_smp_processor_id() (current_thread_info()->cpu) + + extern cpumask_t cpu_callout_map; +-#define cpu_possible_map cpu_callout_map ++extern cpumask_t cpu_possible_map; ++extern cpumask_t cpu_present_map; + + static __inline__ int hard_smp_processor_id(void) + { +diff --git a/include/asm-m32r/uaccess.h b/include/asm-m32r/uaccess.h +index e8ae619..819cc28 100644 +--- a/include/asm-m32r/uaccess.h ++++ b/include/asm-m32r/uaccess.h +@@ -5,17 +5,9 @@ + * linux/include/asm-m32r/uaccess.h + * + * M32R version. +- * Copyright (C) 2004 Hirokazu Takata ++ * Copyright (C) 2004, 2006 Hirokazu Takata + */ + +-#undef UACCESS_DEBUG +- +-#ifdef UACCESS_DEBUG +-#define UAPRINTK(args...) printk(args) +-#else +-#define UAPRINTK(args...) +-#endif /* UACCESS_DEBUG */ +- + /* + * User space memory access functions + */ +@@ -38,27 +30,29 @@ + #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + + #ifdef CONFIG_MMU ++ + #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) + #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) +-#else +-#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) +-#define USER_DS MAKE_MM_SEG(0xFFFFFFFF) +-#endif /* CONFIG_MMU */ +- + #define get_ds() (KERNEL_DS) +-#ifdef CONFIG_MMU + #define get_fs() (current_thread_info()->addr_limit) + #define set_fs(x) (current_thread_info()->addr_limit = (x)) +-#else ++ ++#else /* not CONFIG_MMU */ ++ ++#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) ++#define USER_DS MAKE_MM_SEG(0xFFFFFFFF) ++#define get_ds() (KERNEL_DS) ++ + static inline mm_segment_t get_fs(void) + { +- return USER_DS; ++ return USER_DS; + } + + static inline void set_fs(mm_segment_t s) + { + } +-#endif /* CONFIG_MMU */ ++ ++#endif /* not CONFIG_MMU */ + + #define segment_eq(a,b) ((a).seg == (b).seg) + +@@ -83,9 +77,9 @@ static inline void set_fs(mm_segment_t s + " subx %0, %0\n" \ + " cmpu %4, %1\n" \ + " subx %0, %5\n" \ +- : "=&r"(flag), "=r"(sum) \ +- : "1"(addr), "r"((int)(size)), \ +- "r"(current_thread_info()->addr_limit.seg), "r"(0) \ ++ : "=&r" (flag), "=r" (sum) \ ++ : "1" (addr), "r" ((int)(size)), \ ++ "r" (current_thread_info()->addr_limit.seg), "r" (0) \ + : "cbit" ); \ + flag; }) + +@@ -113,10 +107,10 @@ static inline void set_fs(mm_segment_t s + #else + static inline int access_ok(int type, const void *addr, unsigned long size) + { +- extern unsigned long memory_start, memory_end; +- unsigned long val = (unsigned long)addr; ++ extern unsigned long memory_start, memory_end; ++ unsigned long val = (unsigned long)addr; + +- return ((val >= memory_start) && ((val + size) < memory_end)); ++ return ((val >= memory_start) && ((val + size) < memory_end)); + } + #endif /* CONFIG_MMU */ + +@@ -155,39 +149,6 @@ extern int fixup_exception(struct pt_reg + * accesses to the same area of user memory). + */ + +-extern void __get_user_1(void); +-extern void __get_user_2(void); +-extern void __get_user_4(void); +- +-#ifndef MODULE +-#define __get_user_x(size,ret,x,ptr) \ +- __asm__ __volatile__( \ +- " mv r0, %0\n" \ +- " mv r1, %1\n" \ +- " bl __get_user_" #size "\n" \ +- " mv %0, r0\n" \ +- " mv %1, r1\n" \ +- : "=r"(ret), "=r"(x) \ +- : "0"(ptr) \ +- : "r0", "r1", "r14" ) +-#else /* MODULE */ +-/* +- * Use "jl" instead of "bl" for MODULE +- */ +-#define __get_user_x(size,ret,x,ptr) \ +- __asm__ __volatile__( \ +- " mv r0, %0\n" \ +- " mv r1, %1\n" \ +- " seth lr, #high(__get_user_" #size ")\n" \ +- " or3 lr, lr, #low(__get_user_" #size ")\n" \ +- " jl lr\n" \ +- " mv %0, r0\n" \ +- " mv %1, r1\n" \ +- : "=r"(ret), "=r"(x) \ +- : "0"(ptr) \ +- : "r0", "r1", "r14" ) +-#endif +- + /* Careful: we have to cast the result to the type of the pointer for sign + reasons */ + /** +@@ -208,20 +169,7 @@ extern void __get_user_4(void); + * On error, the variable @x is set to zero. + */ + #define get_user(x,ptr) \ +-({ int __ret_gu; \ +- unsigned long __val_gu; \ +- __chk_user_ptr(ptr); \ +- switch(sizeof (*(ptr))) { \ +- case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ +- case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ +- case 4: __get_user_x(4,__ret_gu,__val_gu,ptr); break; \ +- default: __get_user_x(X,__ret_gu,__val_gu,ptr); break; \ +- } \ +- (x) = (__typeof__(*(ptr)))__val_gu; \ +- __ret_gu; \ +-}) +- +-extern void __put_user_bad(void); ++ __get_user_check((x),(ptr),sizeof(*(ptr))) + + /** + * put_user: - Write a simple value into user space. +@@ -240,8 +188,7 @@ extern void __put_user_bad(void); + * Returns zero on success, or -EFAULT on error. + */ + #define put_user(x,ptr) \ +- __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) +- ++ __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + + /** + * __get_user: - Get a simple variable from user space, with less checking. +@@ -264,8 +211,64 @@ extern void __put_user_bad(void); + * On error, the variable @x is set to zero. + */ + #define __get_user(x,ptr) \ +- __get_user_nocheck((x),(ptr),sizeof(*(ptr))) ++ __get_user_nocheck((x),(ptr),sizeof(*(ptr))) + ++#define __get_user_nocheck(x,ptr,size) \ ++({ \ ++ long __gu_err = 0; \ ++ unsigned long __gu_val; \ ++ might_sleep(); \ ++ __get_user_size(__gu_val,(ptr),(size),__gu_err); \ ++ (x) = (__typeof__(*(ptr)))__gu_val; \ ++ __gu_err; \ ++}) ++ ++#define __get_user_check(x,ptr,size) \ ++({ \ ++ long __gu_err = -EFAULT; \ ++ unsigned long __gu_val = 0; \ ++ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ ++ might_sleep(); \ ++ if (access_ok(VERIFY_READ,__gu_addr,size)) \ ++ __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \ ++ (x) = (__typeof__(*(ptr)))__gu_val; \ ++ __gu_err; \ ++}) ++ ++extern long __get_user_bad(void); ++ ++#define __get_user_size(x,ptr,size,retval) \ ++do { \ ++ retval = 0; \ ++ __chk_user_ptr(ptr); \ ++ switch (size) { \ ++ case 1: __get_user_asm(x,ptr,retval,"ub"); break; \ ++ case 2: __get_user_asm(x,ptr,retval,"uh"); break; \ ++ case 4: __get_user_asm(x,ptr,retval,""); break; \ ++ default: (x) = __get_user_bad(); \ ++ } \ ++} while (0) ++ ++#define __get_user_asm(x, addr, err, itype) \ ++ __asm__ __volatile__( \ ++ " .fillinsn\n" \ ++ "1: ld"itype" %1,@%2\n" \ ++ " .fillinsn\n" \ ++ "2:\n" \ ++ ".section .fixup,\"ax\"\n" \ ++ " .balign 4\n" \ ++ "3: ldi %0,%3\n" \ ++ " seth r14,#high(2b)\n" \ ++ " or3 r14,r14,#low(2b)\n" \ ++ " jmp r14\n" \ ++ ".previous\n" \ ++ ".section __ex_table,\"a\"\n" \ ++ " .balign 4\n" \ ++ " .long 1b,3b\n" \ ++ ".previous" \ ++ : "=&r" (err), "=&r" (x) \ ++ : "r" (addr), "i" (-EFAULT), "0" (err) \ ++ : "r14", "memory") + + /** + * __put_user: - Write a simple value into user space, with less checking. +@@ -287,11 +290,13 @@ extern void __put_user_bad(void); + * Returns zero on success, or -EFAULT on error. + */ + #define __put_user(x,ptr) \ +- __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) ++ __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) ++ + + #define __put_user_nocheck(x,ptr,size) \ + ({ \ + long __pu_err; \ ++ might_sleep(); \ + __put_user_size((x),(ptr),(size),__pu_err); \ + __pu_err; \ + }) +@@ -308,28 +313,28 @@ extern void __put_user_bad(void); + }) + + #if defined(__LITTLE_ENDIAN__) +-#define __put_user_u64(x, addr, err) \ +- __asm__ __volatile__( \ +- " .fillinsn\n" \ +- "1: st %L1,@%2\n" \ +- " .fillinsn\n" \ +- "2: st %H1,@(4,%2)\n" \ +- " .fillinsn\n" \ +- "3:\n" \ +- ".section .fixup,\"ax\"\n" \ +- " .balign 4\n" \ +- "4: ldi %0,%3\n" \ +- " seth r14,#high(3b)\n" \ +- " or3 r14,r14,#low(3b)\n" \ +- " jmp r14\n" \ +- ".previous\n" \ +- ".section __ex_table,\"a\"\n" \ +- " .balign 4\n" \ +- " .long 1b,4b\n" \ +- " .long 2b,4b\n" \ +- ".previous" \ +- : "=&r"(err) \ +- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ ++#define __put_user_u64(x, addr, err) \ ++ __asm__ __volatile__( \ ++ " .fillinsn\n" \ ++ "1: st %L1,@%2\n" \ ++ " .fillinsn\n" \ ++ "2: st %H1,@(4,%2)\n" \ ++ " .fillinsn\n" \ ++ "3:\n" \ ++ ".section .fixup,\"ax\"\n" \ ++ " .balign 4\n" \ ++ "4: ldi %0,%3\n" \ ++ " seth r14,#high(3b)\n" \ ++ " or3 r14,r14,#low(3b)\n" \ ++ " jmp r14\n" \ ++ ".previous\n" \ ++ ".section __ex_table,\"a\"\n" \ ++ " .balign 4\n" \ ++ " .long 1b,4b\n" \ ++ " .long 2b,4b\n" \ ++ ".previous" \ ++ : "=&r" (err) \ ++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ + : "r14", "memory") + + #elif defined(__BIG_ENDIAN__) +@@ -353,13 +358,15 @@ extern void __put_user_bad(void); + " .long 1b,4b\n" \ + " .long 2b,4b\n" \ + ".previous" \ +- : "=&r"(err) \ +- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ ++ : "=&r" (err) \ ++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ + : "r14", "memory") + #else + #error no endian defined + #endif + ++extern void __put_user_bad(void); ++ + #define __put_user_size(x,ptr,size,retval) \ + do { \ + retval = 0; \ +@@ -398,52 +405,8 @@ struct __large_struct { unsigned long bu + " .balign 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ +- : "=&r"(err) \ +- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ +- : "r14", "memory") +- +-#define __get_user_nocheck(x,ptr,size) \ +-({ \ +- long __gu_err; \ +- unsigned long __gu_val; \ +- __get_user_size(__gu_val,(ptr),(size),__gu_err); \ +- (x) = (__typeof__(*(ptr)))__gu_val; \ +- __gu_err; \ +-}) +- +-extern long __get_user_bad(void); +- +-#define __get_user_size(x,ptr,size,retval) \ +-do { \ +- retval = 0; \ +- __chk_user_ptr(ptr); \ +- switch (size) { \ +- case 1: __get_user_asm(x,ptr,retval,"ub"); break; \ +- case 2: __get_user_asm(x,ptr,retval,"uh"); break; \ +- case 4: __get_user_asm(x,ptr,retval,""); break; \ +- default: (x) = __get_user_bad(); \ +- } \ +-} while (0) +- +-#define __get_user_asm(x, addr, err, itype) \ +- __asm__ __volatile__( \ +- " .fillinsn\n" \ +- "1: ld"itype" %1,@%2\n" \ +- " .fillinsn\n" \ +- "2:\n" \ +- ".section .fixup,\"ax\"\n" \ +- " .balign 4\n" \ +- "3: ldi %0,%3\n" \ +- " seth r14,#high(2b)\n" \ +- " or3 r14,r14,#low(2b)\n" \ +- " jmp r14\n" \ +- ".previous\n" \ +- ".section __ex_table,\"a\"\n" \ +- " .balign 4\n" \ +- " .long 1b,3b\n" \ +- ".previous" \ +- : "=&r"(err), "=&r"(x) \ +- : "r"(addr), "i"(-EFAULT), "0"(err) \ ++ : "=&r" (err) \ ++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ + : "r14", "memory") + + /* +@@ -453,7 +416,6 @@ do { \ + * anything, so this is accurate. + */ + +- + /* + * Copy To/From Userspace + */ +@@ -511,8 +473,9 @@ do { \ + " .long 2b,9b\n" \ + " .long 3b,9b\n" \ + ".previous\n" \ +- : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \ +- : "0"(to), "1"(from), "2"(size), "3"(size / 4) \ ++ : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ ++ "=&r" (__c) \ ++ : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ + : "r14", "memory"); \ + } while (0) + +@@ -573,8 +536,9 @@ do { \ + " .long 2b,7b\n" \ + " .long 3b,7b\n" \ + ".previous\n" \ +- : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \ +- : "0"(to), "1"(from), "2"(size), "3"(size / 4) \ ++ : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ ++ "=&r" (__c) \ ++ : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ + : "r14", "memory"); \ + } while (0) + +@@ -676,7 +640,7 @@ unsigned long __generic_copy_from_user(v + #define copy_from_user(to,from,n) \ + ({ \ + might_sleep(); \ +-__generic_copy_from_user((to),(from),(n)); \ ++ __generic_copy_from_user((to),(from),(n)); \ + }) + + long __must_check strncpy_from_user(char *dst, const char __user *src, +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 498ff87..279446e 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -229,10 +229,9 @@ struct page { + unsigned long private; /* Mapping-private opaque data: + * usually used for buffer_heads + * if PagePrivate set; used for +- * swp_entry_t if PageSwapCache. +- * When page is free, this ++ * swp_entry_t if PageSwapCache; + * indicates order in the buddy +- * system. ++ * system if PG_buddy is set. + */ + struct address_space *mapping; /* If low bit clear, points to + * inode address_space, or NULL. +diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h +index d52999c..d7ce72e 100644 +--- a/include/linux/page-flags.h ++++ b/include/linux/page-flags.h +@@ -74,7 +74,9 @@ + #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */ + #define PG_reclaim 17 /* To be reclaimed asap */ + #define PG_nosave_free 18 /* Free, should not be written */ +-#define PG_uncached 19 /* Page has been mapped as uncached */ ++#define PG_buddy 19 /* Page is free, on buddy lists */ ++ ++#define PG_uncached 20 /* Page has been mapped as uncached */ + + /* + * Global page accounting. One instance per CPU. Only unsigned longs are +@@ -319,6 +321,10 @@ extern void __mod_page_state_offset(unsi + #define SetPageNosaveFree(page) set_bit(PG_nosave_free, &(page)->flags) + #define ClearPageNosaveFree(page) clear_bit(PG_nosave_free, &(page)->flags) + ++#define PageBuddy(page) test_bit(PG_buddy, &(page)->flags) ++#define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags) ++#define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags) ++ + #define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags) + #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags) + #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags) +diff --git a/include/net/ip.h b/include/net/ip.h +index fab3d5b..ed84d04 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -95,6 +95,7 @@ extern int ip_local_deliver(struct sk_b + extern int ip_mr_input(struct sk_buff *skb); + extern int ip_output(struct sk_buff *skb); + extern int ip_mc_output(struct sk_buff *skb); ++extern int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); + extern int ip_do_nat(struct sk_buff *skb); + extern void ip_send_check(struct iphdr *ip); + extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); +diff --git a/ipc/shm.c b/ipc/shm.c +index 9162123..f409726 100644 +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -161,6 +161,8 @@ static int shm_mmap(struct file * file, + ret = shmem_mmap(file, vma); + if (ret == 0) { + vma->vm_ops = &shm_vm_ops; ++ if (!(vma->vm_flags & VM_WRITE)) ++ vma->vm_flags &= ~VM_MAYWRITE; + shm_inc(file->f_dentry->d_inode->i_ino); + } + +diff --git a/kernel/power/process.c b/kernel/power/process.c +index 28de118..67b2cdd 100644 +--- a/kernel/power/process.c ++++ b/kernel/power/process.c +@@ -25,8 +25,7 @@ static inline int freezeable(struct task + (p->flags & PF_NOFREEZE) || + (p->exit_state == EXIT_ZOMBIE) || + (p->exit_state == EXIT_DEAD) || +- (p->state == TASK_STOPPED) || +- (p->state == TASK_TRACED)) ++ (p->state == TASK_STOPPED)) + return 0; + return 1; + } +diff --git a/kernel/ptrace.c b/kernel/ptrace.c +index d95a72c..b5eaeb9 100644 +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -57,10 +57,6 @@ void ptrace_untrace(task_t *child) + signal_wake_up(child, 1); + } + } +- if (child->signal->flags & SIGNAL_GROUP_EXIT) { +- sigaddset(&child->pending.signal, SIGKILL); +- signal_wake_up(child, 1); +- } + spin_unlock(&child->sighand->siglock); + } + +@@ -82,7 +78,8 @@ void __ptrace_unlink(task_t *child) + SET_LINKS(child); + } + +- ptrace_untrace(child); ++ if (child->state == TASK_TRACED) ++ ptrace_untrace(child); + } + + /* +diff --git a/kernel/signal.c b/kernel/signal.c +index bc8f80b..acbccf7 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -1688,6 +1688,7 @@ static void ptrace_stop(int exit_code, i + /* Let the debugger run. */ + set_current_state(TASK_TRACED); + spin_unlock_irq(¤t->sighand->siglock); ++ try_to_freeze(); + read_lock(&tasklist_lock); + if (likely(current->ptrace & PT_PTRACED) && + likely(current->parent != current->real_parent || +@@ -1941,9 +1942,9 @@ relock: + /* Let the debugger run. */ + ptrace_stop(signr, signr, info); + +- /* We're back. Did the debugger cancel the sig or group_exit? */ ++ /* We're back. Did the debugger cancel the sig? */ + signr = current->exit_code; +- if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT) ++ if (signr == 0) + continue; + + current->exit_code = 0; +diff --git a/kernel/sys.c b/kernel/sys.c +index f91218a..105e102 100644 +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -1657,7 +1657,19 @@ asmlinkage long sys_setrlimit(unsigned i + (cputime_eq(current->signal->it_prof_expires, cputime_zero) || + new_rlim.rlim_cur <= cputime_to_secs( + current->signal->it_prof_expires))) { +- cputime_t cputime = secs_to_cputime(new_rlim.rlim_cur); ++ unsigned long rlim_cur = new_rlim.rlim_cur; ++ cputime_t cputime; ++ ++ if (rlim_cur == 0) { ++ /* ++ * The caller is asking for an immediate RLIMIT_CPU ++ * expiry. But we use the zero value to mean "it was ++ * never set". So let's cheat and make it one second ++ * instead ++ */ ++ rlim_cur = 1; ++ } ++ cputime = secs_to_cputime(rlim_cur); + read_lock(&tasklist_lock); + spin_lock_irq(¤t->sighand->siglock); + set_process_cpu_timer(current, CPUCLOCK_PROF, +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 234bd48..61de222 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -153,7 +153,8 @@ static void bad_page(struct page *page) + 1 << PG_reclaim | + 1 << PG_slab | + 1 << PG_swapcache | +- 1 << PG_writeback ); ++ 1 << PG_writeback | ++ 1 << PG_buddy ); + set_page_count(page, 0); + reset_page_mapcount(page); + page->mapping = NULL; +@@ -224,12 +225,12 @@ static inline unsigned long page_order(s + + static inline void set_page_order(struct page *page, int order) { + set_page_private(page, order); +- __SetPagePrivate(page); ++ __SetPageBuddy(page); + } + + static inline void rmv_page_order(struct page *page) + { +- __ClearPagePrivate(page); ++ __ClearPageBuddy(page); + set_page_private(page, 0); + } + +@@ -268,11 +269,13 @@ __find_combined_index(unsigned long page + * This function checks whether a page is free && is the buddy + * we can do coalesce a page and its buddy if + * (a) the buddy is not in a hole && +- * (b) the buddy is free && +- * (c) the buddy is on the buddy system && +- * (d) a page and its buddy have the same order. +- * for recording page's order, we use page_private(page) and PG_private. ++ * (b) the buddy is in the buddy system && ++ * (c) a page and its buddy have the same order. ++ * ++ * For recording whether a page is in the buddy system, we use PG_buddy. ++ * Setting, clearing, and testing PG_buddy is serialized by zone->lock. + * ++ * For recording page's order, we use page_private(page). + */ + static inline int page_is_buddy(struct page *page, int order) + { +@@ -281,10 +284,10 @@ static inline int page_is_buddy(struct p + return 0; + #endif + +- if (PagePrivate(page) && +- (page_order(page) == order) && +- page_count(page) == 0) ++ if (PageBuddy(page) && page_order(page) == order) { ++ BUG_ON(page_count(page) != 0); + return 1; ++ } + return 0; + } + +@@ -301,7 +304,7 @@ static inline int page_is_buddy(struct p + * as necessary, plus some accounting needed to play nicely with other + * parts of the VM system. + * At each level, we keep a list of pages, which are heads of continuous +- * free pages of length of (1 << order) and marked with PG_Private.Page's ++ * free pages of length of (1 << order) and marked with PG_buddy. Page's + * order is recorded in page_private(page) field. + * So when we are allocating or freeing one, we can derive the state of the + * other. That is, if we allocate a small block, and both were +@@ -364,7 +367,8 @@ static inline int free_pages_check(struc + 1 << PG_slab | + 1 << PG_swapcache | + 1 << PG_writeback | +- 1 << PG_reserved )))) ++ 1 << PG_reserved | ++ 1 << PG_buddy )))) + bad_page(page); + if (PageDirty(page)) + __ClearPageDirty(page); +@@ -522,7 +526,8 @@ static int prep_new_page(struct page *pa + 1 << PG_slab | + 1 << PG_swapcache | + 1 << PG_writeback | +- 1 << PG_reserved )))) ++ 1 << PG_reserved | ++ 1 << PG_buddy )))) + bad_page(page); + + /* +diff --git a/net/atm/clip.c b/net/atm/clip.c +index 73370de..1842a4e 100644 +--- a/net/atm/clip.c ++++ b/net/atm/clip.c +@@ -613,12 +613,19 @@ static int clip_create(int number) + + + static int clip_device_event(struct notifier_block *this,unsigned long event, +- void *dev) ++ void *arg) + { ++ struct net_device *dev = arg; ++ ++ if (event == NETDEV_UNREGISTER) { ++ neigh_ifdown(&clip_tbl, dev); ++ return NOTIFY_DONE; ++ } ++ + /* ignore non-CLIP devices */ +- if (((struct net_device *) dev)->type != ARPHRD_ATM || +- ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit) ++ if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit) + return NOTIFY_DONE; ++ + switch (event) { + case NETDEV_UP: + DPRINTK("clip_device_event NETDEV_UP\n"); +@@ -686,14 +693,12 @@ static struct notifier_block clip_inet_n + static void atmarpd_close(struct atm_vcc *vcc) + { + DPRINTK("atmarpd_close\n"); +- atmarpd = NULL; /* assumed to be atomic */ +- barrier(); +- unregister_inetaddr_notifier(&clip_inet_notifier); +- unregister_netdevice_notifier(&clip_dev_notifier); +- if (skb_peek(&sk_atm(vcc)->sk_receive_queue)) +- printk(KERN_ERR "atmarpd_close: closing with requests " +- "pending\n"); ++ ++ rtnl_lock(); ++ atmarpd = NULL; + skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); ++ rtnl_unlock(); ++ + DPRINTK("(done)\n"); + module_put(THIS_MODULE); + } +@@ -714,7 +719,12 @@ static struct atm_dev atmarpd_dev = { + + static int atm_init_atmarp(struct atm_vcc *vcc) + { +- if (atmarpd) return -EADDRINUSE; ++ rtnl_lock(); ++ if (atmarpd) { ++ rtnl_unlock(); ++ return -EADDRINUSE; ++ } ++ + if (start_timer) { + start_timer = 0; + init_timer(&idle_timer); +@@ -731,10 +741,7 @@ static int atm_init_atmarp(struct atm_vc + vcc->push = NULL; + vcc->pop = NULL; /* crash */ + vcc->push_oam = NULL; /* crash */ +- if (register_netdevice_notifier(&clip_dev_notifier)) +- printk(KERN_ERR "register_netdevice_notifier failed\n"); +- if (register_inetaddr_notifier(&clip_inet_notifier)) +- printk(KERN_ERR "register_inetaddr_notifier failed\n"); ++ rtnl_unlock(); + return 0; + } + +@@ -992,6 +999,8 @@ static int __init atm_clip_init(void) + + clip_tbl_hook = &clip_tbl; + register_atm_ioctl(&clip_ioctl_ops); ++ register_netdevice_notifier(&clip_dev_notifier); ++ register_inetaddr_notifier(&clip_inet_notifier); + + #ifdef CONFIG_PROC_FS + { +@@ -1012,6 +1021,9 @@ static void __exit atm_clip_exit(void) + + remove_proc_entry("arp", atm_proc_root); + ++ unregister_inetaddr_notifier(&clip_inet_notifier); ++ unregister_netdevice_notifier(&clip_dev_notifier); ++ + deregister_atm_ioctl(&clip_ioctl_ops); + + /* First, stop the idle timer, so it stops banging +diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c +index e060aad..9e27373 100644 +--- a/net/bridge/br_netfilter.c ++++ b/net/bridge/br_netfilter.c +@@ -739,6 +739,15 @@ out: + return NF_STOLEN; + } + ++static int br_nf_dev_queue_xmit(struct sk_buff *skb) ++{ ++ if (skb->protocol == htons(ETH_P_IP) && ++ skb->len > skb->dev->mtu && ++ !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) ++ return ip_fragment(skb, br_dev_queue_push_xmit); ++ else ++ return br_dev_queue_push_xmit(skb); ++} + + /* PF_BRIDGE/POST_ROUTING ********************************************/ + static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, +@@ -798,7 +807,7 @@ static unsigned int br_nf_post_routing(u + realoutdev = nf_bridge->netoutdev; + #endif + NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, +- br_dev_queue_push_xmit); ++ br_nf_dev_queue_xmit); + + return NF_STOLEN; + +@@ -843,7 +852,7 @@ static unsigned int ip_sabotage_out(unsi + if ((out->hard_start_xmit == br_dev_xmit && + okfn != br_nf_forward_finish && + okfn != br_nf_local_out_finish && +- okfn != br_dev_queue_push_xmit) ++ okfn != br_nf_dev_queue_xmit) + #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + || ((out->priv_flags & IFF_802_1Q_VLAN) && + VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index f75ff1d..8dcba38 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -86,8 +86,6 @@ + + int sysctl_ip_default_ttl = IPDEFTTL; + +-static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)); +- + /* Generate a checksum for an outgoing IP datagram. */ + __inline__ void ip_send_check(struct iphdr *iph) + { +@@ -421,7 +419,7 @@ static void ip_copy_metadata(struct sk_b + * single device frame, and queue such a frame for sending. + */ + +-static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) ++int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) + { + struct iphdr *iph; + int raw = 0; +@@ -673,6 +671,8 @@ fail: + return err; + } + ++EXPORT_SYMBOL(ip_fragment); ++ + int + ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) + { +- +To unsubscribe from this list: send the line "unsubscribe linux-kernel" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html +Please read the FAQ at http://www.tux.org/lkml/ + diff --git a/debian/patches/2.6.16.7 b/debian/patches/2.6.16.7 new file mode 100644 index 000000000..ad5a9d841 --- /dev/null +++ b/debian/patches/2.6.16.7 @@ -0,0 +1,14 @@ +diff --git a/mm/madvise.c b/mm/madvise.c +index af3d573..4e19615 100644 +--- a/mm/madvise.c ++++ b/mm/madvise.c +@@ -168,6 +168,9 @@ static long madvise_remove(struct vm_are + return -EINVAL; + } + ++ if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)) ++ return -EACCES; ++ + mapping = vma->vm_file->f_mapping; + + offset = (loff_t)(start - vma->vm_start) diff --git a/debian/patches/2.6.16.8 b/debian/patches/2.6.16.8 new file mode 100644 index 000000000..f662a1cfb --- /dev/null +++ b/debian/patches/2.6.16.8 @@ -0,0 +1,16 @@ +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index fca5fe0..a67955e 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -2750,7 +2750,10 @@ int inet_rtm_getroute(struct sk_buff *in + /* Reserve room for dummy headers, this skb can pass + through good chunk of routing engine. + */ +- skb->mac.raw = skb->data; ++ skb->mac.raw = skb->nh.raw = skb->data; ++ ++ /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ ++ skb->nh.iph->protocol = IPPROTO_ICMP; + skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); + + if (rta[RTA_SRC - 1]) diff --git a/debian/patches/2.6.16.9 b/debian/patches/2.6.16.9 new file mode 100644 index 000000000..890811d99 --- /dev/null +++ b/debian/patches/2.6.16.9 @@ -0,0 +1,178 @@ +diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c +index 0810f81..d2d50cb 100644 +--- a/arch/i386/kernel/cpu/amd.c ++++ b/arch/i386/kernel/cpu/amd.c +@@ -207,6 +207,8 @@ #define CBAR_KEY (0X000000CB) + set_bit(X86_FEATURE_K7, c->x86_capability); + break; + } ++ if (c->x86 >= 6) ++ set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability); + + display_cacheinfo(c); + +diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c +index 22a05de..818ab9e 100644 +--- a/arch/x86_64/kernel/process.c ++++ b/arch/x86_64/kernel/process.c +@@ -527,8 +527,6 @@ __switch_to(struct task_struct *prev_p, + int cpu = smp_processor_id(); + struct tss_struct *tss = &per_cpu(init_tss, cpu); + +- unlazy_fpu(prev_p); +- + /* + * Reload esp0, LDT and the page table pointer: + */ +@@ -591,6 +589,12 @@ __switch_to(struct task_struct *prev_p, + prev->userrsp = read_pda(oldrsp); + write_pda(oldrsp, next->userrsp); + write_pda(pcurrent, next_p); ++ ++ /* This must be here to ensure both math_state_restore() and ++ kernel_fpu_begin() work consistently. ++ And the AMD workaround requires it to be after DS reload. */ ++ unlazy_fpu(prev_p); ++ + write_pda(kernelstack, + task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); + +diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c +index aa55e3c..a4a0bb5 100644 +--- a/arch/x86_64/kernel/setup.c ++++ b/arch/x86_64/kernel/setup.c +@@ -909,6 +909,10 @@ #endif + if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) + set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); + ++ /* Enable workaround for FXSAVE leak */ ++ if (c->x86 >= 6) ++ set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability); ++ + r = get_model_name(c); + if (!r) { + switch (c->x86) { +diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h +index c4ec2a4..9d15eec 100644 +--- a/include/asm-i386/cpufeature.h ++++ b/include/asm-i386/cpufeature.h +@@ -70,6 +70,7 @@ #define X86_FEATURE_K7 (3*32+ 5) /* Ath + #define X86_FEATURE_P3 (3*32+ 6) /* P3 */ + #define X86_FEATURE_P4 (3*32+ 7) /* P4 */ + #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ ++#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ + + /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ + #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ +diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h +index 152d0ba..7b1f011 100644 +--- a/include/asm-i386/i387.h ++++ b/include/asm-i386/i387.h +@@ -13,6 +13,7 @@ #define __ASM_I386_I387_H + + #include + #include ++#include + #include + #include + #include +@@ -38,17 +39,38 @@ #define restore_fpu(tsk) \ + extern void kernel_fpu_begin(void); + #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) + ++/* We need a safe address that is cheap to find and that is already ++ in L1 during context switch. The best choices are unfortunately ++ different for UP and SMP */ ++#ifdef CONFIG_SMP ++#define safe_address (__per_cpu_offset[0]) ++#else ++#define safe_address (kstat_cpu(0).cpustat.user) ++#endif ++ + /* + * These must be called with preempt disabled + */ + static inline void __save_init_fpu( struct task_struct *tsk ) + { ++ /* Use more nops than strictly needed in case the compiler ++ varies code */ + alternative_input( +- "fnsave %1 ; fwait ;" GENERIC_NOP2, +- "fxsave %1 ; fnclex", ++ "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, ++ "fxsave %[fx]\n" ++ "bt $7,%[fsw] ; jc 1f ; fnclex\n1:", + X86_FEATURE_FXSR, +- "m" (tsk->thread.i387.fxsave) +- :"memory"); ++ [fx] "m" (tsk->thread.i387.fxsave), ++ [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); ++ /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception ++ is pending. Clear the x87 state here by setting it to fixed ++ values. __per_cpu_offset[0] is a random variable that should be in L1 */ ++ alternative_input( ++ GENERIC_NOP8 GENERIC_NOP2, ++ "emms\n\t" /* clear stack tags */ ++ "fildl %[addr]", /* set F?P to defined value */ ++ X86_FEATURE_FXSAVE_LEAK, ++ [addr] "m" (safe_address)); + task_thread_info(tsk)->status &= ~TS_USEDFPU; + } + +diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h +index 76bb619..662964b 100644 +--- a/include/asm-x86_64/cpufeature.h ++++ b/include/asm-x86_64/cpufeature.h +@@ -64,6 +64,7 @@ #define X86_FEATURE_CENTAUR_MCR (3*32+ 3 + #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */ + #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */ + #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */ ++#define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */ + + /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ + #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ +diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h +index 876eb9a..cba8a3b 100644 +--- a/include/asm-x86_64/i387.h ++++ b/include/asm-x86_64/i387.h +@@ -72,6 +72,23 @@ #define set_fpu_cwd(t,val) ((t)->thread. + #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val)) + #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val)) + ++#define X87_FSW_ES (1 << 7) /* Exception Summary */ ++ ++/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception ++ is pending. Clear the x87 state here by setting it to fixed ++ values. The kernel data segment can be sometimes 0 and sometimes ++ new user value. Both should be ok. ++ Use the PDA as safe address because it should be already in L1. */ ++static inline void clear_fpu_state(struct i387_fxsave_struct *fx) ++{ ++ if (unlikely(fx->swd & X87_FSW_ES)) ++ asm volatile("fnclex"); ++ alternative_input(ASM_NOP8 ASM_NOP2, ++ " emms\n" /* clear stack tags */ ++ " fildl %%gs:0", /* load to clear state */ ++ X86_FEATURE_FXSAVE_LEAK); ++} ++ + static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) + { + int err; +@@ -119,6 +136,7 @@ #else + #endif + if (unlikely(err)) + __clear_user(fx, sizeof(struct i387_fxsave_struct)); ++ /* No need to clear here because the caller clears USED_MATH */ + return err; + } + +@@ -149,7 +167,7 @@ #else + "i" (offsetof(__typeof__(*tsk), + thread.i387.fxsave))); + #endif +- __asm__ __volatile__("fnclex"); ++ clear_fpu_state(&tsk->thread.i387.fxsave); + } + + static inline void kernel_fpu_begin(void) diff --git a/debian/patches/include-linux-seccomp-abifix.patch b/debian/patches/include-linux-seccomp-abifix.patch new file mode 100644 index 000000000..4c9931063 --- /dev/null +++ b/debian/patches/include-linux-seccomp-abifix.patch @@ -0,0 +1,18 @@ +diff -urN linux-2.6-2.6.16.old/include/linux/seccomp.h linux-2.6-2.6.16/include/linux/seccomp.h +--- linux-2.6-2.6.16.old/include/linux/seccomp.h 2006-03-20 06:53:29.000000000 +0100 ++++ linux-2.6-2.6.16/include/linux/seccomp.h 2006-04-17 12:01:01.000000000 +0200 +@@ -26,9 +26,12 @@ + + #else /* CONFIG_SECCOMP */ + +-typedef struct { } seccomp_t; ++typedef struct { int mode; } seccomp_t; ++ ++static inline void secure_computing(int this_syscall) ++{ ++} + +-#define secure_computing(x) do { } while (0) + /* static inline to preserve typechecking */ + static inline int has_secure_computing(struct thread_info *ti) + { diff --git a/debian/patches/series/8 b/debian/patches/series/8 new file mode 100644 index 000000000..1a661e288 --- /dev/null +++ b/debian/patches/series/8 @@ -0,0 +1,3 @@ ++ include-linux-seccomp-abifix.patch ++ 2.6.16.6 ++ 2.6.16.7 diff --git a/debian/patches/series/9 b/debian/patches/series/9 new file mode 100644 index 000000000..7e4a5a59c --- /dev/null +++ b/debian/patches/series/9 @@ -0,0 +1,2 @@ ++ 2.6.16.8 ++ 2.6.16.9 diff --git a/debian/patches/series/9-extra b/debian/patches/series/9-extra new file mode 100644 index 000000000..51e64a1f8 --- /dev/null +++ b/debian/patches/series/9-extra @@ -0,0 +1 @@ ++ vserver-vs2.0.2-rc17-update.patch *_vserver diff --git a/debian/patches/vserver-vs2.0.2-rc17-update.patch b/debian/patches/vserver-vs2.0.2-rc17-update.patch new file mode 100644 index 000000000..798e10e3a --- /dev/null +++ b/debian/patches/vserver-vs2.0.2-rc17-update.patch @@ -0,0 +1,75 @@ +diff -urN linux-2.6-2.6.16-vs2.0.2-rc16/fs/namei.c linux-2.6-2.6.16-vs2.0.2-rc17/fs/namei.c +--- linux-2.6-2.6.16-vs2.0.2-rc16/fs/namei.c 2006-04-19 14:47:38.000000000 +0200 ++++ linux-2.6-2.6.16-vs2.0.2-rc17/fs/namei.c 2006-04-19 14:48:36.000000000 +0200 +@@ -242,7 +242,7 @@ + + vxwprintk(1, "xid=%d denied access to %p[#%d,%lu] »%s«.", + vx_current_xid(), inode, inode->i_xid, inode->i_ino, +- vxd_path(nd->dentry, nd->mnt)); ++ vxd_cond_path(nd)); + return -EACCES; + } + +diff -urN linux-2.6-2.6.16-vs2.0.2-rc16/include/linux/vserver/debug.h linux-2.6-2.6.16-vs2.0.2-rc17/include/linux/vserver/debug.h +--- linux-2.6-2.6.16-vs2.0.2-rc16/include/linux/vserver/debug.h 2006-04-19 14:47:39.000000000 +0200 ++++ linux-2.6-2.6.16-vs2.0.2-rc17/include/linux/vserver/debug.h 2006-04-19 14:48:36.000000000 +0200 +@@ -60,11 +60,13 @@ + printk(VX_WARNLEVEL f "\n" , ##x); \ + } while (0) + +- + #define vxd_path(d,m) \ + ({ static char _buffer[PATH_MAX]; \ + d_path((d), (m), _buffer, sizeof(_buffer)); }) + ++#define vxd_cond_path(n) \ ++ ((n) ? vxd_path((n)->dentry, (n)->mnt) : "" ) ++ + #else /* CONFIG_VSERVER_DEBUG */ + + #define vx_debug_switch 0 +@@ -82,6 +84,7 @@ + #define vxwprintk(x...) do { } while (0) + + #define vxd_path "" ++#define vxd_cond_path vxd_path + + #endif /* CONFIG_VSERVER_DEBUG */ + +diff -urN linux-2.6-2.6.16-vs2.0.2-rc16/net/ipv4/devinet.c linux-2.6-2.6.16-vs2.0.2-rc17/net/ipv4/devinet.c +--- linux-2.6-2.6.16-vs2.0.2-rc16/net/ipv4/devinet.c 2006-04-19 14:47:39.000000000 +0200 ++++ linux-2.6-2.6.16-vs2.0.2-rc17/net/ipv4/devinet.c 2006-04-19 14:48:37.000000000 +0200 +@@ -529,33 +529,6 @@ + return rc; + } + +-/* +- Check that a device is not member of the ipv4root assigned to the process +- Return true if this is the case +- +- If the process is not bound to specific IP, then it returns 0 (all +- interface are fine). +-*/ +-static inline int devinet_notiproot (struct in_ifaddr *ifa) +-{ +- int ret = 0; +- struct nx_info *nxi; +- +- if ((nxi = current->nx_info)) { +- int i; +- int nbip = nxi->nbipv4; +- __u32 addr = ifa->ifa_local; +- ret = 1; +- for (i=0; iipv4[i] == addr) { +- ret = 0; +- break; +- } +- } +- } +- return ret; +-} +- + + int devinet_ioctl(unsigned int cmd, void __user *arg) + { From 88d24d016a3e228bdabd3e660e6df37ba787336d Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 28 Apr 2006 19:34:43 +0000 Subject: [PATCH 051/108] * debian/arch/defines: Set compiler to gcc-4.0. * debian/lib/python/debian_linux/gencontrol.py: Export settings from base entry. svn path=/dists/trunk/linux-2.6/; revision=6482 --- debian/arch/defines | 3 ++- debian/lib/python/debian_linux/gencontrol.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/debian/arch/defines b/debian/arch/defines index 72d7ec7fd..79d2ff998 100644 --- a/debian/arch/defines +++ b/debian/arch/defines @@ -16,6 +16,7 @@ arches: powerpc s390 sparc +compiler: gcc-4.0 [image] initramfs-generators: initramfs-tools yaird @@ -26,8 +27,8 @@ initramfs-tools: mkinitramfs-kpkg yaird: mkinitrd.yaird [relations] -gcc: gcc (>= 4:4.0) gcc-3.3: gcc-3.3 +gcc-4.0: gcc-4.0 initramfs-fallback: linux-initramfs-tool initramfs-tools: initramfs-tools (>= 0.53) yaird: yaird (>= 0.0.12-8) diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py index 4ea28a25c..6c2163683 100644 --- a/debian/lib/python/debian_linux/gencontrol.py +++ b/debian/lib/python/debian_linux/gencontrol.py @@ -34,6 +34,10 @@ class gencontrol(object): packages['source'] = self.process_package(source[0], self.vars) def do_main(self, packages, makefile): + config_entry = self.config['base',] + vars = self.vars.copy() + vars.update(config_entry) + makeflags = { 'MAJOR': self.version['major'], 'VERSION': self.version['version'], @@ -43,8 +47,6 @@ class gencontrol(object): 'ABINAME': self.abiname, } - vars = self.vars.copy() - self.do_main_setup(vars, makeflags) self.do_main_packages(packages) self.do_main_makefile(makefile, makeflags) From a5016c32504e1aba910ebdf7375202dd13278453 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 28 Apr 2006 19:52:22 +0000 Subject: [PATCH 052/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6484 --- debian/changelog | 42 ++ debian/patches/2.6.16.10 | 676 ++++++++++++++++++ debian/patches/2.6.16.11 | 25 + debian/patches/alpha-build-fix.patch | 22 + debian/patches/series/10 | 3 + debian/patches/series/11-extra | 1 + .../patches/vserver-vs2.0.2-rc18-update.patch | 349 +++++++++ 7 files changed, 1118 insertions(+) create mode 100644 debian/patches/2.6.16.10 create mode 100644 debian/patches/2.6.16.11 create mode 100644 debian/patches/alpha-build-fix.patch create mode 100644 debian/patches/series/10 create mode 100644 debian/patches/series/11-extra create mode 100644 debian/patches/vserver-vs2.0.2-rc18-update.patch diff --git a/debian/changelog b/debian/changelog index 48956e236..355147201 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,48 @@ linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low -- maximilian attems Tue, 18 Apr 2006 02:09:27 +0200 +linux-2.6 (2.6.16-11) UNRELEASED; urgency=low + + * Update vserver patch to 2.0.2-rc18. + - Limit ccaps to root inside a guest + + -- Bastian Blank Fri, 28 Apr 2006 16:08:01 +0200 + +linux-2.6 (2.6.16-10) unstable; urgency=low + + [ Norbert Tretkowski ] + * [alpha] Added backport of for_each_possible_cpu() to fix alpha build. + (closes: #364206) + * Add stable release 2.6.16.10: + - IPC: access to unmapped vmalloc area in grow_ary() + - Add more prevent_tail_call() + - alim15x3: ULI M-1573 south Bridge support + - apm: fix Armada laptops again + - fbdev: Fix return error of fb_write + - Fix file lookup without ref + - m41t00: fix bitmasks when writing to chip + - Open IPMI BT overflow + - x86: be careful about tailcall breakage for sys_open[at] too + - x86: don't allow tail-calls in sys_ftruncate[64]() + - IPV6: XFRM: Fix decoding session with preceding extension header(s). + - IPV6: XFRM: Don't use old copy of pointer after pskb_may_pull(). + - IPV6: Ensure to have hop-by-hop options in our header of &sk_buff. + - selinux: Fix MLS compatibility off-by-one bug + - PPC: fix oops in alsa powermac driver + - MTD_NAND_SHARPSL and MTD_NAND_NANDSIM should be tristate's + - i2c-i801: Fix resume when PEC is used + - Fix hotplug race during device registration + - Fix truesize underflow + - efficeon-agp: Add missing memory mask + - 3ware 9000 disable local irqs during kmap_atomic + - 3ware: kmap_atomic() fix + + [ maximilian attems ] + * Add stable release 2.6.16.11: + - Don't allow a backslash in a path component (CVE-2006-1863) + + -- Bastian Blank Tue, 25 Apr 2006 13:56:19 +0200 + linux-2.6 (2.6.16-9) unstable; urgency=low [ maximilian attems ] diff --git a/debian/patches/2.6.16.10 b/debian/patches/2.6.16.10 new file mode 100644 index 000000000..f679f9e3f --- /dev/null +++ b/debian/patches/2.6.16.10 @@ -0,0 +1,676 @@ +diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c +index 05312a8..558d2d2 100644 +--- a/arch/i386/kernel/apm.c ++++ b/arch/i386/kernel/apm.c +@@ -1081,7 +1081,7 @@ static int apm_console_blank(int blank) + break; + } + +- if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) { ++ if (error == APM_NOT_ENGAGED) { + static int tried; + int eng_error; + if (tried++ == 0) { +diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c +index e7aea77..40dfc29 100644 +--- a/drivers/char/agp/efficeon-agp.c ++++ b/drivers/char/agp/efficeon-agp.c +@@ -64,6 +64,12 @@ static struct gatt_mask efficeon_generic + {.mask = 0x00000001, .type = 0} + }; + ++/* This function does the same thing as mask_memory() for this chipset... */ ++static inline unsigned long efficeon_mask_memory(unsigned long addr) ++{ ++ return addr | 0x00000001; ++} ++ + static struct aper_size_info_lvl2 efficeon_generic_sizes[4] = + { + {256, 65536, 0}, +@@ -251,7 +257,7 @@ static int efficeon_insert_memory(struct + last_page = NULL; + for (i = 0; i < count; i++) { + int index = pg_start + i; +- unsigned long insert = mem->memory[i]; ++ unsigned long insert = efficeon_mask_memory(mem->memory[i]); + + page = (unsigned int *) efficeon_private.l1_table[index >> 10]; + +diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c +index 58dcdee..0030cd8 100644 +--- a/drivers/char/ipmi/ipmi_bt_sm.c ++++ b/drivers/char/ipmi/ipmi_bt_sm.c +@@ -165,7 +165,7 @@ static int bt_start_transaction(struct s + { + unsigned int i; + +- if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH)) ++ if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2))) + return -1; + + if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) +diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c +index 53d3d06..edaee70 100644 +--- a/drivers/char/tty_io.c ++++ b/drivers/char/tty_io.c +@@ -2706,7 +2706,11 @@ #else + } + task_lock(p); + if (p->files) { +- rcu_read_lock(); ++ /* ++ * We don't take a ref to the file, so we must ++ * hold ->file_lock instead. ++ */ ++ spin_lock(&p->files->file_lock); + fdt = files_fdtable(p->files); + for (i=0; i < fdt->max_fds; i++) { + filp = fcheck_files(p->files, i); +@@ -2721,7 +2725,7 @@ #else + break; + } + } +- rcu_read_unlock(); ++ spin_unlock(&p->files->file_lock); + } + task_unlock(p); + } while_each_task_pid(session, PIDTYPE_SID, p); +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 8e0f315..dfca749 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -478,6 +478,11 @@ static s32 i801_access(struct i2c_adapte + ret = i801_transaction(); + } + ++ /* Some BIOSes don't like it when PEC is enabled at reboot or resume ++ time, so we forcibly disable it after every transaction. */ ++ if (hwpec) ++ outb_p(0, SMBAUXCTL); ++ + if(block) + return ret; + if(ret) +diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c +index 2dc3d48..2836fb3 100644 +--- a/drivers/i2c/chips/m41t00.c ++++ b/drivers/i2c/chips/m41t00.c +@@ -129,13 +129,13 @@ m41t00_set_tlet(ulong arg) + if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) + || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) + < 0) +- || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x7f) ++ || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f) + < 0) +- || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x7f) ++ || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f) + < 0) +- || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x7f) ++ || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f) + < 0) +- || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0x7f) ++ || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff) + < 0)) + + dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); +diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c +index cf84350..8b24b4f 100644 +--- a/drivers/ide/pci/alim15x3.c ++++ b/drivers/ide/pci/alim15x3.c +@@ -731,6 +731,8 @@ static unsigned int __devinit ata66_ali1 + + if(m5229_revision <= 0x20) + tmpbyte = (tmpbyte & (~0x02)) | 0x01; ++ else if (m5229_revision == 0xc7) ++ tmpbyte |= 0x03; + else + tmpbyte |= 0x01; + +diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c +index 5ebfd1d..5282fec 100644 +--- a/drivers/macintosh/therm_adt746x.c ++++ b/drivers/macintosh/therm_adt746x.c +@@ -627,8 +627,8 @@ thermostat_init(void) + if(therm_type == ADT7460) + device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); + +-#ifndef CONFIG_I2C_KEYWEST +- request_module("i2c-keywest"); ++#ifndef CONFIG_I2C_POWERMAC ++ request_module("i2c-powermac"); + #endif + + return i2c_add_driver(&thermostat_driver); +diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig +index 1fc4c13..cfe288a 100644 +--- a/drivers/mtd/nand/Kconfig ++++ b/drivers/mtd/nand/Kconfig +@@ -178,17 +178,16 @@ config MTD_NAND_DISKONCHIP_BBTWRITE + Even if you leave this disabled, you can enable BBT writes at module + load time (assuming you build diskonchip as a module) with the module + parameter "inftl_bbt_write=1". +- +- config MTD_NAND_SHARPSL +- bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" +- depends on MTD_NAND && ARCH_PXA +- +- config MTD_NAND_NANDSIM +- bool "Support for NAND Flash Simulator" +- depends on MTD_NAND && MTD_PARTITIONS + ++config MTD_NAND_SHARPSL ++ tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" ++ depends on MTD_NAND && ARCH_PXA ++ ++config MTD_NAND_NANDSIM ++ tristate "Support for NAND Flash Simulator" ++ depends on MTD_NAND && MTD_PARTITIONS + help + The simulator may simulate verious NAND flash chips for the + MTD nand layer. +- ++ + endmenu +diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c +index d9152d0..9132549 100644 +--- a/drivers/scsi/3w-9xxx.c ++++ b/drivers/scsi/3w-9xxx.c +@@ -85,7 +85,7 @@ #include + #include "3w-9xxx.h" + + /* Globals */ +-#define TW_DRIVER_VERSION "2.26.02.005" ++#define TW_DRIVER_VERSION "2.26.02.007" + static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; + static unsigned int twa_device_extension_count; + static int twa_major = -1; +@@ -1944,9 +1944,13 @@ static void twa_scsiop_execute_scsi_comp + } + if (tw_dev->srb[request_id]->use_sg == 1) { + struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer; +- char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; ++ char *buf; ++ unsigned long flags = 0; ++ local_irq_save(flags); ++ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length); + kunmap_atomic(buf - sg->offset, KM_IRQ0); ++ local_irq_restore(flags); + } + } + } /* End twa_scsiop_execute_scsi_complete() */ +diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c +index 25f678d..e8e41e6 100644 +--- a/drivers/scsi/3w-xxxx.c ++++ b/drivers/scsi/3w-xxxx.c +@@ -1508,10 +1508,12 @@ static void tw_transfer_internal(TW_Devi + struct scsi_cmnd *cmd = tw_dev->srb[request_id]; + void *buf; + unsigned int transfer_len; ++ unsigned long flags = 0; + + if (cmd->use_sg) { + struct scatterlist *sg = + (struct scatterlist *)cmd->request_buffer; ++ local_irq_save(flags); + buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + transfer_len = min(sg->length, len); + } else { +@@ -1526,6 +1528,7 @@ static void tw_transfer_internal(TW_Devi + + sg = (struct scatterlist *)cmd->request_buffer; + kunmap_atomic(buf - sg->offset, KM_IRQ0); ++ local_irq_restore(flags); + } + } + +diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c +index 996c7b5..b3094ae 100644 +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -669,13 +669,19 @@ fb_write(struct file *file, const char _ + total_size = info->fix.smem_len; + + if (p > total_size) +- return 0; ++ return -EFBIG; + +- if (count >= total_size) ++ if (count > total_size) { ++ err = -EFBIG; + count = total_size; ++ } ++ ++ if (count + p > total_size) { ++ if (!err) ++ err = -ENOSPC; + +- if (count + p > total_size) + count = total_size - p; ++ } + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, + GFP_KERNEL); +@@ -717,7 +723,7 @@ fb_write(struct file *file, const char _ + + kfree(buffer); + +- return (err) ? err : cnt; ++ return (cnt) ? cnt : err; + } + + #ifdef CONFIG_KMOD +diff --git a/fs/locks.c b/fs/locks.c +index 909eab8..e75ac39 100644 +--- a/fs/locks.c ++++ b/fs/locks.c +@@ -2212,7 +2212,12 @@ void steal_locks(fl_owner_t from) + + lock_kernel(); + j = 0; +- rcu_read_lock(); ++ ++ /* ++ * We are not taking a ref to the file structures, so ++ * we need to acquire ->file_lock. ++ */ ++ spin_lock(&files->file_lock); + fdt = files_fdtable(files); + for (;;) { + unsigned long set; +@@ -2230,7 +2235,7 @@ void steal_locks(fl_owner_t from) + set >>= 1; + } + } +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + unlock_kernel(); + } + EXPORT_SYMBOL(steal_locks); +diff --git a/fs/open.c b/fs/open.c +index 70e0230..f697914 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -330,7 +330,10 @@ out: + + asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) + { +- return do_sys_ftruncate(fd, length, 1); ++ long ret = do_sys_ftruncate(fd, length, 1); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + /* LFS versions of truncate are only needed on 32 bit machines */ +@@ -342,7 +345,10 @@ asmlinkage long sys_truncate64(const cha + + asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) + { +- return do_sys_ftruncate(fd, length, 0); ++ long ret = do_sys_ftruncate(fd, length, 0); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + #endif + +@@ -1083,20 +1089,30 @@ long do_sys_open(int dfd, const char __u + + asmlinkage long sys_open(const char __user *filename, int flags, int mode) + { ++ long ret; ++ + if (force_o_largefile()) + flags |= O_LARGEFILE; + +- return do_sys_open(AT_FDCWD, filename, flags, mode); ++ ret = do_sys_open(AT_FDCWD, filename, flags, mode); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + EXPORT_SYMBOL_GPL(sys_open); + + asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, + int mode) + { ++ long ret; ++ + if (force_o_largefile()) + flags |= O_LARGEFILE; + +- return do_sys_open(dfd, filename, flags, mode); ++ ret = do_sys_open(dfd, filename, flags, mode); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + EXPORT_SYMBOL_GPL(sys_openat); + +diff --git a/fs/proc/base.c b/fs/proc/base.c +index 20feb75..c192cb2 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -294,16 +294,20 @@ static int proc_fd_link(struct inode *in + + files = get_files_struct(task); + if (files) { +- rcu_read_lock(); ++ /* ++ * We are not taking a ref to the file structure, so we must ++ * hold ->file_lock. ++ */ ++ spin_lock(&files->file_lock); + file = fcheck_files(files, fd); + if (file) { + *mnt = mntget(file->f_vfsmnt); + *dentry = dget(file->f_dentry); +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + put_files_struct(files); + return 0; + } +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + put_files_struct(files); + } + return -ENOENT; +@@ -1485,7 +1489,12 @@ static struct dentry *proc_lookupfd(stru + if (!files) + goto out_unlock; + inode->i_mode = S_IFLNK; +- rcu_read_lock(); ++ ++ /* ++ * We are not taking a ref to the file structure, so we must ++ * hold ->file_lock. ++ */ ++ spin_lock(&files->file_lock); + file = fcheck_files(files, fd); + if (!file) + goto out_unlock2; +@@ -1493,7 +1502,7 @@ static struct dentry *proc_lookupfd(stru + inode->i_mode |= S_IRUSR | S_IXUSR; + if (file->f_mode & 2) + inode->i_mode |= S_IWUSR | S_IXUSR; +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + put_files_struct(files); + inode->i_op = &proc_pid_link_inode_operations; + inode->i_size = 64; +@@ -1503,7 +1512,7 @@ static struct dentry *proc_lookupfd(stru + return NULL; + + out_unlock2: +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + put_files_struct(files); + out_unlock: + iput(inode); +diff --git a/ipc/util.c b/ipc/util.c +index 8626219..303b058 100644 +--- a/ipc/util.c ++++ b/ipc/util.c +@@ -182,8 +182,7 @@ static int grow_ary(struct ipc_ids* ids, + if(new == NULL) + return size; + new->size = newsize; +- memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size + +- sizeof(struct ipc_id_ary)); ++ memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size); + for(i=size;ip[i] = NULL; + } +diff --git a/kernel/uid16.c b/kernel/uid16.c +index aa25605..187e2a4 100644 +--- a/kernel/uid16.c ++++ b/kernel/uid16.c +@@ -20,43 +20,67 @@ #include + + asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) + { +- return sys_chown(filename, low2highuid(user), low2highgid(group)); ++ long ret = sys_chown(filename, low2highuid(user), low2highgid(group)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) + { +- return sys_lchown(filename, low2highuid(user), low2highgid(group)); ++ long ret = sys_lchown(filename, low2highuid(user), low2highgid(group)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) + { +- return sys_fchown(fd, low2highuid(user), low2highgid(group)); ++ long ret = sys_fchown(fd, low2highuid(user), low2highgid(group)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) + { +- return sys_setregid(low2highgid(rgid), low2highgid(egid)); ++ long ret = sys_setregid(low2highgid(rgid), low2highgid(egid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setgid16(old_gid_t gid) + { +- return sys_setgid(low2highgid(gid)); ++ long ret = sys_setgid(low2highgid(gid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) + { +- return sys_setreuid(low2highuid(ruid), low2highuid(euid)); ++ long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setuid16(old_uid_t uid) + { +- return sys_setuid(low2highuid(uid)); ++ long ret = sys_setuid(low2highuid(uid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) + { +- return sys_setresuid(low2highuid(ruid), low2highuid(euid), +- low2highuid(suid)); ++ long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid), ++ low2highuid(suid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid) +@@ -72,8 +96,11 @@ asmlinkage long sys_getresuid16(old_uid_ + + asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) + { +- return sys_setresgid(low2highgid(rgid), low2highgid(egid), +- low2highgid(sgid)); ++ long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid), ++ low2highgid(sgid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid) +@@ -89,12 +116,18 @@ asmlinkage long sys_getresgid16(old_gid_ + + asmlinkage long sys_setfsuid16(old_uid_t uid) + { +- return sys_setfsuid(low2highuid(uid)); ++ long ret = sys_setfsuid(low2highuid(uid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setfsgid16(old_gid_t gid) + { +- return sys_setfsgid(low2highgid(gid)); ++ long ret = sys_setfsgid(low2highgid(gid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + static int groups16_to_user(old_gid_t __user *grouplist, +diff --git a/net/core/dev.c b/net/core/dev.c +index 2afb0de..12a214c 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2932,11 +2932,11 @@ void netdev_run_todo(void) + + switch(dev->reg_state) { + case NETREG_REGISTERING: ++ dev->reg_state = NETREG_REGISTERED; + err = netdev_register_sysfs(dev); + if (err) + printk(KERN_ERR "%s: failed sysfs registration (%d)\n", + dev->name, err); +- dev->reg_state = NETREG_REGISTERED; + break; + + case NETREG_UNREGISTERING: +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 9f498a6..310f2e6 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -537,7 +537,9 @@ int tcp_fragment(struct sock *sk, struct + buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); + if (buff == NULL) + return -ENOMEM; /* We'll just try again later. */ +- sk_charge_skb(sk, buff); ++ ++ buff->truesize = skb->len - len; ++ skb->truesize -= buff->truesize; + + /* Correct the sequence numbers. */ + TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; +diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c +index 2a1e7e4..d88cab7 100644 +--- a/net/ipv6/exthdrs.c ++++ b/net/ipv6/exthdrs.c +@@ -489,6 +489,18 @@ int ipv6_parse_hopopts(struct sk_buff *s + { + struct inet6_skb_parm *opt = IP6CB(skb); + ++ /* ++ * skb->nh.raw is equal to skb->data, and ++ * skb->h.raw - skb->nh.raw is always equal to ++ * sizeof(struct ipv6hdr) by definition of ++ * hop-by-hop options. ++ */ ++ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || ++ !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { ++ kfree_skb(skb); ++ return -1; ++ } ++ + opt->hop = sizeof(struct ipv6hdr); + if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { + skb->h.raw += (skb->h.raw[1]+1)<<3; +diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c +index 91cce8b..88c840f 100644 +--- a/net/ipv6/xfrm6_policy.c ++++ b/net/ipv6/xfrm6_policy.c +@@ -191,16 +191,18 @@ error: + static inline void + _decode_session6(struct sk_buff *skb, struct flowi *fl) + { +- u16 offset = sizeof(struct ipv6hdr); ++ u16 offset = skb->h.raw - skb->nh.raw; + struct ipv6hdr *hdr = skb->nh.ipv6h; +- struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); +- u8 nexthdr = skb->nh.ipv6h->nexthdr; ++ struct ipv6_opt_hdr *exthdr; ++ u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff]; + + memset(fl, 0, sizeof(struct flowi)); + ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); + ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); + + while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { ++ exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); ++ + switch (nexthdr) { + case NEXTHDR_ROUTING: + case NEXTHDR_HOP: +diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c +index 640d0bf..84047f6 100644 +--- a/security/selinux/ss/mls.c ++++ b/security/selinux/ss/mls.c +@@ -264,7 +264,7 @@ int mls_context_to_sid(char oldc, + + if (!selinux_mls_enabled) { + if (def_sid != SECSID_NULL && oldc) +- *scontext += strlen(*scontext); ++ *scontext += strlen(*scontext)+1; + return 0; + } + +diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c +index 8131599..882ae98 100644 +--- a/sound/oss/dmasound/tas_common.c ++++ b/sound/oss/dmasound/tas_common.c +@@ -195,8 +195,8 @@ tas_init(int driver_id, const char *driv + + printk(KERN_INFO "tas driver [%s])\n", driver_name); + +-#ifndef CONFIG_I2C_KEYWEST +- request_module("i2c-keywest"); ++#ifndef CONFIG_I2C_POWERMAC ++ request_module("i2c-powermac"); + #endif + tas_node = find_devices("deq"); + if (tas_node == NULL) +diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c +index 08cde51..b96cd94 100644 +--- a/sound/ppc/daca.c ++++ b/sound/ppc/daca.c +@@ -256,7 +256,7 @@ int __init snd_pmac_daca_init(struct snd + + #ifdef CONFIG_KMOD + if (current->fs->root) +- request_module("i2c-keywest"); ++ request_module("i2c-powermac"); + #endif /* CONFIG_KMOD */ + + mix = kmalloc(sizeof(*mix), GFP_KERNEL); +diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c +index 838fc11..39d4cde 100644 +--- a/sound/ppc/tumbler.c ++++ b/sound/ppc/tumbler.c +@@ -1314,7 +1314,7 @@ int __init snd_pmac_tumbler_init(struct + + #ifdef CONFIG_KMOD + if (current->fs->root) +- request_module("i2c-keywest"); ++ request_module("i2c-powermac"); + #endif /* CONFIG_KMOD */ + + mix = kmalloc(sizeof(*mix), GFP_KERNEL); diff --git a/debian/patches/2.6.16.11 b/debian/patches/2.6.16.11 new file mode 100644 index 000000000..9ec0051d0 --- /dev/null +++ b/debian/patches/2.6.16.11 @@ -0,0 +1,25 @@ +diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c +index fed55e3..5e562bc 100644 +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -441,6 +441,20 @@ cifs_lookup(struct inode *parent_dir_ino + cifs_sb = CIFS_SB(parent_dir_inode->i_sb); + pTcon = cifs_sb->tcon; + ++ /* ++ * Don't allow the separator character in a path component. ++ * The VFS will not allow "/", but "\" is allowed by posix. ++ */ ++ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { ++ int i; ++ for (i = 0; i < direntry->d_name.len; i++) ++ if (direntry->d_name.name[i] == '\\') { ++ cFYI(1, ("Invalid file name")); ++ FreeXid(xid); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ + /* can not grab the rename sem here since it would + deadlock in the cases (beginning of sys_rename itself) + in which we already have the sb rename sem */ diff --git a/debian/patches/alpha-build-fix.patch b/debian/patches/alpha-build-fix.patch new file mode 100644 index 000000000..a633d3376 --- /dev/null +++ b/debian/patches/alpha-build-fix.patch @@ -0,0 +1,22 @@ +From: Andrew Morton + +Backport for_each_possible_cpu() into 2.6.16. Fixes the alpha build, and any +future occurrences. + + +Signed-off-by: Andrew Morton +--- + + include/linux/cpumask.h | 1 + + 1 files changed, 1 insertion(+) + +--- a/include/linux/cpumask.h 2006-04-24 19:28:56.000000000 +0200 ++++ b/include/linux/cpumask.h 2006-04-24 19:29:21.000000000 +0200 +@@ -408,6 +408,7 @@ + }) + + #define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) ++#define for_each_possible_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) + #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) + #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) + diff --git a/debian/patches/series/10 b/debian/patches/series/10 new file mode 100644 index 000000000..656a136e7 --- /dev/null +++ b/debian/patches/series/10 @@ -0,0 +1,3 @@ ++ alpha-build-fix.patch ++ 2.6.16.10 ++ 2.6.16.11 diff --git a/debian/patches/series/11-extra b/debian/patches/series/11-extra new file mode 100644 index 000000000..74a272487 --- /dev/null +++ b/debian/patches/series/11-extra @@ -0,0 +1 @@ ++ vserver-vs2.0.2-rc18-update.patch *_vserver diff --git a/debian/patches/vserver-vs2.0.2-rc18-update.patch b/debian/patches/vserver-vs2.0.2-rc18-update.patch new file mode 100644 index 000000000..cdd9420eb --- /dev/null +++ b/debian/patches/vserver-vs2.0.2-rc18-update.patch @@ -0,0 +1,349 @@ +diff -u linux-2.6.16.8-vs2.0.2-rc17/fs/namespace.c linux-2.6.16.11-vs2.0.2-rc18/fs/namespace.c +--- linux-2.6.16.8-vs2.0.2-rc17/fs/namespace.c 2006-03-20 17:34:49 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/fs/namespace.c 2006-04-28 01:59:36 +0200 +@@ -676,7 +676,7 @@ + goto dput_and_out; + + retval = -EPERM; +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) + goto dput_and_out; + + retval = do_umount(nd.mnt, flags); +@@ -700,9 +700,7 @@ + + static int mount_is_safe(struct nameidata *nd) + { +- if (capable(CAP_SYS_ADMIN)) +- return 0; +- if (vx_ccaps(VXC_SECURE_MOUNT)) ++ if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) + return 0; + return -EPERM; + #ifdef notyet +@@ -996,7 +994,7 @@ + int err; + struct super_block *sb = nd->mnt->mnt_sb; + +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_REMOUNT)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_REMOUNT)) + return -EPERM; + + if (!check_mnt(nd->mnt)) +@@ -1030,7 +1028,7 @@ + struct nameidata old_nd, parent_nd; + struct vfsmount *p; + int err = 0; +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) + return -EPERM; + if (!old_name || !*old_name) + return -EINVAL; +@@ -1110,7 +1108,7 @@ + return -EINVAL; + + /* we need capabilities... */ +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) + return -EPERM; + + mnt = do_kern_mount(type, flags, name, data); +@@ -1502,7 +1500,7 @@ + if (!(flags & CLONE_NEWNS)) + return 0; + +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) { ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) { + err = -EPERM; + goto out; + } +diff -u linux-2.6.16.8-vs2.0.2-rc17/fs/quota.c linux-2.6.16.11-vs2.0.2-rc18/fs/quota.c +--- linux-2.6.16.8-vs2.0.2-rc17/fs/quota.c 2006-03-20 17:34:49 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/fs/quota.c 2006-04-28 01:59:36 +0200 +@@ -84,11 +84,11 @@ + if (cmd == Q_GETQUOTA) { + if (((type == USRQUOTA && current->euid != id) || + (type == GRPQUOTA && !in_egroup_p(id))) && +- !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) ++ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) + return -EPERM; + } + else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO) +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) + return -EPERM; + + return 0; +@@ -135,10 +135,10 @@ + if (cmd == Q_XGETQUOTA) { + if (((type == XQM_USRQUOTA && current->euid != id) || + (type == XQM_GRPQUOTA && !in_egroup_p(id))) && +- !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) ++ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) + return -EPERM; + } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) { +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) + return -EPERM; + } + +diff -u linux-2.6.16.8-vs2.0.2-rc17/fs/super.c linux-2.6.16.11-vs2.0.2-rc18/fs/super.c +--- linux-2.6.16.8-vs2.0.2-rc17/fs/super.c 2006-03-20 17:34:49 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/fs/super.c 2006-04-28 01:59:36 +0200 +@@ -815,7 +815,7 @@ + + sb = ERR_PTR(-EPERM); + if ((type->fs_flags & FS_BINARY_MOUNTDATA) && +- !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_BINARY_MOUNT)) ++ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT)) + goto out; + + sb = ERR_PTR(-ENOMEM); +diff -u linux-2.6.16.8-vs2.0.2-rc17/fs/xfs/quota/xfs_qm_syscalls.c linux-2.6.16.11-vs2.0.2-rc18/fs/xfs/quota/xfs_qm_syscalls.c +--- linux-2.6.16.8-vs2.0.2-rc17/fs/xfs/quota/xfs_qm_syscalls.c 2006-03-20 17:34:49 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/fs/xfs/quota/xfs_qm_syscalls.c 2006-04-28 01:59:36 +0200 +@@ -215,7 +215,7 @@ + xfs_qoff_logitem_t *qoffstart; + int nculprits; + +- if (!force && !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) ++ if (!force && !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) + return XFS_ERROR(EPERM); + /* + * No file system can have quotas enabled on disk but not in core. +@@ -384,7 +384,7 @@ + int error; + xfs_inode_t *qip; + +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) + return XFS_ERROR(EPERM); + error = 0; + if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) { +@@ -429,7 +429,7 @@ + uint accflags; + __int64_t sbflags; + +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) + return XFS_ERROR(EPERM); + + flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); +@@ -600,7 +600,7 @@ + int error; + xfs_qcnt_t hard, soft; + +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) + return XFS_ERROR(EPERM); + + if ((newlim->d_fieldmask & +diff -u linux-2.6.16.8-vs2.0.2-rc17/include/linux/vs_base.h linux-2.6.16.11-vs2.0.2-rc18/include/linux/vs_base.h +--- linux-2.6.16.8-vs2.0.2-rc17/include/linux/vs_base.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/include/linux/vs_base.h 2006-04-28 02:00:37 +0200 +@@ -97,6 +97,9 @@ + (current->vx_info && \ + (current->vx_info->vx_initpid == (n))) + ++#define vx_capable(b,c) (capable(b) || \ ++ ((current->euid == 0) && vx_ccaps(c))) ++ + + #else + #warning duplicate inclusion +diff -u linux-2.6.16.8-vs2.0.2-rc17/include/net/route.h linux-2.6.16.11-vs2.0.2-rc18/include/net/route.h +--- linux-2.6.16.8-vs2.0.2-rc17/include/net/route.h 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/include/net/route.h 2006-04-26 19:12:32 +0200 +@@ -229,6 +229,8 @@ + return err; + if (fl.fl4_dst == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) + fl.fl4_dst = nx_info->ipv4[0]; ++ if (fl.fl4_src == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) ++ fl.fl4_src = nx_info->ipv4[0]; + } + if (!fl.fl4_dst || !fl.fl4_src) { + err = __ip_route_output_key(rp, &fl); +diff -u linux-2.6.16.8-vs2.0.2-rc17/kernel/sys.c linux-2.6.16.11-vs2.0.2-rc18/kernel/sys.c +--- linux-2.6.16.8-vs2.0.2-rc17/kernel/sys.c 2006-04-18 02:12:08 +0200 ++++ linux-2.6.16.11-vs2.0.2-rc18/kernel/sys.c 2006-04-28 01:59:36 +0200 +@@ -1547,7 +1547,7 @@ + int errno; + char tmp[__NEW_UTS_LEN]; + +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME)) + return -EPERM; + if (len < 0 || len > __NEW_UTS_LEN) + return -EINVAL; +@@ -1596,7 +1596,7 @@ + int errno; + char tmp[__NEW_UTS_LEN]; + +- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME)) ++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME)) + return -EPERM; + if (len < 0 || len > __NEW_UTS_LEN) + return -EINVAL; +@@ -1664,7 +1664,7 @@ + return -EINVAL; + old_rlim = current->signal->rlim + resource; + if ((new_rlim.rlim_max > old_rlim->rlim_max) && +- !capable(CAP_SYS_RESOURCE) && !vx_ccaps(VXC_SET_RLIMIT)) ++ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT)) + return -EPERM; + if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN) + return -EPERM; +diff -u linux-2.6.16.8-vs2.0.2-rc17/kernel/vserver/legacy.c linux-2.6.16.11-vs2.0.2-rc18/kernel/vserver/legacy.c +--- linux-2.6.16.8-vs2.0.2-rc17/kernel/vserver/legacy.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/kernel/vserver/legacy.c 2006-04-28 03:18:07 +0200 +@@ -31,6 +31,7 @@ + if (!init) + return -ESRCH; + ++ vxi->vx_flags &= ~VXF_STATE_INIT; + return vx_set_init(vxi, init); + } + +@@ -88,7 +89,7 @@ + vx_info_flags(new_vxi, VX_INFO_PRIVATE, 0)) + goto out_put; + +- new_vxi->vx_flags &= ~(VXF_STATE_SETUP|VXF_STATE_INIT); ++ new_vxi->vx_flags &= ~VXF_STATE_SETUP; + + ret = vx_migrate_task(current, new_vxi); + if (ret == 0) { +@@ -102,6 +103,9 @@ + if (vc_data.flags & VX_INFO_NPROC) + new_vxi->limit.rlim[RLIMIT_NPROC] = + current->signal->rlim[RLIMIT_NPROC].rlim_max; ++ ++ /* tweak some defaults for legacy */ ++ new_vxi->vx_flags |= (VXF_HIDE_NETIF|VXF_INFO_INIT); + ret = new_vxi->vx_id; + } + out_put: +diff -u linux-2.6.16.8-vs2.0.2-rc17/kernel/vserver/sched.c linux-2.6.16.11-vs2.0.2-rc18/kernel/vserver/sched.c +--- linux-2.6.16.8-vs2.0.2-rc17/kernel/vserver/sched.c 2006-03-24 16:50:48 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/kernel/vserver/sched.c 2006-04-28 01:39:59 +0200 +@@ -117,7 +117,7 @@ + vavavoom = 0; + + vxi->sched.vavavoom = vavavoom; +- return vavavoom; ++ return vavavoom + vxi->sched.priority_bias; + } + + +diff -u linux-2.6.16.8-vs2.0.2-rc17/net/ipv4/devinet.c linux-2.6.16.11-vs2.0.2-rc18/net/ipv4/devinet.c +--- linux-2.6.16.8-vs2.0.2-rc17/net/ipv4/devinet.c 2006-04-17 20:56:32 +0200 ++++ linux-2.6.16.11-vs2.0.2-rc18/net/ipv4/devinet.c 2006-04-26 19:09:22 +0200 +@@ -607,6 +607,9 @@ + *colon = ':'; + + if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { ++ struct nx_info *nxi = current->nx_info; ++ int hide_netif = vx_flags(VXF_HIDE_NETIF, 0); ++ + if (tryaddrmatch) { + /* Matthias Andree */ + /* compare label and address (4.4BSD style) */ +@@ -615,6 +618,8 @@ + This is checked above. */ + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) { ++ if (hide_netif && !ifa_in_nx_info(ifa, nxi)) ++ continue; + if (!strcmp(ifr.ifr_name, ifa->ifa_label) && + sin_orig.sin_addr.s_addr == + ifa->ifa_address) { +@@ -627,18 +632,18 @@ + comparing just the label */ + if (!ifa) { + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; +- ifap = &ifa->ifa_next) ++ ifap = &ifa->ifa_next) { ++ if (hide_netif && !ifa_in_nx_info(ifa, nxi)) ++ continue; + if (!strcmp(ifr.ifr_name, ifa->ifa_label)) + break; ++ } + } + } + + ret = -EADDRNOTAVAIL; + if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) + goto done; +- if (vx_flags(VXF_HIDE_NETIF, 0) && +- !ifa_in_nx_info(ifa, current->nx_info)) +- goto done; + + switch(cmd) { + case SIOCGIFADDR: /* Get interface address */ +diff -u linux-2.6.16.8-vs2.0.2-rc17/net/ipv4/udp.c linux-2.6.16.11-vs2.0.2-rc18/net/ipv4/udp.c +--- linux-2.6.16.8-vs2.0.2-rc17/net/ipv4/udp.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/net/ipv4/udp.c 2006-04-26 19:08:56 +0200 +@@ -216,16 +216,6 @@ + write_unlock_bh(&udp_hash_lock); + } + +-static inline int udp_in_list(struct nx_info *nx_info, u32 addr) +-{ +- int n = nx_info->nbipv4; +- int i; +- +- for (i=0; iipv4[i] == addr) +- return 1; +- return 0; +-} + + /* UDP is nearly always wildcards out the wazoo, it makes no sense to try + * harder than this. -DaveM +@@ -248,7 +238,7 @@ + continue; + score+=2; + } else if (sk->sk_nx_info) { +- if (udp_in_list(sk->sk_nx_info, daddr)) ++ if (addr_in_nx_info(sk->sk_nx_info, daddr)) + score+=2; + else + continue; +diff -u linux-2.6.16.8-vs2.0.2-rc17/security/commoncap.c linux-2.6.16.11-vs2.0.2-rc18/security/commoncap.c +--- linux-2.6.16.8-vs2.0.2-rc17/security/commoncap.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/security/commoncap.c 2006-04-28 01:59:36 +0200 +@@ -313,7 +313,7 @@ + int cap_syslog (int type) + { + if ((type != 3 && type != 10) && +- !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SYSLOG)) ++ !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG)) + return -EPERM; + return 0; + } +diff -u linux-2.6.16.8-vs2.0.2-rc17/security/security.c linux-2.6.16.11-vs2.0.2-rc18/security/security.c +--- linux-2.6.16.8-vs2.0.2-rc17/security/security.c 2006-03-20 17:34:50 +0100 ++++ linux-2.6.16.11-vs2.0.2-rc18/security/security.c 2006-04-28 01:59:36 +0200 +@@ -200,22 +200,8 @@ + +-int vx_capable(int cap, int ccap) +-{ +- if (security_ops->capable(current, cap)) { +- /* capability denied */ +- return 0; +- } +- if (!vx_ccaps(ccap)) +- return 0; +- +- /* capability granted */ +- current->flags |= PF_SUPERPRIV; +- return 1; +-} + + EXPORT_SYMBOL_GPL(register_security); + EXPORT_SYMBOL_GPL(unregister_security); + EXPORT_SYMBOL_GPL(mod_reg_security); + EXPORT_SYMBOL_GPL(mod_unreg_security); + EXPORT_SYMBOL(capable); +-EXPORT_SYMBOL(vx_capable); + EXPORT_SYMBOL(security_ops); From b47523b093a21cf568bf24401d02520381f9ef76 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 28 Apr 2006 21:18:56 +0000 Subject: [PATCH 053/108] debian/arch/hppa/defines: Fix compiler settings. svn path=/dists/trunk/linux-2.6/; revision=6486 --- debian/arch/hppa/defines | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/arch/hppa/defines b/debian/arch/hppa/defines index 3551b7144..bce0d69d2 100644 --- a/debian/arch/hppa/defines +++ b/debian/arch/hppa/defines @@ -23,5 +23,5 @@ class: 64-bit PA-RISC class: multi-processor 64-bit PA-RISC [relations] -gcc: gcc (>= 4:4.0), binutils-hppa64, gcc-4.0-hppa64 +gcc-4.0: gcc-4.0, binutils-hppa64, gcc-4.0-hppa64 From 4027080008307166f7b31babf8000204bdf8ba6b Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 28 Apr 2006 22:01:54 +0000 Subject: [PATCH 054/108] Merge /dists/sid/linux-2.6. svn path=/dists/trunk/linux-2.6/; revision=6490 --- debian/arch/amd64/defines | 3 ++- debian/arch/i386/defines | 3 ++- debian/changelog | 3 ++- debian/rules | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/debian/arch/amd64/defines b/debian/arch/amd64/defines index 1f3cea6f5..740003105 100644 --- a/debian/arch/amd64/defines +++ b/debian/arch/amd64/defines @@ -13,8 +13,9 @@ subarches: xen-vserver [image] +conflicts: grub (<= 0.95+cvs20040624-17) depends: e2fsprogs (>= 1.35-7) -suggests: grub | lilo (>= 19.1) +suggests: grub (>= 0.97-3) | lilo (>= 19.1) [amd64-generic] class: all x86-64 diff --git a/debian/arch/i386/defines b/debian/arch/i386/defines index 169936b82..65e99e36f 100644 --- a/debian/arch/i386/defines +++ b/debian/arch/i386/defines @@ -13,7 +13,8 @@ subarches: xen-vserver [image] -suggests: grub | lilo (>= 19.1) +conflicts: grub (<= 0.95+cvs20040624-17) +suggests: grub (>= 0.97-3) | lilo (>= 19.1) [686] class: PPro/Celeron/PII/PIII/P4 diff --git a/debian/changelog b/debian/changelog index 355147201..0b6d8a19e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,8 +13,9 @@ linux-2.6 (2.6.16-11) UNRELEASED; urgency=low * Update vserver patch to 2.0.2-rc18. - Limit ccaps to root inside a guest + * Conflict with known broken grub versions. (closes: #361308) - -- Bastian Blank Fri, 28 Apr 2006 16:08:01 +0200 + -- Bastian Blank Fri, 28 Apr 2006 22:52:13 +0200 linux-2.6 (2.6.16-10) unstable; urgency=low diff --git a/debian/rules b/debian/rules index 6ec8830d9..c249299c3 100755 --- a/debian/rules +++ b/debian/rules @@ -37,7 +37,7 @@ $(BUILD_DIR) $(STAMPS_DIR): @[ -d $@ ] || mkdir $@ orig: ../orig/linux-$(MAJOR)-$(VERSION) - rsync --delete --exclude debian --exclude .svn --link-dest=../orig/linux-$(MAJOR)-$(VERSION)/ -av ../orig/linux-$(MAJOR)-$(VERSION)/ . + rsync --delete --exclude debian --exclude .svn --link-dest=../orig/linux-$(MAJOR)-$(VERSION)/ -a ../orig/linux-$(MAJOR)-$(VERSION)/ . ../orig/linux-$(MAJOR)-$(VERSION): if [ -f "../linux-$(MAJOR)_$(VERSION).orig.tar.gz" ]; then \ From 6f59375dcba28f541f02b705e19e73c64d5f6d5b Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Fri, 28 Apr 2006 22:03:51 +0000 Subject: [PATCH 055/108] debian/rules: Use variables in orig targets. svn path=/dists/trunk/linux-2.6/; revision=6491 --- debian/rules | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/debian/rules b/debian/rules index c249299c3..950c5bf92 100755 --- a/debian/rules +++ b/debian/rules @@ -36,13 +36,16 @@ $(STAMPS_DIR)/build-base: $(BUILD_DIR) $(STAMPS_DIR) $(STAMPS_DIR)/setup-base $(BUILD_DIR) $(STAMPS_DIR): @[ -d $@ ] || mkdir $@ -orig: ../orig/linux-$(MAJOR)-$(VERSION) - rsync --delete --exclude debian --exclude .svn --link-dest=../orig/linux-$(MAJOR)-$(VERSION)/ -a ../orig/linux-$(MAJOR)-$(VERSION)/ . +DIR_ORIG = ../orig/linux-$(MAJOR)-$(VERSION) +TAR_ORIG = ../linux-$(MAJOR)_$(VERSION).orig.tar.gz -../orig/linux-$(MAJOR)-$(VERSION): - if [ -f "../linux-$(MAJOR)_$(VERSION).orig.tar.gz" ]; then \ +orig: $(DIR_ORIG) + rsync --delete --exclude debian --exclude .svn --link-dest=$(DIR_ORIG)/ -a $(DIR_ORIG)/ . + +$(DIR_ORIG): + if [ -f $(TAR_ORIG) ]; then \ mkdir -p ../orig; \ - tar -C ../orig -xzf ../linux-$(MAJOR)_$(VERSION).orig.tar.gz; \ + tar -C ../orig -xzf $(TAR_ORIG); \ else \ echo "Can't find orig tarball." >&2; \ exit 1; \ From 87d9d0306f26798bd11557a2d6a4f532102753de Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sat, 29 Apr 2006 15:38:56 +0000 Subject: [PATCH 056/108] debian/arch/defines, debian/arch/hppa/defines: Don't set compiler to gcc-4.0 for now, it breaks too much. svn path=/dists/trunk/linux-2.6/; revision=6492 --- debian/arch/defines | 4 +++- debian/arch/hppa/defines | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/debian/arch/defines b/debian/arch/defines index 79d2ff998..105f14382 100644 --- a/debian/arch/defines +++ b/debian/arch/defines @@ -16,7 +16,8 @@ arches: powerpc s390 sparc -compiler: gcc-4.0 +# Disabled as k-p don't allow proper CC definition without MAKEFLAGS, breaks powerpc +# compiler: gcc-4.0 [image] initramfs-generators: initramfs-tools yaird @@ -27,6 +28,7 @@ initramfs-tools: mkinitramfs-kpkg yaird: mkinitrd.yaird [relations] +gcc: gcc (>= 4:4.0) gcc-3.3: gcc-3.3 gcc-4.0: gcc-4.0 initramfs-fallback: linux-initramfs-tool diff --git a/debian/arch/hppa/defines b/debian/arch/hppa/defines index bce0d69d2..50c2981ab 100644 --- a/debian/arch/hppa/defines +++ b/debian/arch/hppa/defines @@ -23,5 +23,6 @@ class: 64-bit PA-RISC class: multi-processor 64-bit PA-RISC [relations] +gcc: gcc (>= 4:4.0), binutils-hppa64, gcc-4.0-hppa64 gcc-4.0: gcc-4.0, binutils-hppa64, gcc-4.0-hppa64 From ba8a8dcf45455676fcb47c4796f7ca39ef3b1c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20Sch=C3=BCler?= Date: Sun, 30 Apr 2006 14:15:23 +0000 Subject: [PATCH 057/108] Update trunk to 2.6.17-rc3. Clean up and merge series files. Swich from HZ_1000 to HZ_250 svn path=/dists/trunk/linux-2.6/; revision=6499 --- debian/arch/alpha/config | 3 - debian/arch/amd64/config | 14 +-- debian/arch/amd64/config.amd64-k8 | 1 + debian/arch/amd64/config.amd64-k8-smp | 6 ++ debian/arch/amd64/config.em64t-p4-smp | 3 + debian/arch/amd64/defines | 6 +- debian/arch/config | 99 +++++++++++++++++++ debian/arch/hppa/config | 6 -- debian/arch/i386/config | 5 - debian/arch/ia64/config | 4 - debian/arch/powerpc/config | 5 - debian/arch/sparc/config | 3 - debian/changelog | 9 +- debian/patches/series/1-extra | 7 -- debian/patches/series/10 | 3 - debian/patches/series/11-extra | 1 - debian/patches/series/3-extra | 1 - debian/patches/series/4 | 2 - debian/patches/series/5-extra | 1 - debian/patches/series/6 | 1 - debian/patches/series/7 | 4 - debian/patches/series/7-extra | 1 - debian/patches/series/8 | 3 - debian/patches/series/9 | 2 - debian/patches/series/9-extra | 1 - debian/patches/series/{1 => 99experimental.1} | 14 +-- debian/patches/series/99experimental.1-extra | 24 +++++ 27 files changed, 157 insertions(+), 72 deletions(-) delete mode 100644 debian/patches/series/1-extra delete mode 100644 debian/patches/series/10 delete mode 100644 debian/patches/series/11-extra delete mode 100644 debian/patches/series/3-extra delete mode 100644 debian/patches/series/4 delete mode 100644 debian/patches/series/5-extra delete mode 100644 debian/patches/series/6 delete mode 100644 debian/patches/series/7 delete mode 100644 debian/patches/series/7-extra delete mode 100644 debian/patches/series/8 delete mode 100644 debian/patches/series/9 delete mode 100644 debian/patches/series/9-extra rename debian/patches/series/{1 => 99experimental.1} (68%) diff --git a/debian/arch/alpha/config b/debian/arch/alpha/config index 80755c15a..8cd1cc1bc 100644 --- a/debian/arch/alpha/config +++ b/debian/arch/alpha/config @@ -1491,10 +1491,7 @@ CONFIG_MMC_BLOCK=m CONFIG_MMC_WBSD=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m -CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_IPOIB=m -CONFIG_INFINIBAND_IPOIB_DEBUG=y -CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y CONFIG_EXT2_FS=y CONFIG_JBD=m CONFIG_FS_MBCACHE=y diff --git a/debian/arch/amd64/config b/debian/arch/amd64/config index 11993410a..af162f855 100644 --- a/debian/arch/amd64/config +++ b/debian/arch/amd64/config @@ -1398,9 +1398,7 @@ CONFIG_MMC_BLOCK=m CONFIG_MMC_WBSD=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set CONFIG_EDD=m CONFIG_JBD=m CONFIG_XFS_RT=y @@ -1499,16 +1497,12 @@ CONFIG_CRC32=y CONFIG_REED_SOLOMON=m CONFIG_REED_SOLOMON_DEC16=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y -CONFIG_PHYSICAL_START=0x100000 CONFIG_KEXEC=y CONFIG_CRYPTO_AES_X86_64=m -# CONFIG_HZ_250 is not set # CONFIG_HZ_100 is not set CONFIG_ACPI_HOTKEY=m # CONFIG_ACPI_SLEEP_PROC_SLEEP is not set CONFIG_JFFS2_FS_WRITEBUFFER=y -CONFIG_HZ_1000=y -CONFIG_HZ=1000 CONFIG_FB_VESA=y CONFIG_HPET_EMULATE_RTC=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -1546,4 +1540,12 @@ CONFIG_EDAC_POLL=y CONFIG_EDAC_I82860=m CONFIG_EDAC_E752X=m CONFIG_EDAC_R82600=m +CONFIG_SERIAL_8250_PCI=y +# CONFIG_ACPI_IBM_DOCK is not set +CONFIG_SERIAL_8250_PNP=y +CONFIG_REORDER=y +CONFIG_AGP_VIA=m +CONFIG_PHYSICAL_START=0x200000 CONFIG_HOTPLUG_CPU=y +CONFIG_X86_INTERNODE_CACHE_BYTES=128 +CONFIG_ACPI_HOTPLUG_MEMORY=m diff --git a/debian/arch/amd64/config.amd64-k8 b/debian/arch/amd64/config.amd64-k8 index 11e330936..b0274d1a5 100644 --- a/debian/arch/amd64/config.amd64-k8 +++ b/debian/arch/amd64/config.amd64-k8 @@ -47,3 +47,4 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set # CONFIG_DISCONTIGMEM_MANUAL is not set CONFIG_X86_MCE_AMD=y +CONFIG_X86_INTERNODE_CACHE_BYTES=64 diff --git a/debian/arch/amd64/config.amd64-k8-smp b/debian/arch/amd64/config.amd64-k8-smp index 65f6ccc63..5bf827149 100644 --- a/debian/arch/amd64/config.amd64-k8-smp +++ b/debian/arch/amd64/config.amd64-k8-smp @@ -32,3 +32,9 @@ CONFIG_X86_MCE_AMD=y CONFIG_X86_64_ACPI_NUMA=y CONFIG_ACPI_NUMA=y CONFIG_MIGRATION=y +CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y +CONFIG_SCHED_MC=y +CONFIG_NODES_SHIFT=6 +CONFIG_SUSPEND_SMP=y +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_X86_INTERNODE_CACHE_BYTES=64 diff --git a/debian/arch/amd64/config.em64t-p4-smp b/debian/arch/amd64/config.em64t-p4-smp index b4e2aad99..41783ef86 100644 --- a/debian/arch/amd64/config.em64t-p4-smp +++ b/debian/arch/amd64/config.em64t-p4-smp @@ -25,3 +25,6 @@ CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set # CONFIG_DISCONTIGMEM_MANUAL is not set # CONFIG_X86_MCE_AMD is not set +CONFIG_SCHED_MC=y +CONFIG_SUSPEND_SMP=y +CONFIG_ACPI_HOTPLUG_CPU=y diff --git a/debian/arch/amd64/defines b/debian/arch/amd64/defines index 740003105..14ad74e22 100644 --- a/debian/arch/amd64/defines +++ b/debian/arch/amd64/defines @@ -8,9 +8,9 @@ flavours: kernel-arch: x86_64 kernel-header-dirs: x86_64 i386 subarches: - vserver - xen - xen-vserver +# vserver +# xen +# xen-vserver [image] conflicts: grub (<= 0.95+cvs20040624-17) diff --git a/debian/arch/config b/debian/arch/config index faa83db76..e3ee77ab1 100644 --- a/debian/arch/config +++ b/debian/arch/config @@ -812,3 +812,102 @@ CONFIG_VIDEO_CX88_VP3054=m CONFIG_NFSD_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFS_V4=y +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_MMC_SDHCI=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_VIDEO_SAA7127=m +# CONFIG_RELAY is not set +CONFIG_W1_MASTER_DS9490_BRIDGE=m +# CONFIG_BCM43XX_DMA_MODE is not set +CONFIG_RTC_LIB=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_GIGASET_BASE=m +CONFIG_LSF=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_IEEE80211_SOFTMAC=m +CONFIG_NEW_LEDS=y +CONFIG_IP_NF_H323=m +CONFIG_RTC_DRV_M48T86=m +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_SND_RIPTIDE=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_WM8775=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +# CONFIG_RTC_DRV_TEST is not set +CONFIG_W1_MASTER_MATROX=m +CONFIG_IPATH_CORE=m +CONFIG_INFINIBAND_IPATH=m +CONFIG_RTC_INTF_DEV=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_USB_ZC0301=m +CONFIG_VIDEO_MSP3400=m +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_DRV_X1205=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_LEDS_TRIGGER_TIMER=m +# CONFIG_BCM43XX_DEBUG is not set +CONFIG_W1_MASTER_DS9490=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_RTC_DRV_DS1672=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_VIDEO_CX25840=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_LEDS_CLASS=m +CONFIG_VIDEO_USBVIDEO=m +# CONFIG_FB_FIRMWARE_EDID is not set +# CONFIG_USB_GADGET_AT91 is not set +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_INTF_PROC=m +CONFIG_BCM43XX_DMA=y +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_GIGASET_M105=m +CONFIG_NET_WIRELESS_RTNETLINK=y +CONFIG_ISDN_DRV_GIGASET=m +# CONFIG_UNWIND_INFO is not set +CONFIG_BCM43XX=m +CONFIG_USB_DABUSB=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_DVB_ZL10353=m +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +CONFIG_IP_DCCP_CCID2=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_GIGASET_DEBUG is not set +CONFIG_W1_SLAVE_SMEM=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW_QOS=y +CONFIG_VIDEO_CS53L32A=m +# CONFIG_BCM43XX_PIO_MODE is not set +CONFIG_W1_MASTER_DS2482=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_CPIA2=m +CONFIG_BCM43XX_PIO=y +CONFIG_IP_NF_NAT_H323=m +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_WIRELESS_EXT=y +CONFIG_W1_SLAVE_THERM=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_SND_ALS300=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_TOUCHSCREEN=m +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_USB_TOUCHSCREEN_PANJIT=y +CONFIG_USB_TOUCHSCREEN_ITM=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_USB_TOUCHSCREEN_EGALAX=y +CONFIG_USB_TOUCHSCREEN_3M=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 diff --git a/debian/arch/hppa/config b/debian/arch/hppa/config index 9997c6ab7..2c08024d7 100644 --- a/debian/arch/hppa/config +++ b/debian/arch/hppa/config @@ -732,9 +732,7 @@ CONFIG_USB_MOUSE=m # CONFIG_MMC is not set CONFIG_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set CONFIG_EXT2_FS=y CONFIG_JBD=m # CONFIG_JBD_DEBUG is not set @@ -804,16 +802,12 @@ CONFIG_NFS_ACL_SUPPORT=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_HZ=250 CONFIG_FLATMEM_MANUAL=y # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_MEGARAID_MM=m CONFIG_PARPORT_NOT_PC=y CONFIG_MEGARAID_MAILBOX=m # CONFIG_DISCONTIGMEM_MANUAL is not set -CONFIG_SCSI_SYM53C8XX_MMIO=y CONFIG_SPLIT_PTLOCK_CPUS=4096 # CONFIG_IPW2100 is not set diff --git a/debian/arch/i386/config b/debian/arch/i386/config index d4984cb31..d4378dd95 100644 --- a/debian/arch/i386/config +++ b/debian/arch/i386/config @@ -1647,9 +1647,7 @@ CONFIG_MMC_BLOCK=m CONFIG_MMC_WBSD=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set CONFIG_JBD=m CONFIG_XFS_RT=y CONFIG_TMPFS_XATTR=y @@ -1760,9 +1758,6 @@ CONFIG_GENERIC_IRQ_PROBE=y CONFIG_X86_BIOS_REBOOT=y CONFIG_KEXEC=y # CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 CONFIG_PHYSICAL_START=0x100000 CONFIG_HOTPLUG_CPU=y CONFIG_HPET_EMULATE_RTC=y diff --git a/debian/arch/ia64/config b/debian/arch/ia64/config index 0ceeec104..611c85f4c 100644 --- a/debian/arch/ia64/config +++ b/debian/arch/ia64/config @@ -27,8 +27,6 @@ CONFIG_IA64_PAGE_SIZE_16KB=y CONFIG_PGTABLE_3=y # CONFIG_PGTABLE_4 is not set # CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set CONFIG_NUMA=y CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y @@ -1165,9 +1163,7 @@ CONFIG_MMC=m CONFIG_MMC_BLOCK=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set CONFIG_SGI_IOC3=m CONFIG_JBD=m CONFIG_FS_MBCACHE=m diff --git a/debian/arch/powerpc/config b/debian/arch/powerpc/config index 3a06057f1..59eb59f39 100644 --- a/debian/arch/powerpc/config +++ b/debian/arch/powerpc/config @@ -1131,9 +1131,7 @@ CONFIG_MMC_BLOCK=m CONFIG_MMC_WBSD=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set CONFIG_JBD=m CONFIG_FS_MBCACHE=m CONFIG_TMPFS_XATTR=y @@ -1215,9 +1213,6 @@ CONFIG_BOOTX_TEXT=y CONFIG_KEXEC=y CONFIG_PMAC_MEDIABAY=y # CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 CONFIG_SND_POWERMAC_AUTO_DRC=y CONFIG_USB_APPLETOUCH=m CONFIG_SOFTWARE_SUSPEND=y diff --git a/debian/arch/sparc/config b/debian/arch/sparc/config index b9cee081a..cad77deed 100644 --- a/debian/arch/sparc/config +++ b/debian/arch/sparc/config @@ -351,10 +351,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_DEBUG_BUGVERBOSE=y CONFIG_CRC_CCITT=m CONFIG_CRC32=y -CONFIG_HZ=250 -# CONFIG_HZ_1000 is not set # CONFIG_HZ_100 is not set -CONFIG_HZ_250=y CONFIG_SND_SUN_DBRI=m # CONFIG_SOUND_PRIME is not set # CONFIG_PPDEV is not set diff --git a/debian/changelog b/debian/changelog index 0b6d8a19e..1792af7f4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,13 +1,14 @@ -linux-2.6 (2.6.16-99experimental.1) UNRELEASED; urgency=low +linux-2.6 (2.6.17-rc3-99experimental.1) UNRELEASED; urgency=low - [ Bastian Blank ] - * + [ Frederik Schüler ] + * New upstream release. + * Switch HZ from 1000 to 250, following upstreams default. [ maximilian attems ] * Disable broken and known unsecure LSM modules: CONFIG_SECURITY_SECLVL, CONFIG_SECURITY_ROOTPLUG. Upstream plans to remove them for 2.6.18 - -- maximilian attems Tue, 18 Apr 2006 02:09:27 +0200 + -- Frederik Schüler Sun, 30 Apr 2006 15:54:15 +0200 linux-2.6 (2.6.16-11) UNRELEASED; urgency=low diff --git a/debian/patches/series/1-extra b/debian/patches/series/1-extra deleted file mode 100644 index a6048204e..000000000 --- a/debian/patches/series/1-extra +++ /dev/null @@ -1,7 +0,0 @@ -+ maclist.patch arm armeb -+ arm-nslu2-maclist.patch arm armeb -+ vserver-version.patch *_vserver *_xen-vserver -+ vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver -+ vserver-xen-clash.patch *_xen-vserver -+ mips-tulip.patch mipsel -+ mips-tulip_dc21143.patch mipsel diff --git a/debian/patches/series/10 b/debian/patches/series/10 deleted file mode 100644 index 656a136e7..000000000 --- a/debian/patches/series/10 +++ /dev/null @@ -1,3 +0,0 @@ -+ alpha-build-fix.patch -+ 2.6.16.10 -+ 2.6.16.11 diff --git a/debian/patches/series/11-extra b/debian/patches/series/11-extra deleted file mode 100644 index 74a272487..000000000 --- a/debian/patches/series/11-extra +++ /dev/null @@ -1 +0,0 @@ -+ vserver-vs2.0.2-rc18-update.patch *_vserver diff --git a/debian/patches/series/3-extra b/debian/patches/series/3-extra deleted file mode 100644 index 466fd7294..000000000 --- a/debian/patches/series/3-extra +++ /dev/null @@ -1 +0,0 @@ -+ vserver-vs2.0.2-rc14-update.patch *_vserver *_xen-vserver diff --git a/debian/patches/series/4 b/debian/patches/series/4 deleted file mode 100644 index dc52e44c7..000000000 --- a/debian/patches/series/4 +++ /dev/null @@ -1,2 +0,0 @@ -+ 2.6.16.1 -+ mips-sb1-duart-tts.patch diff --git a/debian/patches/series/5-extra b/debian/patches/series/5-extra deleted file mode 100644 index 77e16abab..000000000 --- a/debian/patches/series/5-extra +++ /dev/null @@ -1 +0,0 @@ -+ vserver-vs2.0.2-rc15-update.patch *_vserver diff --git a/debian/patches/series/6 b/debian/patches/series/6 deleted file mode 100644 index c5667a7c9..000000000 --- a/debian/patches/series/6 +++ /dev/null @@ -1 +0,0 @@ -+ 2.6.16.2 diff --git a/debian/patches/series/7 b/debian/patches/series/7 deleted file mode 100644 index ee82a76a5..000000000 --- a/debian/patches/series/7 +++ /dev/null @@ -1,4 +0,0 @@ -+ 2.6.16.3 -+ 2.6.16.4 -+ powerpc-mkvmlinuz-support-2.patch -+ 2.6.16.5 diff --git a/debian/patches/series/7-extra b/debian/patches/series/7-extra deleted file mode 100644 index 9dfd712f5..000000000 --- a/debian/patches/series/7-extra +++ /dev/null @@ -1 +0,0 @@ -+ m68k-2.6.16.patch m68k diff --git a/debian/patches/series/8 b/debian/patches/series/8 deleted file mode 100644 index 1a661e288..000000000 --- a/debian/patches/series/8 +++ /dev/null @@ -1,3 +0,0 @@ -+ include-linux-seccomp-abifix.patch -+ 2.6.16.6 -+ 2.6.16.7 diff --git a/debian/patches/series/9 b/debian/patches/series/9 deleted file mode 100644 index 7e4a5a59c..000000000 --- a/debian/patches/series/9 +++ /dev/null @@ -1,2 +0,0 @@ -+ 2.6.16.8 -+ 2.6.16.9 diff --git a/debian/patches/series/9-extra b/debian/patches/series/9-extra deleted file mode 100644 index 51e64a1f8..000000000 --- a/debian/patches/series/9-extra +++ /dev/null @@ -1 +0,0 @@ -+ vserver-vs2.0.2-rc17-update.patch *_vserver diff --git a/debian/patches/series/1 b/debian/patches/series/99experimental.1 similarity index 68% rename from debian/patches/series/1 rename to debian/patches/series/99experimental.1 index bcdab29d0..ca11d55ab 100644 --- a/debian/patches/series/1 +++ b/debian/patches/series/99experimental.1 @@ -1,6 +1,6 @@ + buslogic-pci-id-table.patch + fbdev-radeon-noaccel.patch -+ fs-asfs-2.patch +#FIXME + fs-asfs-2.patch + modular-ide-pnp.patch + version.patch # @@ -11,15 +11,17 @@ + powerpc-mv643xx-hotplug-support.patch + sparc64-hme-lockup.patch + sparc64-atyfb-xl-gr.patch -+ mips-makefile.patch -+ mips-arch-makefile.patch +#FIXME + mips-makefile.patch +#FIXME + mips-arch-makefile.patch + mips-gettimeofday.patch + mips-ide-scan.patch -+ mips-sb1-probe-ide.patch -+ mips-sb1-eth-1480.patch +#FIXME + mips-sb1-probe-ide.patch +#FIXME + mips-sb1-eth-1480.patch + mips-sb1-eth-napi.patch + mips-sb1-duart.patch + video-vino-64-bit-fix-kernel.diff + s390-drivers-ccw-uevent-modalias.patch + s390-drivers-ccw-uevent-cleanup.patch -+ scripts-newmake.patch +#FIXME + scripts-newmake.patch ++ mips-sb1-duart-tts.patch +#FIXME + powerpc-mkvmlinuz-support-2.patch diff --git a/debian/patches/series/99experimental.1-extra b/debian/patches/series/99experimental.1-extra index b6d0d8ba5..e2f337b0e 100644 --- a/debian/patches/series/99experimental.1-extra +++ b/debian/patches/series/99experimental.1-extra @@ -1,2 +1,26 @@ + xen-tree-merge-22448.patch *_xen *_xen-vserver + xen-tls.patch *_xen *_xen-vserver ++ maclist.patch arm armeb ++ arm-nslu2-maclist.patch arm armeb ++ vserver-version.patch *_vserver *_xen-vserver ++ vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver ++ vserver-xen-clash.patch *_xen-vserver ++ mips-tulip.patch mipsel ++ mips-tulip_dc21143.patch mipsel ++ vserver-vs2.0.2-rc14-update.patch *_vserver *_xen-vserver ++ vserver-vs2.0.2-rc15-update.patch *_vserver ++ xen-tree-merge-22448.patch *_xen *_xen-vserver ++ xen-tls.patch *_xen *_xen-vserver ++ arm-nslu2-maclist.patch arm armeb ++ maclist.patch arm armeb ++ mips-tulip.patch mipsel ++ mips-tulip_dc21143.patch mipsel ++ vserver-version.patch *_vserver *_xen-vserver ++ vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver ++ vserver-vs2.0.2-rc14-update.patch *_vserver *_xen-vserver ++ vserver-vs2.0.2-rc15-update.patch *_vserver ++ vserver-vs2.0.2-rc17-update.patch *_vserver ++ vserver-vs2.0.2-rc18-update.patch *_vserver ++ vserver-xen-clash.patch *_xen-vserver ++ xen-tls.patch *_xen *_xen-vserver ++ xen-tree-merge-22448.patch *_xen *_xen-vserver From 6495dde216d310013aace62cd4e0fb2cd591768e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frederik=20Sch=C3=BCler?= Date: Sun, 30 Apr 2006 14:43:28 +0000 Subject: [PATCH 058/108] Deactivate xen and vserver for all concerned architectures. clean up -extra series file. svn path=/dists/trunk/linux-2.6/; revision=6500 --- debian/arch/i386/defines | 6 ++-- debian/arch/powerpc/defines | 2 +- debian/changelog | 4 ++- debian/patches/series/99experimental.1-extra | 33 ++++++-------------- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/debian/arch/i386/defines b/debian/arch/i386/defines index 65e99e36f..080e78d81 100644 --- a/debian/arch/i386/defines +++ b/debian/arch/i386/defines @@ -8,9 +8,9 @@ flavours: kernel-arch: i386 kernel-header-dirs: i386 subarches: - vserver - xen - xen-vserver +# vserver +# xen +# xen-vserver [image] conflicts: grub (<= 0.95+cvs20040624-17) diff --git a/debian/arch/powerpc/defines b/debian/arch/powerpc/defines index be2c30f24..519231a97 100644 --- a/debian/arch/powerpc/defines +++ b/debian/arch/powerpc/defines @@ -8,7 +8,7 @@ kernel-header-dirs: powerpc ppc m68k kernel-arch: powerpc kpkg-subarch: ppc subarches: - vserver +# vserver [apus] depends: mkvmlinuz (>= 20) diff --git a/debian/changelog b/debian/changelog index 1792af7f4..40a1f3dfb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,12 +3,14 @@ linux-2.6 (2.6.17-rc3-99experimental.1) UNRELEASED; urgency=low [ Frederik Schüler ] * New upstream release. * Switch HZ from 1000 to 250, following upstreams default. + * deactivate xen for amd64 and i386, vserver for amd64 i386 powerpc. [ maximilian attems ] * Disable broken and known unsecure LSM modules: CONFIG_SECURITY_SECLVL, CONFIG_SECURITY_ROOTPLUG. Upstream plans to remove them for 2.6.18 - -- Frederik Schüler Sun, 30 Apr 2006 15:54:15 +0200 + + -- Frederik Schüler Sun, 30 Apr 2006 16:35:05 +0200 linux-2.6 (2.6.16-11) UNRELEASED; urgency=low diff --git a/debian/patches/series/99experimental.1-extra b/debian/patches/series/99experimental.1-extra index e2f337b0e..50b2eaac3 100644 --- a/debian/patches/series/99experimental.1-extra +++ b/debian/patches/series/99experimental.1-extra @@ -1,26 +1,13 @@ -+ xen-tree-merge-22448.patch *_xen *_xen-vserver -+ xen-tls.patch *_xen *_xen-vserver + maclist.patch arm armeb -+ arm-nslu2-maclist.patch arm armeb -+ vserver-version.patch *_vserver *_xen-vserver -+ vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver -+ vserver-xen-clash.patch *_xen-vserver +#FIXME + arm-nslu2-maclist.patch arm armeb + mips-tulip.patch mipsel + mips-tulip_dc21143.patch mipsel -+ vserver-vs2.0.2-rc14-update.patch *_vserver *_xen-vserver -+ vserver-vs2.0.2-rc15-update.patch *_vserver -+ xen-tree-merge-22448.patch *_xen *_xen-vserver -+ xen-tls.patch *_xen *_xen-vserver -+ arm-nslu2-maclist.patch arm armeb -+ maclist.patch arm armeb -+ mips-tulip.patch mipsel -+ mips-tulip_dc21143.patch mipsel -+ vserver-version.patch *_vserver *_xen-vserver -+ vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver -+ vserver-vs2.0.2-rc14-update.patch *_vserver *_xen-vserver -+ vserver-vs2.0.2-rc15-update.patch *_vserver -+ vserver-vs2.0.2-rc17-update.patch *_vserver -+ vserver-vs2.0.2-rc18-update.patch *_vserver -+ vserver-xen-clash.patch *_xen-vserver -+ xen-tls.patch *_xen *_xen-vserver -+ xen-tree-merge-22448.patch *_xen *_xen-vserver +#+ xen-tree-merge-22448.patch *_xen *_xen-vserver +#+ xen-tls.patch *_xen *_xen-vserver +#+ vserver-version.patch *_vserver *_xen-vserver +#+ vserver-xen-clash.patch *_xen-vserver +#+ vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver +#+ vserver-vs2.0.2-rc14-update.patch *_vserver *_xen-vserver +#+ vserver-vs2.0.2-rc15-update.patch *_vserver +#+ vserver-vs2.0.2-rc17-update.patch *_vserver +#+ vserver-vs2.0.2-rc18-update.patch *_vserver From 836f68b7efd69ebff5f6b51df876f60f6786e67b Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Sun, 30 Apr 2006 14:46:26 +0000 Subject: [PATCH 059/108] * debian/changelog: Fix version. * debian/patches/series/0experimental.1, debian/patches/series/0experimental.1-extra: Fix. * debian/patches/vserver-vs2.0.2-rc13.patch, debian/patches/vserver-vs2.0.2-rc14-update.patch, debian/patches/vserver-vs2.0.2-rc15-update.patch, debian/patches/vserver-vs2.0.2-rc17-update.patch, debian/patches/vserver-vs2.0.2-rc18-update.patch, debian/patches/xen-tree-merge-22448.patch: Remove svn path=/dists/trunk/linux-2.6/; revision=6501 --- debian/changelog | 4 +- .../{99experimental.1 => 0experimental.1} | 0 debian/patches/series/0experimental.1-extra | 5 + debian/patches/series/99experimental.1-extra | 13 - debian/patches/vserver-vs2.0.2-rc13.patch | 21745 ----- .../patches/vserver-vs2.0.2-rc14-update.patch | 44 - .../patches/vserver-vs2.0.2-rc15-update.patch | 679 - .../patches/vserver-vs2.0.2-rc17-update.patch | 75 - .../patches/vserver-vs2.0.2-rc18-update.patch | 349 - debian/patches/xen-tree-merge-22448.patch | 79333 ---------------- 10 files changed, 7 insertions(+), 102240 deletions(-) rename debian/patches/series/{99experimental.1 => 0experimental.1} (100%) create mode 100644 debian/patches/series/0experimental.1-extra delete mode 100644 debian/patches/series/99experimental.1-extra delete mode 100644 debian/patches/vserver-vs2.0.2-rc13.patch delete mode 100644 debian/patches/vserver-vs2.0.2-rc14-update.patch delete mode 100644 debian/patches/vserver-vs2.0.2-rc15-update.patch delete mode 100644 debian/patches/vserver-vs2.0.2-rc17-update.patch delete mode 100644 debian/patches/vserver-vs2.0.2-rc18-update.patch delete mode 100644 debian/patches/xen-tree-merge-22448.patch diff --git a/debian/changelog b/debian/changelog index 40a1f3dfb..c839dcb41 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,14 +1,14 @@ -linux-2.6 (2.6.17-rc3-99experimental.1) UNRELEASED; urgency=low +linux-2.6 (2.6.16+2.6.17-rc3-0experimental.1) UNRELEASED; urgency=low [ Frederik Schüler ] * New upstream release. * Switch HZ from 1000 to 250, following upstreams default. - * deactivate xen for amd64 and i386, vserver for amd64 i386 powerpc. [ maximilian attems ] * Disable broken and known unsecure LSM modules: CONFIG_SECURITY_SECLVL, CONFIG_SECURITY_ROOTPLUG. Upstream plans to remove them for 2.6.18 + -- Bastian Blank Sat, 29 Apr 2006 22:56:29 +0200 -- Frederik Schüler Sun, 30 Apr 2006 16:35:05 +0200 diff --git a/debian/patches/series/99experimental.1 b/debian/patches/series/0experimental.1 similarity index 100% rename from debian/patches/series/99experimental.1 rename to debian/patches/series/0experimental.1 diff --git a/debian/patches/series/0experimental.1-extra b/debian/patches/series/0experimental.1-extra new file mode 100644 index 000000000..344d42e9d --- /dev/null +++ b/debian/patches/series/0experimental.1-extra @@ -0,0 +1,5 @@ ++ maclist.patch arm armeb ++ arm-nslu2-maclist.patch arm armeb ++ vserver-version.patch *_vserver *_xen-vserver ++ mips-tulip.patch mipsel ++ mips-tulip_dc21143.patch mipsel diff --git a/debian/patches/series/99experimental.1-extra b/debian/patches/series/99experimental.1-extra deleted file mode 100644 index 50b2eaac3..000000000 --- a/debian/patches/series/99experimental.1-extra +++ /dev/null @@ -1,13 +0,0 @@ -+ maclist.patch arm armeb -#FIXME + arm-nslu2-maclist.patch arm armeb -+ mips-tulip.patch mipsel -+ mips-tulip_dc21143.patch mipsel -#+ xen-tree-merge-22448.patch *_xen *_xen-vserver -#+ xen-tls.patch *_xen *_xen-vserver -#+ vserver-version.patch *_vserver *_xen-vserver -#+ vserver-xen-clash.patch *_xen-vserver -#+ vserver-vs2.0.2-rc13.patch *_vserver *_xen-vserver -#+ vserver-vs2.0.2-rc14-update.patch *_vserver *_xen-vserver -#+ vserver-vs2.0.2-rc15-update.patch *_vserver -#+ vserver-vs2.0.2-rc17-update.patch *_vserver -#+ vserver-vs2.0.2-rc18-update.patch *_vserver diff --git a/debian/patches/vserver-vs2.0.2-rc13.patch b/debian/patches/vserver-vs2.0.2-rc13.patch deleted file mode 100644 index bcfa24ae4..000000000 --- a/debian/patches/vserver-vs2.0.2-rc13.patch +++ /dev/null @@ -1,21745 +0,0 @@ -diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig -index eedf41b..816a4d5 100644 ---- a/arch/alpha/Kconfig -+++ b/arch/alpha/Kconfig -@@ -619,6 +619,8 @@ source "arch/alpha/oprofile/Kconfig" - - source "arch/alpha/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S -index 7af15bf..780cb93 100644 ---- a/arch/alpha/kernel/entry.S -+++ b/arch/alpha/kernel/entry.S -@@ -874,24 +874,15 @@ sys_getxgid: - .globl sys_getxpid - .ent sys_getxpid - sys_getxpid: -+ lda $sp, -16($sp) -+ stq $26, 0($sp) - .prologue 0 -- ldq $2, TI_TASK($8) - -- /* See linux/kernel/timer.c sys_getppid for discussion -- about this loop. */ -- ldq $3, TASK_GROUP_LEADER($2) -- ldq $4, TASK_REAL_PARENT($3) -- ldl $0, TASK_TGID($2) --1: ldl $1, TASK_TGID($4) --#ifdef CONFIG_SMP -- mov $4, $5 -- mb -- ldq $3, TASK_GROUP_LEADER($2) -- ldq $4, TASK_REAL_PARENT($3) -- cmpeq $4, $5, $5 -- beq $5, 1b --#endif -- stq $1, 80($sp) -+ lda $16, 96($sp) -+ jsr $26, do_getxpid -+ ldq $26, 0($sp) -+ -+ lda $sp, 16($sp) - ret - .end sys_getxpid - -diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c -index 0cd0605..edb3086 100644 ---- a/arch/alpha/kernel/ptrace.c -+++ b/arch/alpha/kernel/ptrace.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -283,6 +284,11 @@ do_sys_ptrace(long request, long pid, lo - goto out_notsk; - } - -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) { -+ ret = -EPERM; -+ goto out; -+ } -+ - if (request == PTRACE_ATTACH) { - ret = ptrace_attach(child); - goto out; -diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S -index 4342cea..1c5c9e3 100644 ---- a/arch/alpha/kernel/systbls.S -+++ b/arch/alpha/kernel/systbls.S -@@ -447,7 +447,7 @@ sys_call_table: - .quad sys_stat64 /* 425 */ - .quad sys_lstat64 - .quad sys_fstat64 -- .quad sys_ni_syscall /* sys_vserver */ -+ .quad sys_vserver /* sys_vserver */ - .quad sys_ni_syscall /* sys_mbind */ - .quad sys_ni_syscall /* sys_get_mempolicy */ - .quad sys_ni_syscall /* sys_set_mempolicy */ -diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c -index 486d794..038f38e 100644 ---- a/arch/alpha/mm/init.c -+++ b/arch/alpha/mm/init.c -@@ -21,6 +21,7 @@ - #include - #include /* max_low_pfn */ - #include -+#include - - #include - #include -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 9f80fa5..189262b 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -825,6 +825,8 @@ source "arch/arm/oprofile/Kconfig" - - source "arch/arm/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S -index 3173924..83c02a7 100644 ---- a/arch/arm/kernel/calls.S -+++ b/arch/arm/kernel/calls.S -@@ -322,7 +322,7 @@ - /* 310 */ CALL(sys_request_key) - CALL(sys_keyctl) - CALL(ABI(sys_semtimedop, sys_oabi_semtimedop)) --/* vserver */ CALL(sys_ni_syscall) -+ CALL(sys_vserver) - CALL(sys_ioprio_set) - /* 315 */ CALL(sys_ioprio_get) - CALL(sys_inotify_init) -diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig -index dee23d8..76d4054 100644 ---- a/arch/arm26/Kconfig -+++ b/arch/arm26/Kconfig -@@ -230,6 +230,8 @@ source "drivers/usb/Kconfig" - - source "arch/arm26/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/arm26/kernel/calls.S b/arch/arm26/kernel/calls.S -index e3d2768..3e8672a 100644 ---- a/arch/arm26/kernel/calls.S -+++ b/arch/arm26/kernel/calls.S -@@ -257,6 +257,11 @@ __syscall_start: - .long sys_lremovexattr - .long sys_fremovexattr - .long sys_tkill -+ -+ .rept 313 - (. - __syscall_start) / 4 -+ .long sys_ni_syscall -+ .endr -+ .long sys_vserver /* 313 */ - __syscall_end: - - .rept NR_syscalls - (__syscall_end - __syscall_start) / 4 -diff --git a/arch/arm26/kernel/traps.c b/arch/arm26/kernel/traps.c -index 5847ea5..4110862 100644 ---- a/arch/arm26/kernel/traps.c -+++ b/arch/arm26/kernel/traps.c -@@ -186,8 +186,9 @@ NORET_TYPE void die(const char *str, str - printk("Internal error: %s: %x\n", str, err); - printk("CPU: %d\n", smp_processor_id()); - show_regs(regs); -- printk("Process %s (pid: %d, stack limit = 0x%p)\n", -- current->comm, current->pid, end_of_stack(tsk)); -+ printk("Process %s (pid: %d[#%u], stack limit = 0x%p)\n", -+ current->comm, current->pid, -+ current->xid, end_of_stack(tsk)); - - if (!user_mode(regs) || in_interrupt()) { - __dump_stack(tsk, (unsigned long)(regs + 1)); -diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig -index b832619..4afa431 100644 ---- a/arch/cris/Kconfig -+++ b/arch/cris/Kconfig -@@ -173,6 +173,8 @@ source "drivers/usb/Kconfig" - - source "arch/cris/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/frv/mm/mmu-context.c b/arch/frv/mm/mmu-context.c -index f2c6866..6983198 100644 ---- a/arch/frv/mm/mmu-context.c -+++ b/arch/frv/mm/mmu-context.c -@@ -11,6 +11,7 @@ - - #include - #include -+#include - #include - - #define NR_CXN 4096 -diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig -index 98308b0..a6038b0 100644 ---- a/arch/h8300/Kconfig -+++ b/arch/h8300/Kconfig -@@ -191,6 +191,8 @@ source "fs/Kconfig" - - source "arch/h8300/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig -index 5b1a7d4..e37c177 100644 ---- a/arch/i386/Kconfig -+++ b/arch/i386/Kconfig -@@ -466,23 +466,43 @@ choice - will also likely make your kernel incompatible with binary-only - kernel modules. - -- If you are not absolutely sure what you are doing, leave this -- option alone! -- - config VMSPLIT_3G -- bool "3G/1G user/kernel split" -- config VMSPLIT_3G_OPT -- bool "3G/1G user/kernel split (for full 1G low memory)" -+ bool "3G/1G user/kernel split (Default)" -+ help -+ This is the default split of 3GB userspace to 1GB kernel -+ space, which will result in about 860MB of lowmem. -+ -+ config VMSPLIT_25G -+ bool "2.5G/1.5G user/kernel split" -+ help -+ This split provides 2.5GB userspace and 1.5GB kernel -+ space, which will result in about 1370MB of lowmem. -+ - config VMSPLIT_2G - bool "2G/2G user/kernel split" -+ help -+ This split provides 2GB userspace and 2GB kernel -+ space, which will result in about 1880MB of lowmem. -+ -+ config VMSPLIT_15G -+ bool "1.5G/2.5G user/kernel split" -+ help -+ This split provides 1.5GB userspace and 2.5GB kernel -+ space, which will result in about 2390MB of lowmem. -+ - config VMSPLIT_1G - bool "1G/3G user/kernel split" -+ help -+ This split provides 1GB userspace and 3GB kernel -+ space, which will result in about 2900MB of lowmem. -+ - endchoice - - config PAGE_OFFSET - hex -- default 0xB0000000 if VMSPLIT_3G_OPT -- default 0x78000000 if VMSPLIT_2G -+ default 0xA0000000 if VMSPLIT_25G -+ default 0x80000000 if VMSPLIT_2G -+ default 0x60000000 if VMSPLIT_15G - default 0x40000000 if VMSPLIT_1G - default 0xC0000000 - -@@ -1071,6 +1091,8 @@ endmenu - - source "arch/i386/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c -index f19f3a7..6f96229 100644 ---- a/arch/i386/boot/compressed/misc.c -+++ b/arch/i386/boot/compressed/misc.c -@@ -309,7 +309,7 @@ static void setup_normal_output_buffer(v - #else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); - #endif -- output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */ -+ output_data = (char *)PHYSICAL_START; /* Normally Points to 1M */ - free_mem_end_ptr = (long)real_mode; - } - -@@ -334,8 +334,8 @@ static void setup_output_buffer_if_we_ru - low_buffer_size = low_buffer_end - LOW_BUFFER_START; - high_loaded = 1; - free_mem_end_ptr = (long)high_buffer_start; -- if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { -- high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); -+ if ((PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { -+ high_buffer_start = (uch *)(PHYSICAL_START + low_buffer_size); - mv->hcount = 0; /* say: we need not to move high_buffer */ - } - else mv->hcount = -1; -diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c -index ab62a9f..0fc23c0 100644 ---- a/arch/i386/kernel/setup.c -+++ b/arch/i386/kernel/setup.c -@@ -1192,8 +1192,8 @@ void __init setup_bootmem_allocator(void - * the (very unlikely) case of us accidentally initializing the - * bootmem allocator with an invalid RAM area. - */ -- reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) + -- bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START)); -+ reserve_bootmem(PHYSICAL_START, (PFN_PHYS(min_low_pfn) + -+ bootmap_size + PAGE_SIZE-1) - (PHYSICAL_START)); - - /* - * reserve physical page 0 - it's a special BIOS page on many boxes, -diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c -index a4a6197..e68b2ba 100644 ---- a/arch/i386/kernel/sys_i386.c -+++ b/arch/i386/kernel/sys_i386.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -217,7 +218,7 @@ asmlinkage int sys_uname(struct old_utsn - if (!name) - return -EFAULT; - down_read(&uts_sem); -- err=copy_to_user(name, &system_utsname, sizeof (*name)); -+ err=copy_to_user(name, vx_new_utsname(), sizeof (*name)); - up_read(&uts_sem); - return err?-EFAULT:0; - } -@@ -225,6 +226,7 @@ asmlinkage int sys_uname(struct old_utsn - asmlinkage int sys_olduname(struct oldold_utsname __user * name) - { - int error; -+ struct new_utsname *ptr; - - if (!name) - return -EFAULT; -@@ -233,15 +235,16 @@ asmlinkage int sys_olduname(struct oldol - - down_read(&uts_sem); - -- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); -+ ptr = vx_new_utsname(); -+ error = __copy_to_user(&name->sysname,ptr->sysname,__OLD_UTS_LEN); - error |= __put_user(0,name->sysname+__OLD_UTS_LEN); -- error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); -+ error |= __copy_to_user(&name->nodename,ptr->nodename,__OLD_UTS_LEN); - error |= __put_user(0,name->nodename+__OLD_UTS_LEN); -- error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); -+ error |= __copy_to_user(&name->release,ptr->release,__OLD_UTS_LEN); - error |= __put_user(0,name->release+__OLD_UTS_LEN); -- error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); -+ error |= __copy_to_user(&name->version,ptr->version,__OLD_UTS_LEN); - error |= __put_user(0,name->version+__OLD_UTS_LEN); -- error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); -+ error |= __copy_to_user(&name->machine,ptr->machine,__OLD_UTS_LEN); - error |= __put_user(0,name->machine+__OLD_UTS_LEN); - - up_read(&uts_sem); -diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S -index ac687d0..5c2afb2 100644 ---- a/arch/i386/kernel/syscall_table.S -+++ b/arch/i386/kernel/syscall_table.S -@@ -272,7 +272,7 @@ ENTRY(sys_call_table) - .long sys_tgkill /* 270 */ - .long sys_utimes - .long sys_fadvise64_64 -- .long sys_ni_syscall /* sys_vserver */ -+ .long sys_vserver - .long sys_mbind - .long sys_get_mempolicy - .long sys_set_mempolicy -diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c -index b814dbd..610d2f9 100644 ---- a/arch/i386/kernel/traps.c -+++ b/arch/i386/kernel/traps.c -@@ -53,6 +53,7 @@ - #include - - #include -+#include - - #include "mach_traps.h" - -@@ -252,8 +253,9 @@ void show_registers(struct pt_regs *regs - regs->esi, regs->edi, regs->ebp, esp); - printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n", - regs->xds & 0xffff, regs->xes & 0xffff, ss); -- printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)", -- current->comm, current->pid, current_thread_info(), current); -+ printk(KERN_EMERG "Process %s (pid: %d[#%u], threadinfo=%p task=%p)", -+ current->comm, current->pid, current->xid, -+ current_thread_info(), current); - /* - * When in-kernel, we also print out the stack and code at the - * time of the fault.. -@@ -333,6 +335,8 @@ void die(const char * str, struct pt_reg - static int die_counter; - unsigned long flags; - -+ vxh_throw_oops(); -+ - if (die.lock_owner != raw_smp_processor_id()) { - console_verbose(); - spin_lock_irqsave(&die.lock, flags); -@@ -365,8 +369,9 @@ void die(const char * str, struct pt_reg - #endif - if (nl) - printk("\n"); -- notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); -+ notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); - show_registers(regs); -+ vxh_dump_history(); - } else - printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); - -diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig -index a85ea9d..0a36092 100644 ---- a/arch/ia64/Kconfig -+++ b/arch/ia64/Kconfig -@@ -464,6 +464,8 @@ endmenu - - source "arch/ia64/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c -index 4e7a6a1..96b3e14 100644 ---- a/arch/ia64/ia32/binfmt_elf32.c -+++ b/arch/ia64/ia32/binfmt_elf32.c -@@ -236,7 +236,8 @@ ia32_setup_arg_pages (struct linux_binpr - kmem_cache_free(vm_area_cachep, mpnt); - return ret; - } -- current->mm->stack_vm = current->mm->total_vm = vma_pages(mpnt); -+ vx_vmpages_sub(current->mm, current->mm->total_vm - vma_pages(mpnt)); -+ current->mm->stack_vm = current->mm->total_vm; - } - - for (i = 0 ; i < MAX_ARG_PAGES ; i++) { -diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S -index 95fe044..f51b6c9 100644 ---- a/arch/ia64/ia32/ia32_entry.S -+++ b/arch/ia64/ia32/ia32_entry.S -@@ -483,7 +483,7 @@ ia32_syscall_table: - data8 sys_tgkill /* 270 */ - data8 compat_sys_utimes - data8 sys32_fadvise64_64 -- data8 sys_ni_syscall -+ data8 sys32_vserver - data8 sys_ni_syscall - data8 sys_ni_syscall /* 275 */ - data8 sys_ni_syscall -diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S -index 930fdfc..f1f3cc1 100644 ---- a/arch/ia64/kernel/entry.S -+++ b/arch/ia64/kernel/entry.S -@@ -1591,7 +1591,7 @@ sys_call_table: - data8 sys_mq_notify - data8 sys_mq_getsetattr - data8 sys_ni_syscall // reserved for kexec_load -- data8 sys_ni_syscall // reserved for vserver -+ data8 sys_vserver - data8 sys_waitid // 1270 - data8 sys_add_key - data8 sys_request_key -diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c -index 9c5194b..1c3017c 100644 ---- a/arch/ia64/kernel/perfmon.c -+++ b/arch/ia64/kernel/perfmon.c -@@ -41,6 +41,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -2355,7 +2357,7 @@ pfm_smpl_buffer_alloc(struct task_struct - */ - insert_vm_struct(mm, vma); - -- mm->total_vm += size >> PAGE_SHIFT; -+ vx_vmpages_add(mm, size >> PAGE_SHIFT); - vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, - vma_pages(vma)); - up_write(&task->mm->mmap_sem); -diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c -index eaed14a..7c8db71 100644 ---- a/arch/ia64/kernel/ptrace.c -+++ b/arch/ia64/kernel/ptrace.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -1443,6 +1444,9 @@ sys_ptrace (long request, pid_t pid, uns - read_unlock(&tasklist_lock); - if (!child) - goto out; -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) -+ goto out_tsk; -+ - ret = -EPERM; - if (pid == 1) /* no messing around with init! */ - goto out_tsk; -diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c -index 463f6bb..0b00de6 100644 ---- a/arch/ia64/kernel/signal.c -+++ b/arch/ia64/kernel/signal.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c -index af7eb08..ea0308f 100644 ---- a/arch/ia64/mm/fault.c -+++ b/arch/ia64/mm/fault.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c -index 8cbf164..9b6ca24 100644 ---- a/arch/ia64/sn/kernel/xpc_main.c -+++ b/arch/ia64/sn/kernel/xpc_main.c -@@ -109,6 +109,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] = - 0644, - NULL, - &proc_dointvec_minmax, -+ NULL, - &sysctl_intvec, - NULL, - &xpc_hb_min_interval, -@@ -122,6 +123,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] = - 0644, - NULL, - &proc_dointvec_minmax, -+ NULL, - &sysctl_intvec, - NULL, - &xpc_hb_check_min_interval, -@@ -146,6 +148,7 @@ static ctl_table xpc_sys_xpc_dir[] = { - 0644, - NULL, - &proc_dointvec_minmax, -+ NULL, - &sysctl_intvec, - NULL, - &xpc_disengage_request_min_timelimit, -diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c -index 340a3bf..aed14f3 100644 ---- a/arch/m32r/kernel/ptrace.c -+++ b/arch/m32r/kernel/ptrace.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig -index 8849439..c83a593 100644 ---- a/arch/m68k/Kconfig -+++ b/arch/m68k/Kconfig -@@ -650,6 +650,8 @@ source "fs/Kconfig" - - source "arch/m68k/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c -index 540638c..deddf39 100644 ---- a/arch/m68k/kernel/ptrace.c -+++ b/arch/m68k/kernel/ptrace.c -@@ -280,6 +280,8 @@ long arch_ptrace(struct task_struct *chi - ret = ptrace_request(child, request, addr, data); - break; - } -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) -+ goto out_tsk; - - return ret; - out_eio: -diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig -index e50858d..1ae18d8 100644 ---- a/arch/m68knommu/Kconfig -+++ b/arch/m68knommu/Kconfig -@@ -646,6 +646,8 @@ source "fs/Kconfig" - - source "arch/m68knommu/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 3a0f89d..8158f36 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1814,6 +1814,8 @@ source "arch/mips/oprofile/Kconfig" - - source "arch/mips/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c -index e00e5f6..b98d134 100644 ---- a/arch/mips/kernel/linux32.c -+++ b/arch/mips/kernel/linux32.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -1099,7 +1100,7 @@ asmlinkage long sys32_newuname(struct ne - int ret = 0; - - down_read(&uts_sem); -- if (copy_to_user(name,&system_utsname,sizeof *name)) -+ if (copy_to_user(name, vx_new_utsname(), sizeof *name)) - ret = -EFAULT; - up_read(&uts_sem); - -diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c -index f838b36..0d533ef 100644 ---- a/arch/mips/kernel/ptrace.c -+++ b/arch/mips/kernel/ptrace.c -@@ -476,6 +476,8 @@ asmlinkage void do_syscall_trace(struct - goto out; - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - goto out; -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) -+ goto out_tsk; - - /* The 0x80 provides a way for the tracing parent to distinguish - between a syscall stop and SIGTRAP delivery */ -diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c -index 0d5cf97..b375e8d 100644 ---- a/arch/mips/kernel/ptrace32.c -+++ b/arch/mips/kernel/ptrace32.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S -index 2f2dc54..200b74d 100644 ---- a/arch/mips/kernel/scall32-o32.S -+++ b/arch/mips/kernel/scall32-o32.S -@@ -607,7 +607,7 @@ einval: li v0, -EINVAL - sys sys_mq_timedreceive 5 - sys sys_mq_notify 2 /* 4275 */ - sys sys_mq_getsetattr 3 -- sys sys_ni_syscall 0 /* sys_vserver */ -+ sys sys_vserver 3 - sys sys_waitid 5 - sys sys_ni_syscall 0 /* available, was setaltroot */ - sys sys_add_key 5 /* 4280 */ -diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S -index 98bf25d..da9bb04 100644 ---- a/arch/mips/kernel/scall64-64.S -+++ b/arch/mips/kernel/scall64-64.S -@@ -433,7 +433,7 @@ sys_call_table: - PTR sys_mq_timedreceive - PTR sys_mq_notify - PTR sys_mq_getsetattr /* 5235 */ -- PTR sys_ni_syscall /* sys_vserver */ -+ PTR sys_vserver - PTR sys_waitid - PTR sys_ni_syscall /* available, was setaltroot */ - PTR sys_add_key -diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S -index 02c8267..bd8b965 100644 ---- a/arch/mips/kernel/scall64-n32.S -+++ b/arch/mips/kernel/scall64-n32.S -@@ -359,7 +359,7 @@ EXPORT(sysn32_call_table) - PTR compat_sys_mq_timedreceive - PTR compat_sys_mq_notify - PTR compat_sys_mq_getsetattr -- PTR sys_ni_syscall /* 6240, sys_vserver */ -+ PTR sys32_vserver /* 6240 */ - PTR sysn32_waitid - PTR sys_ni_syscall /* available, was setaltroot */ - PTR sys_add_key -diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S -index 797e0d8..3bc13a4 100644 ---- a/arch/mips/kernel/scall64-o32.S -+++ b/arch/mips/kernel/scall64-o32.S -@@ -481,7 +481,7 @@ sys_call_table: - PTR compat_sys_mq_timedreceive - PTR compat_sys_mq_notify /* 4275 */ - PTR compat_sys_mq_getsetattr -- PTR sys_ni_syscall /* sys_vserver */ -+ PTR sys32_vserver - PTR sys32_waitid - PTR sys_ni_syscall /* available, was setaltroot */ - PTR sys_add_key /* 4280 */ -diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c -index 1da2eeb..3838796 100644 ---- a/arch/mips/kernel/syscall.c -+++ b/arch/mips/kernel/syscall.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -229,7 +230,7 @@ out: - */ - asmlinkage int sys_uname(struct old_utsname __user * name) - { -- if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) -+ if (name && !copy_to_user(name, vx_new_utsname(), sizeof (*name))) - return 0; - return -EFAULT; - } -@@ -240,21 +241,23 @@ asmlinkage int sys_uname(struct old_utsn - asmlinkage int sys_olduname(struct oldold_utsname __user * name) - { - int error; -+ struct new_utsname *ptr; - - if (!name) - return -EFAULT; - if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) - return -EFAULT; - -- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); -+ ptr = vx_new_utsname(); -+ error = __copy_to_user(&name->sysname,ptr->sysname,__OLD_UTS_LEN); - error -= __put_user(0,name->sysname+__OLD_UTS_LEN); -- error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); -+ error -= __copy_to_user(&name->nodename,ptr->nodename,__OLD_UTS_LEN); - error -= __put_user(0,name->nodename+__OLD_UTS_LEN); -- error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); -+ error -= __copy_to_user(&name->release,ptr->release,__OLD_UTS_LEN); - error -= __put_user(0,name->release+__OLD_UTS_LEN); -- error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); -+ error -= __copy_to_user(&name->version,ptr->version,__OLD_UTS_LEN); - error -= __put_user(0,name->version+__OLD_UTS_LEN); -- error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); -+ error -= __copy_to_user(&name->machine,ptr->machine,__OLD_UTS_LEN); - error = __put_user(0,name->machine+__OLD_UTS_LEN); - error = error ? -EFAULT : 0; - -@@ -290,10 +293,10 @@ asmlinkage int _sys_sysmips(int cmd, lon - return -EFAULT; - - down_write(&uts_sem); -- strncpy(system_utsname.nodename, nodename, len); -+ strncpy(vx_new_uts(nodename), nodename, len); - nodename[__NEW_UTS_LEN] = '\0'; -- strlcpy(system_utsname.nodename, nodename, -- sizeof(system_utsname.nodename)); -+ strlcpy(vx_new_uts(nodename), nodename, -+ sizeof(vx_new_uts(nodename))); - up_write(&uts_sem); - return 0; - } -diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c -index 0fc3730..338a7a1 100644 ---- a/arch/mips/kernel/sysirix.c -+++ b/arch/mips/kernel/sysirix.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig -index eca33cf..5284537 100644 ---- a/arch/parisc/Kconfig -+++ b/arch/parisc/Kconfig -@@ -213,6 +213,8 @@ source "arch/parisc/oprofile/Kconfig" - - source "arch/parisc/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c -index 6135690..12d9384 100644 ---- a/arch/parisc/kernel/sys_parisc32.c -+++ b/arch/parisc/kernel/sys_parisc32.c -@@ -657,6 +657,7 @@ asmlinkage int sys32_sysinfo(struct sysi - - do { - seq = read_seqbegin(&xtime_lock); -+ /* FIXME: requires vx virtualization */ - val.uptime = jiffies / HZ; - - val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); -diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S -index 71011ea..4e2d76e 100644 ---- a/arch/parisc/kernel/syscall_table.S -+++ b/arch/parisc/kernel/syscall_table.S -@@ -368,7 +368,7 @@ - ENTRY_COMP(mbind) /* 260 */ - ENTRY_COMP(get_mempolicy) - ENTRY_COMP(set_mempolicy) -- ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */ -+ ENTRY_DIFF(vserver) - ENTRY_SAME(add_key) - ENTRY_SAME(request_key) /* 265 */ - ENTRY_SAME(keyctl) -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index a834f9e..502a4bc 100644 ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -974,6 +974,8 @@ endmenu - - source "arch/powerpc/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - config KEYS_COMPAT -diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c -index c225cf1..edec59b 100644 ---- a/arch/powerpc/kernel/process.c -+++ b/arch/powerpc/kernel/process.c -@@ -425,8 +425,9 @@ void show_regs(struct pt_regs * regs) - trap = TRAP(regs); - if (trap == 0x300 || trap == 0x600) - printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); -- printk("TASK = %p[%d] '%s' THREAD: %p", -- current, current->pid, current->comm, task_thread_info(current)); -+ printk("TASK = %p[%d,#%u] '%s' THREAD: %p", -+ current, current->pid, current->xid, -+ current->comm, task_thread_info(current)); - - #ifdef CONFIG_SMP - printk(" CPU: %d", smp_processor_id()); -diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c -index 826ee3d..94e0076 100644 ---- a/arch/powerpc/kernel/ptrace32.c -+++ b/arch/powerpc/kernel/ptrace32.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c -index ad895c9..7db2919 100644 ---- a/arch/powerpc/kernel/syscalls.c -+++ b/arch/powerpc/kernel/syscalls.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -259,7 +260,7 @@ long ppc_newuname(struct new_utsname __u - int err = 0; - - down_read(&uts_sem); -- if (copy_to_user(name, &system_utsname, sizeof(*name))) -+ if (copy_to_user(name, vx_new_utsname(), sizeof(*name))) - err = -EFAULT; - up_read(&uts_sem); - if (!err) -@@ -272,7 +273,7 @@ int sys_uname(struct old_utsname __user - int err = 0; - - down_read(&uts_sem); -- if (copy_to_user(name, &system_utsname, sizeof(*name))) -+ if (copy_to_user(name, vx_new_utsname(), sizeof(*name))) - err = -EFAULT; - up_read(&uts_sem); - if (!err) -@@ -283,25 +284,22 @@ int sys_uname(struct old_utsname __user - int sys_olduname(struct oldold_utsname __user *name) - { - int error; -+ struct new_utsname *ptr; - - if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname))) - return -EFAULT; - - down_read(&uts_sem); -- error = __copy_to_user(&name->sysname, &system_utsname.sysname, -- __OLD_UTS_LEN); -+ ptr = vx_new_utsname(); -+ error = __copy_to_user(&name->sysname, ptr->sysname, __OLD_UTS_LEN); - error |= __put_user(0, name->sysname + __OLD_UTS_LEN); -- error |= __copy_to_user(&name->nodename, &system_utsname.nodename, -- __OLD_UTS_LEN); -+ error |= __copy_to_user(&name->nodename, ptr->nodename, __OLD_UTS_LEN); - error |= __put_user(0, name->nodename + __OLD_UTS_LEN); -- error |= __copy_to_user(&name->release, &system_utsname.release, -- __OLD_UTS_LEN); -+ error |= __copy_to_user(&name->release, ptr->release, __OLD_UTS_LEN); - error |= __put_user(0, name->release + __OLD_UTS_LEN); -- error |= __copy_to_user(&name->version, &system_utsname.version, -- __OLD_UTS_LEN); -+ error |= __copy_to_user(&name->version, ptr->version, __OLD_UTS_LEN); - error |= __put_user(0, name->version + __OLD_UTS_LEN); -- error |= __copy_to_user(&name->machine, &system_utsname.machine, -- __OLD_UTS_LEN); -+ error |= __copy_to_user(&name->machine, ptr->machine, __OLD_UTS_LEN); - error |= override_machine(name->machine); - up_read(&uts_sem); - -diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S -index 1ad55f0..0bf1062 100644 ---- a/arch/powerpc/kernel/systbl.S -+++ b/arch/powerpc/kernel/systbl.S -@@ -296,7 +296,7 @@ COMPAT_SYS(fstatfs64) - SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64) - PPC_SYS(rtas) - OLDSYS(debug_setcontext) --SYSCALL(ni_syscall) -+SYSX(sys_vserver, sys32_vserver, sys_vserver) - SYSCALL(ni_syscall) - COMPAT_SYS(mbind) - COMPAT_SYS(get_mempolicy) -diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c -index 04f7df3..41ec594 100644 ---- a/arch/powerpc/kernel/vdso.c -+++ b/arch/powerpc/kernel/vdso.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -294,7 +295,7 @@ int arch_setup_additional_pages(struct l - kmem_cache_free(vm_area_cachep, vma); - return -ENOMEM; - } -- mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; -+ vx_vmpages_add(mm, (vma->vm_end - vma->vm_start) >> PAGE_SHIFT); - up_write(&mm->mmap_sem); - - return 0; -diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig -index 11899f0..a598ec3 100644 ---- a/arch/ppc/Kconfig -+++ b/arch/ppc/Kconfig -@@ -1394,6 +1394,8 @@ source "arch/powerpc/oprofile/Kconfig" - - source "arch/ppc/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig -index b7ca5bf..13dbfd3 100644 ---- a/arch/s390/Kconfig -+++ b/arch/s390/Kconfig -@@ -472,6 +472,8 @@ source "arch/s390/oprofile/Kconfig" - - source "arch/s390/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c -index da6fbae..476e064 100644 ---- a/arch/s390/kernel/process.c -+++ b/arch/s390/kernel/process.c -@@ -164,9 +164,9 @@ void show_regs(struct pt_regs *regs) - struct task_struct *tsk = current; - - printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted()); -- printk("Process %s (pid: %d, task: %p, ksp: %p)\n", -- current->comm, current->pid, (void *) tsk, -- (void *) tsk->thread.ksp); -+ printk("Process %s (pid: %d[#%u], task: %p, ksp: %p)\n", -+ current->comm, current->pid, current->xid, -+ (void *) tsk, (void *) tsk->thread.ksp); - - show_registers(regs); - /* Show stack backtrace if pt_regs is from kernel mode */ -diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c -index 37dfe33..a10dc7a 100644 ---- a/arch/s390/kernel/ptrace.c -+++ b/arch/s390/kernel/ptrace.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -723,7 +724,13 @@ sys_ptrace(long request, long pid, long - goto out; - } - -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) { -+ ret = -EPERM; -+ goto out_tsk; -+ } -+ - ret = do_ptrace(child, request, addr, data); -+out_tsk: - put_task_struct(child); - out: - unlock_kernel(); -diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S -index 7c88d85..4280067 100644 ---- a/arch/s390/kernel/syscalls.S -+++ b/arch/s390/kernel/syscalls.S -@@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett - SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 */ - SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper) - SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper) --NI_SYSCALL /* reserved for vserver */ -+SYSCALL(sys_vserver,sys_vserver,sys32_vserver) - SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) - SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) - SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) -diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig -index e9b275d..68b398e 100644 ---- a/arch/sh/Kconfig -+++ b/arch/sh/Kconfig -@@ -633,6 +633,8 @@ source "arch/sh/oprofile/Kconfig" - - source "arch/sh/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c -index 42638b9..6c0370f 100644 ---- a/arch/sh/kernel/kgdb_stub.c -+++ b/arch/sh/kernel/kgdb_stub.c -@@ -412,7 +412,7 @@ static struct task_struct *get_thread(in - if (pid == PID_MAX) pid = 0; - - /* First check via PID */ -- thread = find_task_by_pid(pid); -+ thread = find_task_by_real_pid(pid); - - if (thread) - return thread; -diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig -index f944b58..60aa2b7 100644 ---- a/arch/sparc/Kconfig -+++ b/arch/sparc/Kconfig -@@ -284,6 +284,8 @@ source "fs/Kconfig" - - source "arch/sparc/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c -index 1baf13e..d4dc454 100644 ---- a/arch/sparc/kernel/ptrace.c -+++ b/arch/sparc/kernel/ptrace.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -299,6 +300,10 @@ asmlinkage void do_ptrace(struct pt_regs - pt_error_return(regs, -ret); - goto out; - } -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) { -+ pt_error_return(regs, ESRCH); -+ goto out_tsk; -+ } - - if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) - || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { -diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c -index 0cdfc9d..8fa541c 100644 ---- a/arch/sparc/kernel/sys_sparc.c -+++ b/arch/sparc/kernel/sys_sparc.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -470,13 +471,13 @@ asmlinkage int sys_getdomainname(char __ - - down_read(&uts_sem); - -- nlen = strlen(system_utsname.domainname) + 1; -+ nlen = strlen(vx_new_uts(domainname)) + 1; - - if (nlen < len) - len = nlen; - if (len > __NEW_UTS_LEN) - goto done; -- if (copy_to_user(name, system_utsname.domainname, len)) -+ if (copy_to_user(name, vx_new_uts(domainname), len)) - goto done; - err = 0; - done: -diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S -index 768de64..fab6bfd 100644 ---- a/arch/sparc/kernel/systbls.S -+++ b/arch/sparc/kernel/systbls.S -@@ -72,7 +72,7 @@ sys_call_table: - /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl - /*255*/ .long sys_nis_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep - /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun --/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy -+/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy - /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink - /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid - /*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat -diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig -index 4c0a50a..eb58ca4 100644 ---- a/arch/sparc64/Kconfig -+++ b/arch/sparc64/Kconfig -@@ -394,6 +394,8 @@ endmenu - - source "arch/sparc64/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c -index 202a80c..0a6331c 100644 ---- a/arch/sparc64/kernel/binfmt_aout32.c -+++ b/arch/sparc64/kernel/binfmt_aout32.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c -index 3f9746f..5a1eb33 100644 ---- a/arch/sparc64/kernel/ptrace.c -+++ b/arch/sparc64/kernel/ptrace.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -209,6 +210,10 @@ asmlinkage void do_ptrace(struct pt_regs - pt_error_return(regs, -ret); - goto out; - } -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) { -+ pt_error_return(regs, ESRCH); -+ goto out_tsk; -+ } - - if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) - || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { -diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c -index 5f8c822..781027a 100644 ---- a/arch/sparc64/kernel/sys_sparc.c -+++ b/arch/sparc64/kernel/sys_sparc.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -476,13 +477,13 @@ asmlinkage long sys_getdomainname(char _ - - down_read(&uts_sem); - -- nlen = strlen(system_utsname.domainname) + 1; -+ nlen = strlen(vx_new_uts(domainname)) + 1; - - if (nlen < len) - len = nlen; - if (len > __NEW_UTS_LEN) - goto done; -- if (copy_to_user(name, system_utsname.domainname, len)) -+ if (copy_to_user(name, vx_new_uts(domainname), len)) - goto done; - err = 0; - done: -diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S -index c3adb7a..294e1a2 100644 ---- a/arch/sparc64/kernel/systbls.S -+++ b/arch/sparc64/kernel/systbls.S -@@ -73,7 +73,7 @@ sys_call_table32: - /*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl - .word sys_ni_syscall, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep - /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun -- .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy -+ .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy - /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink - .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid - /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat -@@ -142,7 +142,7 @@ sys_call_table: - /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl - .word sys_ni_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep - /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun -- .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy -+ .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy - /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink - .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid - /*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat -diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c -index 4885ca6..612477d 100644 ---- a/arch/sparc64/solaris/fs.c -+++ b/arch/sparc64/solaris/fs.c -@@ -363,7 +363,7 @@ static int report_statvfs(struct vfsmoun - int j = strlen (p); - - if (j > 15) j = 15; -- if (IS_RDONLY(inode)) i = 1; -+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1; - if (mnt->mnt_flags & MNT_NOSUID) i |= 2; - if (!sysv_valid_dev(inode->i_sb->s_dev)) - return -EOVERFLOW; -@@ -399,7 +399,7 @@ static int report_statvfs64(struct vfsmo - int j = strlen (p); - - if (j > 15) j = 15; -- if (IS_RDONLY(inode)) i = 1; -+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1; - if (mnt->mnt_flags & MNT_NOSUID) i |= 2; - if (!sysv_valid_dev(inode->i_sb->s_dev)) - return -EOVERFLOW; -diff --git a/arch/um/Kconfig b/arch/um/Kconfig -index 5982fe2..bdf4519 100644 ---- a/arch/um/Kconfig -+++ b/arch/um/Kconfig -@@ -290,6 +290,8 @@ source "drivers/connector/Kconfig" - - source "fs/Kconfig" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c -index 54388d1..6e85bbf 100644 ---- a/arch/um/drivers/mconsole_kern.c -+++ b/arch/um/drivers/mconsole_kern.c -@@ -21,6 +21,7 @@ - #include "linux/proc_fs.h" - #include "linux/syscalls.h" - #include "linux/console.h" -+#include "linux/vs_cvirt.h" - #include "asm/irq.h" - #include "asm/uaccess.h" - #include "user_util.h" -diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c -index 3113cab..ea4a9e3 100644 ---- a/arch/um/kernel/process_kern.c -+++ b/arch/um/kernel/process_kern.c -@@ -23,6 +23,8 @@ - #include "linux/proc_fs.h" - #include "linux/ptrace.h" - #include "linux/random.h" -+#include "linux/vs_cvirt.h" -+ - #include "asm/unistd.h" - #include "asm/mman.h" - #include "asm/segment.h" -diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c -index 8e1a350..d144baa 100644 ---- a/arch/um/kernel/syscall_kern.c -+++ b/arch/um/kernel/syscall_kern.c -@@ -15,6 +15,8 @@ - #include "linux/unistd.h" - #include "linux/slab.h" - #include "linux/utime.h" -+#include -+ - #include "asm/mman.h" - #include "asm/uaccess.h" - #include "kern_util.h" -@@ -110,7 +112,7 @@ long sys_uname(struct old_utsname * name - if (!name) - return -EFAULT; - down_read(&uts_sem); -- err=copy_to_user(name, &system_utsname, sizeof (*name)); -+ err=copy_to_user(name, vx_new_utsname(), sizeof (*name)); - up_read(&uts_sem); - return err?-EFAULT:0; - } -@@ -118,6 +120,7 @@ long sys_uname(struct old_utsname * name - long sys_olduname(struct oldold_utsname * name) - { - long error; -+ struct new_utsname *ptr; - - if (!name) - return -EFAULT; -@@ -126,19 +129,20 @@ long sys_olduname(struct oldold_utsname - - down_read(&uts_sem); - -- error = __copy_to_user(&name->sysname,&system_utsname.sysname, -+ ptr = vx_new_utsname(); -+ error = __copy_to_user(&name->sysname,ptr->sysname, - __OLD_UTS_LEN); - error |= __put_user(0,name->sysname+__OLD_UTS_LEN); -- error |= __copy_to_user(&name->nodename,&system_utsname.nodename, -+ error |= __copy_to_user(&name->nodename,ptr->nodename, - __OLD_UTS_LEN); - error |= __put_user(0,name->nodename+__OLD_UTS_LEN); -- error |= __copy_to_user(&name->release,&system_utsname.release, -+ error |= __copy_to_user(&name->release,ptr->release, - __OLD_UTS_LEN); - error |= __put_user(0,name->release+__OLD_UTS_LEN); -- error |= __copy_to_user(&name->version,&system_utsname.version, -+ error |= __copy_to_user(&name->version,ptr->version, - __OLD_UTS_LEN); - error |= __put_user(0,name->version+__OLD_UTS_LEN); -- error |= __copy_to_user(&name->machine,&system_utsname.machine, -+ error |= __copy_to_user(&name->machine,ptr->machine, - __OLD_UTS_LEN); - error |= __put_user(0,name->machine+__OLD_UTS_LEN); - -diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig -index e7fc3e5..10f31fa 100644 ---- a/arch/v850/Kconfig -+++ b/arch/v850/Kconfig -@@ -320,6 +320,8 @@ source "drivers/usb/Kconfig" - - source "arch/v850/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c -index 67e0575..061bd4d 100644 ---- a/arch/v850/kernel/ptrace.c -+++ b/arch/v850/kernel/ptrace.c -@@ -137,6 +137,8 @@ long arch_ptrace(struct task_struct *chi - break; - rval = -EIO; - goto out; -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) -+ goto out_tsk; - - /* Read/write the word at location ADDR in the registers. */ - case PTRACE_PEEKUSR: -diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig -index e18eb79..196fae7 100644 ---- a/arch/x86_64/Kconfig -+++ b/arch/x86_64/Kconfig -@@ -588,6 +588,8 @@ endmenu - - source "arch/x86_64/Kconfig.debug" - -+source "kernel/vserver/Kconfig" -+ - source "security/Kconfig" - - source "crypto/Kconfig" -diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c -index 3bf58af..7aac2ca 100644 ---- a/arch/x86_64/ia32/ia32_aout.c -+++ b/arch/x86_64/ia32/ia32_aout.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c -index 572b3b2..4cccf13 100644 ---- a/arch/x86_64/ia32/ia32_binfmt.c -+++ b/arch/x86_64/ia32/ia32_binfmt.c -@@ -371,7 +371,8 @@ int ia32_setup_arg_pages(struct linux_bi - kmem_cache_free(vm_area_cachep, mpnt); - return ret; - } -- mm->stack_vm = mm->total_vm = vma_pages(mpnt); -+ vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt)); -+ mm->stack_vm = mm->total_vm; - } - - for (i = 0 ; i < MAX_ARG_PAGES ; i++) { -diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S -index 00dee17..f331a49 100644 ---- a/arch/x86_64/ia32/ia32entry.S -+++ b/arch/x86_64/ia32/ia32entry.S -@@ -650,7 +650,7 @@ ia32_sys_call_table: - .quad sys_tgkill /* 270 */ - .quad compat_sys_utimes - .quad sys32_fadvise64_64 -- .quad quiet_ni_syscall /* sys_vserver */ -+ .quad sys32_vserver - .quad sys_mbind - .quad compat_sys_get_mempolicy /* 275 */ - .quad sys_set_mempolicy -diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c -index 23a4515..8945338 100644 ---- a/arch/x86_64/ia32/ptrace32.c -+++ b/arch/x86_64/ia32/ptrace32.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c -index 2bc55af..f3d4615 100644 ---- a/arch/x86_64/ia32/sys_ia32.c -+++ b/arch/x86_64/ia32/sys_ia32.c -@@ -62,6 +62,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -882,6 +883,7 @@ asmlinkage long sys32_mmap2(unsigned lon - asmlinkage long sys32_olduname(struct oldold_utsname __user * name) - { - int error; -+ struct new_utsname *ptr; - - if (!name) - return -EFAULT; -@@ -890,13 +892,14 @@ asmlinkage long sys32_olduname(struct ol - - down_read(&uts_sem); - -- error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); -+ ptr = vx_new_utsname(); -+ error = __copy_to_user(&name->sysname,ptr->sysname,__OLD_UTS_LEN); - __put_user(0,name->sysname+__OLD_UTS_LEN); -- __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); -+ __copy_to_user(&name->nodename,ptr->nodename,__OLD_UTS_LEN); - __put_user(0,name->nodename+__OLD_UTS_LEN); -- __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); -+ __copy_to_user(&name->release,ptr->release,__OLD_UTS_LEN); - __put_user(0,name->release+__OLD_UTS_LEN); -- __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); -+ __copy_to_user(&name->version,ptr->version,__OLD_UTS_LEN); - __put_user(0,name->version+__OLD_UTS_LEN); - { - char *arch = "x86_64"; -@@ -919,7 +922,7 @@ long sys32_uname(struct old_utsname __us - if (!name) - return -EFAULT; - down_read(&uts_sem); -- err=copy_to_user(name, &system_utsname, sizeof (*name)); -+ err=copy_to_user(name, vx_new_utsname(), sizeof (*name)); - up_read(&uts_sem); - if (personality(current->personality) == PER_LINUX32) - err |= copy_to_user(&name->machine, "i686", 5); -diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c -index 3a01329..cba1692 100644 ---- a/arch/x86_64/ia32/syscall32.c -+++ b/arch/x86_64/ia32/syscall32.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -70,7 +71,7 @@ int syscall32_setup_pages(struct linux_b - kmem_cache_free(vm_area_cachep, vma); - return ret; - } -- mm->total_vm += npages; -+ vx_vmpages_add(mm, npages); - up_write(&mm->mmap_sem); - return 0; - } -diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c -index 6449ea8..142fbf7 100644 ---- a/arch/x86_64/kernel/sys_x86_64.c -+++ b/arch/x86_64/kernel/sys_x86_64.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -148,7 +149,7 @@ asmlinkage long sys_uname(struct new_uts - { - int err; - down_read(&uts_sem); -- err = copy_to_user(name, &system_utsname, sizeof (*name)); -+ err = copy_to_user(name, vx_new_utsname(), sizeof (*name)); - up_read(&uts_sem); - if (personality(current->personality) == PER_LINUX32) - err |= copy_to_user(&name->machine, "i686", 5); -diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c -index 28d50dc..906be26 100644 ---- a/arch/x86_64/kernel/traps.c -+++ b/arch/x86_64/kernel/traps.c -@@ -321,8 +321,9 @@ void show_registers(struct pt_regs *regs - - printk("CPU %d ", cpu); - __show_regs(regs); -- printk("Process %s (pid: %d, threadinfo %p, task %p)\n", -- cur->comm, cur->pid, task_thread_info(cur), cur); -+ printk("Process %s (pid: %d[#%u], threadinfo %p, task %p)\n", -+ cur->comm, cur->pid, cur->xid, -+ task_thread_info(cur), cur); - - /* - * When in-kernel, we also print out the stack and code at the -diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig -index 8b13316..3e1f17f 100644 ---- a/drivers/block/Kconfig -+++ b/drivers/block/Kconfig -@@ -315,6 +315,13 @@ config BLK_DEV_CRYPTOLOOP - instead, which can be configured to be on-disk compatible with the - cryptoloop device. - -+config BLK_DEV_VROOT -+ tristate "Virtual Root device support" -+ depends on QUOTACTL -+ ---help--- -+ Saying Y here will allow you to use quota/fs ioctls on a shared -+ partition within a virtual server without compromising security. -+ - config BLK_DEV_NBD - tristate "Network block device support" - depends on NET -diff --git a/drivers/block/Makefile b/drivers/block/Makefile -index 3ec1f8d..00f2e4e 100644 ---- a/drivers/block/Makefile -+++ b/drivers/block/Makefile -@@ -30,4 +30,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryp - obj-$(CONFIG_VIODASD) += viodasd.o - obj-$(CONFIG_BLK_DEV_SX8) += sx8.o - obj-$(CONFIG_BLK_DEV_UB) += ub.o -+obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o - -diff --git a/drivers/block/vroot.c b/drivers/block/vroot.c -new file mode 100644 -index 0000000..ac4441c ---- /dev/null -+++ b/drivers/block/vroot.c -@@ -0,0 +1,289 @@ -+/* -+ * linux/drivers/block/vroot.c -+ * -+ * written by Herbert Pötzl, 9/11/2002 -+ * ported to 2.6.10 by Herbert Pötzl, 30/12/2004 -+ * -+ * based on the loop.c code by Theodore Ts'o. -+ * -+ * Copyright (C) 2002-2005 by Herbert Pötzl. -+ * Redistribution of this file is permitted under the -+ * GNU General Public License. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+static int max_vroot = 8; -+ -+static struct vroot_device *vroot_dev; -+static struct gendisk **disks; -+ -+ -+static int vroot_set_dev( -+ struct vroot_device *vr, -+ struct file *vr_file, -+ struct block_device *bdev, -+ unsigned int arg) -+{ -+ struct block_device *real_bdev; -+ struct file *file; -+ struct inode *inode; -+ int error; -+ -+ error = -EBUSY; -+ if (vr->vr_state != Vr_unbound) -+ goto out; -+ -+ error = -EBADF; -+ file = fget(arg); -+ if (!file) -+ goto out; -+ -+ error = -EINVAL; -+ inode = file->f_dentry->d_inode; -+ -+ -+ if (S_ISBLK(inode->i_mode)) { -+ real_bdev = inode->i_bdev; -+ vr->vr_device = real_bdev; -+ __iget(real_bdev->bd_inode); -+ } else -+ goto out_fput; -+ -+ vxdprintk(VXD_CBIT(misc, 0), -+ "vroot[%d]_set_dev: dev=" VXF_DEV, -+ vr->vr_number, VXD_DEV(real_bdev)); -+ -+ vr->vr_state = Vr_bound; -+ error = 0; -+ -+ out_fput: -+ fput(file); -+ out: -+ return error; -+} -+ -+static int vroot_clr_dev( -+ struct vroot_device *vr, -+ struct file *vr_file, -+ struct block_device *bdev) -+{ -+ struct block_device *real_bdev; -+ -+ if (vr->vr_state != Vr_bound) -+ return -ENXIO; -+ if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */ -+ return -EBUSY; -+ -+ real_bdev = vr->vr_device; -+ -+ vxdprintk(VXD_CBIT(misc, 0), -+ "vroot[%d]_clr_dev: dev=" VXF_DEV, -+ vr->vr_number, VXD_DEV(real_bdev)); -+ -+ bdput(real_bdev); -+ vr->vr_state = Vr_unbound; -+ vr->vr_device = NULL; -+ return 0; -+} -+ -+ -+static int vr_ioctl(struct inode * inode, struct file * file, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data; -+ int err; -+ -+ down(&vr->vr_ctl_mutex); -+ switch (cmd) { -+ case VROOT_SET_DEV: -+ err = vroot_set_dev(vr, file, inode->i_bdev, arg); -+ break; -+ case VROOT_CLR_DEV: -+ err = vroot_clr_dev(vr, file, inode->i_bdev); -+ break; -+ default: -+ err = -EINVAL; -+ break; -+ } -+ up(&vr->vr_ctl_mutex); -+ return err; -+} -+ -+static int vr_open(struct inode *inode, struct file *file) -+{ -+ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data; -+ -+ down(&vr->vr_ctl_mutex); -+ vr->vr_refcnt++; -+ up(&vr->vr_ctl_mutex); -+ return 0; -+} -+ -+static int vr_release(struct inode *inode, struct file *file) -+{ -+ struct vroot_device *vr = inode->i_bdev->bd_disk->private_data; -+ -+ down(&vr->vr_ctl_mutex); -+ --vr->vr_refcnt; -+ up(&vr->vr_ctl_mutex); -+ return 0; -+} -+ -+static struct block_device_operations vr_fops = { -+ .owner = THIS_MODULE, -+ .open = vr_open, -+ .release = vr_release, -+ .ioctl = vr_ioctl, -+}; -+ -+struct block_device *__vroot_get_real_bdev(struct block_device *bdev) -+{ -+ struct inode *inode = bdev->bd_inode; -+ struct vroot_device *vr; -+ struct block_device *real_bdev; -+ int minor = iminor(inode); -+ -+ vr = &vroot_dev[minor]; -+ real_bdev = vr->vr_device; -+ -+ vxdprintk(VXD_CBIT(misc, 0), -+ "vroot[%d]_get_real_bdev: dev=" VXF_DEV, -+ vr->vr_number, VXD_DEV(real_bdev)); -+ -+ if (vr->vr_state != Vr_bound) -+ return ERR_PTR(-ENXIO); -+ -+ __iget(real_bdev->bd_inode); -+ return real_bdev; -+} -+ -+/* -+ * And now the modules code and kernel interface. -+ */ -+ -+module_param(max_vroot, int, 0); -+ -+MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR); -+ -+MODULE_AUTHOR ("Herbert Pötzl"); -+MODULE_DESCRIPTION ("Virtual Root Device Mapper"); -+ -+ -+int __init vroot_init(void) -+{ -+ int err, i; -+ -+ if (max_vroot < 1 || max_vroot > 256) { -+ max_vroot = MAX_VROOT_DEFAULT; -+ printk(KERN_WARNING "vroot: invalid max_vroot " -+ "(must be between 1 and 256), " -+ "using default (%d)\n", max_vroot); -+ } -+ -+ if (register_blkdev(VROOT_MAJOR, "vroot")) -+ return -EIO; -+ -+ err = -ENOMEM; -+ vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL); -+ if (!vroot_dev) -+ goto out_mem1; -+ memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device)); -+ -+ disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL); -+ if (!disks) -+ goto out_mem2; -+ -+ for (i = 0; i < max_vroot; i++) { -+ disks[i] = alloc_disk(1); -+ if (!disks[i]) -+ goto out_mem3; -+ } -+ -+ devfs_mk_dir("vroot"); -+ -+ for (i = 0; i < max_vroot; i++) { -+ struct vroot_device *vr = &vroot_dev[i]; -+ struct gendisk *disk = disks[i]; -+ -+ memset(vr, 0, sizeof(*vr)); -+ init_MUTEX(&vr->vr_ctl_mutex); -+ vr->vr_number = i; -+ disk->major = VROOT_MAJOR; -+ disk->first_minor = i; -+ disk->fops = &vr_fops; -+ sprintf(disk->disk_name, "vroot%d", i); -+ sprintf(disk->devfs_name, "vroot/%d", i); -+ disk->private_data = vr; -+ } -+ -+ err = register_vroot_grb(&__vroot_get_real_bdev); -+ if (err) -+ goto out_reg; -+ -+ for (i = 0; i < max_vroot; i++) -+ add_disk(disks[i]); -+ printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot); -+ return 0; -+ -+out_reg: -+ devfs_remove("vroot"); -+out_mem3: -+ while (i--) -+ put_disk(disks[i]); -+ kfree(disks); -+out_mem2: -+ kfree(vroot_dev); -+out_mem1: -+ unregister_blkdev(VROOT_MAJOR, "vroot"); -+ printk(KERN_ERR "vroot: ran out of memory\n"); -+ return err; -+} -+ -+void vroot_exit(void) -+{ -+ int i; -+ -+ if (unregister_vroot_grb(&__vroot_get_real_bdev)) -+ printk(KERN_WARNING "vroot: cannot unregister grb\n"); -+ -+ for (i = 0; i < max_vroot; i++) { -+ del_gendisk(disks[i]); -+ put_disk(disks[i]); -+ } -+ devfs_remove("vroot"); -+ if (unregister_blkdev(VROOT_MAJOR, "vroot")) -+ printk(KERN_WARNING "vroot: cannot unregister blkdev\n"); -+ -+ kfree(disks); -+ kfree(vroot_dev); -+} -+ -+module_init(vroot_init); -+module_exit(vroot_exit); -+ -+#ifndef MODULE -+ -+static int __init max_vroot_setup(char *str) -+{ -+ max_vroot = simple_strtol(str, NULL, 0); -+ return 1; -+} -+ -+__setup("max_vroot=", max_vroot_setup); -+ -+#endif -+ -diff --git a/drivers/char/random.c b/drivers/char/random.c -index 86be04b..05c343f 100644 ---- a/drivers/char/random.c -+++ b/drivers/char/random.c -@@ -1174,7 +1174,7 @@ static char sysctl_bootid[16]; - static int proc_do_uuid(ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) - { -- ctl_table fake_table; -+ ctl_table fake_table = {0}; - unsigned char buf[64], tmp_uuid[16], *uuid; - - uuid = table->data; -diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c -index 53d3d06..7f47d83 100644 ---- a/drivers/char/tty_io.c -+++ b/drivers/char/tty_io.c -@@ -103,6 +103,7 @@ - #include - #include - #include -+#include - - #include - -@@ -2381,13 +2382,16 @@ static int tiocsctty(struct tty_struct * - - static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) - { -+ pid_t pgrp; - /* - * (tty == real_tty) is a cheap way of - * testing if the tty is NOT a master pty. - */ - if (tty == real_tty && current->signal->tty != real_tty) - return -ENOTTY; -- return put_user(real_tty->pgrp, p); -+ -+ pgrp = vx_map_pid(real_tty->pgrp); -+ return put_user(pgrp, p); - } - - static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) -@@ -2405,6 +2409,8 @@ static int tiocspgrp(struct tty_struct * - return -ENOTTY; - if (get_user(pgrp, p)) - return -EFAULT; -+ -+ pgrp = vx_rmap_pid(pgrp); - if (pgrp < 0) - return -EINVAL; - if (session_of_pgrp(pgrp) != current->signal->session) -diff --git a/drivers/infiniband/core/uverbs_mem.c b/drivers/infiniband/core/uverbs_mem.c -index 36a32c3..a945edd 100644 ---- a/drivers/infiniband/core/uverbs_mem.c -+++ b/drivers/infiniband/core/uverbs_mem.c -@@ -36,6 +36,7 @@ - - #include - #include -+#include - - #include "uverbs.h" - -@@ -161,7 +162,7 @@ out: - if (ret < 0) - __ib_umem_release(dev, mem, 0); - else -- current->mm->locked_vm = locked; -+ vx_vmlocked_sub(current->mm, current->mm->locked_vm - locked); - - up_write(¤t->mm->mmap_sem); - free_page((unsigned long) page_list); -@@ -174,8 +175,8 @@ void ib_umem_release(struct ib_device *d - __ib_umem_release(dev, umem, 1); - - down_write(¤t->mm->mmap_sem); -- current->mm->locked_vm -= -- PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT; -+ vx_vmlocked_sub(current->mm, -+ PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT); - up_write(¤t->mm->mmap_sem); - } - -@@ -184,7 +185,7 @@ static void ib_umem_account(void *work_p - struct ib_umem_account_work *work = work_ptr; - - down_write(&work->mm->mmap_sem); -- work->mm->locked_vm -= work->diff; -+ vx_vmlocked_sub(work->mm, work->diff); - up_write(&work->mm->mmap_sem); - mmput(work->mm); - kfree(work); -diff --git a/fs/attr.c b/fs/attr.c -index 97de946..bb1c58c 100644 ---- a/fs/attr.c -+++ b/fs/attr.c -@@ -15,6 +15,9 @@ - #include - #include - #include -+#include -+#include -+#include - - /* Taken over from the old code... */ - -@@ -56,6 +59,28 @@ int inode_change_ok(struct inode *inode, - if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) - goto error; - } -+ -+ /* Check for evil vserver activity */ -+ if (vx_check(0, VX_ADMIN)) -+ goto fine; -+ -+ if (IS_BARRIER(inode)) { -+ vxwprintk(1, "xid=%d messing with the barrier.", -+ vx_current_xid()); -+ goto error; -+ } -+ switch (inode->i_sb->s_magic) { -+ case PROC_SUPER_MAGIC: -+ vxwprintk(1, "xid=%d messing with the procfs.", -+ vx_current_xid()); -+ goto error; -+ case DEVPTS_SUPER_MAGIC: -+ if (vx_check(inode->i_xid, VX_IDENT)) -+ goto fine; -+ vxwprintk(1, "xid=%d messing with the devpts.", -+ vx_current_xid()); -+ goto error; -+ } - fine: - retval = 0; - error: -@@ -79,6 +104,8 @@ int inode_setattr(struct inode * inode, - inode->i_uid = attr->ia_uid; - if (ia_valid & ATTR_GID) - inode->i_gid = attr->ia_gid; -+ if ((ia_valid & ATTR_XID) && IS_TAGXID(inode)) -+ inode->i_xid = attr->ia_xid; - if (ia_valid & ATTR_ATIME) - inode->i_atime = timespec_trunc(attr->ia_atime, - inode->i_sb->s_time_gran); -@@ -153,7 +180,8 @@ int notify_change(struct dentry * dentry - error = security_inode_setattr(dentry, attr); - if (!error) { - if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || -- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) -+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || -+ (ia_valid & ATTR_XID && attr->ia_xid != inode->i_xid)) - error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; - if (!error) - error = inode_setattr(inode, attr); -diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c -index f312103..0cfa5a6 100644 ---- a/fs/binfmt_aout.c -+++ b/fs/binfmt_aout.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c -index c2eac2a..814b570 100644 ---- a/fs/binfmt_elf.c -+++ b/fs/binfmt_elf.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c -index 108d56b..5b32e27 100644 ---- a/fs/binfmt_flat.c -+++ b/fs/binfmt_flat.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c -index 00a91dc..e1cb594 100644 ---- a/fs/binfmt_som.c -+++ b/fs/binfmt_som.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c -index bfb8a23..caba0b5 100644 ---- a/fs/devpts/inode.c -+++ b/fs/devpts/inode.c -@@ -19,7 +19,19 @@ - #include - #include - --#define DEVPTS_SUPER_MAGIC 0x1cd1 -+ -+static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd) -+{ -+ int ret = -EACCES; -+ -+ if (vx_check(inode->i_xid, VX_IDENT)) -+ ret = generic_permission(inode, mask, NULL); -+ return ret; -+} -+ -+static struct inode_operations devpts_file_inode_operations = { -+ .permission = devpts_permission, -+}; - - static struct vfsmount *devpts_mnt; - static struct dentry *devpts_root; -@@ -69,6 +81,24 @@ static int devpts_remount(struct super_b - return 0; - } - -+static int devpts_filter(struct dentry *de) -+{ -+ return vx_check(de->d_inode->i_xid, VX_IDENT); -+} -+ -+static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir) -+{ -+ return dcache_readdir_filter(filp, dirent, filldir, devpts_filter); -+} -+ -+static struct file_operations devpts_dir_operations = { -+ .open = dcache_dir_open, -+ .release = dcache_dir_close, -+ .llseek = dcache_dir_lseek, -+ .read = generic_read_dir, -+ .readdir = devpts_readdir, -+}; -+ - static struct super_operations devpts_sops = { - .statfs = simple_statfs, - .remount_fs = devpts_remount, -@@ -95,8 +125,9 @@ devpts_fill_super(struct super_block *s, - inode->i_uid = inode->i_gid = 0; - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; - inode->i_op = &simple_dir_inode_operations; -- inode->i_fop = &simple_dir_operations; -+ inode->i_fop = &devpts_dir_operations; - inode->i_nlink = 2; -+ inode->i_xid = vx_current_xid(); - - devpts_root = s->s_root = d_alloc_root(inode); - if (s->s_root) -@@ -155,6 +186,8 @@ int devpts_pty_new(struct tty_struct *tt - inode->i_gid = config.setgid ? config.gid : current->fsgid; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - init_special_inode(inode, S_IFCHR|config.mode, device); -+ inode->i_xid = vx_current_xid(); -+ inode->i_op = &devpts_file_inode_operations; - inode->u.generic_ip = tty; - - dentry = get_node(number); -diff --git a/fs/exec.c b/fs/exec.c -index 0b515ac..aa030cb 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -49,6 +49,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -436,7 +437,8 @@ int setup_arg_pages(struct linux_binprm - kmem_cache_free(vm_area_cachep, mpnt); - return ret; - } -- mm->stack_vm = mm->total_vm = vma_pages(mpnt); -+ vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt)); -+ mm->stack_vm = mm->total_vm; - } - - for (i = 0 ; i < MAX_ARG_PAGES ; i++) { -diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c -index 2c00953..21cee4f 100644 ---- a/fs/ext2/balloc.c -+++ b/fs/ext2/balloc.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - /* - * balloc.c contains the blocks allocation and deallocation routines -@@ -109,6 +110,8 @@ static int reserve_blocks(struct super_b - free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); - root_blocks = le32_to_cpu(es->s_r_blocks_count); - -+ DLIMIT_ADJUST_BLOCK(sb, vx_current_xid(), &free_blocks, &root_blocks); -+ - if (free_blocks < count) - count = free_blocks; - -@@ -259,6 +262,7 @@ do_more: - } - error_return: - brelse(bitmap_bh); -+ DLIMIT_FREE_BLOCK(inode, freed); - release_blocks(sb, freed); - DQUOT_FREE_BLOCK(inode, freed); - } -@@ -362,6 +366,10 @@ int ext2_new_block(struct inode *inode, - *err = -ENOSPC; - goto out_dquot; - } -+ if (DLIMIT_ALLOC_BLOCK(inode, es_alloc)) { -+ *err = -ENOSPC; -+ goto out_dlimit; -+ } - - ext2_debug ("goal=%lu.\n", goal); - -@@ -509,6 +517,8 @@ got_block: - *err = 0; - out_release: - group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc); -+ DLIMIT_FREE_BLOCK(inode, es_alloc); -+out_dlimit: - release_blocks(sb, es_alloc); - out_dquot: - DQUOT_FREE_BLOCK(inode, dq_alloc); -diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h -index 00de0a7..3c537fc 100644 ---- a/fs/ext2/ext2.h -+++ b/fs/ext2/ext2.h -@@ -162,6 +162,7 @@ extern struct file_operations ext2_xip_f - extern struct address_space_operations ext2_aops; - extern struct address_space_operations ext2_aops_xip; - extern struct address_space_operations ext2_nobh_aops; -+extern int ext2_sync_flags(struct inode *inode); - - /* namei.c */ - extern struct inode_operations ext2_dir_inode_operations; -diff --git a/fs/ext2/file.c b/fs/ext2/file.c -index a484412..addf2c3 100644 ---- a/fs/ext2/file.c -+++ b/fs/ext2/file.c -@@ -79,4 +79,5 @@ struct inode_operations ext2_file_inode_ - #endif - .setattr = ext2_setattr, - .permission = ext2_permission, -+ .sync_flags = ext2_sync_flags, - }; -diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c -index e527652..11e7d7a 100644 ---- a/fs/ext2/ialloc.c -+++ b/fs/ext2/ialloc.c -@@ -18,6 +18,8 @@ - #include - #include - #include -+#include -+#include - #include "ext2.h" - #include "xattr.h" - #include "acl.h" -@@ -126,6 +128,7 @@ void ext2_free_inode (struct inode * ino - ext2_xattr_delete_inode(inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); -+ DLIMIT_FREE_INODE(inode); - } - - es = EXT2_SB(sb)->s_es; -@@ -465,6 +468,11 @@ struct inode *ext2_new_inode(struct inod - if (!inode) - return ERR_PTR(-ENOMEM); - -+ inode->i_xid = vx_current_fsxid(sb); -+ if (DLIMIT_ALLOC_INODE(inode)) { -+ err = -ENOSPC; -+ goto fail_dlim; -+ } - ei = EXT2_I(inode); - sbi = EXT2_SB(sb); - es = sbi->s_es; -@@ -579,7 +587,8 @@ got: - inode->i_blocks = 0; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; - memset(ei->i_data, 0, sizeof(ei->i_data)); -- ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL; -+ ei->i_flags = EXT2_I(dir)->i_flags & -+ ~(EXT2_BTREE_FL|EXT2_IUNLINK_FL|EXT2_BARRIER_FL); - if (S_ISLNK(mode)) - ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL); - /* dirsync is only applied to directories */ -@@ -627,12 +636,15 @@ fail_free_drop: - - fail_drop: - DQUOT_DROP(inode); -+ DLIMIT_FREE_INODE(inode); - inode->i_flags |= S_NOQUOTA; - inode->i_nlink = 0; - iput(inode); - return ERR_PTR(err); - - fail: -+ DLIMIT_FREE_INODE(inode); -+fail_dlim: - make_bad_inode(inode); - iput(inode); - return ERR_PTR(err); -diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c -index a717837..5a08051 100644 ---- a/fs/ext2/inode.c -+++ b/fs/ext2/inode.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - #include "ext2.h" - #include "acl.h" - #include "xip.h" -@@ -1054,25 +1055,70 @@ void ext2_set_inode_flags(struct inode * - { - unsigned int flags = EXT2_I(inode)->i_flags; - -- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); -+ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER | -+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC); -+ -+ if (flags & EXT2_IMMUTABLE_FL) -+ inode->i_flags |= S_IMMUTABLE; -+ if (flags & EXT2_IUNLINK_FL) -+ inode->i_flags |= S_IUNLINK; -+ if (flags & EXT2_BARRIER_FL) -+ inode->i_flags |= S_BARRIER; -+ - if (flags & EXT2_SYNC_FL) - inode->i_flags |= S_SYNC; - if (flags & EXT2_APPEND_FL) - inode->i_flags |= S_APPEND; -- if (flags & EXT2_IMMUTABLE_FL) -- inode->i_flags |= S_IMMUTABLE; - if (flags & EXT2_NOATIME_FL) - inode->i_flags |= S_NOATIME; - if (flags & EXT2_DIRSYNC_FL) - inode->i_flags |= S_DIRSYNC; - } - -+int ext2_sync_flags(struct inode *inode) -+{ -+ unsigned int oldflags, newflags; -+ -+ oldflags = EXT2_I(inode)->i_flags; -+ newflags = oldflags & ~(EXT2_APPEND_FL | -+ EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL | -+ EXT2_BARRIER_FL | EXT2_NOATIME_FL | -+ EXT2_SYNC_FL | EXT2_DIRSYNC_FL); -+ -+ if (IS_APPEND(inode)) -+ newflags |= EXT2_APPEND_FL; -+ if (IS_IMMUTABLE(inode)) -+ newflags |= EXT2_IMMUTABLE_FL; -+ if (IS_IUNLINK(inode)) -+ newflags |= EXT2_IUNLINK_FL; -+ if (IS_BARRIER(inode)) -+ newflags |= EXT2_BARRIER_FL; -+ -+ /* we do not want to copy superblock flags */ -+ if (inode->i_flags & S_NOATIME) -+ newflags |= EXT2_NOATIME_FL; -+ if (inode->i_flags & S_SYNC) -+ newflags |= EXT2_SYNC_FL; -+ if (inode->i_flags & S_DIRSYNC) -+ newflags |= EXT2_DIRSYNC_FL; -+ -+ if (oldflags ^ newflags) { -+ EXT2_I(inode)->i_flags = newflags; -+ inode->i_ctime = CURRENT_TIME; -+ mark_inode_dirty(inode); -+ } -+ -+ return 0; -+} -+ - void ext2_read_inode (struct inode * inode) - { - struct ext2_inode_info *ei = EXT2_I(inode); - ino_t ino = inode->i_ino; - struct buffer_head * bh; - struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh); -+ uid_t uid; -+ gid_t gid; - int n; - - #ifdef CONFIG_EXT2_FS_POSIX_ACL -@@ -1083,12 +1129,17 @@ void ext2_read_inode (struct inode * ino - goto bad_inode; - - inode->i_mode = le16_to_cpu(raw_inode->i_mode); -- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); -- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); -+ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); -+ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); - if (!(test_opt (inode->i_sb, NO_UID32))) { -- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; -- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; -+ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; -+ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; - } -+ inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); -+ inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); -+ inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, -+ le16_to_cpu(raw_inode->i_raw_xid)); -+ - inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); - inode->i_size = le32_to_cpu(raw_inode->i_size); - inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); -@@ -1186,8 +1237,8 @@ static int ext2_update_inode(struct inod - struct ext2_inode_info *ei = EXT2_I(inode); - struct super_block *sb = inode->i_sb; - ino_t ino = inode->i_ino; -- uid_t uid = inode->i_uid; -- gid_t gid = inode->i_gid; -+ uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); -+ gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); - struct buffer_head * bh; - struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh); - int n; -@@ -1222,6 +1273,9 @@ static int ext2_update_inode(struct inod - raw_inode->i_uid_high = 0; - raw_inode->i_gid_high = 0; - } -+#ifdef CONFIG_INOXID_INTERN -+ raw_inode->i_raw_xid = cpu_to_le16(inode->i_xid); -+#endif - raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); - raw_inode->i_size = cpu_to_le32(inode->i_size); - raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); -@@ -1308,11 +1362,13 @@ int ext2_setattr(struct dentry *dentry, - if (error) - return error; - if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || -- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { -+ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) || -+ (iattr->ia_valid & ATTR_XID && iattr->ia_xid != inode->i_xid)) { - error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0; - if (error) - return error; - } -+ - error = inode_setattr(inode, iattr); - if (!error && (iattr->ia_valid & ATTR_MODE)) - error = ext2_acl_chmod(inode); -diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c -index 3ca9afd..6ef1d95 100644 ---- a/fs/ext2/ioctl.c -+++ b/fs/ext2/ioctl.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -30,7 +31,8 @@ int ext2_ioctl (struct inode * inode, st - case EXT2_IOC_SETFLAGS: { - unsigned int oldflags; - -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) -@@ -50,7 +52,9 @@ int ext2_ioctl (struct inode * inode, st - * - * This test looks nicer. Thanks to Pauline Middelink - */ -- if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { -+ if ((oldflags & EXT2_IMMUTABLE_FL) || -+ ((flags ^ oldflags) & (EXT2_APPEND_FL | -+ EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL))) { - if (!capable(CAP_LINUX_IMMUTABLE)) - return -EPERM; - } -@@ -69,7 +73,8 @@ int ext2_ioctl (struct inode * inode, st - case EXT2_IOC_SETVERSION: - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) - return -EPERM; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - if (get_user(inode->i_generation, (int __user *) arg)) - return -EFAULT; -diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c -index ad1432a..30d7141 100644 ---- a/fs/ext2/namei.c -+++ b/fs/ext2/namei.c -@@ -31,6 +31,7 @@ - */ - - #include -+#include - #include "ext2.h" - #include "xattr.h" - #include "acl.h" -@@ -82,6 +83,7 @@ static struct dentry *ext2_lookup(struct - inode = iget(dir->i_sb, ino); - if (!inode) - return ERR_PTR(-EACCES); -+ vx_propagate_xid(nd, inode); - } - return d_splice_alias(inode, dentry); - } -@@ -407,6 +409,7 @@ struct inode_operations ext2_dir_inode_o - #endif - .setattr = ext2_setattr, - .permission = ext2_permission, -+ .sync_flags = ext2_sync_flags, - }; - - struct inode_operations ext2_special_inode_operations = { -@@ -418,4 +421,5 @@ struct inode_operations ext2_special_ino - #endif - .setattr = ext2_setattr, - .permission = ext2_permission, -+ .sync_flags = ext2_sync_flags, - }; -diff --git a/fs/ext2/super.c b/fs/ext2/super.c -index cb6f9bd..66c3b1e 100644 ---- a/fs/ext2/super.c -+++ b/fs/ext2/super.c -@@ -289,7 +289,7 @@ enum { - Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug, - Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr, - Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota, -- Opt_usrquota, Opt_grpquota -+ Opt_usrquota, Opt_grpquota, Opt_tagxid - }; - - static match_table_t tokens = { -@@ -317,6 +317,7 @@ static match_table_t tokens = { - {Opt_acl, "acl"}, - {Opt_noacl, "noacl"}, - {Opt_xip, "xip"}, -+ {Opt_tagxid, "tagxid"}, - {Opt_grpquota, "grpquota"}, - {Opt_ignore, "noquota"}, - {Opt_quota, "quota"}, -@@ -380,6 +381,11 @@ static int parse_options (char * options - case Opt_nouid32: - set_opt (sbi->s_mount_opt, NO_UID32); - break; -+#ifndef CONFIG_INOXID_NONE -+ case Opt_tagxid: -+ set_opt (sbi->s_mount_opt, TAGXID); -+ break; -+#endif - case Opt_nocheck: - clear_opt (sbi->s_mount_opt, CHECK); - break; -@@ -681,6 +687,8 @@ static int ext2_fill_super(struct super_ - if (!parse_options ((char *) data, sbi)) - goto failed_mount; - -+ if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGXID) -+ sb->s_flags |= MS_TAGXID; - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? - MS_POSIXACL : 0); -@@ -990,6 +998,13 @@ static int ext2_remount (struct super_bl - goto restore_opts; - } - -+ if ((sbi->s_mount_opt & EXT2_MOUNT_TAGXID) && -+ !(sb->s_flags & MS_TAGXID)) { -+ printk("EXT2-fs: %s: tagxid not permitted on remount.\n", -+ sb->s_id); -+ return -EINVAL; -+ } -+ - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); - -diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c -index 1e67d87..f86ceeb 100644 ---- a/fs/ext2/symlink.c -+++ b/fs/ext2/symlink.c -@@ -38,6 +38,7 @@ struct inode_operations ext2_symlink_ino - .listxattr = ext2_listxattr, - .removexattr = generic_removexattr, - #endif -+ .sync_flags = ext2_sync_flags, - }; - - struct inode_operations ext2_fast_symlink_inode_operations = { -@@ -49,4 +50,5 @@ struct inode_operations ext2_fast_symlin - .listxattr = ext2_listxattr, - .removexattr = generic_removexattr, - #endif -+ .sync_flags = ext2_sync_flags, - }; -diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c -index 86ae8e9..24c816a 100644 ---- a/fs/ext2/xattr.c -+++ b/fs/ext2/xattr.c -@@ -60,6 +60,7 @@ - #include - #include - #include -+#include - #include "ext2.h" - #include "xattr.h" - #include "acl.h" -@@ -645,8 +646,12 @@ ext2_xattr_set2(struct inode *inode, str - the inode. */ - ea_bdebug(new_bh, "reusing block"); - -+ error = -ENOSPC; -+ if (DLIMIT_ALLOC_BLOCK(inode, 1)) -+ goto cleanup; - error = -EDQUOT; - if (DQUOT_ALLOC_BLOCK(inode, 1)) { -+ DLIMIT_FREE_BLOCK(inode, 1); - unlock_buffer(new_bh); - goto cleanup; - } -@@ -740,6 +745,7 @@ ext2_xattr_set2(struct inode *inode, str - le32_to_cpu(HDR(old_bh)->h_refcount) - 1); - if (ce) - mb_cache_entry_release(ce); -+ DLIMIT_FREE_BLOCK(inode, 1); - DQUOT_FREE_BLOCK(inode, 1); - mark_buffer_dirty(old_bh); - ea_bdebug(old_bh, "refcount now=%d", -@@ -804,6 +810,7 @@ ext2_xattr_delete_inode(struct inode *in - mark_buffer_dirty(bh); - if (IS_SYNC(inode)) - sync_dirty_buffer(bh); -+ DLIMIT_FREE_BLOCK(inode, 1); - DQUOT_FREE_BLOCK(inode, 1); - } - EXT2_I(inode)->i_file_acl = 0; -diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c -index 6250fcd..656cd16 100644 ---- a/fs/ext3/balloc.c -+++ b/fs/ext3/balloc.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - /* - * balloc.c contains the blocks allocation and deallocation routines -@@ -504,8 +505,10 @@ void ext3_free_blocks(handle_t *handle, - return; - } - ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); -- if (dquot_freed_blocks) -+ if (dquot_freed_blocks) { -+ DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks); - DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); -+ } - return; - } - -@@ -1116,18 +1119,32 @@ out: - return ret; - } - --static int ext3_has_free_blocks(struct ext3_sb_info *sbi) -+static int ext3_has_free_blocks(struct super_block *sb) - { -- int free_blocks, root_blocks; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ int free_blocks, root_blocks, cond; - - free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); - root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); -- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && -+ -+ vxdprintk(VXD_CBIT(dlim, 3), -+ "ext3_has_free_blocks(%p): free=%u, root=%u", -+ sb, free_blocks, root_blocks); -+ -+ DLIMIT_ADJUST_BLOCK(sb, vx_current_xid(), &free_blocks, &root_blocks); -+ -+ cond = (free_blocks < root_blocks + 1 && -+ !capable(CAP_SYS_RESOURCE) && - sbi->s_resuid != current->fsuid && -- (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { -- return 0; -- } -- return 1; -+ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))); -+ -+ vxdprintk(VXD_CBIT(dlim, 3), -+ "ext3_has_free_blocks(%p): %u<%u+1, %c, %u!=%u r=%d", -+ sb, free_blocks, root_blocks, -+ !capable(CAP_SYS_RESOURCE)?'1':'0', -+ sbi->s_resuid, current->fsuid, cond?0:1); -+ -+ return (cond ? 0 : 1); - } - - /* -@@ -1138,7 +1155,7 @@ static int ext3_has_free_blocks(struct e - */ - int ext3_should_retry_alloc(struct super_block *sb, int *retries) - { -- if (!ext3_has_free_blocks(EXT3_SB(sb)) || (*retries)++ > 3) -+ if (!ext3_has_free_blocks(sb) || (*retries)++ > 3) - return 0; - - jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); -@@ -1193,6 +1210,8 @@ int ext3_new_block(handle_t *handle, str - *errp = -EDQUOT; - return 0; - } -+ if (DLIMIT_ALLOC_BLOCK(inode, 1)) -+ goto out_dlimit; - - sbi = EXT3_SB(sb); - es = EXT3_SB(sb)->s_es; -@@ -1209,7 +1228,7 @@ int ext3_new_block(handle_t *handle, str - if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0)) - my_rsv = &block_i->rsv_window_node; - -- if (!ext3_has_free_blocks(sbi)) { -+ if (!ext3_has_free_blocks(sb)) { - *errp = -ENOSPC; - goto out; - } -@@ -1393,6 +1412,9 @@ allocated: - io_error: - *errp = -EIO; - out: -+ if (!performed_allocation) -+ DLIMIT_FREE_BLOCK(inode, 1); -+out_dlimit: - if (fatal) { - *errp = fatal; - ext3_std_error(sb, fatal); -diff --git a/fs/ext3/file.c b/fs/ext3/file.c -index 98e7834..9aae45c 100644 ---- a/fs/ext3/file.c -+++ b/fs/ext3/file.c -@@ -131,5 +131,6 @@ struct inode_operations ext3_file_inode_ - .removexattr = generic_removexattr, - #endif - .permission = ext3_permission, -+ .sync_flags = ext3_sync_flags, - }; - -diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c -index dc82646..17c75f5 100644 ---- a/fs/ext3/ialloc.c -+++ b/fs/ext3/ialloc.c -@@ -23,6 +23,8 @@ - #include - #include - #include -+#include -+#include - - #include - -@@ -127,6 +129,7 @@ void ext3_free_inode (handle_t *handle, - ext3_xattr_delete_inode(handle, inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); -+ DLIMIT_FREE_INODE(inode); - - is_directory = S_ISDIR(inode->i_mode); - -@@ -443,6 +446,12 @@ struct inode *ext3_new_inode(handle_t *h - inode = new_inode(sb); - if (!inode) - return ERR_PTR(-ENOMEM); -+ -+ inode->i_xid = vx_current_fsxid(sb); -+ if (DLIMIT_ALLOC_INODE(inode)) { -+ err = -ENOSPC; -+ goto out_dlimit; -+ } - ei = EXT3_I(inode); - - sbi = EXT3_SB(sb); -@@ -565,7 +574,8 @@ got: - ei->i_dir_start_lookup = 0; - ei->i_disksize = 0; - -- ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL; -+ ei->i_flags = EXT3_I(dir)->i_flags & -+ ~(EXT3_INDEX_FL|EXT3_IUNLINK_FL|EXT3_BARRIER_FL); - if (S_ISLNK(mode)) - ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL); - /* dirsync only applies to directories */ -@@ -620,6 +630,8 @@ got: - fail: - ext3_std_error(sb, err); - out: -+ DLIMIT_FREE_INODE(inode); -+out_dlimit: - iput(inode); - ret = ERR_PTR(err); - really_out: -@@ -631,6 +643,7 @@ fail_free_drop: - - fail_drop: - DQUOT_DROP(inode); -+ DLIMIT_FREE_INODE(inode); - inode->i_flags |= S_NOQUOTA; - inode->i_nlink = 0; - iput(inode); -diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c -index 0384e53..045eaf9 100644 ---- a/fs/ext3/inode.c -+++ b/fs/ext3/inode.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - #include "xattr.h" - #include "acl.h" - -@@ -2422,19 +2423,77 @@ void ext3_set_inode_flags(struct inode * - { - unsigned int flags = EXT3_I(inode)->i_flags; - -- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); -+ inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER | -+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC); -+ -+ if (flags & EXT3_IMMUTABLE_FL) -+ inode->i_flags |= S_IMMUTABLE; -+ if (flags & EXT3_IUNLINK_FL) -+ inode->i_flags |= S_IUNLINK; -+ if (flags & EXT3_BARRIER_FL) -+ inode->i_flags |= S_BARRIER; -+ - if (flags & EXT3_SYNC_FL) - inode->i_flags |= S_SYNC; - if (flags & EXT3_APPEND_FL) - inode->i_flags |= S_APPEND; -- if (flags & EXT3_IMMUTABLE_FL) -- inode->i_flags |= S_IMMUTABLE; - if (flags & EXT3_NOATIME_FL) - inode->i_flags |= S_NOATIME; - if (flags & EXT3_DIRSYNC_FL) - inode->i_flags |= S_DIRSYNC; - } - -+int ext3_sync_flags(struct inode *inode) -+{ -+ unsigned int oldflags, newflags; -+ int err = 0; -+ -+ oldflags = EXT3_I(inode)->i_flags; -+ newflags = oldflags & ~(EXT3_APPEND_FL | -+ EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL | -+ EXT3_BARRIER_FL | EXT3_NOATIME_FL | -+ EXT3_SYNC_FL | EXT3_DIRSYNC_FL); -+ -+ if (IS_APPEND(inode)) -+ newflags |= EXT3_APPEND_FL; -+ if (IS_IMMUTABLE(inode)) -+ newflags |= EXT3_IMMUTABLE_FL; -+ if (IS_IUNLINK(inode)) -+ newflags |= EXT3_IUNLINK_FL; -+ if (IS_BARRIER(inode)) -+ newflags |= EXT3_BARRIER_FL; -+ -+ /* we do not want to copy superblock flags */ -+ if (inode->i_flags & S_NOATIME) -+ newflags |= EXT3_NOATIME_FL; -+ if (inode->i_flags & S_SYNC) -+ newflags |= EXT3_SYNC_FL; -+ if (inode->i_flags & S_DIRSYNC) -+ newflags |= EXT3_DIRSYNC_FL; -+ -+ if (oldflags ^ newflags) { -+ handle_t *handle; -+ struct ext3_iloc iloc; -+ -+ handle = ext3_journal_start(inode, 1); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ err = ext3_reserve_inode_write(handle, inode, &iloc); -+ if (err) -+ goto flags_err; -+ -+ EXT3_I(inode)->i_flags = newflags; -+ inode->i_ctime = CURRENT_TIME; -+ -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ flags_err: -+ ext3_journal_stop(handle); -+ } -+ return err; -+} -+ - void ext3_read_inode(struct inode * inode) - { - struct ext3_iloc iloc; -@@ -2442,6 +2501,8 @@ void ext3_read_inode(struct inode * inod - struct ext3_inode_info *ei = EXT3_I(inode); - struct buffer_head *bh; - int block; -+ uid_t uid; -+ gid_t gid; - - #ifdef CONFIG_EXT3_FS_POSIX_ACL - ei->i_acl = EXT3_ACL_NOT_CACHED; -@@ -2454,12 +2515,17 @@ void ext3_read_inode(struct inode * inod - bh = iloc.bh; - raw_inode = ext3_raw_inode(&iloc); - inode->i_mode = le16_to_cpu(raw_inode->i_mode); -- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); -- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); -+ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); -+ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); - if(!(test_opt (inode->i_sb, NO_UID32))) { -- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; -- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; -+ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; -+ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; - } -+ inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); -+ inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); -+ inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, -+ le16_to_cpu(raw_inode->i_raw_xid)); -+ - inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); - inode->i_size = le32_to_cpu(raw_inode->i_size); - inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime); -@@ -2586,6 +2652,8 @@ static int ext3_do_update_inode(handle_t - struct ext3_inode *raw_inode = ext3_raw_inode(iloc); - struct ext3_inode_info *ei = EXT3_I(inode); - struct buffer_head *bh = iloc->bh; -+ uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); -+ gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); - int err = 0, rc, block; - - /* For fields not not tracking in the in-memory inode, -@@ -2595,29 +2663,32 @@ static int ext3_do_update_inode(handle_t - - raw_inode->i_mode = cpu_to_le16(inode->i_mode); - if(!(test_opt(inode->i_sb, NO_UID32))) { -- raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); -- raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); -+ raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid)); -+ raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid)); - /* - * Fix up interoperability with old kernels. Otherwise, old inodes get - * re-used with the upper 16 bits of the uid/gid intact - */ - if(!ei->i_dtime) { - raw_inode->i_uid_high = -- cpu_to_le16(high_16_bits(inode->i_uid)); -+ cpu_to_le16(high_16_bits(uid)); - raw_inode->i_gid_high = -- cpu_to_le16(high_16_bits(inode->i_gid)); -+ cpu_to_le16(high_16_bits(gid)); - } else { - raw_inode->i_uid_high = 0; - raw_inode->i_gid_high = 0; - } - } else { - raw_inode->i_uid_low = -- cpu_to_le16(fs_high2lowuid(inode->i_uid)); -+ cpu_to_le16(fs_high2lowuid(uid)); - raw_inode->i_gid_low = -- cpu_to_le16(fs_high2lowgid(inode->i_gid)); -+ cpu_to_le16(fs_high2lowgid(gid)); - raw_inode->i_uid_high = 0; - raw_inode->i_gid_high = 0; - } -+#ifdef CONFIG_INOXID_INTERN -+ raw_inode->i_raw_xid = cpu_to_le16(inode->i_xid); -+#endif - raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); - raw_inode->i_size = cpu_to_le32(ei->i_disksize); - raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); -@@ -2770,7 +2841,8 @@ int ext3_setattr(struct dentry *dentry, - return error; - - if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || -- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { -+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || -+ (ia_valid & ATTR_XID && attr->ia_xid != inode->i_xid)) { - handle_t *handle; - - /* (user+group)*(old+new) structure, inode write (sb, -@@ -2792,6 +2864,8 @@ int ext3_setattr(struct dentry *dentry, - inode->i_uid = attr->ia_uid; - if (attr->ia_valid & ATTR_GID) - inode->i_gid = attr->ia_gid; -+ if ((attr->ia_valid & ATTR_XID) && IS_TAGXID(inode)) -+ inode->i_xid = attr->ia_xid; - error = ext3_mark_inode_dirty(handle, inode); - ext3_journal_stop(handle); - } -diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c -index 556cd55..6ed8a19 100644 ---- a/fs/ext3/ioctl.c -+++ b/fs/ext3/ioctl.c -@@ -8,11 +8,13 @@ - */ - - #include -+#include - #include - #include - #include - #include - #include -+#include - #include - - -@@ -36,7 +38,8 @@ int ext3_ioctl (struct inode * inode, st - unsigned int oldflags; - unsigned int jflag; - -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) -@@ -59,7 +62,9 @@ int ext3_ioctl (struct inode * inode, st - * - * This test looks nicer. Thanks to Pauline Middelink - */ -- if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { -+ if ((oldflags & EXT3_IMMUTABLE_FL) || -+ ((flags ^ oldflags) & (EXT3_APPEND_FL | -+ EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL))) { - if (!capable(CAP_LINUX_IMMUTABLE)) - return -EPERM; - } -@@ -112,7 +117,8 @@ flags_err: - - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) - return -EPERM; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - if (get_user(generation, (int __user *) arg)) - return -EFAULT; -@@ -166,7 +172,8 @@ flags_err: - if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) - return -ENOTTY; - -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) -@@ -201,7 +208,8 @@ flags_err: - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; - -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - - if (get_user(n_blocks_count, (__u32 __user *)arg)) -@@ -222,7 +230,8 @@ flags_err: - if (!capable(CAP_SYS_RESOURCE)) - return -EPERM; - -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - - if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg, -@@ -237,6 +246,38 @@ flags_err: - return err; - } - -+#if defined(CONFIG_VSERVER_LEGACY) && !defined(CONFIG_INOXID_NONE) -+ case EXT3_IOC_SETXID: { -+ handle_t *handle; -+ struct ext3_iloc iloc; -+ int xid; -+ int err; -+ -+ /* fixme: if stealth, return -ENOTTY */ -+ if (!capable(CAP_CONTEXT)) -+ return -EPERM; -+ if (IS_RDONLY(inode)) -+ return -EROFS; -+ if (!(inode->i_sb->s_flags & MS_TAGXID)) -+ return -ENOSYS; -+ if (get_user(xid, (int *) arg)) -+ return -EFAULT; -+ -+ handle = ext3_journal_start(inode, 1); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ err = ext3_reserve_inode_write(handle, inode, &iloc); -+ if (err) -+ return err; -+ -+ inode->i_xid = (xid & 0xFFFF); -+ inode->i_ctime = CURRENT_TIME; -+ -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ ext3_journal_stop(handle); -+ return err; -+ } -+#endif - - default: - return -ENOTTY; -diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c -index b8f5cd1..329eae3 100644 ---- a/fs/ext3/namei.c -+++ b/fs/ext3/namei.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include "namei.h" - #include "xattr.h" -@@ -1004,6 +1005,7 @@ static struct dentry *ext3_lookup(struct - - if (!inode) - return ERR_PTR(-EACCES); -+ vx_propagate_xid(nd, inode); - } - return d_splice_alias(inode, dentry); - } -@@ -2373,6 +2375,7 @@ struct inode_operations ext3_dir_inode_o - .removexattr = generic_removexattr, - #endif - .permission = ext3_permission, -+ .sync_flags = ext3_sync_flags, - }; - - struct inode_operations ext3_special_inode_operations = { -@@ -2384,4 +2387,5 @@ struct inode_operations ext3_special_ino - .removexattr = generic_removexattr, - #endif - .permission = ext3_permission, -+ .sync_flags = ext3_sync_flags, - }; -diff --git a/fs/ext3/super.c b/fs/ext3/super.c -index 56bf765..4337596 100644 ---- a/fs/ext3/super.c -+++ b/fs/ext3/super.c -@@ -634,7 +634,7 @@ enum { - Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, - Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, - Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, -- Opt_grpquota -+ Opt_grpquota, Opt_tagxid - }; - - static match_table_t tokens = { -@@ -683,6 +683,7 @@ static match_table_t tokens = { - {Opt_quota, "quota"}, - {Opt_usrquota, "usrquota"}, - {Opt_barrier, "barrier=%u"}, -+ {Opt_tagxid, "tagxid"}, - {Opt_err, NULL}, - {Opt_resize, "resize"}, - }; -@@ -775,6 +776,11 @@ static int parse_options (char *options, - case Opt_nouid32: - set_opt (sbi->s_mount_opt, NO_UID32); - break; -+#ifndef CONFIG_INOXID_NONE -+ case Opt_tagxid: -+ set_opt (sbi->s_mount_opt, TAGXID); -+ break; -+#endif - case Opt_nocheck: - clear_opt (sbi->s_mount_opt, CHECK); - break; -@@ -1429,6 +1435,9 @@ static int ext3_fill_super (struct super - NULL, 0)) - goto failed_mount; - -+ if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGXID) -+ sb->s_flags |= MS_TAGXID; -+ - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); - -@@ -2238,6 +2247,12 @@ static int ext3_remount (struct super_bl - - if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) - ext3_abort(sb, __FUNCTION__, "Abort forced by user"); -+ if ((sbi->s_mount_opt & EXT3_MOUNT_TAGXID) && -+ !(sb->s_flags & MS_TAGXID)) { -+ printk("EXT3-fs: %s: tagxid not permitted on remount.\n", -+ sb->s_id); -+ return -EINVAL; -+ } - - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); -diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c -index 4f79122..d9526d7 100644 ---- a/fs/ext3/symlink.c -+++ b/fs/ext3/symlink.c -@@ -40,6 +40,7 @@ struct inode_operations ext3_symlink_ino - .listxattr = ext3_listxattr, - .removexattr = generic_removexattr, - #endif -+ .sync_flags = ext3_sync_flags, - }; - - struct inode_operations ext3_fast_symlink_inode_operations = { -@@ -51,4 +52,5 @@ struct inode_operations ext3_fast_symlin - .listxattr = ext3_listxattr, - .removexattr = generic_removexattr, - #endif -+ .sync_flags = ext3_sync_flags, - }; -diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c -index e8d60bf..fac3f24 100644 ---- a/fs/ext3/xattr.c -+++ b/fs/ext3/xattr.c -@@ -58,6 +58,7 @@ - #include - #include - #include -+#include - #include "xattr.h" - #include "acl.h" - -@@ -495,6 +496,7 @@ ext3_xattr_release_block(handle_t *handl - ext3_journal_dirty_metadata(handle, bh); - if (IS_SYNC(inode)) - handle->h_sync = 1; -+ DLIMIT_FREE_BLOCK(inode, 1); - DQUOT_FREE_BLOCK(inode, 1); - unlock_buffer(bh); - ea_bdebug(bh, "refcount now=%d; releasing", -@@ -763,11 +765,14 @@ inserted: - if (new_bh == bs->bh) - ea_bdebug(new_bh, "keeping"); - else { -+ error = -ENOSPC; -+ if (DLIMIT_ALLOC_BLOCK(inode, 1)) -+ goto cleanup; - /* The old block is released after updating - the inode. */ - error = -EDQUOT; - if (DQUOT_ALLOC_BLOCK(inode, 1)) -- goto cleanup; -+ goto cleanup_dlimit; - error = ext3_journal_get_write_access(handle, - new_bh); - if (error) -@@ -843,6 +848,8 @@ cleanup: - - cleanup_dquot: - DQUOT_FREE_BLOCK(inode, 1); -+cleanup_dlimit: -+ DLIMIT_FREE_BLOCK(inode, 1); - goto cleanup; - - bad_block: -diff --git a/fs/fcntl.c b/fs/fcntl.c -index dc4a700..84d0e40 100644 ---- a/fs/fcntl.c -+++ b/fs/fcntl.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -85,6 +86,8 @@ repeat: - error = -EMFILE; - if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) - goto out; -+ if (!vx_files_avail(1)) -+ goto out; - - error = expand_files(files, newfd); - if (error < 0) -@@ -126,6 +129,7 @@ static int dupfd(struct file *file, unsi - FD_SET(fd, fdt->open_fds); - FD_CLR(fd, fdt->close_on_exec); - spin_unlock(&files->file_lock); -+ vx_openfd_inc(fd); - fd_install(fd, file); - } else { - spin_unlock(&files->file_lock); -@@ -178,6 +182,9 @@ asmlinkage long sys_dup2(unsigned int ol - - if (tofree) - filp_close(tofree, files); -+ else -+ vx_openfd_inc(newfd); /* fd was unused */ -+ - err = newfd; - out: - return err; -@@ -481,7 +488,7 @@ void send_sigio(struct fown_struct *fown - - read_lock(&tasklist_lock); - if (pid > 0) { -- p = find_task_by_pid(pid); -+ p = find_task_by_real_pid(pid); - if (p) { - send_sigio_to_task(p, fown, fd, band); - } -@@ -516,7 +523,7 @@ int send_sigurg(struct fown_struct *fown - - read_lock(&tasklist_lock); - if (pid > 0) { -- p = find_task_by_pid(pid); -+ p = find_task_by_real_pid(pid); - if (p) { - send_sigurg_to_task(p, fown); - } -diff --git a/fs/file_table.c b/fs/file_table.c -index 44fabea..cc11ccb 100644 ---- a/fs/file_table.c -+++ b/fs/file_table.c -@@ -22,6 +22,8 @@ - #include - #include - #include -+#include -+#include - - #include - -@@ -119,6 +121,8 @@ struct file *get_empty_filp(void) - rwlock_init(&f->f_owner.lock); - /* f->f_version: 0 */ - INIT_LIST_HEAD(&f->f_u.fu_list); -+ f->f_xid = vx_current_xid(); -+ vx_files_inc(f); - return f; - - over: -@@ -173,6 +177,8 @@ void fastcall __fput(struct file *file) - fops_put(file->f_op); - if (file->f_mode & FMODE_WRITE) - put_write_access(inode); -+ vx_files_dec(file); -+ file->f_xid = 0; - file_kill(file); - file->f_dentry = NULL; - file->f_vfsmnt = NULL; -@@ -238,6 +244,8 @@ void put_filp(struct file *file) - { - if (atomic_dec_and_test(&file->f_count)) { - security_file_free(file); -+ vx_files_dec(file); -+ file->f_xid = 0; - file_kill(file); - file_free(file); - } -diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c -index 13cf848..cccd9fc 100644 ---- a/fs/hfsplus/ioctl.c -+++ b/fs/hfsplus/ioctl.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include "hfsplus_fs.h" - -@@ -35,7 +36,8 @@ int hfsplus_ioctl(struct inode *inode, s - flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */ - return put_user(flags, (int __user *)arg); - case HFSPLUS_IOC_EXT2_SETFLAGS: { -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) -diff --git a/fs/inode.c b/fs/inode.c -index d0be615..e989f5f 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -116,6 +116,9 @@ static struct inode *alloc_inode(struct - struct address_space * const mapping = &inode->i_data; - - inode->i_sb = sb; -+ -+ /* essential because of inode slab reuse */ -+ inode->i_xid = 0; - inode->i_blkbits = sb->s_blocksize_bits; - inode->i_flags = 0; - atomic_set(&inode->i_count, 1); -@@ -236,6 +239,8 @@ void __iget(struct inode * inode) - inodes_stat.nr_unused--; - } - -+EXPORT_SYMBOL_GPL(__iget); -+ - /** - * clear_inode - clear an inode - * @inode: inode to clear -diff --git a/fs/ioctl.c b/fs/ioctl.c -index f8aeec3..cfcaad7 100644 ---- a/fs/ioctl.c -+++ b/fs/ioctl.c -@@ -13,10 +13,19 @@ - #include - #include - #include -+#include -+#include -+#include - - #include - #include - -+ -+#ifdef CONFIG_VSERVER_LEGACY -+extern int vx_proc_ioctl(struct inode *, struct file *, -+ unsigned int, unsigned long); -+#endif -+ - static long do_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) - { -@@ -147,6 +156,48 @@ int vfs_ioctl(struct file *filp, unsigne - else - error = -ENOTTY; - break; -+#ifdef CONFIG_VSERVER_LEGACY -+#ifndef CONFIG_INOXID_NONE -+ case FIOC_GETXID: { -+ struct inode *inode = filp->f_dentry->d_inode; -+ -+ /* fixme: if stealth, return -ENOTTY */ -+ error = -EPERM; -+ if (capable(CAP_CONTEXT)) -+ error = put_user(inode->i_xid, (int *) arg); -+ break; -+ } -+ case FIOC_SETXID: { -+ struct inode *inode = filp->f_dentry->d_inode; -+ int xid; -+ -+ /* fixme: if stealth, return -ENOTTY */ -+ error = -EPERM; -+ if (!capable(CAP_CONTEXT)) -+ break; -+ error = -EROFS; -+ if (IS_RDONLY(inode)) -+ break; -+ error = -ENOSYS; -+ if (!(inode->i_sb->s_flags & MS_TAGXID)) -+ break; -+ error = -EFAULT; -+ if (get_user(xid, (int *) arg)) -+ break; -+ error = 0; -+ inode->i_xid = (xid & 0xFFFF); -+ inode->i_ctime = CURRENT_TIME; -+ mark_inode_dirty(inode); -+ break; -+ } -+#endif -+ case FIOC_GETXFLG: -+ case FIOC_SETXFLG: -+ error = -ENOTTY; -+ if (filp->f_dentry->d_inode->i_sb->s_magic == PROC_SUPER_MAGIC) -+ error = vx_proc_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); -+ break; -+#endif - default: - if (S_ISREG(filp->f_dentry->d_inode->i_mode)) - error = file_ioctl(filp, cmd, arg); -diff --git a/fs/ioprio.c b/fs/ioprio.c -index ca77008..5d86209 100644 ---- a/fs/ioprio.c -+++ b/fs/ioprio.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - static int set_task_ioprio(struct task_struct *task, int ioprio) - { -@@ -95,7 +96,7 @@ asmlinkage long sys_ioprio_set(int which - if (!who) - user = current->user; - else -- user = find_user(who); -+ user = find_user(who, vx_current_xid()); - - if (!user) - break; -@@ -149,7 +150,7 @@ asmlinkage long sys_ioprio_get(int which - if (!who) - user = current->user; - else -- user = find_user(who); -+ user = find_user(who, vx_current_xid()); - - if (!user) - break; -diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c -index 461e493..5df5582 100644 ---- a/fs/jfs/acl.c -+++ b/fs/jfs/acl.c -@@ -229,7 +229,8 @@ int jfs_setattr(struct dentry *dentry, s - return rc; - - if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || -- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { -+ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) || -+ (iattr->ia_valid & ATTR_XID && iattr->ia_xid != inode->i_xid)) { - if (DQUOT_TRANSFER(inode, iattr)) - return -EDQUOT; - } -diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c -index 9f942ca..3df7857 100644 ---- a/fs/jfs/inode.c -+++ b/fs/jfs/inode.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include "jfs_incore.h" - #include "jfs_inode.h" - #include "jfs_filsys.h" -@@ -143,6 +144,7 @@ void jfs_delete_inode(struct inode *inod - DQUOT_INIT(inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); -+ DLIMIT_FREE_INODE(inode); - } - - clear_inode(inode); -diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c -index 404f33e..e567174 100644 ---- a/fs/jfs/jfs_dtree.c -+++ b/fs/jfs/jfs_dtree.c -@@ -102,6 +102,7 @@ - - #include - #include -+#include - #include "jfs_incore.h" - #include "jfs_superblock.h" - #include "jfs_filsys.h" -@@ -383,10 +384,10 @@ static u32 add_index(tid_t tid, struct i - */ - if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage)) - goto clean_up; -- if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) { -- DQUOT_FREE_BLOCK(ip, sbi->nbperpage); -- goto clean_up; -- } -+ if (DLIMIT_ALLOC_BLOCK(ip, sbi->nbperpage)) -+ goto clean_up_quota; -+ if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) -+ goto clean_up_dlim; - - /* - * Save the table, we're going to overwrite it with the -@@ -479,6 +480,10 @@ static u32 add_index(tid_t tid, struct i - - return index; - -+ clean_up_dlim: -+ DLIMIT_FREE_BLOCK(ip, sbi->nbperpage); -+ clean_up_quota: -+ DQUOT_FREE_BLOCK(ip, sbi->nbperpage); - clean_up: - - jfs_ip->next_index--; -@@ -930,7 +935,8 @@ int dtInsert(tid_t tid, struct inode *ip - static int dtSplitUp(tid_t tid, - struct inode *ip, struct dtsplit * split, struct btstack * btstack) - { -- struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); -+ struct super_block *sb = ip->i_sb; -+ struct jfs_sb_info *sbi = JFS_SBI(sb); - int rc = 0; - struct metapage *smp; - dtpage_t *sp; /* split page */ -@@ -952,6 +958,7 @@ static int dtSplitUp(tid_t tid, - struct tlock *tlck; - struct lv *lv; - int quota_allocation = 0; -+ int dlimit_allocation = 0; - - /* get split page */ - smp = split->mp; -@@ -1033,6 +1040,12 @@ static int dtSplitUp(tid_t tid, - } - quota_allocation += n; - -+ if (DLIMIT_ALLOC_BLOCK(ip, n)) { -+ rc = -ENOSPC; -+ goto extendOut; -+ } -+ dlimit_allocation += n; -+ - if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen, - (s64) n, &nxaddr))) - goto extendOut; -@@ -1301,6 +1314,9 @@ static int dtSplitUp(tid_t tid, - freeKeyName: - kfree(key.name); - -+ /* Rollback dlimit allocation */ -+ if (rc && dlimit_allocation) -+ DLIMIT_FREE_BLOCK(ip, dlimit_allocation); - /* Rollback quota allocation */ - if (rc && quota_allocation) - DQUOT_FREE_BLOCK(ip, quota_allocation); -@@ -1368,6 +1384,12 @@ static int dtSplitPage(tid_t tid, struct - release_metapage(rmp); - return -EDQUOT; - } -+ /* Allocate blocks to dlimit. */ -+ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { -+ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd)); -+ release_metapage(rmp); -+ return -ENOSPC; -+ } - - jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); - -@@ -1918,6 +1940,12 @@ static int dtSplitRoot(tid_t tid, - release_metapage(rmp); - return -EDQUOT; - } -+ /* Allocate blocks to dlimit. */ -+ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { -+ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd)); -+ release_metapage(rmp); -+ return -ENOSPC; -+ } - - BT_MARK_DIRTY(rmp, ip); - /* -@@ -2284,6 +2312,8 @@ static int dtDeleteUp(tid_t tid, struct - - xlen = lengthPXD(&fp->header.self); - -+ /* Free dlimit allocation. */ -+ DLIMIT_FREE_BLOCK(ip, xlen); - /* Free quota allocation. */ - DQUOT_FREE_BLOCK(ip, xlen); - -@@ -2360,6 +2390,8 @@ static int dtDeleteUp(tid_t tid, struct - - xlen = lengthPXD(&p->header.self); - -+ /* Free dlimit allocation */ -+ DLIMIT_FREE_BLOCK(ip, xlen); - /* Free quota allocation */ - DQUOT_FREE_BLOCK(ip, xlen); - -diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c -index 4879603..ecd440e 100644 ---- a/fs/jfs/jfs_extent.c -+++ b/fs/jfs/jfs_extent.c -@@ -18,6 +18,7 @@ - - #include - #include -+#include - #include "jfs_incore.h" - #include "jfs_inode.h" - #include "jfs_superblock.h" -@@ -146,6 +147,13 @@ extAlloc(struct inode *ip, s64 xlen, s64 - up(&JFS_IP(ip)->commit_sem); - return -EDQUOT; - } -+ /* Allocate blocks to dlimit. */ -+ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) { -+ DQUOT_FREE_BLOCK(ip, nxlen); -+ dbFree(ip, nxaddr, (s64) nxlen); -+ up(&JFS_IP(ip)->commit_sem); -+ return -ENOSPC; -+ } - - /* determine the value of the extent flag */ - xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0; -@@ -164,6 +172,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 - */ - if (rc) { - dbFree(ip, nxaddr, nxlen); -+ DLIMIT_FREE_BLOCK(ip, nxlen); - DQUOT_FREE_BLOCK(ip, nxlen); - up(&JFS_IP(ip)->commit_sem); - return (rc); -@@ -261,6 +270,13 @@ int extRealloc(struct inode *ip, s64 nxl - up(&JFS_IP(ip)->commit_sem); - return -EDQUOT; - } -+ /* Allocate blocks to dlimit. */ -+ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) { -+ DQUOT_FREE_BLOCK(ip, nxlen); -+ dbFree(ip, nxaddr, (s64) nxlen); -+ up(&JFS_IP(ip)->commit_sem); -+ return -ENOSPC; -+ } - - delta = nxlen - xlen; - -@@ -297,6 +313,7 @@ int extRealloc(struct inode *ip, s64 nxl - /* extend the extent */ - if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) { - dbFree(ip, xaddr + xlen, delta); -+ DLIMIT_FREE_BLOCK(ip, nxlen); - DQUOT_FREE_BLOCK(ip, nxlen); - goto exit; - } -@@ -308,6 +325,7 @@ int extRealloc(struct inode *ip, s64 nxl - */ - if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) { - dbFree(ip, nxaddr, nxlen); -+ DLIMIT_FREE_BLOCK(ip, nxlen); - DQUOT_FREE_BLOCK(ip, nxlen); - goto exit; - } -diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h -index 72a5588..7f0d552 100644 ---- a/fs/jfs/jfs_filsys.h -+++ b/fs/jfs/jfs_filsys.h -@@ -84,6 +84,7 @@ - #define JFS_DIR_INDEX 0x00200000 /* Persistant index for */ - /* directory entries */ - -+#define JFS_TAGXID 0x00800000 /* xid tagging */ - - /* - * buffer cache configuration -diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c -index 31b4aa1..a321fc4 100644 ---- a/fs/jfs/jfs_imap.c -+++ b/fs/jfs/jfs_imap.c -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - - #include "jfs_incore.h" - #include "jfs_inode.h" -@@ -3076,14 +3077,21 @@ static void duplicateIXtree(struct super - static int copy_from_dinode(struct dinode * dip, struct inode *ip) - { - struct jfs_inode_info *jfs_ip = JFS_IP(ip); -+ uid_t uid; -+ gid_t gid; - - jfs_ip->fileset = le32_to_cpu(dip->di_fileset); - jfs_ip->mode2 = le32_to_cpu(dip->di_mode); - - ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; - ip->i_nlink = le32_to_cpu(dip->di_nlink); -- ip->i_uid = le32_to_cpu(dip->di_uid); -- ip->i_gid = le32_to_cpu(dip->di_gid); -+ -+ uid = le32_to_cpu(dip->di_uid); -+ gid = le32_to_cpu(dip->di_gid); -+ ip->i_uid = INOXID_UID(XID_TAG(ip), uid, gid); -+ ip->i_gid = INOXID_GID(XID_TAG(ip), uid, gid); -+ ip->i_xid = INOXID_XID(XID_TAG(ip), uid, gid, 0); -+ - ip->i_size = le64_to_cpu(dip->di_size); - ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); - ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); -@@ -3134,6 +3142,8 @@ static int copy_from_dinode(struct dinod - static void copy_to_dinode(struct dinode * dip, struct inode *ip) - { - struct jfs_inode_info *jfs_ip = JFS_IP(ip); -+ uid_t uid; -+ gid_t gid; - - dip->di_fileset = cpu_to_le32(jfs_ip->fileset); - dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); -@@ -3142,8 +3152,11 @@ static void copy_to_dinode(struct dinode - dip->di_size = cpu_to_le64(ip->i_size); - dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); - dip->di_nlink = cpu_to_le32(ip->i_nlink); -- dip->di_uid = cpu_to_le32(ip->i_uid); -- dip->di_gid = cpu_to_le32(ip->i_gid); -+ -+ uid = XIDINO_UID(XID_TAG(ip), ip->i_uid, ip->i_xid); -+ gid = XIDINO_GID(XID_TAG(ip), ip->i_gid, ip->i_xid); -+ dip->di_uid = cpu_to_le32(uid); -+ dip->di_gid = cpu_to_le32(gid); - /* - * mode2 is only needed for storing the higher order bits. - * Trust i_mode for the lower order ones -diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c -index 2af5efb..4340659 100644 ---- a/fs/jfs/jfs_inode.c -+++ b/fs/jfs/jfs_inode.c -@@ -18,6 +18,8 @@ - - #include - #include -+#include -+#include - #include "jfs_incore.h" - #include "jfs_inode.h" - #include "jfs_filsys.h" -@@ -62,10 +64,17 @@ struct inode *ialloc(struct inode *paren - } else - inode->i_gid = current->fsgid; - -+ inode->i_xid = vx_current_fsxid(sb); -+ if (DLIMIT_ALLOC_INODE(inode)) { -+ iput(inode); -+ return NULL; -+ } -+ - /* - * Allocate inode to quota. - */ - if (DQUOT_ALLOC_INODE(inode)) { -+ DLIMIT_FREE_INODE(inode); - DQUOT_DROP(inode); - inode->i_flags |= S_NOQUOTA; - inode->i_nlink = 0; -diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c -index e72f4eb..677890c 100644 ---- a/fs/jfs/jfs_xtree.c -+++ b/fs/jfs/jfs_xtree.c -@@ -21,6 +21,7 @@ - - #include - #include -+#include - #include "jfs_incore.h" - #include "jfs_filsys.h" - #include "jfs_metapage.h" -@@ -841,7 +842,12 @@ int xtInsert(tid_t tid, /* transaction - hint = 0; - if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen))) - goto out; -+ if ((rc = DLIMIT_ALLOC_BLOCK(ip, xlen))) { -+ DQUOT_FREE_BLOCK(ip, xlen); -+ goto out; -+ } - if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) { -+ DLIMIT_FREE_BLOCK(ip, xlen); - DQUOT_FREE_BLOCK(ip, xlen); - goto out; - } -@@ -871,6 +877,7 @@ int xtInsert(tid_t tid, /* transaction - /* undo data extent allocation */ - if (*xaddrp == 0) { - dbFree(ip, xaddr, (s64) xlen); -+ DLIMIT_FREE_BLOCK(ip, xlen); - DQUOT_FREE_BLOCK(ip, xlen); - } - return rc; -@@ -1231,6 +1238,7 @@ xtSplitPage(tid_t tid, struct inode *ip, - struct tlock *tlck; - struct xtlock *sxtlck = NULL, *rxtlck = NULL; - int quota_allocation = 0; -+ int dlimit_allocation = 0; - - smp = split->mp; - sp = XT_PAGE(ip, smp); -@@ -1243,13 +1251,20 @@ xtSplitPage(tid_t tid, struct inode *ip, - rbn = addressPXD(pxd); - - /* Allocate blocks to quota. */ -- if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { -+ if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { - rc = -EDQUOT; - goto clean_up; - } - - quota_allocation += lengthPXD(pxd); - -+ /* Allocate blocks to dlimit. */ -+ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { -+ rc = -ENOSPC; -+ goto clean_up; -+ } -+ dlimit_allocation += lengthPXD(pxd); -+ - /* - * allocate the new right page for the split - */ -@@ -1451,6 +1466,9 @@ xtSplitPage(tid_t tid, struct inode *ip, - - clean_up: - -+ /* Rollback dlimit allocation. */ -+ if (dlimit_allocation) -+ DLIMIT_FREE_BLOCK(ip, dlimit_allocation); - /* Rollback quota allocation. */ - if (quota_allocation) - DQUOT_FREE_BLOCK(ip, quota_allocation); -@@ -1515,6 +1533,12 @@ xtSplitRoot(tid_t tid, - release_metapage(rmp); - return -EDQUOT; - } -+ /* Allocate blocks to dlimit. */ -+ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { -+ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd)); -+ release_metapage(rmp); -+ return -ENOSPC; -+ } - - jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp); - -@@ -3941,6 +3965,8 @@ s64 xtTruncate(tid_t tid, struct inode * - else - ip->i_size = newsize; - -+ /* update dlimit allocation to reflect freed blocks */ -+ DLIMIT_FREE_BLOCK(ip, nfreed); - /* update quota allocation to reflect freed blocks */ - DQUOT_FREE_BLOCK(ip, nfreed); - -diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c -index 4abbe86..a32f2f5 100644 ---- a/fs/jfs/namei.c -+++ b/fs/jfs/namei.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include "jfs_incore.h" - #include "jfs_superblock.h" - #include "jfs_inode.h" -@@ -1465,6 +1466,7 @@ static struct dentry *jfs_lookup(struct - return ERR_PTR(-EACCES); - } - -+ vx_propagate_xid(nd, ip); - dentry = d_splice_alias(ip, dentry); - - if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)) -diff --git a/fs/jfs/super.c b/fs/jfs/super.c -index 8d31f13..b71f608 100644 ---- a/fs/jfs/super.c -+++ b/fs/jfs/super.c -@@ -195,7 +195,7 @@ static void jfs_put_super(struct super_b - enum { - Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, - Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota, -- Opt_usrquota, Opt_grpquota -+ Opt_usrquota, Opt_grpquota, Opt_tagxid - }; - - static match_table_t tokens = { -@@ -205,6 +205,7 @@ static match_table_t tokens = { - {Opt_resize, "resize=%u"}, - {Opt_resize_nosize, "resize"}, - {Opt_errors, "errors=%s"}, -+ {Opt_tagxid, "tagxid"}, - {Opt_ignore, "noquota"}, - {Opt_ignore, "quota"}, - {Opt_usrquota, "usrquota"}, -@@ -313,7 +314,11 @@ static int parse_options(char *options, - "JFS: quota operations not supported\n"); - break; - #endif -- -+#ifndef CONFIG_INOXID_NONE -+ case Opt_tagxid: -+ *flag |= JFS_TAGXID; -+ break; -+#endif - default: - printk("jfs: Unrecognized mount option \"%s\" " - " or missing value\n", p); -@@ -344,6 +349,13 @@ static int jfs_remount(struct super_bloc - if (!parse_options(data, sb, &newLVSize, &flag)) { - return -EINVAL; - } -+ -+ if ((flag & JFS_TAGXID) && !(sb->s_flags & MS_TAGXID)) { -+ printk(KERN_ERR "JFS: %s: tagxid not permitted on remount.\n", -+ sb->s_id); -+ return -EINVAL; -+ } -+ - if (newLVSize) { - if (sb->s_flags & MS_RDONLY) { - printk(KERN_ERR -@@ -415,6 +427,9 @@ static int jfs_fill_super(struct super_b - #ifdef CONFIG_JFS_POSIX_ACL - sb->s_flags |= MS_POSIXACL; - #endif -+ /* map mount option tagxid */ -+ if (sbi->flag & JFS_TAGXID) -+ sb->s_flags |= MS_TAGXID; - - if (newLVSize) { - printk(KERN_ERR "resize option for remount only\n"); -diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c -index f23048f..cba307d 100644 ---- a/fs/jfs/xattr.c -+++ b/fs/jfs/xattr.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include "jfs_incore.h" - #include "jfs_superblock.h" - #include "jfs_dmap.h" -@@ -263,9 +264,16 @@ static int ea_write(struct inode *ip, st - if (DQUOT_ALLOC_BLOCK(ip, nblocks)) { - return -EDQUOT; - } -+ /* Allocate new blocks to dlimit. */ -+ if (DLIMIT_ALLOC_BLOCK(ip, nblocks)) { -+ DQUOT_FREE_BLOCK(ip, nblocks); -+ return -ENOSPC; -+ } - - rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno); - if (rc) { -+ /*Rollback dlimit allocation. */ -+ DLIMIT_FREE_BLOCK(ip, nblocks); - /*Rollback quota allocation. */ - DQUOT_FREE_BLOCK(ip, nblocks); - return rc; -@@ -332,6 +340,8 @@ static int ea_write(struct inode *ip, st - - failed: - /* Rollback quota allocation. */ -+ DLIMIT_FREE_BLOCK(ip, nblocks); -+ /* Rollback quota allocation. */ - DQUOT_FREE_BLOCK(ip, nblocks); - - dbFree(ip, blkno, nblocks); -@@ -468,6 +478,7 @@ static int ea_get(struct inode *inode, s - s64 blkno; - int rc; - int quota_allocation = 0; -+ int dlimit_allocation = 0; - - /* When fsck.jfs clears a bad ea, it doesn't clear the size */ - if (ji->ea.flag == 0) -@@ -543,6 +554,12 @@ static int ea_get(struct inode *inode, s - - quota_allocation = blocks_needed; - -+ /* Allocate new blocks to dlimit. */ -+ rc = -ENOSPC; -+ if (DLIMIT_ALLOC_BLOCK(inode, blocks_needed)) -+ goto clean_up; -+ dlimit_allocation = blocks_needed; -+ - rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed, - &blkno); - if (rc) -@@ -599,6 +616,9 @@ static int ea_get(struct inode *inode, s - return ea_size; - - clean_up: -+ /* Rollback dlimit allocation */ -+ if (dlimit_allocation) -+ DLIMIT_FREE_BLOCK(inode, dlimit_allocation); - /* Rollback quota allocation */ - if (quota_allocation) - DQUOT_FREE_BLOCK(inode, quota_allocation); -@@ -675,8 +695,10 @@ static int ea_put(tid_t tid, struct inod - } - - /* If old blocks exist, they must be removed from quota allocation. */ -- if (old_blocks) -+ if (old_blocks) { -+ DLIMIT_FREE_BLOCK(inode, old_blocks); - DQUOT_FREE_BLOCK(inode, old_blocks); -+ } - - inode->i_ctime = CURRENT_TIME; - -diff --git a/fs/libfs.c b/fs/libfs.c -index 71fd08f..30110a2 100644 ---- a/fs/libfs.c -+++ b/fs/libfs.c -@@ -122,7 +122,8 @@ static inline unsigned char dt_type(stru - * both impossible due to the lock on directory. - */ - --int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) -+static inline int do_dcache_readdir_filter(struct file * filp, -+ void * dirent, filldir_t filldir, int (*filter)(struct dentry *dentry)) - { - struct dentry *dentry = filp->f_dentry; - struct dentry *cursor = filp->private_data; -@@ -156,6 +157,8 @@ int dcache_readdir(struct file * filp, v - next = list_entry(p, struct dentry, d_u.d_child); - if (d_unhashed(next) || !next->d_inode) - continue; -+ if (filter && !filter(next)) -+ continue; - - spin_unlock(&dcache_lock); - if (filldir(dirent, next->d_name.name, next->d_name.len, filp->f_pos, next->d_inode->i_ino, dt_type(next->d_inode)) < 0) -@@ -172,6 +175,18 @@ int dcache_readdir(struct file * filp, v - return 0; - } - -+int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) -+{ -+ return do_dcache_readdir_filter(filp, dirent, filldir, NULL); -+} -+ -+int dcache_readdir_filter(struct file * filp, void * dirent, filldir_t filldir, -+ int (*filter)(struct dentry *)) -+{ -+ return do_dcache_readdir_filter(filp, dirent, filldir, filter); -+} -+ -+ - ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos) - { - return -EISDIR; -@@ -621,6 +636,7 @@ EXPORT_SYMBOL(dcache_dir_close); - EXPORT_SYMBOL(dcache_dir_lseek); - EXPORT_SYMBOL(dcache_dir_open); - EXPORT_SYMBOL(dcache_readdir); -+EXPORT_SYMBOL(dcache_readdir_filter); - EXPORT_SYMBOL(generic_read_dir); - EXPORT_SYMBOL(get_sb_pseudo); - EXPORT_SYMBOL(simple_commit_write); -diff --git a/fs/locks.c b/fs/locks.c -index 909eab8..5141c22 100644 ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -125,6 +125,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -150,12 +151,16 @@ static kmem_cache_t *filelock_cache; - /* Allocate an empty lock structure. */ - static struct file_lock *locks_alloc_lock(void) - { -+ if (!vx_locks_avail(1)) -+ return NULL; - return kmem_cache_alloc(filelock_cache, SLAB_KERNEL); - } - - /* Free a lock which is not in use. */ - static void locks_free_lock(struct file_lock *fl) - { -+ vx_locks_dec(fl); -+ - if (fl == NULL) { - BUG(); - return; -@@ -199,6 +204,7 @@ void locks_init_lock(struct file_lock *f - fl->fl_start = fl->fl_end = 0; - fl->fl_ops = NULL; - fl->fl_lmops = NULL; -+ fl->fl_xid = -1; - } - - EXPORT_SYMBOL(locks_init_lock); -@@ -236,6 +242,8 @@ void locks_copy_lock(struct file_lock *n - fl->fl_ops->fl_copy_lock(new, fl); - if (fl->fl_lmops && fl->fl_lmops->fl_copy_lock) - fl->fl_lmops->fl_copy_lock(new, fl); -+ -+ new->fl_xid = fl->fl_xid; - } - - EXPORT_SYMBOL(locks_copy_lock); -@@ -272,6 +280,11 @@ static int flock_make_lock(struct file * - fl->fl_flags = FL_FLOCK; - fl->fl_type = type; - fl->fl_end = OFFSET_MAX; -+ -+ vxd_assert(filp->f_xid == vx_current_xid(), -+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); -+ fl->fl_xid = filp->f_xid; -+ vx_locks_inc(fl); - - *lock = fl; - return 0; -@@ -457,6 +470,11 @@ static int lease_alloc(struct file *filp - if (fl == NULL) - return -ENOMEM; - -+ fl->fl_xid = vx_current_xid(); -+ if (filp) -+ vxd_assert(filp->f_xid == fl->fl_xid, -+ "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid); -+ vx_locks_inc(fl); - error = lease_init(filp, type, fl); - if (error) - return error; -@@ -771,7 +789,7 @@ out: - - EXPORT_SYMBOL(posix_lock_file); - --static int __posix_lock_file(struct inode *inode, struct file_lock *request) -+static int __posix_lock_file(struct inode *inode, struct file_lock *request, xid_t xid) - { - struct file_lock *fl; - struct file_lock *new_fl, *new_fl2; -@@ -780,12 +798,18 @@ static int __posix_lock_file(struct inod - struct file_lock **before; - int error, added = 0; - -+ vxd_assert(xid == vx_current_xid(), -+ "xid(%d) == current(%d)", xid, vx_current_xid()); - /* - * We may need two file_lock structures for this operation, - * so we get them in advance to avoid races. - */ - new_fl = locks_alloc_lock(); -+ new_fl->fl_xid = xid; -+ vx_locks_inc(new_fl); - new_fl2 = locks_alloc_lock(); -+ new_fl2->fl_xid = xid; -+ vx_locks_inc(new_fl2); - - lock_kernel(); - if (request->fl_type != F_UNLCK) { -@@ -963,7 +987,7 @@ static int __posix_lock_file(struct inod - */ - int posix_lock_file(struct file *filp, struct file_lock *fl) - { -- return __posix_lock_file(filp->f_dentry->d_inode, fl); -+ return __posix_lock_file(filp->f_dentry->d_inode, fl, filp->f_xid); - } - - /** -@@ -980,7 +1004,8 @@ int posix_lock_file_wait(struct file *fi - int error; - might_sleep (); - for (;;) { -- error = __posix_lock_file(filp->f_dentry->d_inode, fl); -+ error = __posix_lock_file(filp->f_dentry->d_inode, -+ fl, filp->f_xid); - if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP)) - break; - error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); -@@ -1052,7 +1077,7 @@ int locks_mandatory_area(int read_write, - fl.fl_end = offset + count - 1; - - for (;;) { -- error = __posix_lock_file(inode, &fl); -+ error = __posix_lock_file(inode, &fl, filp->f_xid); - if (error != -EAGAIN) - break; - if (!(fl.fl_flags & FL_SLEEP)) -@@ -1613,6 +1638,11 @@ int fcntl_setlk(unsigned int fd, struct - if (file_lock == NULL) - return -ENOLCK; - -+ vxd_assert(filp->f_xid == vx_current_xid(), -+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); -+ file_lock->fl_xid = filp->f_xid; -+ vx_locks_inc(file_lock); -+ - /* - * This might block, so we do it before checking the inode. - */ -@@ -1665,7 +1695,8 @@ again: - error = filp->f_op->lock(filp, cmd, file_lock); - else { - for (;;) { -- error = __posix_lock_file(inode, file_lock); -+ error = __posix_lock_file(inode, file_lock, -+ filp->f_xid); - if ((error != -EAGAIN) || (cmd == F_SETLK)) - break; - error = wait_event_interruptible(file_lock->fl_wait, -@@ -1756,6 +1787,11 @@ int fcntl_setlk64(unsigned int fd, struc - if (file_lock == NULL) - return -ENOLCK; - -+ vxd_assert(filp->f_xid == vx_current_xid(), -+ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); -+ file_lock->fl_xid = filp->f_xid; -+ vx_locks_inc(file_lock); -+ - /* - * This might block, so we do it before checking the inode. - */ -@@ -1808,7 +1844,8 @@ again: - error = filp->f_op->lock(filp, cmd, file_lock); - else { - for (;;) { -- error = __posix_lock_file(inode, file_lock); -+ error = __posix_lock_file(inode, file_lock, -+ filp->f_xid); - if ((error != -EAGAIN) || (cmd == F_SETLK64)) - break; - error = wait_event_interruptible(file_lock->fl_wait, -@@ -2081,6 +2118,10 @@ int get_locks_status(char *buffer, char - list_for_each(tmp, &file_lock_list) { - struct list_head *btmp; - struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link); -+ -+ if (!vx_check(fl->fl_xid, VX_IDENT|VX_WATCH)) -+ continue; -+ - lock_get_status(q, fl, ++i, ""); - move_lock_status(&q, &pos, offset); - -diff --git a/fs/namei.c b/fs/namei.c -index 8dc2b03..aacff04 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -32,6 +32,9 @@ - #include - #include - #include -+#include -+#include -+#include - #include - #include - -@@ -225,6 +228,24 @@ int generic_permission(struct inode *ino - return -EACCES; - } - -+static inline int xid_permission(struct inode *inode, int mask, struct nameidata *nd) -+{ -+ if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN)) { -+ vxwprintk(1, "xid=%d did hit the barrier.", -+ vx_current_xid()); -+ return -EACCES; -+ } -+ if (inode->i_xid == 0) -+ return 0; -+ if (vx_check(inode->i_xid, VX_ADMIN|VX_WATCH|VX_IDENT)) -+ return 0; -+ -+ vxwprintk(1, "xid=%d denied access to %p[#%d,%lu] »%s«.", -+ vx_current_xid(), inode, inode->i_xid, inode->i_ino, -+ vxd_path(nd->dentry, nd->mnt)); -+ return -EACCES; -+} -+ - int permission(struct inode *inode, int mask, struct nameidata *nd) - { - int retval, submask; -@@ -235,7 +256,7 @@ int permission(struct inode *inode, int - /* - * Nobody gets write access to a read-only fs. - */ -- if (IS_RDONLY(inode) && -+ if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; - -@@ -249,6 +270,8 @@ int permission(struct inode *inode, int - - /* Ordinary permission routines do not understand MAY_APPEND. */ - submask = mask & ~MAY_APPEND; -+ if ((retval = xid_permission(inode, mask, nd))) -+ return retval; - if (inode->i_op && inode->i_op->permission) - retval = inode->i_op->permission(inode, submask, nd); - else -@@ -702,7 +725,8 @@ static __always_inline void follow_dotdo - if (nd->dentry == current->fs->root && - nd->mnt == current->fs->rootmnt) { - read_unlock(¤t->fs->lock); -- break; -+ /* for sane '/' avoid follow_mount() */ -+ return; - } - read_unlock(¤t->fs->lock); - spin_lock(&dcache_lock); -@@ -739,16 +763,34 @@ static int do_lookup(struct nameidata *n - { - struct vfsmount *mnt = nd->mnt; - struct dentry *dentry = __d_lookup(nd->dentry, name); -+ struct inode *inode; - - if (!dentry) - goto need_lookup; - if (dentry->d_op && dentry->d_op->d_revalidate) - goto need_revalidate; -+ inode = dentry->d_inode; -+ if (!inode) -+ goto done; -+ if (!vx_check(inode->i_xid, VX_WATCH|VX_ADMIN|VX_HOSTID|VX_IDENT)) -+ goto hidden; -+ if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) { -+ struct proc_dir_entry *de = PDE(inode); -+ -+ if (de && !vx_hide_check(0, de->vx_flags)) -+ goto hidden; -+ } - done: - path->mnt = mnt; - path->dentry = dentry; - __follow_mount(path); - return 0; -+hidden: -+ vxwprintk(1, "xid=%d did lookup hidden %p[#%d,%lu] »%s«.", -+ vx_current_xid(), inode, inode->i_xid, inode->i_ino, -+ vxd_path(dentry, mnt)); -+ dput(dentry); -+ return -ENOENT; - - need_lookup: - dentry = real_lookup(nd->dentry, name, nd); -@@ -1345,7 +1387,8 @@ static inline int check_sticky(struct in - * 10. We don't allow removal of NFS sillyrenamed files; it's handled by - * nfs_async_unlink(). - */ --static int may_delete(struct inode *dir,struct dentry *victim,int isdir) -+static int may_delete(struct inode *dir, struct dentry *victim, -+ int isdir, struct nameidata *nd) - { - int error; - -@@ -1354,13 +1397,13 @@ static int may_delete(struct inode *dir, - - BUG_ON(victim->d_parent->d_inode != dir); - -- error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); -+ error = permission(dir,MAY_WRITE | MAY_EXEC, nd); - if (error) - return error; - if (IS_APPEND(dir)) - return -EPERM; - if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)|| -- IS_IMMUTABLE(victim->d_inode)) -+ IS_IXORUNLINK(victim->d_inode)) - return -EPERM; - if (isdir) { - if (!S_ISDIR(victim->d_inode->i_mode)) -@@ -1507,7 +1550,8 @@ int may_open(struct nameidata *nd, int a - return -EACCES; - - flag &= ~O_TRUNC; -- } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE)) -+ } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt)) -+ && (flag & FMODE_WRITE)) - return -EROFS; - /* - * An append-only file must be opened in append mode for writing. -@@ -1773,9 +1817,10 @@ fail: - } - EXPORT_SYMBOL_GPL(lookup_create); - --int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -+int vfs_mknod(struct inode *dir, struct dentry *dentry, -+ int mode, dev_t dev, struct nameidata *nd) - { -- int error = may_create(dir, dentry, NULL); -+ int error = may_create(dir, dentry, nd); - - if (error) - return error; -@@ -1825,11 +1870,12 @@ asmlinkage long sys_mknodat(int dfd, con - error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); - break; - case S_IFCHR: case S_IFBLK: -- error = vfs_mknod(nd.dentry->d_inode,dentry,mode, -- new_decode_dev(dev)); -+ error = vfs_mknod(nd.dentry->d_inode, dentry, mode, -+ new_decode_dev(dev), &nd); - break; - case S_IFIFO: case S_IFSOCK: -- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); -+ error = vfs_mknod(nd.dentry->d_inode, dentry, mode, -+ 0, &nd); - break; - case S_IFDIR: - error = -EPERM; -@@ -1852,9 +1898,10 @@ asmlinkage long sys_mknod(const char __u - return sys_mknodat(AT_FDCWD, filename, mode, dev); - } - --int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) -+int vfs_mkdir(struct inode *dir, struct dentry *dentry, -+ int mode, struct nameidata *nd) - { -- int error = may_create(dir, dentry, NULL); -+ int error = may_create(dir, dentry, nd); - - if (error) - return error; -@@ -1893,7 +1940,8 @@ asmlinkage long sys_mkdirat(int dfd, con - if (!IS_ERR(dentry)) { - if (!IS_POSIXACL(nd.dentry->d_inode)) - mode &= ~current->fs->umask; -- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); -+ error = vfs_mkdir(nd.dentry->d_inode, dentry, -+ mode, &nd); - dput(dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); -@@ -1938,9 +1986,10 @@ void dentry_unhash(struct dentry *dentry - spin_unlock(&dcache_lock); - } - --int vfs_rmdir(struct inode *dir, struct dentry *dentry) -+int vfs_rmdir(struct inode *dir, struct dentry *dentry, -+ struct nameidata *nd) - { -- int error = may_delete(dir, dentry, 1); -+ int error = may_delete(dir, dentry, 1, nd); - - if (error) - return error; -@@ -2001,7 +2050,7 @@ static long do_rmdir(int dfd, const char - dentry = lookup_hash(&nd); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -- error = vfs_rmdir(nd.dentry->d_inode, dentry); -+ error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd); - dput(dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); -@@ -2017,9 +2066,10 @@ asmlinkage long sys_rmdir(const char __u - return do_rmdir(AT_FDCWD, pathname); - } - --int vfs_unlink(struct inode *dir, struct dentry *dentry) -+int vfs_unlink(struct inode *dir, struct dentry *dentry, -+ struct nameidata *nd) - { -- int error = may_delete(dir, dentry, 0); -+ int error = may_delete(dir, dentry, 0, nd); - - if (error) - return error; -@@ -2081,7 +2131,7 @@ static long do_unlinkat(int dfd, const c - inode = dentry->d_inode; - if (inode) - atomic_inc(&inode->i_count); -- error = vfs_unlink(nd.dentry->d_inode, dentry); -+ error = vfs_unlink(nd.dentry->d_inode, dentry, &nd); - exit2: - dput(dentry); - } -@@ -2116,9 +2166,10 @@ asmlinkage long sys_unlink(const char __ - return do_unlinkat(AT_FDCWD, pathname); - } - --int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) -+int vfs_symlink(struct inode *dir, struct dentry *dentry, -+ const char *oldname, int mode, struct nameidata *nd) - { -- int error = may_create(dir, dentry, NULL); -+ int error = may_create(dir, dentry, nd); - - if (error) - return error; -@@ -2159,7 +2210,8 @@ asmlinkage long sys_symlinkat(const char - dentry = lookup_create(&nd, 0); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); -+ error = vfs_symlink(nd.dentry->d_inode, dentry, -+ from, S_IALLUGO, &nd); - dput(dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); -@@ -2176,7 +2228,8 @@ asmlinkage long sys_symlink(const char _ - return sys_symlinkat(oldname, AT_FDCWD, newname); - } - --int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) -+int vfs_link(struct dentry *old_dentry, struct inode *dir, -+ struct dentry *new_dentry, struct nameidata *nd) - { - struct inode *inode = old_dentry->d_inode; - int error; -@@ -2184,7 +2237,7 @@ int vfs_link(struct dentry *old_dentry, - if (!inode) - return -ENOENT; - -- error = may_create(dir, new_dentry, NULL); -+ error = may_create(dir, new_dentry, nd); - if (error) - return error; - -@@ -2194,7 +2247,7 @@ int vfs_link(struct dentry *old_dentry, - /* - * A link to an append-only or immutable file cannot be created. - */ -- if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) -+ if (IS_APPEND(inode) || IS_IXORUNLINK(inode)) - return -EPERM; - if (!dir->i_op || !dir->i_op->link) - return -EPERM; -@@ -2251,7 +2304,8 @@ asmlinkage long sys_linkat(int olddfd, c - new_dentry = lookup_create(&nd, 0); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { -- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -+ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, -+ new_dentry, &nd); - dput(new_dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); -@@ -2383,14 +2437,14 @@ int vfs_rename(struct inode *old_dir, st - if (old_dentry->d_inode == new_dentry->d_inode) - return 0; - -- error = may_delete(old_dir, old_dentry, is_dir); -+ error = may_delete(old_dir, old_dentry, is_dir, NULL); - if (error) - return error; - - if (!new_dentry->d_inode) - error = may_create(new_dir, new_dentry, NULL); - else -- error = may_delete(new_dir, new_dentry, is_dir); -+ error = may_delete(new_dir, new_dentry, is_dir, NULL); - if (error) - return error; - -@@ -2468,6 +2522,9 @@ static int do_rename(int olddfd, const c - error = -EINVAL; - if (old_dentry == trap) - goto exit4; -+ error = -EROFS; -+ if (MNT_IS_RDONLY(newnd.mnt)) -+ goto exit4; - new_dentry = lookup_hash(&newnd); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) -diff --git a/fs/namespace.c b/fs/namespace.c -index 058a448..8668603 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -23,6 +23,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include "pnode.h" -@@ -241,6 +243,7 @@ static struct vfsmount *clone_mnt(struct - mnt->mnt_root = dget(root); - mnt->mnt_mountpoint = mnt->mnt_root; - mnt->mnt_parent = mnt; -+ mnt->mnt_xid = old->mnt_xid; - - if (flag & CL_SLAVE) { - list_add(&mnt->mnt_slave, &old->mnt_slave_list); -@@ -349,43 +352,85 @@ static inline void mangle(struct seq_fil - seq_escape(m, s, " \t\n\\"); - } - -+static int mnt_is_reachable(struct vfsmount *mnt) -+{ -+ struct vfsmount *root_mnt; -+ struct dentry *root, *point; -+ int ret; -+ -+ if (mnt == mnt->mnt_namespace->root) -+ return 1; -+ -+ spin_lock(&dcache_lock); -+ root_mnt = current->fs->rootmnt; -+ root = current->fs->root; -+ point = root; -+ -+ while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) { -+ point = mnt->mnt_mountpoint; -+ mnt = mnt->mnt_parent; -+ } -+ -+ ret = (mnt == root_mnt) && is_subdir(point, root); -+ -+ spin_unlock(&dcache_lock); -+ -+ return ret; -+} -+ - static int show_vfsmnt(struct seq_file *m, void *v) - { - struct vfsmount *mnt = v; - int err = 0; - static struct proc_fs_info { -- int flag; -- char *str; -+ int s_flag; -+ int mnt_flag; -+ char *set_str; -+ char *unset_str; - } fs_info[] = { -- { MS_SYNCHRONOUS, ",sync" }, -- { MS_DIRSYNC, ",dirsync" }, -- { MS_MANDLOCK, ",mand" }, -- { 0, NULL } -- }; -- static struct proc_fs_info mnt_info[] = { -- { MNT_NOSUID, ",nosuid" }, -- { MNT_NODEV, ",nodev" }, -- { MNT_NOEXEC, ",noexec" }, -- { MNT_NOATIME, ",noatime" }, -- { MNT_NODIRATIME, ",nodiratime" }, -- { 0, NULL } -+ { MS_RDONLY, MNT_RDONLY, "ro", "rw" }, -+ { MS_SYNCHRONOUS, 0, ",sync", NULL }, -+ { MS_DIRSYNC, 0, ",dirsync", NULL }, -+ { MS_MANDLOCK, 0, ",mand", NULL }, -+ { MS_TAGXID, 0, ",tagxid", NULL }, -+ { MS_NOATIME, MNT_NOATIME, ",noatime", NULL }, -+ { MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL }, -+ { 0, MNT_NOSUID, ",nosuid", NULL }, -+ { 0, MNT_NODEV, ",nodev", NULL }, -+ { 0, MNT_NOEXEC, ",noexec", NULL }, -+ { 0, 0, NULL, NULL } - }; -- struct proc_fs_info *fs_infop; -+ struct proc_fs_info *p; -+ unsigned long s_flags = mnt->mnt_sb->s_flags; -+ int mnt_flags = mnt->mnt_flags; - -- mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); -- seq_putc(m, ' '); -- seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); -- seq_putc(m, ' '); -+ if (vx_flags(VXF_HIDE_MOUNT, 0)) -+ return 0; -+ if (!mnt_is_reachable(mnt)) -+ return 0; -+ -+ if (!vx_check(0, VX_ADMIN|VX_WATCH) && -+ mnt == current->fs->rootmnt) { -+ seq_puts(m, "/dev/root / "); -+ } else { -+ mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); -+ seq_putc(m, ' '); -+ seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); -+ seq_putc(m, ' '); -+ } - mangle(m, mnt->mnt_sb->s_type->name); -- seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); -- for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { -- if (mnt->mnt_sb->s_flags & fs_infop->flag) -- seq_puts(m, fs_infop->str); -- } -- for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) { -- if (mnt->mnt_flags & fs_infop->flag) -- seq_puts(m, fs_infop->str); -+ seq_putc(m, ' '); -+ for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) { -+ if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) { -+ if (p->set_str) -+ seq_puts(m, p->set_str); -+ } else { -+ if (p->unset_str) -+ seq_puts(m, p->unset_str); -+ } - } -+ if (mnt->mnt_flags & MNT_XID) -+ seq_printf(m, ",xid=%d", mnt->mnt_xid); - if (mnt->mnt_sb->s_op->show_options) - err = mnt->mnt_sb->s_op->show_options(m, mnt); - seq_puts(m, " 0 0\n"); -@@ -475,15 +520,11 @@ void release_mounts(struct list_head *he - } - } - --void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) -+static inline void __umount_list(struct vfsmount *mnt, -+ int propagate, struct list_head *kill) - { - struct vfsmount *p; - -- for (p = mnt; p; p = next_mnt(p, mnt)) { -- list_del(&p->mnt_hash); -- list_add(&p->mnt_hash, kill); -- } -- - if (propagate) - propagate_umount(kill); - -@@ -499,6 +540,33 @@ void umount_tree(struct vfsmount *mnt, i - } - } - -+void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) -+{ -+ struct vfsmount *p; -+ -+ for (p = mnt; p; p = next_mnt(p, mnt)) { -+ list_del(&p->mnt_hash); -+ list_add(&p->mnt_hash, kill); -+ // p->mnt_namespace = NULL; -+ } -+ __umount_list(mnt, propagate, kill); -+} -+ -+void umount_unused(struct vfsmount *mnt, struct fs_struct *fs) -+{ -+ struct vfsmount *p; -+ LIST_HEAD(kill); -+ -+ for (p = mnt; p; p = next_mnt(p, mnt)) { -+ if (p == fs->rootmnt || p == fs->pwdmnt) -+ continue; -+ list_del(&p->mnt_list); -+ list_add(&p->mnt_list, &kill); -+ p->mnt_namespace = NULL; -+ } -+ __umount_list(mnt, 0, &kill); -+} -+ - static int do_umount(struct vfsmount *mnt, int flags) - { - struct super_block *sb = mnt->mnt_sb; -@@ -608,7 +676,7 @@ asmlinkage long sys_umount(char __user * - goto dput_and_out; - - retval = -EPERM; -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) - goto dput_and_out; - - retval = do_umount(nd.mnt, flags); -@@ -634,6 +702,8 @@ static int mount_is_safe(struct nameidat - { - if (capable(CAP_SYS_ADMIN)) - return 0; -+ if (vx_ccaps(VXC_SECURE_MOUNT)) -+ return 0; - return -EPERM; - #ifdef notyet - if (S_ISLNK(nd->dentry->d_inode->i_mode)) -@@ -861,11 +931,13 @@ static int do_change_type(struct nameida - /* - * do loopback mount. - */ --static int do_loopback(struct nameidata *nd, char *old_name, int recurse) -+static int do_loopback(struct nameidata *nd, char *old_name, xid_t xid, -+ unsigned long flags, int mnt_flags) - { - struct nameidata old_nd; - struct vfsmount *mnt = NULL; - int err = mount_is_safe(nd); -+ int recurse = flags & MS_REC; - if (err) - return err; - if (!old_name || !*old_name) -@@ -891,6 +963,12 @@ static int do_loopback(struct nameidata - if (!mnt) - goto out; - -+ mnt->mnt_flags = mnt_flags; -+ if (flags & MS_XID) { -+ mnt->mnt_xid = xid; -+ mnt->mnt_flags |= MNT_XID; -+ } -+ - err = graft_tree(mnt, nd); - if (err) { - LIST_HEAD(umount_list); -@@ -899,6 +977,7 @@ static int do_loopback(struct nameidata - spin_unlock(&vfsmount_lock); - release_mounts(&umount_list); - } -+ mnt->mnt_flags = mnt_flags; - - out: - up_write(&namespace_sem); -@@ -912,12 +991,12 @@ out: - * on it - tough luck. - */ - static int do_remount(struct nameidata *nd, int flags, int mnt_flags, -- void *data) -+ void *data, xid_t xid) - { - int err; - struct super_block *sb = nd->mnt->mnt_sb; - -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_REMOUNT)) - return -EPERM; - - if (!check_mnt(nd->mnt)) -@@ -951,7 +1030,7 @@ static int do_move_mount(struct nameidat - struct nameidata old_nd, parent_nd; - struct vfsmount *p; - int err = 0; -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) - return -EPERM; - if (!old_name || !*old_name) - return -EINVAL; -@@ -1031,7 +1110,7 @@ static int do_new_mount(struct nameidata - return -EINVAL; - - /* we need capabilities... */ -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) - return -EPERM; - - mnt = do_kern_mount(type, flags, name, data); -@@ -1269,6 +1348,7 @@ long do_mount(char *dev_name, char *dir_ - struct nameidata nd; - int retval = 0; - int mnt_flags = 0; -+ xid_t xid = 0; - - /* Discard magic */ - if ((flags & MS_MGC_MSK) == MS_MGC_VAL) -@@ -1284,7 +1364,17 @@ long do_mount(char *dev_name, char *dir_ - if (data_page) - ((char *)data_page)[PAGE_SIZE - 1] = 0; - -+ retval = vx_parse_xid(data_page, &xid, 1); -+ if (retval) { -+ mnt_flags |= MNT_XID; -+ /* bind and re-mounts get xid flag */ -+ if (flags & (MS_BIND|MS_REMOUNT)) -+ flags |= MS_XID; -+ } -+ - /* Separate the per-mountpoint flags */ -+ if (flags & MS_RDONLY) -+ mnt_flags |= MNT_RDONLY; - if (flags & MS_NOSUID) - mnt_flags |= MNT_NOSUID; - if (flags & MS_NODEV) -@@ -1296,6 +1386,8 @@ long do_mount(char *dev_name, char *dir_ - if (flags & MS_NODIRATIME) - mnt_flags |= MNT_NODIRATIME; - -+ if (vx_ccaps(VXC_SECURE_MOUNT)) -+ mnt_flags |= MNT_NODEV; - flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | - MS_NOATIME | MS_NODIRATIME); - -@@ -1310,9 +1402,9 @@ long do_mount(char *dev_name, char *dir_ - - if (flags & MS_REMOUNT) - retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, -- data_page); -+ data_page, xid); - else if (flags & MS_BIND) -- retval = do_loopback(&nd, dev_name, flags & MS_REC); -+ retval = do_loopback(&nd, dev_name, xid, flags, mnt_flags); - else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) - retval = do_change_type(&nd, flags); - else if (flags & MS_MOVE) -@@ -1411,7 +1503,7 @@ int copy_namespace(int flags, struct tas - if (!(flags & CLONE_NEWNS)) - return 0; - -- if (!capable(CAP_SYS_ADMIN)) { -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) { - err = -EPERM; - goto out; - } -diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c -index a1554be..07d6baf 100644 ---- a/fs/nfs/dir.c -+++ b/fs/nfs/dir.c -@@ -28,9 +28,11 @@ - #include - #include - #include -+#include - #include - #include - #include -+#include - - #include "nfs4_fs.h" - #include "delegation.h" -@@ -869,6 +871,7 @@ static struct dentry *nfs_lookup(struct - inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr); - if (!inode) - goto out_unlock; -+ vx_propagate_xid(nd, inode); - no_entry: - res = d_add_unique(dentry, inode); - if (res != NULL) -@@ -902,7 +905,8 @@ static int is_atomic_open(struct inode * - if (nd->flags & LOOKUP_DIRECTORY) - return 0; - /* Are we trying to write to a read only partition? */ -- if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE))) -+ if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) && -+ (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE))) - return 0; - return 1; - } -diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c -index a77ee95..d2205df 100644 ---- a/fs/nfs/inode.c -+++ b/fs/nfs/inode.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -336,12 +337,16 @@ nfs_sb_init(struct super_block *sb, rpc_ - } - server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD; - -+ if (server->flags & NFS_MOUNT_TAGXID) -+ sb->s_flags |= MS_TAGXID; -+ - sb->s_maxbytes = fsinfo.maxfilesize; - if (sb->s_maxbytes > MAX_LFS_FILESIZE) - sb->s_maxbytes = MAX_LFS_FILESIZE; - - server->client->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0; - server->client->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0; -+ server->client->cl_tagxid = (server->flags & NFS_MOUNT_TAGXID) ? 1 : 0; - - /* We're airborne Set socket buffersize */ - rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100); -@@ -413,6 +418,7 @@ nfs_create_client(struct nfs_server *ser - - clnt->cl_intr = 1; - clnt->cl_softrtry = 1; -+ clnt->cl_tagxid = 1; - - return clnt; - -@@ -593,6 +599,7 @@ static int nfs_show_options(struct seq_f - { NFS_MOUNT_NOAC, ",noac", "" }, - { NFS_MOUNT_NONLM, ",nolock", ",lock" }, - { NFS_MOUNT_NOACL, ",noacl", "" }, -+ { NFS_MOUNT_TAGXID, ",tagxid", "" }, - { 0, NULL, NULL } - }; - struct proc_nfs_info *nfs_infop; -@@ -805,8 +812,10 @@ nfs_fhget(struct super_block *sb, struct - nfsi->change_attr = fattr->change_attr; - inode->i_size = nfs_size_to_loff_t(fattr->size); - inode->i_nlink = fattr->nlink; -- inode->i_uid = fattr->uid; -- inode->i_gid = fattr->gid; -+ inode->i_uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid); -+ inode->i_gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid); -+ inode->i_xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0); -+ /* maybe fattr->xid someday */ - if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) { - /* - * report the blocks in 512byte units -@@ -897,6 +906,8 @@ void nfs_setattr_update_inode(struct ino - inode->i_uid = attr->ia_uid; - if ((attr->ia_valid & ATTR_GID) != 0) - inode->i_gid = attr->ia_gid; -+ if ((attr->ia_valid & ATTR_XID) && IS_TAGXID(inode)) -+ inode->i_xid = attr->ia_xid; - spin_lock(&inode->i_lock); - NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; - spin_unlock(&inode->i_lock); -@@ -1294,6 +1305,9 @@ static int nfs_check_inode_attributes(st - struct nfs_inode *nfsi = NFS_I(inode); - loff_t cur_size, new_isize; - int data_unstable; -+ uid_t uid; -+ gid_t gid; -+ xid_t xid; - - - if ((fattr->valid & NFS_ATTR_FATTR) == 0) -@@ -1333,10 +1347,15 @@ static int nfs_check_inode_attributes(st - nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; - } - -+ uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid); -+ gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid); -+ xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0); -+ - /* Have any file permissions changed? */ - if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) -- || inode->i_uid != fattr->uid -- || inode->i_gid != fattr->gid) -+ || inode->i_uid != uid -+ || inode->i_gid != gid -+ || inode->i_xid != xid) - nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; - - /* Has the link count changed? */ -@@ -1420,6 +1439,9 @@ static int nfs_update_inode(struct inode - loff_t cur_isize, new_isize; - unsigned int invalid = 0; - int data_stable; -+ uid_t uid; -+ gid_t gid; -+ xid_t xid; - - dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", - __FUNCTION__, inode->i_sb->s_id, inode->i_ino, -@@ -1498,15 +1520,21 @@ static int nfs_update_inode(struct inode - } - memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); - -+ uid = INOXID_UID(XID_TAG(inode), fattr->uid, fattr->gid); -+ gid = INOXID_GID(XID_TAG(inode), fattr->uid, fattr->gid); -+ xid = INOXID_XID(XID_TAG(inode), fattr->uid, fattr->gid, 0); -+ - if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || -- inode->i_uid != fattr->uid || -- inode->i_gid != fattr->gid) -+ inode->i_uid != uid || -+ inode->i_gid != gid || -+ inode->i_xid != xid) - invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; - - inode->i_mode = fattr->mode; - inode->i_nlink = fattr->nlink; -- inode->i_uid = fattr->uid; -- inode->i_gid = fattr->gid; -+ inode->i_uid = uid; -+ inode->i_gid = gid; -+ inode->i_xid = xid; - - if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) { - /* -diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c -index b6c0b50..d525c30 100644 ---- a/fs/nfs/nfs3xdr.c -+++ b/fs/nfs/nfs3xdr.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #define NFSDBG_FACILITY NFSDBG_XDR - -@@ -178,7 +179,7 @@ xdr_decode_fattr(u32 *p, struct nfs_fatt - } - - static inline u32 * --xdr_encode_sattr(u32 *p, struct iattr *attr) -+xdr_encode_sattr(u32 *p, struct iattr *attr, int tagxid) - { - if (attr->ia_valid & ATTR_MODE) { - *p++ = xdr_one; -@@ -186,15 +187,17 @@ xdr_encode_sattr(u32 *p, struct iattr *a - } else { - *p++ = xdr_zero; - } -- if (attr->ia_valid & ATTR_UID) { -+ if (attr->ia_valid & ATTR_UID || -+ (tagxid && (attr->ia_valid & ATTR_XID))) { - *p++ = xdr_one; -- *p++ = htonl(attr->ia_uid); -+ *p++ = htonl(XIDINO_UID(tagxid, attr->ia_uid, attr->ia_xid)); - } else { - *p++ = xdr_zero; - } -- if (attr->ia_valid & ATTR_GID) { -+ if (attr->ia_valid & ATTR_GID || -+ (tagxid && (attr->ia_valid & ATTR_XID))) { - *p++ = xdr_one; -- *p++ = htonl(attr->ia_gid); -+ *p++ = htonl(XIDINO_GID(tagxid, attr->ia_gid, attr->ia_xid)); - } else { - *p++ = xdr_zero; - } -@@ -279,7 +282,8 @@ static int - nfs3_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs3_sattrargs *args) - { - p = xdr_encode_fhandle(p, args->fh); -- p = xdr_encode_sattr(p, args->sattr); -+ p = xdr_encode_sattr(p, args->sattr, -+ req->rq_task->tk_client->cl_tagxid); - *p++ = htonl(args->guard); - if (args->guard) - p = xdr_encode_time3(p, &args->guardtime); -@@ -370,7 +374,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req - *p++ = args->verifier[0]; - *p++ = args->verifier[1]; - } else -- p = xdr_encode_sattr(p, args->sattr); -+ p = xdr_encode_sattr(p, args->sattr, -+ req->rq_task->tk_client->cl_tagxid); - - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -@@ -384,7 +389,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req, - { - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name, args->len); -- p = xdr_encode_sattr(p, args->sattr); -+ p = xdr_encode_sattr(p, args->sattr, -+ req->rq_task->tk_client->cl_tagxid); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; - } -@@ -397,7 +403,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re - { - p = xdr_encode_fhandle(p, args->fromfh); - p = xdr_encode_array(p, args->fromname, args->fromlen); -- p = xdr_encode_sattr(p, args->sattr); -+ p = xdr_encode_sattr(p, args->sattr, -+ req->rq_task->tk_client->cl_tagxid); - p = xdr_encode_array(p, args->topath, args->tolen); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -@@ -412,7 +419,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req, - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name, args->len); - *p++ = htonl(args->type); -- p = xdr_encode_sattr(p, args->sattr); -+ p = xdr_encode_sattr(p, args->sattr, -+ req->rq_task->tk_client->cl_tagxid); - if (args->type == NF3CHR || args->type == NF3BLK) { - *p++ = htonl(MAJOR(args->rdev)); - *p++ = htonl(MINOR(args->rdev)); -diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c -index c0a754e..a12c6a8 100644 ---- a/fs/nfs/nfsroot.c -+++ b/fs/nfs/nfsroot.c -@@ -87,6 +87,7 @@ - #include - #include - #include -+#include - - /* Define this to allow debugging output */ - #undef NFSROOT_DEBUG -@@ -124,7 +125,7 @@ enum { - Opt_soft, Opt_hard, Opt_intr, - Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, - Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp, -- Opt_acl, Opt_noacl, -+ Opt_acl, Opt_noacl, Opt_tagxid, - /* Error token */ - Opt_err - }; -@@ -161,6 +162,7 @@ static match_table_t __initdata tokens = - {Opt_tcp, "tcp"}, - {Opt_acl, "acl"}, - {Opt_noacl, "noacl"}, -+ {Opt_tagxid, "tagxid"}, - {Opt_err, NULL} - - }; -@@ -275,6 +277,11 @@ static int __init root_nfs_parse(char *n - case Opt_noacl: - nfs_data.flags |= NFS_MOUNT_NOACL; - break; -+#ifndef CONFIG_INOXID_NONE -+ case Opt_tagxid: -+ nfs_data.flags |= NFS_MOUNT_TAGXID; -+ break; -+#endif - default: - printk(KERN_WARNING "Root-NFS: unknown " - "option: %s\n", p); -@@ -312,7 +319,7 @@ static int __init root_nfs_name(char *na - /* Override them by options set on kernel command-line */ - root_nfs_parse(name, buf); - -- cp = system_utsname.nodename; -+ cp = vx_new_uts(nodename); - if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) { - printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n"); - return -1; -diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c -index cfe9ce8..672a9b1 100644 ---- a/fs/nfsd/auth.c -+++ b/fs/nfsd/auth.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - #define CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE)) - -@@ -42,18 +43,20 @@ int nfsd_setuser(struct svc_rqst *rqstp, - } - - if (cred->cr_uid != (uid_t) -1) -- current->fsuid = cred->cr_uid; -+ current->fsuid = INOXID_UID(XID_TAG_NFSD, cred->cr_uid, cred->cr_gid); - else - current->fsuid = exp->ex_anon_uid; - if (cred->cr_gid != (gid_t) -1) -- current->fsgid = cred->cr_gid; -+ current->fsgid = INOXID_GID(XID_TAG_NFSD, cred->cr_uid, cred->cr_gid); - else - current->fsgid = exp->ex_anon_gid; - -+ current->xid = INOXID_XID(XID_TAG_NFSD, cred->cr_uid, cred->cr_gid, 0); -+ - if (!cred->cr_group_info) - return -ENOMEM; - ret = set_current_groups(cred->cr_group_info); -- if ((cred->cr_uid)) { -+ if (INOXID_UID(XID_TAG_NFSD, cred->cr_uid, cred->cr_gid)) { - cap_t(current->cap_effective) &= ~CAP_NFSD_MASK; - } else { - cap_t(current->cap_effective) |= (CAP_NFSD_MASK & -diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c -index 243d94b..75491e3 100644 ---- a/fs/nfsd/nfs3xdr.c -+++ b/fs/nfsd/nfs3xdr.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #define NFSDDBG_FACILITY NFSDDBG_XDR - -@@ -111,6 +112,8 @@ static inline u32 * - decode_sattr3(u32 *p, struct iattr *iap) - { - u32 tmp; -+ uid_t uid = 0; -+ gid_t gid = 0; - - iap->ia_valid = 0; - -@@ -120,12 +123,15 @@ decode_sattr3(u32 *p, struct iattr *iap) - } - if (*p++) { - iap->ia_valid |= ATTR_UID; -- iap->ia_uid = ntohl(*p++); -+ uid = ntohl(*p++); - } - if (*p++) { - iap->ia_valid |= ATTR_GID; -- iap->ia_gid = ntohl(*p++); -+ gid = ntohl(*p++); - } -+ iap->ia_uid = INOXID_UID(XID_TAG_NFSD, uid, gid); -+ iap->ia_gid = INOXID_GID(XID_TAG_NFSD, uid, gid); -+ iap->ia_xid = INOXID_XID(XID_TAG_NFSD, uid, gid, 0); - if (*p++) { - u64 newsize; - -@@ -163,8 +169,10 @@ encode_fattr3(struct svc_rqst *rqstp, u3 - *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); - *p++ = htonl((u32) stat->mode); - *p++ = htonl((u32) stat->nlink); -- *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); -- *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); -+ *p++ = htonl((u32) nfsd_ruid(rqstp, -+ XIDINO_UID(XID_TAG(dentry->d_inode), stat->uid, stat->xid))); -+ *p++ = htonl((u32) nfsd_rgid(rqstp, -+ XIDINO_GID(XID_TAG(dentry->d_inode), stat->gid, stat->xid))); - if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { - p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); - } else { -diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c -index 06da750..a725cd1 100644 ---- a/fs/nfsd/nfs4recover.c -+++ b/fs/nfsd/nfs4recover.c -@@ -155,7 +155,7 @@ nfsd4_create_clid_dir(struct nfs4_client - dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); - goto out_put; - } -- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); -+ status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU, NULL); - out_put: - dput(dentry); - out_unlock: -@@ -259,7 +259,7 @@ nfsd4_remove_clid_file(struct dentry *di - return -EINVAL; - } - mutex_lock(&dir->d_inode->i_mutex); -- status = vfs_unlink(dir->d_inode, dentry); -+ status = vfs_unlink(dir->d_inode, dentry, NULL); - mutex_unlock(&dir->d_inode->i_mutex); - return status; - } -@@ -274,7 +274,7 @@ nfsd4_clear_clid_dir(struct dentry *dir, - * a kernel from the future.... */ - nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); - mutex_lock(&dir->d_inode->i_mutex); -- status = vfs_rmdir(dir->d_inode, dentry); -+ status = vfs_rmdir(dir->d_inode, dentry, NULL); - mutex_unlock(&dir->d_inode->i_mutex); - return status; - } -diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c -index 69d3501..753cd9f 100644 ---- a/fs/nfsd/nfs4xdr.c -+++ b/fs/nfsd/nfs4xdr.c -@@ -57,6 +57,7 @@ - #include - #include - #include -+#include - - #define NFSDDBG_FACILITY NFSDDBG_XDR - -@@ -1561,14 +1562,18 @@ out_acl: - WRITE32(stat.nlink); - } - if (bmval1 & FATTR4_WORD1_OWNER) { -- status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen); -+ status = nfsd4_encode_user(rqstp, -+ XIDINO_UID(XID_TAG(dentry->d_inode), -+ stat.uid, stat.xid), &p, &buflen); - if (status == nfserr_resource) - goto out_resource; - if (status) - goto out; - } - if (bmval1 & FATTR4_WORD1_OWNER_GROUP) { -- status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen); -+ status = nfsd4_encode_group(rqstp, -+ XIDINO_GID(XID_TAG(dentry->d_inode), -+ stat.gid, stat.xid), &p, &buflen); - if (status == nfserr_resource) - goto out_resource; - if (status) -diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c -index e3a0797..9671d96 100644 ---- a/fs/nfsd/nfsxdr.c -+++ b/fs/nfsd/nfsxdr.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #define NFSDDBG_FACILITY NFSDDBG_XDR - -@@ -102,6 +103,8 @@ static inline u32 * - decode_sattr(u32 *p, struct iattr *iap) - { - u32 tmp, tmp1; -+ uid_t uid = 0; -+ gid_t gid = 0; - - iap->ia_valid = 0; - -@@ -115,12 +118,15 @@ decode_sattr(u32 *p, struct iattr *iap) - } - if ((tmp = ntohl(*p++)) != (u32)-1) { - iap->ia_valid |= ATTR_UID; -- iap->ia_uid = tmp; -+ uid = tmp; - } - if ((tmp = ntohl(*p++)) != (u32)-1) { - iap->ia_valid |= ATTR_GID; -- iap->ia_gid = tmp; -+ gid = tmp; - } -+ iap->ia_uid = INOXID_UID(XID_TAG_NFSD, uid, gid); -+ iap->ia_gid = INOXID_GID(XID_TAG_NFSD, uid, gid); -+ iap->ia_xid = INOXID_XID(XID_TAG_NFSD, uid, gid, 0); - if ((tmp = ntohl(*p++)) != (u32)-1) { - iap->ia_valid |= ATTR_SIZE; - iap->ia_size = tmp; -@@ -164,8 +170,10 @@ encode_fattr(struct svc_rqst *rqstp, u32 - *p++ = htonl(nfs_ftypes[type >> 12]); - *p++ = htonl((u32) stat->mode); - *p++ = htonl((u32) stat->nlink); -- *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); -- *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); -+ *p++ = htonl((u32) nfsd_ruid(rqstp, -+ XIDINO_UID(XID_TAG(dentry->d_inode), stat->uid, stat->xid))); -+ *p++ = htonl((u32) nfsd_rgid(rqstp, -+ XIDINO_GID(XID_TAG(dentry->d_inode), stat->gid, stat->xid))); - - if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { - *p++ = htonl(NFS_MAXPATHLEN); -diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c -index 5320e5a..c9a49da 100644 ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -1160,13 +1160,13 @@ nfsd_create(struct svc_rqst *rqstp, stru - err = vfs_create(dirp, dchild, iap->ia_mode, NULL); - break; - case S_IFDIR: -- err = vfs_mkdir(dirp, dchild, iap->ia_mode); -+ err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL); - break; - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: -- err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); -+ err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL); - break; - default: - printk("nfsd: bad file type %o in nfsd_create\n", type); -@@ -1446,11 +1446,13 @@ nfsd_symlink(struct svc_rqst *rqstp, str - else { - strncpy(path_alloced, path, plen); - path_alloced[plen] = 0; -- err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); -+ err = vfs_symlink(dentry->d_inode, dnew, -+ path_alloced, mode, NULL); - kfree(path_alloced); - } - } else -- err = vfs_symlink(dentry->d_inode, dnew, path, mode); -+ err = vfs_symlink(dentry->d_inode, dnew, -+ path, mode, NULL); - - if (!err) - if (EX_ISSYNC(fhp->fh_export)) -@@ -1508,7 +1510,7 @@ nfsd_link(struct svc_rqst *rqstp, struct - dold = tfhp->fh_dentry; - dest = dold->d_inode; - -- err = vfs_link(dold, dirp, dnew); -+ err = vfs_link(dold, dirp, dnew, NULL); - if (!err) { - if (EX_ISSYNC(ffhp->fh_export)) { - err = nfserrno(nfsd_sync_dir(ddir)); -@@ -1670,9 +1672,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru - err = -EPERM; - } else - #endif -- err = vfs_unlink(dirp, rdentry); -+ err = vfs_unlink(dirp, rdentry, NULL); - } else { /* It's RMDIR */ -- err = vfs_rmdir(dirp, rdentry); -+ err = vfs_rmdir(dirp, rdentry, NULL); - } - - dput(rdentry); -@@ -1781,7 +1783,8 @@ nfsd_permission(struct svc_export *exp, - */ - if (!(acc & MAY_LOCAL_ACCESS)) - if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) { -- if (EX_RDONLY(exp) || IS_RDONLY(inode)) -+ if (EX_RDONLY(exp) || IS_RDONLY(inode) -+ || MNT_IS_RDONLY(exp->ex_mnt)) - return nfserr_rofs; - if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode)) - return nfserr_perm; -diff --git a/fs/open.c b/fs/open.c -index 70e0230..a0bf558 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -27,6 +27,9 @@ - #include - #include - #include -+#include -+#include -+#include - - #include - -@@ -45,6 +48,8 @@ int vfs_statfs(struct super_block *sb, s - if (retval == 0 && buf->f_frsize == 0) - buf->f_frsize = buf->f_bsize; - } -+ if (!vx_check(0, VX_ADMIN|VX_WATCH)) -+ vx_vsi_statfs(sb, buf); - } - return retval; - } -@@ -248,7 +253,7 @@ static long do_sys_truncate(const char _ - goto dput_and_out; - - error = -EROFS; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt)) - goto dput_and_out; - - error = -EPERM; -@@ -372,7 +377,7 @@ asmlinkage long sys_utime(char __user * - inode = nd.dentry->d_inode; - - error = -EROFS; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt)) - goto dput_and_out; - - /* Don't worry, the checks are done in inode_change_ok() */ -@@ -429,7 +434,7 @@ long do_utimes(int dfd, char __user *fil - inode = nd.dentry->d_inode; - - error = -EROFS; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt)) - goto dput_and_out; - - /* Don't worry, the checks are done in inode_change_ok() */ -@@ -516,7 +521,8 @@ asmlinkage long sys_faccessat(int dfd, c - if (!res) { - res = vfs_permission(&nd, mode); - /* SuS v2 requires we report a read only fs too */ -- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) -+ if(!res && (mode & S_IWOTH) -+ && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt)) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; - path_release(&nd); -@@ -627,7 +633,7 @@ asmlinkage long sys_fchmod(unsigned int - inode = dentry->d_inode; - - err = -EROFS; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt)) - goto out_putf; - err = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -@@ -660,7 +666,7 @@ asmlinkage long sys_fchmodat(int dfd, co - inode = nd.dentry->d_inode; - - error = -EROFS; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt)) - goto dput_and_out; - - error = -EPERM; -@@ -686,7 +692,8 @@ asmlinkage long sys_chmod(const char __u - return sys_fchmodat(AT_FDCWD, filename, mode); - } - --static int chown_common(struct dentry * dentry, uid_t user, gid_t group) -+static int chown_common(struct dentry *dentry, struct vfsmount *mnt, -+ uid_t user, gid_t group) - { - struct inode * inode; - int error; -@@ -698,7 +705,7 @@ static int chown_common(struct dentry * - goto out; - } - error = -EROFS; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) - goto out; - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -@@ -706,11 +713,11 @@ static int chown_common(struct dentry * - newattrs.ia_valid = ATTR_CTIME; - if (user != (uid_t) -1) { - newattrs.ia_valid |= ATTR_UID; -- newattrs.ia_uid = user; -+ newattrs.ia_uid = vx_map_uid(user); - } - if (group != (gid_t) -1) { - newattrs.ia_valid |= ATTR_GID; -- newattrs.ia_gid = group; -+ newattrs.ia_gid = vx_map_gid(group); - } - if (!S_ISDIR(inode->i_mode)) - newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; -@@ -728,7 +735,7 @@ asmlinkage long sys_chown(const char __u - - error = user_path_walk(filename, &nd); - if (!error) { -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group); - path_release(&nd); - } - return error; -@@ -747,7 +754,7 @@ asmlinkage long sys_fchownat(int dfd, co - follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; - error = __user_walk_fd(dfd, filename, follow, &nd); - if (!error) { -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group); - path_release(&nd); - } - out: -@@ -761,7 +768,7 @@ asmlinkage long sys_lchown(const char __ - - error = user_path_walk_link(filename, &nd); - if (!error) { -- error = chown_common(nd.dentry, user, group); -+ error = chown_common(nd.dentry, nd.mnt, user, group); - path_release(&nd); - } - return error; -@@ -775,7 +782,7 @@ asmlinkage long sys_fchown(unsigned int - - file = fget(fd); - if (file) { -- error = chown_common(file->f_dentry, user, group); -+ error = chown_common(file->f_dentry, file->f_vfsmnt, user, group); - fput(file); - } - return error; -@@ -999,6 +1006,7 @@ repeat: - FD_SET(fd, fdt->open_fds); - FD_CLR(fd, fdt->close_on_exec); - fdt->next_fd = fd + 1; -+ vx_openfd_inc(fd); - #if 1 - /* Sanity check */ - if (fdt->fd[fd] != NULL) { -@@ -1021,6 +1029,7 @@ static void __put_unused_fd(struct files - __FD_CLR(fd, fdt->open_fds); - if (fd < fdt->next_fd) - fdt->next_fd = fd; -+ vx_openfd_dec(fd); - } - - void fastcall put_unused_fd(unsigned int fd) -diff --git a/fs/proc/array.c b/fs/proc/array.c -index 7eb1bd7..8434cba 100644 ---- a/fs/proc/array.c -+++ b/fs/proc/array.c -@@ -75,6 +75,9 @@ - #include - #include - #include -+#include -+#include -+#include - - #include - #include -@@ -135,7 +138,9 @@ static const char *task_state_array[] = - "T (stopped)", /* 4 */ - "T (tracing stop)", /* 8 */ - "Z (zombie)", /* 16 */ -- "X (dead)" /* 32 */ -+ "X (dead)", /* 32 */ -+ "N (noninteractive)", /* 64 */ -+ "H (on hold)" /* 128 */ - }; - - static inline const char * get_task_state(struct task_struct *tsk) -@@ -144,7 +149,8 @@ static inline const char * get_task_stat - TASK_INTERRUPTIBLE | - TASK_UNINTERRUPTIBLE | - TASK_STOPPED | -- TASK_TRACED)) | -+ TASK_TRACED | -+ TASK_ONHOLD)) | - (tsk->exit_state & (EXIT_ZOMBIE | - EXIT_DEAD)); - const char **p = &task_state_array[0]; -@@ -161,8 +167,13 @@ static inline char * task_state(struct t - struct group_info *group_info; - int g; - struct fdtable *fdt = NULL; -+ pid_t pid, ptgid, tppid, tgid; - - read_lock(&tasklist_lock); -+ tgid = vx_map_tgid(p->tgid); -+ pid = vx_map_pid(p->pid); -+ ptgid = vx_map_pid(p->group_leader->real_parent->tgid); -+ tppid = vx_map_pid(p->parent->pid); - buffer += sprintf(buffer, - "State:\t%s\n" - "SleepAVG:\t%lu%%\n" -@@ -174,9 +185,8 @@ static inline char * task_state(struct t - "Gid:\t%d\t%d\t%d\t%d\n", - get_task_state(p), - (p->sleep_avg/1024)*100/(1020000000/1024), -- p->tgid, -- p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0, -- pid_alive(p) && p->ptrace ? p->parent->pid : 0, -+ tgid, pid, (pid > 1) ? ptgid : 0, -+ pid_alive(p) && p->ptrace ? tppid : 0, - p->uid, p->euid, p->suid, p->fsuid, - p->gid, p->egid, p->sgid, p->fsgid); - read_unlock(&tasklist_lock); -@@ -296,6 +306,12 @@ static inline char *task_cap(struct task - int proc_pid_status(struct task_struct *task, char * buffer) - { - char * orig = buffer; -+#ifdef CONFIG_VSERVER_LEGACY -+ struct vx_info *vxi; -+#endif -+#ifdef CONFIG_VSERVER_LEGACYNET -+ struct nx_info *nxi; -+#endif - struct mm_struct *mm = get_task_mm(task); - - buffer = task_name(task, buffer); -@@ -308,6 +324,46 @@ int proc_pid_status(struct task_struct * - buffer = task_sig(task, buffer); - buffer = task_cap(task, buffer); - buffer = cpuset_task_status_allowed(task, buffer); -+ -+ if (task_vx_flags(task, VXF_INFO_HIDE, 0)) -+ goto skip; -+#ifdef CONFIG_VSERVER_LEGACY -+ buffer += sprintf (buffer,"s_context: %d\n", vx_task_xid(task)); -+ vxi = task_get_vx_info(task); -+ if (vxi) { -+ buffer += sprintf (buffer,"ctxflags: %08llx\n" -+ ,(unsigned long long)vxi->vx_flags); -+ buffer += sprintf (buffer,"initpid: %d\n" -+ ,vxi->vx_initpid); -+ } else { -+ buffer += sprintf (buffer,"ctxflags: none\n"); -+ buffer += sprintf (buffer,"initpid: none\n"); -+ } -+ put_vx_info(vxi); -+#else -+ buffer += sprintf (buffer,"VxID: %d\n", vx_task_xid(task)); -+#endif -+#ifdef CONFIG_VSERVER_LEGACYNET -+ nxi = task_get_nx_info(task); -+ if (nxi) { -+ int i; -+ -+ buffer += sprintf (buffer,"ipv4root:"); -+ for (i=0; inbipv4; i++){ -+ buffer += sprintf (buffer," %08x/%08x" -+ ,nxi->ipv4[i] -+ ,nxi->mask[i]); -+ } -+ *buffer++ = '\n'; -+ buffer += sprintf (buffer,"ipv4root_bcast: %08x\n" -+ ,nxi->v4_bcast); -+ } else { -+ buffer += sprintf (buffer,"ipv4root: 0\n"); -+ buffer += sprintf (buffer,"ipv4root_bcast: 0\n"); -+ } -+ put_nx_info(nxi); -+#endif -+skip: - #if defined(CONFIG_S390) - buffer = task_show_regs(task, buffer); - #endif -@@ -322,7 +378,7 @@ static int do_task_stat(struct task_stru - sigset_t sigign, sigcatch; - char state; - int res; -- pid_t ppid, pgid = -1, sid = -1; -+ pid_t pid, ppid, pgid = -1, sid = -1; - int num_threads = 0; - struct mm_struct *mm; - unsigned long long start_time; -@@ -388,7 +444,11 @@ static int do_task_stat(struct task_stru - } - it_real_value = task->signal->real_timer.expires; - } -- ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0; -+ pid = vx_info_map_pid(task->vx_info, pid_alive(task) ? task->pid : 0); -+ ppid = (!(pid > 1)) ? 0 : vx_info_map_tgid(task->vx_info, -+ task->group_leader->real_parent->tgid); -+ pgid = vx_info_map_pid(task->vx_info, pgid); -+ - read_unlock(&tasklist_lock); - - if (!whole || num_threads<2) -@@ -412,10 +472,21 @@ static int do_task_stat(struct task_stru - /* convert nsec -> ticks */ - start_time = nsec_to_clock_t(start_time); - -+ /* fixup start time for virt uptime */ -+ if (vx_flags(VXF_VIRT_UPTIME, 0)) { -+ unsigned long long bias = -+ current->vx_info->cvirt.bias_clock; -+ -+ if (start_time > bias) -+ start_time -= bias; -+ else -+ start_time = 0; -+ } -+ - res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ - %lu %lu %lu %lu %lu %ld %ld %ld %ld %d %ld %llu %lu %ld %lu %lu %lu %lu %lu \ - %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n", -- task->pid, -+ pid, - tcomm, - state, - ppid, -diff --git a/fs/proc/base.c b/fs/proc/base.c -index 20feb75..0f3449e 100644 ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -72,6 +72,8 @@ - #include - #include - #include -+#include -+#include - #include "internal.h" - - /* -@@ -121,6 +123,8 @@ enum pid_directory_inos { - PROC_TGID_ATTR_EXEC, - PROC_TGID_ATTR_FSCREATE, - #endif -+ PROC_TGID_VX_INFO, -+ PROC_TGID_IP_INFO, - #ifdef CONFIG_AUDITSYSCALL - PROC_TGID_LOGINUID, - #endif -@@ -161,6 +165,8 @@ enum pid_directory_inos { - PROC_TID_ATTR_EXEC, - PROC_TID_ATTR_FSCREATE, - #endif -+ PROC_TID_VX_INFO, -+ PROC_TID_IP_INFO, - #ifdef CONFIG_AUDITSYSCALL - PROC_TID_LOGINUID, - #endif -@@ -216,6 +222,8 @@ static struct pid_entry tgid_base_stuff[ - #ifdef CONFIG_CPUSETS - E(PROC_TGID_CPUSET, "cpuset", S_IFREG|S_IRUGO), - #endif -+ E(PROC_TGID_VX_INFO, "vinfo", S_IFREG|S_IRUGO), -+ E(PROC_TGID_IP_INFO, "ninfo", S_IFREG|S_IRUGO), - E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO), - E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR), - #ifdef CONFIG_AUDITSYSCALL -@@ -258,6 +266,8 @@ static struct pid_entry tid_base_stuff[] - #ifdef CONFIG_CPUSETS - E(PROC_TID_CPUSET, "cpuset", S_IFREG|S_IRUGO), - #endif -+ E(PROC_TID_VX_INFO, "vinfo", S_IFREG|S_IRUGO), -+ E(PROC_TID_IP_INFO, "ninfo", S_IFREG|S_IRUGO), - E(PROC_TID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO), - E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR), - #ifdef CONFIG_AUDITSYSCALL -@@ -537,6 +547,11 @@ static int proc_check_chroot(struct dent - struct dentry *de, *base; - struct vfsmount *our_vfsmnt, *mnt; - int res = 0; -+ -+ /* context admin override */ -+ if (capable(CAP_CONTEXT)) -+ goto override; -+ - read_lock(¤t->fs->lock); - our_vfsmnt = mntget(current->fs->rootmnt); - base = dget(current->fs->root); -@@ -546,11 +561,11 @@ static int proc_check_chroot(struct dent - de = root; - mnt = vfsmnt; - -- while (vfsmnt != our_vfsmnt) { -- if (vfsmnt == vfsmnt->mnt_parent) -+ while (mnt != our_vfsmnt) { -+ if (mnt == mnt->mnt_parent) - goto out; -- de = vfsmnt->mnt_mountpoint; -- vfsmnt = vfsmnt->mnt_parent; -+ de = mnt->mnt_mountpoint; -+ mnt = mnt->mnt_parent; - } - - if (!is_subdir(de, base)) -@@ -560,8 +575,9 @@ static int proc_check_chroot(struct dent - exit: - dput(base); - mntput(our_vfsmnt); -+override: - dput(root); -- mntput(mnt); -+ mntput(vfsmnt); - return res; - out: - spin_unlock(&vfsmount_lock); -@@ -1221,7 +1237,7 @@ static int proc_pident_readdir(struct fi - struct inode *inode = dentry->d_inode; - struct pid_entry *p; - ino_t ino; -- int ret; -+ int ret, hide; - - ret = -ENOENT; - if (!pid_alive(proc_task(inode))) -@@ -1252,11 +1268,20 @@ static int proc_pident_readdir(struct fi - goto out; - } - p = ents + i; -+ hide = vx_flags(VXF_INFO_HIDE, 0); - while (p->name) { -+ if (hide) { -+ switch (p->type) { -+ case PROC_TGID_VX_INFO: -+ case PROC_TGID_IP_INFO: -+ goto skip; -+ } -+ } - if (filldir(dirent, p->name, p->len, filp->f_pos, - fake_ino(pid, p->type), p->mode >> 12) < 0) - goto out; - filp->f_pos++; -+ skip: - p++; - } - } -@@ -1330,6 +1355,7 @@ static struct inode *proc_pid_make_inode - inode->i_uid = task->euid; - inode->i_gid = task->egid; - } -+ inode->i_xid = vx_task_xid(task); - security_task_to_inode(task, inode); - - out: -@@ -1355,6 +1381,11 @@ static int pid_revalidate(struct dentry - { - struct inode *inode = dentry->d_inode; - struct task_struct *task = proc_task(inode); -+ -+ if (!vx_check(vx_task_xid(task), VX_IDENT)) -+ goto out_drop; -+ /* discard wrong fakeinit */ -+ - if (pid_alive(task)) { - if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) { - inode->i_uid = task->euid; -@@ -1366,6 +1397,7 @@ static int pid_revalidate(struct dentry - security_task_to_inode(task, inode); - return 1; - } -+out_drop: - d_drop(dentry); - return 0; - } -@@ -1600,6 +1632,9 @@ static struct file_operations proc_tgid_ - static struct inode_operations proc_tgid_attr_inode_operations; - #endif - -+extern int proc_pid_vx_info(struct task_struct *, char *); -+extern int proc_pid_nx_info(struct task_struct *, char *); -+ - static int get_tid_list(int index, unsigned int *tids, struct inode *dir); - - /* SMP-safe */ -@@ -1787,15 +1822,33 @@ static struct dentry *proc_pident_lookup - inode->i_fop = &proc_loginuid_operations; - break; - #endif -+ case PROC_TID_VX_INFO: -+ case PROC_TGID_VX_INFO: -+ if (task_vx_flags(task, VXF_INFO_HIDE, 0)) -+ goto out_noent; -+ inode->i_fop = &proc_info_file_operations; -+ ei->op.proc_read = proc_pid_vx_info; -+ break; -+ case PROC_TID_IP_INFO: -+ case PROC_TGID_IP_INFO: -+ if (task_vx_flags(task, VXF_INFO_HIDE, 0)) -+ goto out_noent; -+ inode->i_fop = &proc_info_file_operations; -+ ei->op.proc_read = proc_pid_nx_info; -+ break; - default: - printk("procfs: impossible type (%d)",p->type); -- iput(inode); -- return ERR_PTR(-EINVAL); -+ error = -EINVAL; -+ goto out_put; - } - dentry->d_op = &pid_dentry_operations; - d_add(dentry, inode); - return NULL; - -+out_noent: -+ error=-ENOENT; -+out_put: -+ iput(inode); - out: - return ERR_PTR(error); - } -@@ -1879,14 +1932,14 @@ static int proc_self_readlink(struct den - int buflen) - { - char tmp[30]; -- sprintf(tmp, "%d", current->tgid); -+ sprintf(tmp, "%d", vx_map_tgid(current->tgid)); - return vfs_readlink(dentry,buffer,buflen,tmp); - } - - static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) - { - char tmp[30]; -- sprintf(tmp, "%d", current->tgid); -+ sprintf(tmp, "%d", vx_map_tgid(current->tgid)); - return ERR_PTR(vfs_follow_link(nd,tmp)); - } - -@@ -1949,6 +2002,20 @@ void proc_pid_flush(struct dentry *proc_ - } - } - -+#define VXF_FAKE_INIT (VXF_INFO_INIT|VXF_STATE_INIT) -+ -+static inline int proc_pid_visible(struct task_struct *task, int pid) -+{ -+ if ((pid == 1) && -+ !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT)) -+ goto visible; -+ if (vx_check(vx_task_xid(task), VX_WATCH|VX_IDENT)) -+ goto visible; -+ return 0; -+visible: -+ return 1; -+} -+ - /* SMP-safe */ - struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) - { -@@ -1985,13 +2052,14 @@ struct dentry *proc_pid_lookup(struct in - if (!task) - goto out; - -- inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); -+ /* check for context visibility */ -+ if (!proc_pid_visible(task, tgid)) -+ goto out_drop_task; - -+ inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); -+ if (!inode) -+ goto out_drop_task; - -- if (!inode) { -- put_task_struct(task); -- goto out; -- } - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; - inode->i_op = &proc_tgid_base_inode_operations; - inode->i_fop = &proc_tgid_base_operations; -@@ -2020,6 +2088,8 @@ struct dentry *proc_pid_lookup(struct in - goto out; - } - return NULL; -+out_drop_task: -+ put_task_struct(task); - out: - return ERR_PTR(-ENOENT); - } -@@ -2035,6 +2105,8 @@ static struct dentry *proc_task_lookup(s - tid = name_to_int(dentry); - if (tid == ~0U) - goto out; -+ if (vx_current_initpid(tid)) -+ goto out; - - read_lock(&tasklist_lock); - task = find_task_by_pid(tid); -@@ -2046,11 +2118,14 @@ static struct dentry *proc_task_lookup(s - if (leader->tgid != task->tgid) - goto out_drop_task; - -- inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); -- -+ /* check for context visibility */ -+ if (!proc_pid_visible(task, tid)) -+ goto out_drop_task; - -+ inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); - if (!inode) - goto out_drop_task; -+ - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; - inode->i_op = &proc_tid_base_inode_operations; - inode->i_fop = &proc_tid_base_operations; -@@ -2090,7 +2165,7 @@ static int get_tgid_list(int index, unsi - read_lock(&tasklist_lock); - p = NULL; - if (version) { -- p = find_task_by_pid(version); -+ p = find_task_by_real_pid(version); - if (p && !thread_group_leader(p)) - p = NULL; - } -@@ -2102,11 +2177,15 @@ static int get_tgid_list(int index, unsi - - for ( ; p != &init_task; p = next_task(p)) { - int tgid = p->pid; -+ - if (!pid_alive(p)) - continue; -+ /* check for context visibility */ -+ if (!proc_pid_visible(p, tgid)) -+ continue; - if (--index >= 0) - continue; -- tgids[nr_tgids] = tgid; -+ tgids[nr_tgids] = vx_map_tgid(tgid); - nr_tgids++; - if (nr_tgids >= PROC_MAXPIDS) - break; -@@ -2136,10 +2215,13 @@ static int get_tid_list(int index, unsig - if (pid_alive(task)) do { - int tid = task->pid; - -+ /* check for context visibility */ -+ if (!proc_pid_visible(task, tid)) -+ continue; - if (--index >= 0) - continue; - if (tids != NULL) -- tids[nr_tids] = tid; -+ tids[nr_tids] = vx_map_pid(tid); - nr_tids++; - if (nr_tids >= PROC_MAXPIDS) - break; -@@ -2215,11 +2297,14 @@ static int proc_task_readdir(struct file - unsigned int nr_tids, i; - struct dentry *dentry = filp->f_dentry; - struct inode *inode = dentry->d_inode; -+ struct task_struct *task = proc_task(inode); - int retval = -ENOENT; - ino_t ino; - unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ - -- if (!pid_alive(proc_task(inode))) -+ if (!vx_check(vx_task_xid(task), VX_WATCH|VX_IDENT)) -+ goto out; -+ if (!pid_alive(task)) - goto out; - retval = 0; - -diff --git a/fs/proc/generic.c b/fs/proc/generic.c -index 20e5c45..38c8540 100644 ---- a/fs/proc/generic.c -+++ b/fs/proc/generic.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - - #include "internal.h" -@@ -385,11 +386,15 @@ struct dentry *proc_lookup(struct inode - for (de = de->subdir; de ; de = de->next) { - if (de->namelen != dentry->d_name.len) - continue; -+ if (!vx_hide_check(0, de->vx_flags)) -+ continue; - if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { - unsigned int ino = de->low_ino; - - error = -EINVAL; - inode = proc_get_inode(dir->i_sb, ino, de); -+ /* generic proc entries belong to the host */ -+ inode->i_xid = 0; - break; - } - } -@@ -461,9 +466,12 @@ int proc_readdir(struct file * filp, - } - - do { -+ if (!vx_hide_check(0, de->vx_flags)) -+ goto skip; - if (filldir(dirent, de->name, de->namelen, filp->f_pos, - de->low_ino, de->mode >> 12) < 0) - goto out; -+ skip: - filp->f_pos++; - de = de->next; - } while (de); -@@ -581,6 +589,7 @@ static struct proc_dir_entry *proc_creat - ent->namelen = len; - ent->mode = mode; - ent->nlink = nlink; -+ ent->vx_flags = IATTR_PROC_DEFAULT; - out: - return ent; - } -@@ -601,7 +610,8 @@ struct proc_dir_entry *proc_symlink(cons - kfree(ent->data); - kfree(ent); - ent = NULL; -- } -+ } else -+ ent->vx_flags = IATTR_PROC_SYMLINK; - } else { - kfree(ent); - ent = NULL; -diff --git a/fs/proc/inode.c b/fs/proc/inode.c -index 075d3e9..6d25888 100644 ---- a/fs/proc/inode.c -+++ b/fs/proc/inode.c -@@ -170,6 +170,8 @@ struct inode *proc_get_inode(struct supe - inode->i_uid = de->uid; - inode->i_gid = de->gid; - } -+ if (de->vx_flags) -+ PROC_I(inode)->vx_flags = de->vx_flags; - if (de->size) - inode->i_size = de->size; - if (de->nlink) -diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c -index 1d24fea..d84fdcb 100644 ---- a/fs/proc/proc_misc.c -+++ b/fs/proc/proc_misc.c -@@ -53,6 +53,8 @@ - #include - #include "internal.h" - -+#include -+ - #define LOAD_INT(x) ((x) >> FSHIFT) - #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) - /* -@@ -82,17 +84,32 @@ static int proc_calc_metrics(char *page, - static int loadavg_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) - { -+ unsigned int running, threads; - int a, b, c; - int len; - -- a = avenrun[0] + (FIXED_1/200); -- b = avenrun[1] + (FIXED_1/200); -- c = avenrun[2] + (FIXED_1/200); -- len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", -+ if (vx_flags(VXF_VIRT_LOAD, 0)) { -+ struct vx_info *vxi = current->vx_info; -+ -+ a = vxi->cvirt.load[0] + (FIXED_1/200); -+ b = vxi->cvirt.load[1] + (FIXED_1/200); -+ c = vxi->cvirt.load[2] + (FIXED_1/200); -+ -+ running = atomic_read(&vxi->cvirt.nr_running); -+ threads = atomic_read(&vxi->cvirt.nr_threads); -+ } else { -+ a = avenrun[0] + (FIXED_1/200); -+ b = avenrun[1] + (FIXED_1/200); -+ c = avenrun[2] + (FIXED_1/200); -+ -+ running = nr_running(); -+ threads = nr_threads; -+ } -+ len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n", - LOAD_INT(a), LOAD_FRAC(a), - LOAD_INT(b), LOAD_FRAC(b), - LOAD_INT(c), LOAD_FRAC(c), -- nr_running(), nr_threads, last_pid); -+ running, threads, last_pid); - return proc_calc_metrics(page, start, off, count, eof, len); - } - -@@ -106,6 +123,9 @@ static int uptime_read_proc(char *page, - - do_posix_clock_monotonic_gettime(&uptime); - cputime_to_timespec(idletime, &idle); -+ if (vx_flags(VXF_VIRT_UPTIME, 0)) -+ vx_vsi_uptime(&uptime, &idle); -+ - len = sprintf(page,"%lu.%02lu %lu.%02lu\n", - (unsigned long) uptime.tv_sec, - (uptime.tv_nsec / (NSEC_PER_SEC / 100)), -@@ -143,7 +163,7 @@ static int meminfo_read_proc(char *page, - * sysctl_overcommit_ratio / 100) + total_swap_pages; - - cached = get_page_cache_size() - total_swapcache_pages - i.bufferram; -- if (cached < 0) -+ if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0)) - cached = 0; - - get_vmalloc_info(&vmi); -@@ -238,8 +258,9 @@ static int version_read_proc(char *page, - { - int len; - -- strcpy(page, linux_banner); -- len = strlen(page); -+ len = sprintf(page, vx_linux_banner, -+ vx_new_uts(release), -+ vx_new_uts(version)); - return proc_calc_metrics(page, start, off, count, eof, len); - } - -diff --git a/fs/proc/root.c b/fs/proc/root.c -index c3fd361..307ba7b 100644 ---- a/fs/proc/root.c -+++ b/fs/proc/root.c -@@ -25,6 +25,9 @@ struct proc_dir_entry *proc_net, *proc_n - #ifdef CONFIG_SYSCTL - struct proc_dir_entry *proc_sys_root; - #endif -+struct proc_dir_entry *proc_virtual; -+ -+extern void proc_vx_init(void); - - static struct super_block *proc_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) -@@ -78,6 +81,7 @@ void __init proc_root_init(void) - proc_device_tree_init(); - #endif - proc_bus = proc_mkdir("bus", NULL); -+ proc_vx_init(); - } - - static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat -diff --git a/fs/quota.c b/fs/quota.c -index ba9e0bf..1b690cc 100644 ---- a/fs/quota.c -+++ b/fs/quota.c -@@ -17,6 +17,9 @@ - #include - #include - #include -+#include -+#include -+#include - - /* Check validity of generic quotactl commands */ - static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) -@@ -81,11 +84,11 @@ static int generic_quotactl_valid(struct - if (cmd == Q_GETQUOTA) { - if (((type == USRQUOTA && current->euid != id) || - (type == GRPQUOTA && !in_egroup_p(id))) && -- !capable(CAP_SYS_ADMIN)) -+ !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) - return -EPERM; - } - else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO) -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) - return -EPERM; - - return 0; -@@ -132,10 +135,10 @@ static int xqm_quotactl_valid(struct sup - if (cmd == Q_XGETQUOTA) { - if (((type == XQM_USRQUOTA && current->euid != id) || - (type == XQM_GRPQUOTA && !in_egroup_p(id))) && -- !capable(CAP_SYS_ADMIN)) -+ !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) - return -EPERM; - } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) { -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) - return -EPERM; - } - -@@ -337,6 +340,43 @@ static int do_quotactl(struct super_bloc - return 0; - } - -+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE) -+ -+#include -+#include -+ -+static vroot_grb_func *vroot_get_real_bdev = NULL; -+ -+static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED; -+ -+int register_vroot_grb(vroot_grb_func *func) { -+ int ret = -EBUSY; -+ -+ spin_lock(&vroot_grb_lock); -+ if (!vroot_get_real_bdev) { -+ vroot_get_real_bdev = func; -+ ret = 0; -+ } -+ spin_unlock(&vroot_grb_lock); -+ return ret; -+} -+EXPORT_SYMBOL(register_vroot_grb); -+ -+int unregister_vroot_grb(vroot_grb_func *func) { -+ int ret = -EINVAL; -+ -+ spin_lock(&vroot_grb_lock); -+ if (vroot_get_real_bdev) { -+ vroot_get_real_bdev = NULL; -+ ret = 0; -+ } -+ spin_unlock(&vroot_grb_lock); -+ return ret; -+} -+EXPORT_SYMBOL(unregister_vroot_grb); -+ -+#endif -+ - /* - * This is the system call interface. This communicates with - * the user-level programs. Currently this only supports diskquota -@@ -362,6 +402,23 @@ asmlinkage long sys_quotactl(unsigned in - putname(tmp); - if (IS_ERR(bdev)) - return PTR_ERR(bdev); -+#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE) -+ if (bdev && bdev->bd_inode && -+ imajor(bdev->bd_inode) == VROOT_MAJOR) { -+ struct block_device *bdnew = (void *)-EINVAL; -+ -+ if (vroot_get_real_bdev) -+ bdnew = vroot_get_real_bdev(bdev); -+ else -+ vxdprintk(VXD_CBIT(misc, 0), -+ "vroot_get_real_bdev not set"); -+ -+ bdput(bdev); -+ if (IS_ERR(bdnew)) -+ return PTR_ERR(bdnew); -+ bdev = bdnew; -+ } -+#endif - sb = get_super(bdev); - bdput(bdev); - if (!sb) -diff --git a/fs/read_write.c b/fs/read_write.c -index 3f7a1a6..fbee209 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -667,9 +667,8 @@ static ssize_t do_sendfile(int out_fd, i - if (!(in_file->f_mode & FMODE_PREAD)) - goto fput_in; - retval = rw_verify_area(READ, in_file, ppos, count); -- if (retval < 0) -+ if (retval) - goto fput_in; -- count = retval; - - retval = security_file_permission (in_file, MAY_READ); - if (retval) -@@ -689,9 +688,8 @@ static ssize_t do_sendfile(int out_fd, i - goto fput_out; - out_inode = out_file->f_dentry->d_inode; - retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); -- if (retval < 0) -+ if (retval) - goto fput_out; -- count = retval; - - retval = security_file_permission (out_file, MAY_WRITE); - if (retval) -diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c -index 909f71e..49cd1aa 100644 ---- a/fs/reiserfs/bitmap.c -+++ b/fs/reiserfs/bitmap.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - #define PREALLOCATION_SIZE 9 - -@@ -411,8 +412,10 @@ static void _reiserfs_free_block(struct - set_sb_free_blocks(rs, sb_free_blocks(rs) + 1); - - journal_mark_dirty(th, s, sbh); -- if (for_unformatted) -+ if (for_unformatted) { -+ DLIMIT_FREE_BLOCK(inode, 1); - DQUOT_FREE_BLOCK_NODIRTY(inode, 1); -+ } - } - - void reiserfs_free_block(struct reiserfs_transaction_handle *th, -@@ -1021,6 +1024,7 @@ static inline int blocknrs_and_prealloc_ - int passno = 0; - int nr_allocated = 0; - int bigalloc = 0; -+ int blocks; - - determine_prealloc_size(hint); - if (!hint->formatted_node) { -@@ -1030,22 +1034,34 @@ static inline int blocknrs_and_prealloc_ - "reiserquota: allocating %d blocks id=%u", - amount_needed, hint->inode->i_uid); - #endif -- quota_ret = -- DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed); -- if (quota_ret) /* Quota exceeded? */ -+ quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, -+ amount_needed); -+ if (quota_ret) - return QUOTA_EXCEEDED; -+ if (DLIMIT_ALLOC_BLOCK(hint->inode, amount_needed)) { -+ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, -+ amount_needed); -+ return NO_DISK_SPACE; -+ } -+ - if (hint->preallocate && hint->prealloc_size) { - #ifdef REISERQUOTA_DEBUG - reiserfs_debug(s, REISERFS_DEBUG_CODE, - "reiserquota: allocating (prealloc) %d blocks id=%u", - hint->prealloc_size, hint->inode->i_uid); - #endif -- quota_ret = -- DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode, -- hint->prealloc_size); -+ quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode, -+ hint->prealloc_size); -+ if (!quota_ret && -+ DLIMIT_ALLOC_BLOCK(hint->inode, hint->prealloc_size)) { -+ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, -+ hint->prealloc_size); -+ quota_ret = 1; -+ } - if (quota_ret) - hint->preallocate = hint->prealloc_size = 0; - } -+ - /* for unformatted nodes, force large allocations */ - bigalloc = amount_needed; - } -@@ -1093,7 +1109,10 @@ static inline int blocknrs_and_prealloc_ - nr_allocated, - hint->inode->i_uid); - #endif -- DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated); /* Free not allocated blocks */ -+ /* Free not allocated blocks */ -+ blocks = amount_needed + hint->prealloc_size - nr_allocated; -+ DLIMIT_FREE_BLOCK(hint->inode, blocks); -+ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks); - } - while (nr_allocated--) - reiserfs_free_block(hint->th, hint->inode, -@@ -1125,10 +1144,10 @@ static inline int blocknrs_and_prealloc_ - REISERFS_I(hint->inode)->i_prealloc_count, - hint->inode->i_uid); - #endif -- DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + -- hint->prealloc_size - nr_allocated - -- REISERFS_I(hint->inode)-> -- i_prealloc_count); -+ blocks = amount_needed + hint->prealloc_size - nr_allocated - -+ REISERFS_I(hint->inode)->i_prealloc_count; -+ DLIMIT_FREE_BLOCK(hint->inode, blocks); -+ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks); - } - - return CARRY_ON; -diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c -index be12879..db38c09 100644 ---- a/fs/reiserfs/file.c -+++ b/fs/reiserfs/file.c -@@ -1586,4 +1586,5 @@ struct inode_operations reiserfs_file_in - .listxattr = reiserfs_listxattr, - .removexattr = reiserfs_removexattr, - .permission = reiserfs_permission, -+ .sync_flags = reiserfs_sync_flags, - }; -diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c -index d60f623..a218e53 100644 ---- a/fs/reiserfs/inode.c -+++ b/fs/reiserfs/inode.c -@@ -17,6 +17,8 @@ - #include - #include - #include -+#include -+#include - - extern int reiserfs_default_io_size; /* default io size devuned in super.c */ - -@@ -57,6 +59,7 @@ void reiserfs_delete_inode(struct inode - * stat data deletion */ - if (!err) - DQUOT_FREE_INODE(inode); -+ DLIMIT_FREE_INODE(inode); - - if (journal_end(&th, inode->i_sb, jbegin_count)) { - mutex_unlock(&inode->i_mutex); -@@ -1126,6 +1129,8 @@ static void init_inode(struct inode *ino - struct buffer_head *bh; - struct item_head *ih; - __u32 rdev; -+ uid_t uid; -+ gid_t gid; - //int version = ITEM_VERSION_1; - - bh = PATH_PLAST_BUFFER(path); -@@ -1149,12 +1154,13 @@ static void init_inode(struct inode *ino - (struct stat_data_v1 *)B_I_PITEM(bh, ih); - unsigned long blocks; - -+ uid = sd_v1_uid(sd); -+ gid = sd_v1_gid(sd); -+ - set_inode_item_key_version(inode, KEY_FORMAT_3_5); - set_inode_sd_version(inode, STAT_DATA_V1); - inode->i_mode = sd_v1_mode(sd); - inode->i_nlink = sd_v1_nlink(sd); -- inode->i_uid = sd_v1_uid(sd); -- inode->i_gid = sd_v1_gid(sd); - inode->i_size = sd_v1_size(sd); - inode->i_atime.tv_sec = sd_v1_atime(sd); - inode->i_mtime.tv_sec = sd_v1_mtime(sd); -@@ -1196,11 +1202,12 @@ static void init_inode(struct inode *ino - // (directories and symlinks) - struct stat_data *sd = (struct stat_data *)B_I_PITEM(bh, ih); - -+ uid = sd_v2_uid(sd); -+ gid = sd_v2_gid(sd); -+ - inode->i_mode = sd_v2_mode(sd); - inode->i_nlink = sd_v2_nlink(sd); -- inode->i_uid = sd_v2_uid(sd); - inode->i_size = sd_v2_size(sd); -- inode->i_gid = sd_v2_gid(sd); - inode->i_mtime.tv_sec = sd_v2_mtime(sd); - inode->i_atime.tv_sec = sd_v2_atime(sd); - inode->i_ctime.tv_sec = sd_v2_ctime(sd); -@@ -1230,6 +1237,10 @@ static void init_inode(struct inode *ino - sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode); - } - -+ inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid); -+ inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid); -+ inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid, 0); -+ - pathrelse(path); - if (S_ISREG(inode->i_mode)) { - inode->i_op = &reiserfs_file_inode_operations; -@@ -1252,13 +1263,15 @@ static void init_inode(struct inode *ino - static void inode2sd(void *sd, struct inode *inode, loff_t size) - { - struct stat_data *sd_v2 = (struct stat_data *)sd; -+ uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid); -+ gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid); - __u16 flags; - -+ set_sd_v2_uid(sd_v2, uid); -+ set_sd_v2_gid(sd_v2, gid); - set_sd_v2_mode(sd_v2, inode->i_mode); - set_sd_v2_nlink(sd_v2, inode->i_nlink); -- set_sd_v2_uid(sd_v2, inode->i_uid); - set_sd_v2_size(sd_v2, size); -- set_sd_v2_gid(sd_v2, inode->i_gid); - set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec); - set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec); - set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec); -@@ -1789,6 +1802,10 @@ int reiserfs_new_inode(struct reiserfs_t - - BUG_ON(!th->t_trans_id); - -+ if (DLIMIT_ALLOC_INODE(inode)) { -+ err = -ENOSPC; -+ goto out_bad_dlimit; -+ } - if (DQUOT_ALLOC_INODE(inode)) { - err = -EDQUOT; - goto out_end_trans; -@@ -1974,6 +1991,9 @@ int reiserfs_new_inode(struct reiserfs_t - DQUOT_FREE_INODE(inode); - - out_end_trans: -+ DLIMIT_FREE_INODE(inode); -+ -+ out_bad_dlimit: - journal_end(th, th->t_super, th->t_blocks_allocated); - /* Drop can be outside and it needs more credits so it's better to have it outside */ - DQUOT_DROP(inode); -@@ -2701,6 +2721,14 @@ void sd_attrs_to_i_attrs(__u16 sd_attrs, - inode->i_flags |= S_IMMUTABLE; - else - inode->i_flags &= ~S_IMMUTABLE; -+ if (sd_attrs & REISERFS_IUNLINK_FL) -+ inode->i_flags |= S_IUNLINK; -+ else -+ inode->i_flags &= ~S_IUNLINK; -+ if (sd_attrs & REISERFS_BARRIER_FL) -+ inode->i_flags |= S_BARRIER; -+ else -+ inode->i_flags &= ~S_BARRIER; - if (sd_attrs & REISERFS_APPEND_FL) - inode->i_flags |= S_APPEND; - else -@@ -2723,6 +2751,14 @@ void i_attrs_to_sd_attrs(struct inode *i - *sd_attrs |= REISERFS_IMMUTABLE_FL; - else - *sd_attrs &= ~REISERFS_IMMUTABLE_FL; -+ if (inode->i_flags & S_IUNLINK) -+ *sd_attrs |= REISERFS_IUNLINK_FL; -+ else -+ *sd_attrs &= ~REISERFS_IUNLINK_FL; -+ if (inode->i_flags & S_BARRIER) -+ *sd_attrs |= REISERFS_BARRIER_FL; -+ else -+ *sd_attrs &= ~REISERFS_BARRIER_FL; - if (inode->i_flags & S_SYNC) - *sd_attrs |= REISERFS_SYNC_FL; - else -@@ -2900,6 +2936,22 @@ static ssize_t reiserfs_direct_IO(int rw - reiserfs_get_blocks_direct_io, NULL); - } - -+int reiserfs_sync_flags(struct inode *inode) -+{ -+ u16 oldflags, newflags; -+ -+ oldflags = REISERFS_I(inode)->i_attrs; -+ newflags = oldflags; -+ i_attrs_to_sd_attrs(inode, &newflags); -+ -+ if (oldflags ^ newflags) { -+ REISERFS_I(inode)->i_attrs = newflags; -+ inode->i_ctime = CURRENT_TIME_SEC; -+ mark_inode_dirty(inode); -+ } -+ return 0; -+} -+ - int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) - { - struct inode *inode = dentry->d_inode; -@@ -2944,9 +2996,11 @@ int reiserfs_setattr(struct dentry *dent - } - - error = inode_change_ok(inode, attr); -+ - if (!error) { - if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || -- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { -+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || -+ (ia_valid & ATTR_XID && attr->ia_xid != inode->i_xid)) { - error = reiserfs_chown_xattrs(inode, attr); - - if (!error) { -@@ -2976,6 +3030,9 @@ int reiserfs_setattr(struct dentry *dent - inode->i_uid = attr->ia_uid; - if (attr->ia_valid & ATTR_GID) - inode->i_gid = attr->ia_gid; -+ if ((attr->ia_valid & ATTR_XID) && -+ IS_TAGXID(inode)) -+ inode->i_xid = attr->ia_xid; - mark_inode_dirty(inode); - error = - journal_end(&th, inode->i_sb, jbegin_count); -diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c -index 745c881..e2dbca0 100644 ---- a/fs/reiserfs/ioctl.c -+++ b/fs/reiserfs/ioctl.c -@@ -4,6 +4,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -23,7 +24,7 @@ static int reiserfs_unpack(struct inode - int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) - { -- unsigned int flags; -+ unsigned int flags, oldflags; - - switch (cmd) { - case REISERFS_IOC_UNPACK: -@@ -42,12 +43,14 @@ int reiserfs_ioctl(struct inode *inode, - - flags = REISERFS_I(inode)->i_attrs; - i_attrs_to_sd_attrs(inode, (__u16 *) & flags); -+ flags &= REISERFS_FL_USER_VISIBLE; - return put_user(flags, (int __user *)arg); - case REISERFS_IOC_SETFLAGS:{ - if (!reiserfs_attrs(inode->i_sb)) - return -ENOTTY; - -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - - if ((current->fsuid != inode->i_uid) -@@ -57,10 +60,12 @@ int reiserfs_ioctl(struct inode *inode, - if (get_user(flags, (int __user *)arg)) - return -EFAULT; - -- if (((flags ^ REISERFS_I(inode)-> -- i_attrs) & (REISERFS_IMMUTABLE_FL | -- REISERFS_APPEND_FL)) -- && !capable(CAP_LINUX_IMMUTABLE)) -+ oldflags = REISERFS_I(inode) -> i_attrs; -+ if (((oldflags & REISERFS_IMMUTABLE_FL) || -+ ((flags ^ oldflags) & -+ (REISERFS_IMMUTABLE_FL | REISERFS_IUNLINK_FL | -+ REISERFS_APPEND_FL))) && -+ !capable(CAP_LINUX_IMMUTABLE)) - return -EPERM; - - if ((flags & REISERFS_NOTAIL_FL) && -@@ -71,6 +76,9 @@ int reiserfs_ioctl(struct inode *inode, - if (result) - return result; - } -+ -+ flags = flags & REISERFS_FL_USER_MODIFIABLE; -+ flags |= oldflags & ~REISERFS_FL_USER_MODIFIABLE; - sd_attrs_to_i_attrs(flags, inode); - REISERFS_I(inode)->i_attrs = flags; - inode->i_ctime = CURRENT_TIME_SEC; -@@ -82,7 +90,8 @@ int reiserfs_ioctl(struct inode *inode, - case REISERFS_IOC_SETVERSION: - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) - return -EPERM; -- if (IS_RDONLY(inode)) -+ if (IS_RDONLY(inode) || -+ (filp && MNT_IS_RDONLY(filp->f_vfsmnt))) - return -EROFS; - if (get_user(inode->i_generation, (int __user *)arg)) - return -EFAULT; -diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c -index 284f785..6faa29e 100644 ---- a/fs/reiserfs/namei.c -+++ b/fs/reiserfs/namei.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } - #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--; -@@ -365,6 +366,7 @@ static struct dentry *reiserfs_lookup(st - reiserfs_write_unlock(dir->i_sb); - return ERR_PTR(-EACCES); - } -+ vx_propagate_xid(nd, inode); - - /* Propogate the priv_object flag so we know we're in the priv tree */ - if (is_reiserfs_priv_object(dir)) -@@ -600,6 +602,7 @@ static int new_inode_init(struct inode * - } else { - inode->i_gid = current->fsgid; - } -+ inode->i_xid = vx_current_fsxid(inode->i_sb); - DQUOT_INIT(inode); - return 0; - } -@@ -1546,6 +1549,7 @@ struct inode_operations reiserfs_dir_ino - .listxattr = reiserfs_listxattr, - .removexattr = reiserfs_removexattr, - .permission = reiserfs_permission, -+ .sync_flags = reiserfs_sync_flags, - }; - - /* -@@ -1562,6 +1566,7 @@ struct inode_operations reiserfs_symlink - .listxattr = reiserfs_listxattr, - .removexattr = reiserfs_removexattr, - .permission = reiserfs_permission, -+ .sync_flags = reiserfs_sync_flags, - - }; - -@@ -1575,5 +1580,6 @@ struct inode_operations reiserfs_special - .listxattr = reiserfs_listxattr, - .removexattr = reiserfs_removexattr, - .permission = reiserfs_permission, -+ .sync_flags = reiserfs_sync_flags, - - }; -diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c -index e2d08d7..83ea55e 100644 ---- a/fs/reiserfs/stree.c -+++ b/fs/reiserfs/stree.c -@@ -57,6 +57,7 @@ - #include - #include - #include -+#include - - /* Does the buffer contain a disk block which is in the tree. */ - inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh) -@@ -1365,6 +1366,7 @@ int reiserfs_delete_item(struct reiserfs - "reiserquota delete_item(): freeing %u, id=%u type=%c", - quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih)); - #endif -+ DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes); - DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes); - - /* Return deleted body length */ -@@ -1451,6 +1453,7 @@ void reiserfs_delete_solid_item(struct r - quota_cut_bytes, inode->i_uid, - key2type(key)); - #endif -+ DLIMIT_FREE_SPACE(inode, quota_cut_bytes); - DQUOT_FREE_SPACE_NODIRTY(inode, - quota_cut_bytes); - } -@@ -1808,6 +1811,7 @@ int reiserfs_cut_from_item(struct reiser - "reiserquota cut_from_item(): freeing %u id=%u type=%c", - quota_cut_bytes, p_s_inode->i_uid, '?'); - #endif -+ DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes); - DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes); - return n_ret_value; - } -@@ -2048,6 +2052,11 @@ int reiserfs_paste_into_item(struct reis - pathrelse(p_s_search_path); - return -EDQUOT; - } -+ if (DLIMIT_ALLOC_SPACE(inode, n_pasted_size)) { -+ DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size); -+ pathrelse(p_s_search_path); -+ return -ENOSPC; -+ } - init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path, - n_pasted_size); - #ifdef DISPLACE_NEW_PACKING_LOCALITIES -@@ -2100,6 +2109,7 @@ int reiserfs_paste_into_item(struct reis - n_pasted_size, inode->i_uid, - key2type(&(p_s_key->on_disk_key))); - #endif -+ DLIMIT_FREE_SPACE(inode, n_pasted_size); - DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size); - return retval; - } -@@ -2137,6 +2147,11 @@ int reiserfs_insert_item(struct reiserfs - pathrelse(p_s_path); - return -EDQUOT; - } -+ if (DLIMIT_ALLOC_SPACE(inode, quota_bytes)) { -+ DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes); -+ pathrelse(p_s_path); -+ return -ENOSPC; -+ } - } - init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path, - IH_SIZE + ih_item_len(p_s_ih)); -@@ -2184,7 +2199,9 @@ int reiserfs_insert_item(struct reiserfs - "reiserquota insert_item(): freeing %u id=%u type=%c", - quota_bytes, inode->i_uid, head2type(p_s_ih)); - #endif -- if (inode) -+ if (inode) { -+ DLIMIT_FREE_SPACE(inode, quota_bytes); - DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes); -+ } - return retval; - } -diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c -index d63da75..92a4bfd 100644 ---- a/fs/reiserfs/super.c -+++ b/fs/reiserfs/super.c -@@ -882,6 +882,9 @@ static int reiserfs_parse_options(struct - {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT}, - {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT}, - #endif -+#ifndef CONFIG_INOXID_NONE -+ {"tagxid",.setmask = 1 << REISERFS_TAGXID}, -+#endif - #ifdef CONFIG_REISERFS_FS_POSIX_ACL - {"acl",.setmask = 1 << REISERFS_POSIXACL}, - {"noacl",.clrmask = 1 << REISERFS_POSIXACL}, -@@ -1154,6 +1157,12 @@ static int reiserfs_remount(struct super - return -EINVAL; - } - -+ if ((mount_options & (1 << REISERFS_TAGXID)) && -+ !(s->s_flags & MS_TAGXID)) { -+ reiserfs_warning(s, "reiserfs: tagxid not permitted on remount."); -+ return -EINVAL; -+ } -+ - handle_attrs(s); - - /* Add options that are safe here */ -@@ -1729,6 +1738,10 @@ static int reiserfs_fill_super(struct su - goto error; - } - -+ /* map mount option tagxid */ -+ if (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_TAGXID)) -+ s->s_flags |= MS_TAGXID; -+ - rs = SB_DISK_SUPER_BLOCK(s); - /* Let's do basic sanity check to verify that underlying device is not - smaller than the filesystem. If the check fails then abort and scream, -diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c -index ffb79c4..b99819a 100644 ---- a/fs/reiserfs/xattr.c -+++ b/fs/reiserfs/xattr.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -824,7 +825,7 @@ int reiserfs_delete_xattrs(struct inode - if (dir->d_inode->i_nlink <= 2) { - root = get_xa_root(inode->i_sb); - reiserfs_write_lock_xattrs(inode->i_sb); -- err = vfs_rmdir(root->d_inode, dir); -+ err = vfs_rmdir(root->d_inode, dir, NULL); - reiserfs_write_unlock_xattrs(inode->i_sb); - dput(root); - } else { -diff --git a/fs/stat.c b/fs/stat.c -index 9948cc1..543f1b8 100644 ---- a/fs/stat.c -+++ b/fs/stat.c -@@ -27,6 +27,7 @@ void generic_fillattr(struct inode *inod - stat->nlink = inode->i_nlink; - stat->uid = inode->i_uid; - stat->gid = inode->i_gid; -+ stat->xid = inode->i_xid; - stat->rdev = inode->i_rdev; - stat->atime = inode->i_atime; - stat->mtime = inode->i_mtime; -diff --git a/fs/super.c b/fs/super.c -index e20b558..df4551c 100644 ---- a/fs/super.c -+++ b/fs/super.c -@@ -37,6 +37,8 @@ - #include /* for the emergency remount stuff */ - #include - #include -+#include -+#include - #include - - -@@ -803,7 +805,7 @@ struct vfsmount * - do_kern_mount(const char *fstype, int flags, const char *name, void *data) - { - struct file_system_type *type = get_fs_type(fstype); -- struct super_block *sb = ERR_PTR(-ENOMEM); -+ struct super_block *sb; - struct vfsmount *mnt; - int error; - char *secdata = NULL; -@@ -811,6 +813,12 @@ do_kern_mount(const char *fstype, int fl - if (!type) - return ERR_PTR(-ENODEV); - -+ sb = ERR_PTR(-EPERM); -+ if ((type->fs_flags & FS_BINARY_MOUNTDATA) && -+ !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_BINARY_MOUNT)) -+ goto out; -+ -+ sb = ERR_PTR(-ENOMEM); - mnt = alloc_vfsmnt(name); - if (!mnt) - goto out; -@@ -832,6 +840,13 @@ do_kern_mount(const char *fstype, int fl - sb = type->get_sb(type, flags, name, data); - if (IS_ERR(sb)) - goto out_free_secdata; -+ -+ error = -EPERM; -+ if (!capable(CAP_SYS_ADMIN) && !sb->s_bdev && -+ (sb->s_magic != PROC_SUPER_MAGIC) && -+ (sb->s_magic != DEVPTS_SUPER_MAGIC)) -+ goto out_sb; -+ - error = security_sb_kern_mount(sb, secdata); - if (error) - goto out_sb; -diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c -index f1117e8..ea01b08 100644 ---- a/fs/sysfs/mount.c -+++ b/fs/sysfs/mount.c -@@ -11,8 +11,6 @@ - - #include "sysfs.h" - --/* Random magic number */ --#define SYSFS_MAGIC 0x62656572 - - struct vfsmount *sysfs_mount; - struct super_block * sysfs_sb = NULL; -@@ -38,7 +36,7 @@ static int sysfs_fill_super(struct super - - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; -- sb->s_magic = SYSFS_MAGIC; -+ sb->s_magic = SYSFS_SUPER_MAGIC; - sb->s_op = &sysfs_ops; - sb->s_time_gran = 1; - sysfs_sb = sb; -diff --git a/fs/xattr.c b/fs/xattr.c -index 80eca7d..ad83a51 100644 ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - - -@@ -167,7 +168,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr); - */ - static long - setxattr(struct dentry *d, char __user *name, void __user *value, -- size_t size, int flags) -+ size_t size, int flags, struct vfsmount *mnt) - { - int error; - void *kvalue = NULL; -@@ -194,6 +195,9 @@ setxattr(struct dentry *d, char __user * - } - } - -+ if (MNT_IS_RDONLY(mnt)) -+ return -EROFS; -+ - error = vfs_setxattr(d, kname, kvalue, size, flags); - kfree(kvalue); - return error; -@@ -209,7 +213,7 @@ sys_setxattr(char __user *path, char __u - error = user_path_walk(path, &nd); - if (error) - return error; -- error = setxattr(nd.dentry, name, value, size, flags); -+ error = setxattr(nd.dentry, name, value, size, flags, nd.mnt); - path_release(&nd); - return error; - } -@@ -224,7 +228,7 @@ sys_lsetxattr(char __user *path, char __ - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = setxattr(nd.dentry, name, value, size, flags); -+ error = setxattr(nd.dentry, name, value, size, flags, nd.mnt); - path_release(&nd); - return error; - } -@@ -239,7 +243,7 @@ sys_fsetxattr(int fd, char __user *name, - f = fget(fd); - if (!f) - return error; -- error = setxattr(f->f_dentry, name, value, size, flags); -+ error = setxattr(f->f_dentry, name, value, size, flags, f->f_vfsmnt); - fput(f); - return error; - } -@@ -412,7 +416,7 @@ sys_flistxattr(int fd, char __user *list - * Extended attribute REMOVE operations - */ - static long --removexattr(struct dentry *d, char __user *name) -+removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt) - { - int error; - char kname[XATTR_NAME_MAX + 1]; -@@ -423,6 +427,9 @@ removexattr(struct dentry *d, char __use - if (error < 0) - return error; - -+ if (MNT_IS_RDONLY(mnt)) -+ return -EROFS; -+ - return vfs_removexattr(d, kname); - } - -@@ -435,7 +442,7 @@ sys_removexattr(char __user *path, char - error = user_path_walk(path, &nd); - if (error) - return error; -- error = removexattr(nd.dentry, name); -+ error = removexattr(nd.dentry, name, nd.mnt); - path_release(&nd); - return error; - } -@@ -449,7 +456,7 @@ sys_lremovexattr(char __user *path, char - error = user_path_walk_link(path, &nd); - if (error) - return error; -- error = removexattr(nd.dentry, name); -+ error = removexattr(nd.dentry, name, nd.mnt); - path_release(&nd); - return error; - } -@@ -463,7 +470,7 @@ sys_fremovexattr(int fd, char __user *na - f = fget(fd); - if (!f) - return error; -- error = removexattr(f->f_dentry, name); -+ error = removexattr(f->f_dentry, name, f->f_vfsmnt); - fput(f); - return error; - } -diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c -index 4db4779..bff7f6d 100644 ---- a/fs/xfs/linux-2.6/xfs_ioctl.c -+++ b/fs/xfs/linux-2.6/xfs_ioctl.c -@@ -1100,6 +1100,8 @@ xfs_ioc_fsgeometry( - #define LINUX_XFLAG_APPEND 0x00000020 /* writes to file may only append */ - #define LINUX_XFLAG_NODUMP 0x00000040 /* do not dump file */ - #define LINUX_XFLAG_NOATIME 0x00000080 /* do not update atime */ -+#define LINUX_XFLAG_BARRIER 0x04000000 /* chroot() barrier */ -+#define LINUX_XFLAG_IUNLINK 0x08000000 /* immutable unlink */ - - STATIC unsigned int - xfs_merge_ioc_xflags( -@@ -1140,6 +1142,10 @@ xfs_di2lxflags( - - if (di_flags & XFS_DIFLAG_IMMUTABLE) - flags |= LINUX_XFLAG_IMMUTABLE; -+ if (di_flags & XFS_DIFLAG_IUNLINK) -+ flags |= LINUX_XFLAG_IUNLINK; -+ if (di_flags & XFS_DIFLAG_BARRIER) -+ flags |= LINUX_XFLAG_BARRIER; - if (di_flags & XFS_DIFLAG_APPEND) - flags |= LINUX_XFLAG_APPEND; - if (di_flags & XFS_DIFLAG_SYNC) -diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c -index d7f6f2d..40fdc3e 100644 ---- a/fs/xfs/linux-2.6/xfs_iops.c -+++ b/fs/xfs/linux-2.6/xfs_iops.c -@@ -55,6 +55,7 @@ - #include - #include - #include -+#include - - /* - * Get a XFS inode from a given vnode. -@@ -410,6 +411,7 @@ linvfs_lookup( - d_add(dentry, NULL); - return NULL; - } -+ vx_propagate_xid(nd, LINVFS_GET_IP(cvp)); - - return d_splice_alias(LINVFS_GET_IP(cvp), dentry); - } -@@ -646,6 +648,41 @@ linvfs_getattr( - } - - STATIC int -+linvfs_sync_flags(struct inode *inode) -+{ -+ unsigned int oldflags, newflags; -+ vattr_t vattr; -+ int flags = 0; -+ int error; -+ vnode_t *vp = LINVFS_GET_VP(inode); -+ -+ memset(&vattr, 0, sizeof(vattr_t)); -+ -+ vattr.va_mask = XFS_AT_XFLAGS; -+ VOP_GETATTR(vp, &vattr, 0, NULL, error); -+ if (error) -+ return error; -+ oldflags = vattr.va_xflags; -+ newflags = oldflags & ~(XFS_XFLAG_IMMUTABLE | -+ XFS_XFLAG_IUNLINK | XFS_XFLAG_BARRIER); -+ -+ if (IS_IMMUTABLE(inode)) -+ newflags |= XFS_XFLAG_IMMUTABLE; -+ if (IS_IUNLINK(inode)) -+ newflags |= XFS_XFLAG_IUNLINK; -+ if (IS_BARRIER(inode)) -+ newflags |= XFS_XFLAG_BARRIER; -+ -+ if (oldflags ^ newflags) { -+ vattr.va_xflags = newflags; -+ vattr.va_mask |= XFS_AT_XFLAGS; -+ VOP_SETATTR(vp, &vattr, flags, NULL, error); -+ } -+ vn_revalidate(vp); -+ return error; -+} -+ -+STATIC int - linvfs_setattr( - struct dentry *dentry, - struct iattr *attr) -@@ -657,6 +694,10 @@ linvfs_setattr( - int flags = 0; - int error; - -+ error = inode_change_ok(inode, attr); -+ if (error) -+ return error; -+ - memset(&vattr, 0, sizeof(vattr_t)); - if (ia_valid & ATTR_UID) { - vattr.va_mask |= XFS_AT_UID; -@@ -666,6 +707,10 @@ linvfs_setattr( - vattr.va_mask |= XFS_AT_GID; - vattr.va_gid = attr->ia_gid; - } -+ if ((ia_valid & ATTR_XID) && IS_TAGXID(inode)) { -+ vattr.va_mask |= XFS_AT_XID; -+ vattr.va_xid = attr->ia_xid; -+ } - if (ia_valid & ATTR_SIZE) { - vattr.va_mask |= XFS_AT_SIZE; - vattr.va_size = attr->ia_size; -@@ -825,6 +870,7 @@ struct inode_operations linvfs_file_inod - .getxattr = linvfs_getxattr, - .listxattr = linvfs_listxattr, - .removexattr = linvfs_removexattr, -+ .sync_flags = linvfs_sync_flags, - }; - - struct inode_operations linvfs_dir_inode_operations = { -@@ -844,6 +890,7 @@ struct inode_operations linvfs_dir_inode - .getxattr = linvfs_getxattr, - .listxattr = linvfs_listxattr, - .removexattr = linvfs_removexattr, -+ .sync_flags = linvfs_sync_flags, - }; - - struct inode_operations linvfs_symlink_inode_operations = { -@@ -857,4 +904,5 @@ struct inode_operations linvfs_symlink_i - .getxattr = linvfs_getxattr, - .listxattr = linvfs_listxattr, - .removexattr = linvfs_removexattr, -+ .sync_flags = linvfs_sync_flags, - }; -diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h -index 67389b7..b554e6f 100644 ---- a/fs/xfs/linux-2.6/xfs_linux.h -+++ b/fs/xfs/linux-2.6/xfs_linux.h -@@ -133,6 +133,7 @@ BUFFER_FNS(PrivateStart, unwritten); - #define current_pid() (current->pid) - #define current_fsuid(cred) (current->fsuid) - #define current_fsgid(cred) (current->fsgid) -+#define current_fsxid(cred,vp) (vx_current_fsxid(LINVFS_GET_IP(vp)->i_sb)) - - #define NBPP PAGE_SIZE - #define DPPSHFT (PAGE_SHIFT - 9) -diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c -index f22e426..92d8ba6 100644 ---- a/fs/xfs/linux-2.6/xfs_super.c -+++ b/fs/xfs/linux-2.6/xfs_super.c -@@ -161,6 +161,7 @@ xfs_revalidate_inode( - inode->i_nlink = ip->i_d.di_nlink; - inode->i_uid = ip->i_d.di_uid; - inode->i_gid = ip->i_d.di_gid; -+ inode->i_xid = ip->i_d.di_xid; - - switch (inode->i_mode & S_IFMT) { - case S_IFBLK: -@@ -189,6 +190,14 @@ xfs_revalidate_inode( - inode->i_flags |= S_IMMUTABLE; - else - inode->i_flags &= ~S_IMMUTABLE; -+ if (ip->i_d.di_flags & XFS_DIFLAG_IUNLINK) -+ inode->i_flags |= S_IUNLINK; -+ else -+ inode->i_flags &= ~S_IUNLINK; -+ if (ip->i_d.di_flags & XFS_DIFLAG_BARRIER) -+ inode->i_flags |= S_BARRIER; -+ else -+ inode->i_flags &= ~S_BARRIER; - if (ip->i_d.di_flags & XFS_DIFLAG_APPEND) - inode->i_flags |= S_APPEND; - else -@@ -729,6 +738,12 @@ linvfs_remount( - int error; - - VFS_PARSEARGS(vfsp, options, args, 1, error); -+ if ((args->flags2 & XFSMNT2_TAGXID) && -+ !(sb->s_flags & MS_TAGXID)) { -+ printk("XFS: %s: tagxid not permitted on remount.\n", -+ sb->s_id); -+ error = EINVAL; -+ } - if (!error) - VFS_MNTUPDATE(vfsp, flags, args, error); - kmem_free(args, sizeof(*args)); -diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c -index a025649..6c39207 100644 ---- a/fs/xfs/linux-2.6/xfs_sysctl.c -+++ b/fs/xfs/linux-2.6/xfs_sysctl.c -@@ -58,74 +58,74 @@ xfs_stats_clear_proc_handler( - STATIC ctl_table xfs_table[] = { - {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.restrict_chown.min, &xfs_params.restrict_chown.max}, - - {XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.sgid_inherit.min, &xfs_params.sgid_inherit.max}, - - {XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.symlink_mode.min, &xfs_params.symlink_mode.max}, - - {XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.panic_mask.min, &xfs_params.panic_mask.max}, - - {XFS_ERRLEVEL, "error_level", &xfs_params.error_level.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.error_level.min, &xfs_params.error_level.max}, - - {XFS_SYNCD_TIMER, "xfssyncd_centisecs", &xfs_params.syncd_timer.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.syncd_timer.min, &xfs_params.syncd_timer.max}, - - {XFS_INHERIT_SYNC, "inherit_sync", &xfs_params.inherit_sync.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.inherit_sync.min, &xfs_params.inherit_sync.max}, - - {XFS_INHERIT_NODUMP, "inherit_nodump", &xfs_params.inherit_nodump.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.inherit_nodump.min, &xfs_params.inherit_nodump.max}, - - {XFS_INHERIT_NOATIME, "inherit_noatime", &xfs_params.inherit_noatim.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max}, - - {XFS_BUF_TIMER, "xfsbufd_centisecs", &xfs_params.xfs_buf_timer.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.xfs_buf_timer.min, &xfs_params.xfs_buf_timer.max}, - - {XFS_BUF_AGE, "age_buffer_centisecs", &xfs_params.xfs_buf_age.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.xfs_buf_age.min, &xfs_params.xfs_buf_age.max}, - - {XFS_INHERIT_NOSYM, "inherit_nosymlinks", &xfs_params.inherit_nosym.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.inherit_nosym.min, &xfs_params.inherit_nosym.max}, - - {XFS_ROTORSTEP, "rotorstep", &xfs_params.rotorstep.val, - sizeof(int), 0644, NULL, &proc_dointvec_minmax, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.rotorstep.min, &xfs_params.rotorstep.max}, - - /* please keep this the last entry */ - #ifdef CONFIG_PROC_FS - {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, - sizeof(int), 0644, NULL, &xfs_stats_clear_proc_handler, -- &sysctl_intvec, NULL, -+ NULL, &sysctl_intvec, NULL, - &xfs_params.stats_clear.min, &xfs_params.stats_clear.max}, - #endif /* CONFIG_PROC_FS */ - -diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c -index 260dd84..d973914 100644 ---- a/fs/xfs/linux-2.6/xfs_vnode.c -+++ b/fs/xfs/linux-2.6/xfs_vnode.c -@@ -103,6 +103,7 @@ vn_revalidate_core( - inode->i_nlink = vap->va_nlink; - inode->i_uid = vap->va_uid; - inode->i_gid = vap->va_gid; -+ inode->i_xid = vap->va_xid; - inode->i_blocks = vap->va_nblocks; - inode->i_mtime = vap->va_mtime; - inode->i_ctime = vap->va_ctime; -@@ -111,6 +112,14 @@ vn_revalidate_core( - inode->i_flags |= S_IMMUTABLE; - else - inode->i_flags &= ~S_IMMUTABLE; -+ if (vap->va_xflags & XFS_XFLAG_IUNLINK) -+ inode->i_flags |= S_IUNLINK; -+ else -+ inode->i_flags &= ~S_IUNLINK; -+ if (vap->va_xflags & XFS_XFLAG_BARRIER) -+ inode->i_flags |= S_BARRIER; -+ else -+ inode->i_flags &= ~S_BARRIER; - if (vap->va_xflags & XFS_XFLAG_APPEND) - inode->i_flags |= S_APPEND; - else -diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h -index 0fe2419..696c62a 100644 ---- a/fs/xfs/linux-2.6/xfs_vnode.h -+++ b/fs/xfs/linux-2.6/xfs_vnode.h -@@ -386,6 +386,7 @@ typedef struct vattr { - xfs_nlink_t va_nlink; /* number of references to file */ - uid_t va_uid; /* owner user id */ - gid_t va_gid; /* owner group id */ -+ xid_t va_xid; /* owner group id */ - xfs_ino_t va_nodeid; /* file id */ - xfs_off_t va_size; /* file size in bytes */ - u_long va_blocksize; /* blocksize preferred for i/o */ -@@ -434,13 +435,15 @@ typedef struct vattr { - #define XFS_AT_PROJID 0x04000000 - #define XFS_AT_SIZE_NOPERM 0x08000000 - #define XFS_AT_GENCOUNT 0x10000000 -+#define XFS_AT_XID 0x20000000 - - #define XFS_AT_ALL (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\ - XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\ - XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\ - XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\ - XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\ -- XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT) -+ XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT\ -+ XFS_AT_XID) - - #define XFS_AT_STAT (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\ - XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\ -diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c -index 6768843..b3ec736 100644 ---- a/fs/xfs/quota/xfs_qm_syscalls.c -+++ b/fs/xfs/quota/xfs_qm_syscalls.c -@@ -215,7 +215,7 @@ xfs_qm_scall_quotaoff( - xfs_qoff_logitem_t *qoffstart; - int nculprits; - -- if (!force && !capable(CAP_SYS_ADMIN)) -+ if (!force && !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) - return XFS_ERROR(EPERM); - /* - * No file system can have quotas enabled on disk but not in core. -@@ -384,7 +384,7 @@ xfs_qm_scall_trunc_qfiles( - int error; - xfs_inode_t *qip; - -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) - return XFS_ERROR(EPERM); - error = 0; - if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) { -@@ -429,7 +429,7 @@ xfs_qm_scall_quotaon( - uint accflags; - __int64_t sbflags; - -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) - return XFS_ERROR(EPERM); - - flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); -@@ -600,7 +600,7 @@ xfs_qm_scall_setqlim( - int error; - xfs_qcnt_t hard, soft; - -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) - return XFS_ERROR(EPERM); - - if ((newlim->d_fieldmask & -diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h -index f57cc9a..6203fb4 100644 ---- a/fs/xfs/xfs_clnt.h -+++ b/fs/xfs/xfs_clnt.h -@@ -100,5 +100,7 @@ struct xfs_mount_args { - */ - #define XFSMNT2_COMPAT_IOSIZE 0x00000001 /* don't report large preferred - * I/O size in stat(2) */ -+#define XFSMNT2_TAGXID 0x80000000 /* context xid tagging */ -+ - - #endif /* __XFS_CLNT_H__ */ -diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h -index 79d0d9e..a70e0b3 100644 ---- a/fs/xfs/xfs_dinode.h -+++ b/fs/xfs/xfs_dinode.h -@@ -53,7 +53,8 @@ typedef struct xfs_dinode_core - __uint32_t di_gid; /* owner's group id */ - __uint32_t di_nlink; /* number of links to file */ - __uint16_t di_projid; /* owner's project id */ -- __uint8_t di_pad[8]; /* unused, zeroed space */ -+ __uint16_t di_xid; /* vserver context id */ -+ __uint8_t di_pad[6]; /* unused, zeroed space */ - __uint16_t di_flushiter; /* incremented on flush */ - xfs_timestamp_t di_atime; /* time last accessed */ - xfs_timestamp_t di_mtime; /* time last modified */ -@@ -257,6 +258,9 @@ typedef enum xfs_dinode_fmt - #define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ - #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ - #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ -+#define XFS_DIFLAG_BARRIER_BIT 13 /* chroot() barrier */ -+#define XFS_DIFLAG_IUNLINK_BIT 14 /* immutable unlink */ -+ - #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) - #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) - #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) -@@ -270,12 +274,14 @@ typedef enum xfs_dinode_fmt - #define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT) - #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) - #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) -+#define XFS_DIFLAG_BARRIER (1 << XFS_DIFLAG_BARRIER_BIT) -+#define XFS_DIFLAG_IUNLINK (1 << XFS_DIFLAG_IUNLINK_BIT) - - #define XFS_DIFLAG_ANY \ - (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ - XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ - XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ - XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ -- XFS_DIFLAG_EXTSZINHERIT) -+ XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_BARRIER | XFS_DIFLAG_IUNLINK) - - #endif /* __XFS_DINODE_H__ */ -diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h -index 14010f1..5354048 100644 ---- a/fs/xfs/xfs_fs.h -+++ b/fs/xfs/xfs_fs.h -@@ -67,6 +67,8 @@ struct fsxattr { - #define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ - #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ - #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ -+#define XFS_XFLAG_BARRIER 0x00004000 /* chroot() barrier */ -+#define XFS_XFLAG_IUNLINK 0x00008000 /* immutable unlink */ - #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ - - /* -@@ -295,7 +297,8 @@ typedef struct xfs_bstat { - __s32 bs_extents; /* number of extents */ - __u32 bs_gen; /* generation count */ - __u16 bs_projid; /* project id */ -- unsigned char bs_pad[14]; /* pad space, unused */ -+ __u16 bs_xid; /* context id */ -+ unsigned char bs_pad[12]; /* pad space, unused */ - __u32 bs_dmevmask; /* DMIG event mask */ - __u16 bs_dmstate; /* DMIG state info */ - __u16 bs_aextents; /* attribute number of extents */ -diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c -index 1d7f5a7..6a4089a 100644 ---- a/fs/xfs/xfs_inode.c -+++ b/fs/xfs/xfs_inode.c -@@ -52,6 +52,7 @@ - #include "xfs_mac.h" - #include "xfs_acl.h" - -+#include - - kmem_zone_t *xfs_ifork_zone; - kmem_zone_t *xfs_inode_zone; -@@ -734,20 +735,35 @@ xfs_xlate_dinode_core( - xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf; - xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip; - xfs_arch_t arch = ARCH_CONVERT; -+ uint32_t uid = 0, gid = 0; -+ uint16_t xid = 0; - - ASSERT(dir); - -+ if (dir < 0) { -+ xid = mem_core->di_xid; -+ /* FIXME: supposed to use superblock flag */ -+ uid = XIDINO_UID(1, mem_core->di_uid, xid); -+ gid = XIDINO_GID(1, mem_core->di_gid, xid); -+ xid = XIDINO_XID(1, xid); -+ } -+ - INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch); - INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch); - INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch); - INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch); - INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch); -- INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch); -- INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch); -+ INT_XLATE(buf_core->di_uid, uid, dir, arch); -+ INT_XLATE(buf_core->di_gid, gid, dir, arch); -+ INT_XLATE(buf_core->di_xid, xid, dir, arch); - INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch); - INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch); - - if (dir > 0) { -+ /* FIXME: supposed to use superblock flag */ -+ mem_core->di_uid = INOXID_UID(1, uid, gid); -+ mem_core->di_gid = INOXID_GID(1, uid, gid); -+ mem_core->di_xid = INOXID_XID(1, uid, gid, xid); - memcpy(mem_core->di_pad, buf_core->di_pad, - sizeof(buf_core->di_pad)); - } else { -@@ -796,6 +812,10 @@ _xfs_dic2xflags( - flags |= XFS_XFLAG_PREALLOC; - if (di_flags & XFS_DIFLAG_IMMUTABLE) - flags |= XFS_XFLAG_IMMUTABLE; -+ if (di_flags & XFS_DIFLAG_IUNLINK) -+ flags |= XFS_XFLAG_IUNLINK; -+ if (di_flags & XFS_DIFLAG_BARRIER) -+ flags |= XFS_XFLAG_BARRIER; - if (di_flags & XFS_DIFLAG_APPEND) - flags |= XFS_XFLAG_APPEND; - if (di_flags & XFS_DIFLAG_SYNC) -@@ -1125,6 +1145,7 @@ xfs_ialloc( - ASSERT(ip->i_d.di_nlink == nlink); - ip->i_d.di_uid = current_fsuid(cr); - ip->i_d.di_gid = current_fsgid(cr); -+ ip->i_d.di_xid = current_fsxid(cr, vp); - ip->i_d.di_projid = prid; - memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); - -diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c -index c59450e..d2a21c4 100644 ---- a/fs/xfs/xfs_itable.c -+++ b/fs/xfs/xfs_itable.c -@@ -85,6 +85,7 @@ xfs_bulkstat_one_iget( - buf->bs_mode = dic->di_mode; - buf->bs_uid = dic->di_uid; - buf->bs_gid = dic->di_gid; -+ buf->bs_xid = dic->di_xid; - buf->bs_size = dic->di_size; - vn_atime_to_bstime(vp, &buf->bs_atime); - buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; -@@ -159,6 +160,7 @@ xfs_bulkstat_one_dinode( - buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT); - buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT); - buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT); -+ buf->bs_xid = INT_GET(dic->di_xid, ARCH_CONVERT); - buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT); - buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT); - buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT); -diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h -index cd3cf96..74eec62 100644 ---- a/fs/xfs/xfs_mount.h -+++ b/fs/xfs/xfs_mount.h -@@ -412,6 +412,7 @@ typedef struct xfs_mount { - #define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred - * I/O size in stat() */ - -+#define XFS_MOUNT_TAGXID (1ULL << 31) /* context xid tagging */ - - /* - * Default minimum read and write sizes. -diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c -index b6ad370..09665b7 100644 ---- a/fs/xfs/xfs_vfsops.c -+++ b/fs/xfs/xfs_vfsops.c -@@ -296,6 +296,8 @@ xfs_start_flags( - - if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE) - mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; -+ if (ap->flags2 & XFSMNT2_TAGXID) -+ mp->m_flags |= XFS_MOUNT_TAGXID; - - /* - * no recovery flag requires a read-only mount -@@ -390,6 +392,8 @@ xfs_finish_flags( - return XFS_ERROR(EINVAL); - } - -+ if (ap->flags2 & XFSMNT2_TAGXID) -+ vfs->vfs_super->s_flags |= MS_TAGXID; - return 0; - } - -@@ -1653,6 +1657,7 @@ xfs_vget( - * in stat(). */ - #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ - #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ -+#define MNTOPT_TAGXID "tagxid" /* context xid tagging for inodes */ - - STATIC unsigned long - suffix_strtoul(const char *cp, char **endp, unsigned int base) -@@ -1829,6 +1834,10 @@ xfs_parseargs( - args->flags |= XFSMNT_ATTR2; - } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { - args->flags &= ~XFSMNT_ATTR2; -+#ifndef CONFIG_INOXID_NONE -+ } else if (!strcmp(this_char, MNTOPT_TAGXID)) { -+ args->flags2 |= XFSMNT2_TAGXID; -+#endif - } else if (!strcmp(this_char, "osyncisdsync")) { - /* no-op, this is now the default */ - printk("XFS: osyncisdsync is now the default, option is deprecated.\n"); -diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c -index eaab355..aa90340 100644 ---- a/fs/xfs/xfs_vnodeops.c -+++ b/fs/xfs/xfs_vnodeops.c -@@ -154,6 +154,7 @@ xfs_getattr( - vap->va_mode = ip->i_d.di_mode; - vap->va_uid = ip->i_d.di_uid; - vap->va_gid = ip->i_d.di_gid; -+ vap->va_xid = ip->i_d.di_xid; - vap->va_projid = ip->i_d.di_projid; - - /* -@@ -254,6 +255,7 @@ xfs_setattr( - uint commit_flags=0; - uid_t uid=0, iuid=0; - gid_t gid=0, igid=0; -+ xid_t xid=0, ixid=0; - int timeflags = 0; - vnode_t *vp; - xfs_prid_t projid=0, iprojid=0; -@@ -310,6 +312,7 @@ xfs_setattr( - (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) { - uint qflags = 0; - -+ /* FIXME: handle xid? */ - if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) { - uid = vap->va_uid; - qflags |= XFS_QMOPT_UQUOTA; -@@ -390,6 +393,8 @@ xfs_setattr( - if (mask & - (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID| - XFS_AT_GID|XFS_AT_PROJID)) { -+ /* FIXME: handle xid? */ -+ - /* - * CAP_FOWNER overrides the following restrictions: - * -@@ -438,7 +443,7 @@ xfs_setattr( - * and can change the group id only to a group of which he - * or she is a member. - */ -- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) { -+ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_XID|XFS_AT_PROJID)) { - /* - * These IDs could have changed since we last looked at them. - * But, we're assured that if the ownership did change -@@ -446,10 +451,12 @@ xfs_setattr( - * would have changed also. - */ - iuid = ip->i_d.di_uid; -- iprojid = ip->i_d.di_projid; - igid = ip->i_d.di_gid; -- gid = (mask & XFS_AT_GID) ? vap->va_gid : igid; -+ ixid = ip->i_d.di_xid; -+ iprojid = ip->i_d.di_projid; - uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid; -+ gid = (mask & XFS_AT_GID) ? vap->va_gid : igid; -+ xid = (mask & XFS_AT_XID) ? vap->va_xid : ixid; - projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid : - iprojid; - -@@ -477,6 +484,7 @@ xfs_setattr( - if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || - (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) || - (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { -+ /* FIXME: handle xid? */ - ASSERT(tp); - code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, - capable(CAP_FOWNER) ? -@@ -693,7 +701,7 @@ xfs_setattr( - * and can change the group id only to a group of which he - * or she is a member. - */ -- if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) { -+ if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_XID|XFS_AT_PROJID)) { - /* - * CAP_FSETID overrides the following restrictions: - * -@@ -709,6 +717,12 @@ xfs_setattr( - * Change the ownerships and register quota modifications - * in the transaction. - */ -+ if (ixid != xid) { -+ if (XFS_IS_GQUOTA_ON(mp)) { -+ /* FIXME: handle xid quota? */ -+ } -+ ip->i_d.di_xid = xid; -+ } - if (iuid != uid) { - if (XFS_IS_UQUOTA_ON(mp)) { - ASSERT(mask & XFS_AT_UID); -@@ -789,6 +803,10 @@ xfs_setattr( - di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC); - if (vap->va_xflags & XFS_XFLAG_IMMUTABLE) - di_flags |= XFS_DIFLAG_IMMUTABLE; -+ if (vap->va_xflags & XFS_XFLAG_IUNLINK) -+ di_flags |= XFS_DIFLAG_IUNLINK; -+ if (vap->va_xflags & XFS_XFLAG_BARRIER) -+ di_flags |= XFS_DIFLAG_BARRIER; - if (vap->va_xflags & XFS_XFLAG_APPEND) - di_flags |= XFS_DIFLAG_APPEND; - if (vap->va_xflags & XFS_XFLAG_SYNC) -diff --git a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h -index f49bfb7..1a17998 100644 ---- a/include/asm-arm/tlb.h -+++ b/include/asm-arm/tlb.h -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - /* - * TLB handling. This allows us to remove pages from the page -diff --git a/include/asm-arm26/tlb.h b/include/asm-arm26/tlb.h -index 08ddd85..d730584 100644 ---- a/include/asm-arm26/tlb.h -+++ b/include/asm-arm26/tlb.h -@@ -3,6 +3,7 @@ - - #include - #include -+#include - - /* - * TLB handling. This allows us to remove pages from the page -diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h -index be4c2fb..d296fb5 100644 ---- a/include/asm-arm26/unistd.h -+++ b/include/asm-arm26/unistd.h -@@ -304,6 +304,8 @@ - #define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279) - #define __NR_waitid (__NR_SYSCALL_BASE+280) - -+#define __NR_vserver (__NR_SYSCALL_BASE+313) -+ - /* - * The following SWIs are ARM private. FIXME - make appropriate for arm26 - */ -diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h -index cdd4145..8dbedfa 100644 ---- a/include/asm-generic/tlb.h -+++ b/include/asm-generic/tlb.h -@@ -15,6 +15,7 @@ - - #include - #include -+#include - #include - #include - -diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h -index 4153d80..2962b84 100644 ---- a/include/asm-i386/elf.h -+++ b/include/asm-i386/elf.h -@@ -71,7 +71,7 @@ typedef struct user_fxsr_struct elf_fpxr - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - --#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) -+#define ELF_ET_DYN_BASE ((TASK_UNMAPPED_BASE) * 2) - - /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is - now struct_user_regs, they are different) */ -diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h -index 997ca5d..53cfb1c 100644 ---- a/include/asm-i386/page.h -+++ b/include/asm-i386/page.h -@@ -109,19 +109,15 @@ extern int page_is_ram(unsigned long pag - - #endif /* __ASSEMBLY__ */ - --#ifdef __ASSEMBLY__ - #define __PAGE_OFFSET CONFIG_PAGE_OFFSET - #define __PHYSICAL_START CONFIG_PHYSICAL_START --#else --#define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET) --#define __PHYSICAL_START ((unsigned long)CONFIG_PHYSICAL_START) --#endif - #define __KERNEL_START (__PAGE_OFFSET + __PHYSICAL_START) -- -+#define __MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) - - #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) -+#define PHYSICAL_START ((unsigned long)__PHYSICAL_START) - #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) --#define MAXMEM (-__PAGE_OFFSET-__VMALLOC_RESERVE) -+#define MAXMEM ((unsigned long)__MAXMEM) - #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) - #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) - #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) -diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h -index feca5d9..bb5f709 100644 ---- a/include/asm-i386/processor.h -+++ b/include/asm-i386/processor.h -@@ -316,9 +316,10 @@ extern unsigned int mca_pentium_flag; - extern int bootloader_type; - - /* -- * User space process size: 3GB (default). -+ * User space process size: (3GB default). - */ --#define TASK_SIZE (PAGE_OFFSET) -+#define __TASK_SIZE (__PAGE_OFFSET) -+#define TASK_SIZE ((unsigned long)__TASK_SIZE) - - /* This decides where the kernel will search for a free chunk of vm - * space during mmap's. -diff --git a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h -index 834370b..e2c6e18 100644 ---- a/include/asm-ia64/tlb.h -+++ b/include/asm-ia64/tlb.h -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h -index 3555699..0333931 100644 ---- a/include/asm-powerpc/unistd.h -+++ b/include/asm-powerpc/unistd.h -@@ -275,7 +275,7 @@ - #endif - #define __NR_rtas 255 - #define __NR_sys_debug_setcontext 256 --/* Number 257 is reserved for vserver */ -+#define __NR_vserver 257 - /* 258 currently unused */ - #define __NR_mbind 259 - #define __NR_get_mempolicy 260 -diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h -index 657d582..c9371e9 100644 ---- a/include/asm-s390/unistd.h -+++ b/include/asm-s390/unistd.h -@@ -255,7 +255,7 @@ - #define __NR_clock_gettime (__NR_timer_create+6) - #define __NR_clock_getres (__NR_timer_create+7) - #define __NR_clock_nanosleep (__NR_timer_create+8) --/* Number 263 is reserved for vserver */ -+#define __NR_vserver 263 - #define __NR_fadvise64_64 264 - #define __NR_statfs64 265 - #define __NR_fstatfs64 266 -diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h -index 64ec640..12ef6c0 100644 ---- a/include/asm-sparc/unistd.h -+++ b/include/asm-sparc/unistd.h -@@ -283,7 +283,7 @@ - #define __NR_timer_getoverrun 264 - #define __NR_timer_delete 265 - #define __NR_timer_create 266 --/* #define __NR_vserver 267 Reserved for VSERVER */ -+#define __NR_vserver 267 - #define __NR_io_setup 268 - #define __NR_io_destroy 269 - #define __NR_io_submit 270 -diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h -index 61c0188..41a5d1c 100644 ---- a/include/asm-sparc64/tlb.h -+++ b/include/asm-sparc64/tlb.h -@@ -3,6 +3,7 @@ - - #include - #include -+#include - #include - #include - #include -diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h -index a284986..13f7e2f 100644 ---- a/include/asm-sparc64/unistd.h -+++ b/include/asm-sparc64/unistd.h -@@ -285,7 +285,7 @@ - #define __NR_timer_getoverrun 264 - #define __NR_timer_delete 265 - #define __NR_timer_create 266 --/* #define __NR_vserver 267 Reserved for VSERVER */ -+#define __NR_vserver 267 - #define __NR_io_setup 268 - #define __NR_io_destroy 269 - #define __NR_io_submit 270 -diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h -index da0341c..732a094 100644 ---- a/include/asm-x86_64/unistd.h -+++ b/include/asm-x86_64/unistd.h -@@ -532,7 +532,7 @@ __SYSCALL(__NR_tgkill, sys_tgkill) - #define __NR_utimes 235 - __SYSCALL(__NR_utimes, sys_utimes) - #define __NR_vserver 236 --__SYSCALL(__NR_vserver, sys_ni_syscall) -+__SYSCALL(__NR_vserver, sys_vserver) - #define __NR_mbind 237 - __SYSCALL(__NR_mbind, sys_mbind) - #define __NR_set_mempolicy 238 -diff --git a/include/linux/capability.h b/include/linux/capability.h -index 5a23ce7..34918bf 100644 ---- a/include/linux/capability.h -+++ b/include/linux/capability.h -@@ -235,6 +235,7 @@ typedef __u32 kernel_cap_t; - arbitrary SCSI commands */ - /* Allow setting encryption key on loopback filesystem */ - /* Allow setting zone reclaim policy */ -+/* Allow the selection of a security context */ - - #define CAP_SYS_ADMIN 21 - -@@ -288,6 +289,11 @@ typedef __u32 kernel_cap_t; - - #define CAP_AUDIT_CONTROL 30 - -+/* Allow context manipulations */ -+/* Allow changing context info on files */ -+ -+#define CAP_CONTEXT 31 -+ - #ifdef __KERNEL__ - /* - * Bounding set -diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h -index b672ddc..3ca2799 100644 ---- a/include/linux/devpts_fs.h -+++ b/include/linux/devpts_fs.h -@@ -30,5 +30,7 @@ static inline void devpts_pty_kill(int n - - #endif - -+#define DEVPTS_SUPER_MAGIC 0x00001cd1 -+ - - #endif /* _LINUX_DEVPTS_FS_H */ -diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h -index f7bd1c7..d953a90 100644 ---- a/include/linux/ext2_fs.h -+++ b/include/linux/ext2_fs.h -@@ -192,10 +192,17 @@ struct ext2_group_desc - #define EXT2_NOTAIL_FL 0x00008000 /* file tail should not be merged */ - #define EXT2_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ - #define EXT2_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ -+#define EXT2_BARRIER_FL 0x04000000 /* Barrier for chroot() */ -+#define EXT2_IUNLINK_FL 0x08000000 /* Immutable unlink */ - #define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ - -+#ifdef CONFIG_VSERVER_LEGACY -+#define EXT2_FL_USER_VISIBLE 0x0803DFFF /* User visible flags */ -+#define EXT2_FL_USER_MODIFIABLE 0x080380FF /* User modifiable flags */ -+#else - #define EXT2_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ - #define EXT2_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ -+#endif - - /* - * ioctl commands -@@ -240,7 +247,7 @@ struct ext2_inode { - struct { - __u8 l_i_frag; /* Fragment number */ - __u8 l_i_fsize; /* Fragment size */ -- __u16 i_pad1; -+ __u16 l_i_xid; /* LRU Context */ - __le16 l_i_uid_high; /* these 2 fields */ - __le16 l_i_gid_high; /* were reserved2[0] */ - __u32 l_i_reserved2; -@@ -272,6 +279,7 @@ struct ext2_inode { - #define i_gid_low i_gid - #define i_uid_high osd2.linux2.l_i_uid_high - #define i_gid_high osd2.linux2.l_i_gid_high -+#define i_raw_xid osd2.linux2.l_i_xid - #define i_reserved2 osd2.linux2.l_i_reserved2 - #endif - -@@ -313,8 +321,9 @@ struct ext2_inode { - #define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */ - #define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */ - #define EXT2_MOUNT_XIP 0x010000 /* Execute in place */ --#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */ --#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */ -+#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */ -+#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */ -+#define EXT2_MOUNT_TAGXID (1<<24) /* Enable Context Tags */ - - - #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt -diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h -index c0272d7..af52318 100644 ---- a/include/linux/ext3_fs.h -+++ b/include/linux/ext3_fs.h -@@ -185,10 +185,20 @@ struct ext3_group_desc - #define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */ - #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ - #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ -+#define EXT3_BARRIER_FL 0x04000000 /* Barrier for chroot() */ -+#define EXT3_IUNLINK_FL 0x08000000 /* Immutable unlink */ - #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ - -+#ifdef CONFIG_VSERVER_LEGACY -+#define EXT3_FL_USER_VISIBLE 0x0803DFFF /* User visible flags */ -+#define EXT3_FL_USER_MODIFIABLE 0x080380FF /* User modifiable flags */ -+#else - #define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ - #define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ -+#endif -+#ifdef CONFIG_VSERVER_LEGACY -+#define EXT3_IOC_SETXID FIOC_SETXIDJ -+#endif - - /* - * Inode dynamic state flags -@@ -287,7 +297,7 @@ struct ext3_inode { - struct { - __u8 l_i_frag; /* Fragment number */ - __u8 l_i_fsize; /* Fragment size */ -- __u16 i_pad1; -+ __u16 l_i_xid; /* LRU Context */ - __le16 l_i_uid_high; /* these 2 fields */ - __le16 l_i_gid_high; /* were reserved2[0] */ - __u32 l_i_reserved2; -@@ -321,6 +331,7 @@ struct ext3_inode { - #define i_gid_low i_gid - #define i_uid_high osd2.linux2.l_i_uid_high - #define i_gid_high osd2.linux2.l_i_gid_high -+#define i_raw_xid osd2.linux2.l_i_xid - #define i_reserved2 osd2.linux2.l_i_reserved2 - - #elif defined(__GNU__) -@@ -375,6 +386,7 @@ struct ext3_inode { - #define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ - #define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ - #define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ -+#define EXT3_MOUNT_TAGXID (1<<24) /* Enable Context Tags */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -775,6 +787,7 @@ extern unsigned long ext3_count_free (st - extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int); - extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); - extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); -+extern int ext3_sync_flags(struct inode *inode); - - extern void ext3_read_inode (struct inode *); - extern int ext3_write_inode (struct inode *, int); -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 128d008..0e48413 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -109,6 +109,8 @@ extern int dir_notify_enable; - #define MS_PRIVATE (1<<18) /* change to private */ - #define MS_SLAVE (1<<19) /* change to slave */ - #define MS_SHARED (1<<20) /* change to shared */ -+#define MS_TAGXID (1<<24) /* tag inodes with context information */ -+#define MS_XID (1<<25) /* use specific xid for this mount */ - #define MS_ACTIVE (1<<30) - #define MS_NOUSER (1<<31) - -@@ -135,6 +137,8 @@ extern int dir_notify_enable; - #define S_NOCMTIME 128 /* Do not update file c/mtime */ - #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */ - #define S_PRIVATE 512 /* Inode is fs-internal */ -+#define S_BARRIER 1024 /* Barrier for chroot() */ -+#define S_IUNLINK 2048 /* Immutable unlink */ - - /* - * Note that nosuid etc flags are inode-specific: setting some file-system -@@ -151,18 +155,22 @@ extern int dir_notify_enable; - */ - #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg)) - --#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY) -+#define IS_RDONLY(inode) __IS_FLG(inode, MS_RDONLY) - #define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \ - ((inode)->i_flags & S_SYNC)) - #define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \ - ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) - #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) -+#define IS_TAGXID(inode) __IS_FLG(inode, MS_TAGXID) - - #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) - #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) - #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) -+#define IS_IUNLINK(inode) ((inode)->i_flags & S_IUNLINK) -+#define IS_IXORUNLINK(inode) ((IS_IUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode)) - #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) - -+#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_flags & S_BARRIER)) - #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) - #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) - #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) -@@ -265,6 +273,7 @@ typedef void (dio_iodone_t)(struct kiocb - #define ATTR_KILL_SUID 2048 - #define ATTR_KILL_SGID 4096 - #define ATTR_FILE 8192 -+#define ATTR_XID 16384 - - /* - * This is the Inode Attributes structure, used for notify_change(). It -@@ -280,6 +289,7 @@ struct iattr { - umode_t ia_mode; - uid_t ia_uid; - gid_t ia_gid; -+ xid_t ia_xid; - loff_t ia_size; - struct timespec ia_atime; - struct timespec ia_mtime; -@@ -293,6 +303,9 @@ struct iattr { - struct file *ia_file; - }; - -+#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */ -+#define ATTR_FLAG_IUNLINK 1024 /* Immutable unlink */ -+ - /* - * Includes for diskquotas. - */ -@@ -471,6 +484,7 @@ struct inode { - unsigned int i_nlink; - uid_t i_uid; - gid_t i_gid; -+ xid_t i_xid; - dev_t i_rdev; - loff_t i_size; - struct timespec i_atime; -@@ -633,6 +647,7 @@ struct file { - struct fown_struct f_owner; - unsigned int f_uid, f_gid; - struct file_ra_state f_ra; -+ xid_t f_xid; - - unsigned long f_version; - void *f_security; -@@ -712,6 +727,7 @@ struct file_lock { - unsigned char fl_type; - loff_t fl_start; - loff_t fl_end; -+ xid_t fl_xid; - - struct fasync_struct * fl_fasync; /* for lease break notifications */ - unsigned long fl_break_time; /* for nonblocking lease breaks */ -@@ -904,12 +920,12 @@ static inline void unlock_super(struct s - */ - extern int vfs_permission(struct nameidata *, int); - extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); --extern int vfs_mkdir(struct inode *, struct dentry *, int); --extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); --extern int vfs_symlink(struct inode *, struct dentry *, const char *, int); --extern int vfs_link(struct dentry *, struct inode *, struct dentry *); --extern int vfs_rmdir(struct inode *, struct dentry *); --extern int vfs_unlink(struct inode *, struct dentry *); -+extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *); -+extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *); -+extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *); -+extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *); -+extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *); -+extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *); - extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); - - /* -@@ -1049,6 +1065,7 @@ struct inode_operations { - ssize_t (*listxattr) (struct dentry *, char *, size_t); - int (*removexattr) (struct dentry *, const char *); - void (*truncate_range)(struct inode *, loff_t, loff_t); -+ int (*sync_flags) (struct inode *); - }; - - struct seq_file; -@@ -1695,6 +1712,7 @@ extern int dcache_dir_open(struct inode - extern int dcache_dir_close(struct inode *, struct file *); - extern loff_t dcache_dir_lseek(struct file *, loff_t, int); - extern int dcache_readdir(struct file *, void *, filldir_t); -+extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *)); - extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); - extern int simple_statfs(struct super_block *, struct kstatfs *); - extern int simple_link(struct dentry *, struct inode *, struct dentry *); -diff --git a/include/linux/init_task.h b/include/linux/init_task.h -index dcfd2ec..653f9e1 100644 ---- a/include/linux/init_task.h -+++ b/include/linux/init_task.h -@@ -121,6 +121,10 @@ extern struct group_info init_groups; - .journal_info = NULL, \ - .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ - .fs_excl = ATOMIC_INIT(0), \ -+ .xid = 0, \ -+ .vx_info = NULL, \ -+ .nid = 0, \ -+ .nx_info = NULL, \ - } - - -diff --git a/include/linux/ipc.h b/include/linux/ipc.h -index b291189..079c2fe 100644 ---- a/include/linux/ipc.h -+++ b/include/linux/ipc.h -@@ -66,6 +66,7 @@ struct kern_ipc_perm - mode_t mode; - unsigned long seq; - void *security; -+ xid_t xid; - }; - - #endif /* __KERNEL__ */ -diff --git a/include/linux/kernel.h b/include/linux/kernel.h -index 3b507bf..d1c9dea 100644 ---- a/include/linux/kernel.h -+++ b/include/linux/kernel.h -@@ -17,6 +17,7 @@ - #include - - extern const char linux_banner[]; -+extern const char vx_linux_banner[]; - - #define INT_MAX ((int)(~0U>>1)) - #define INT_MIN (-INT_MAX - 1) -diff --git a/include/linux/major.h b/include/linux/major.h -index e36a467..5cc9d84 100644 ---- a/include/linux/major.h -+++ b/include/linux/major.h -@@ -15,6 +15,7 @@ - #define HD_MAJOR IDE0_MAJOR - #define PTY_SLAVE_MAJOR 3 - #define TTY_MAJOR 4 -+#define VROOT_MAJOR 4 - #define TTYAUX_MAJOR 5 - #define LP_MAJOR 6 - #define VCS_MAJOR 7 -diff --git a/include/linux/mount.h b/include/linux/mount.h -index b7472ae..a708e36 100644 ---- a/include/linux/mount.h -+++ b/include/linux/mount.h -@@ -22,10 +22,14 @@ - #define MNT_NOEXEC 0x04 - #define MNT_NOATIME 0x08 - #define MNT_NODIRATIME 0x10 -+#define MNT_RDONLY 0x20 -+ -+#define MNT_IS_RDONLY(m) ((m) && ((m)->mnt_flags & MNT_RDONLY)) - - #define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */ - #define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */ - #define MNT_PNODE_MASK 0x3000 /* propogation flag mask */ -+#define MNT_XID 0x8000 - - struct vfsmount { - struct list_head mnt_hash; -@@ -47,6 +51,7 @@ struct vfsmount { - struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */ - struct namespace *mnt_namespace; /* containing namespace */ - int mnt_pinned; -+ xid_t mnt_xid; /* xid tagging used for vfsmount */ - }; - - static inline struct vfsmount *mntget(struct vfsmount *mnt) -diff --git a/include/linux/namespace.h b/include/linux/namespace.h -index 3abc8e3..4e234d8 100644 ---- a/include/linux/namespace.h -+++ b/include/linux/namespace.h -@@ -16,6 +16,7 @@ struct namespace { - extern int copy_namespace(int, struct task_struct *); - extern void __put_namespace(struct namespace *namespace); - extern struct namespace *dup_namespace(struct task_struct *, struct fs_struct *); -+extern void umount_unused(struct vfsmount *, struct fs_struct *); - - static inline void put_namespace(struct namespace *namespace) - { -diff --git a/include/linux/net.h b/include/linux/net.h -index 28195a2..3a89224 100644 ---- a/include/linux/net.h -+++ b/include/linux/net.h -@@ -62,6 +62,7 @@ typedef enum { - #define SOCK_ASYNC_WAITDATA 1 - #define SOCK_NOSPACE 2 - #define SOCK_PASSCRED 3 -+#define SOCK_USER_SOCKET 4 - - #ifndef ARCH_HAS_SOCKET_TYPES - /** -diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h -index 659c754..b1531a0 100644 ---- a/include/linux/nfs_mount.h -+++ b/include/linux/nfs_mount.h -@@ -61,6 +61,7 @@ struct nfs_mount_data { - #define NFS_MOUNT_NOACL 0x0800 /* 4 */ - #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */ - #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */ -+#define NFS_MOUNT_TAGXID 0x8000 /* tagxid */ - #define NFS_MOUNT_FLAGMASK 0xFFFF - - #endif -diff --git a/include/linux/percpu.h b/include/linux/percpu.h -index cb9039a..e436dbd 100644 ---- a/include/linux/percpu.h -+++ b/include/linux/percpu.h -@@ -8,7 +8,7 @@ - - /* Enough to cover all DEFINE_PER_CPUs in kernel, including modules. */ - #ifndef PERCPU_ENOUGH_ROOM --#define PERCPU_ENOUGH_ROOM 32768 -+#define PERCPU_ENOUGH_ROOM 65536 - #endif - - /* Must be an lvalue. */ -diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h -index aa6322d..c892f9b 100644 ---- a/include/linux/proc_fs.h -+++ b/include/linux/proc_fs.h -@@ -55,6 +55,7 @@ struct proc_dir_entry { - nlink_t nlink; - uid_t uid; - gid_t gid; -+ int vx_flags; - unsigned long size; - struct inode_operations * proc_iops; - struct file_operations * proc_fops; -@@ -248,9 +249,11 @@ extern void kclist_add(struct kcore_list - struct proc_inode { - struct task_struct *task; - int type; -+ int vx_flags; - union { - int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); - int (*proc_read)(struct task_struct *task, char *page); -+ int (*proc_vid_read)(int vid, char *page); - } op; - struct proc_dir_entry *pde; - struct inode vfs_inode; -diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h -index dad78ce..6213f2f 100644 ---- a/include/linux/reiserfs_fs.h -+++ b/include/linux/reiserfs_fs.h -@@ -829,6 +829,18 @@ struct stat_data_v1 { - #define REISERFS_COMPR_FL EXT2_COMPR_FL - #define REISERFS_NOTAIL_FL EXT2_NOTAIL_FL - -+/* unfortunately reiserfs sdattr is only 16 bit */ -+#define REISERFS_BARRIER_FL (EXT2_BARRIER_FL >> 16) -+#define REISERFS_IUNLINK_FL (EXT2_IUNLINK_FL >> 16) -+ -+#ifdef CONFIG_VSERVER_LEGACY -+#define REISERFS_FL_USER_VISIBLE (REISERFS_IUNLINK_FL|0x80FF) -+#define REISERFS_FL_USER_MODIFIABLE (REISERFS_IUNLINK_FL|0x80FF) -+#else -+#define REISERFS_FL_USER_VISIBLE 0x80FF -+#define REISERFS_FL_USER_MODIFIABLE 0x80FF -+#endif -+ - /* persistent flags that file inherits from the parent directory */ - #define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \ - REISERFS_SYNC_FL | \ -@@ -1904,6 +1916,7 @@ static inline void reiserfs_update_sd(st - void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode); - void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs); - int reiserfs_setattr(struct dentry *dentry, struct iattr *attr); -+int reiserfs_sync_flags(struct inode *inode); - - /* namei.c */ - void set_de_name_and_namelen(struct reiserfs_dir_entry *de); -diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h -index 31b4c0b..3204ea0 100644 ---- a/include/linux/reiserfs_fs_sb.h -+++ b/include/linux/reiserfs_fs_sb.h -@@ -456,6 +456,7 @@ enum reiserfs_mount_options { - REISERFS_POSIXACL, - REISERFS_BARRIER_NONE, - REISERFS_BARRIER_FLUSH, -+ REISERFS_TAGXID, - - /* Actions on error */ - REISERFS_ERROR_PANIC, -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 62e6314..e02d5dd 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -129,6 +130,7 @@ extern unsigned long nr_iowait(void); - #define EXIT_DEAD 32 - /* in tsk->state again */ - #define TASK_NONINTERACTIVE 64 -+#define TASK_ONHOLD 128 - - #define __set_task_state(tsk, state_value) \ - do { (tsk)->state = (state_value); } while (0) -@@ -257,27 +259,30 @@ extern void arch_unmap_area_topdown(stru - * The mm counters are not protected by its page_table_lock, - * so must be incremented atomically. - */ --#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value) --#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member)) --#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member) --#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member) --#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member) - typedef atomic_long_t mm_counter_t; -+#define __set_mm_counter(mm, member, value) \ -+ atomic_long_set(&(mm)->_##member, value) -+#define get_mm_counter(mm, member) \ -+ ((unsigned long)atomic_long_read(&(mm)->_##member)) - - #else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ - /* - * The mm counters are protected by its page_table_lock, - * so can be incremented directly. - */ --#define set_mm_counter(mm, member, value) (mm)->_##member = (value) --#define get_mm_counter(mm, member) ((mm)->_##member) --#define add_mm_counter(mm, member, value) (mm)->_##member += (value) --#define inc_mm_counter(mm, member) (mm)->_##member++ --#define dec_mm_counter(mm, member) (mm)->_##member-- - typedef unsigned long mm_counter_t; -+#define __set_mm_counter(mm, member, value) (mm)->_##member = (value) -+#define get_mm_counter(mm, member) ((mm)->_##member) - - #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ - -+#define set_mm_counter(mm, member, value) \ -+ vx_ ## member ## pages_sub((mm), (get_mm_counter(mm, member) - value)) -+#define add_mm_counter(mm, member, value) \ -+ vx_ ## member ## pages_add((mm), (value)) -+#define inc_mm_counter(mm, member) vx_ ## member ## pages_inc((mm)) -+#define dec_mm_counter(mm, member) vx_ ## member ## pages_dec((mm)) -+ - #define get_mm_rss(mm) \ - (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss)) - #define update_hiwater_rss(mm) do { \ -@@ -336,6 +341,7 @@ struct mm_struct { - - /* Architecture-specific MM context */ - mm_context_t context; -+ struct vx_info *mm_vx_info; - - /* Token based thrashing protection. */ - unsigned long swap_token_time; -@@ -514,9 +520,10 @@ struct user_struct { - /* Hash table maintenance information */ - struct list_head uidhash_list; - uid_t uid; -+ xid_t xid; - }; - --extern struct user_struct *find_user(uid_t); -+extern struct user_struct *find_user(xid_t, uid_t); - - extern struct user_struct root_user; - #define INIT_USER (&root_user) -@@ -818,6 +825,14 @@ struct task_struct { - - void *security; - struct audit_context *audit_context; -+ -+/* vserver context data */ -+ struct vx_info *vx_info; -+ struct nx_info *nx_info; -+ -+ xid_t xid; -+ nid_t nid; -+ - seccomp_t seccomp; - - /* Thread group tracking */ -@@ -1020,13 +1035,19 @@ extern struct task_struct init_task; - - extern struct mm_struct init_mm; - --#define find_task_by_pid(nr) find_task_by_pid_type(PIDTYPE_PID, nr) -+ -+#define find_task_by_real_pid(nr) \ -+ find_task_by_pid_type(PIDTYPE_PID, nr) -+#define find_task_by_pid(nr) \ -+ find_task_by_pid_type(PIDTYPE_PID, \ -+ vx_rmap_pid(nr)) -+ - extern struct task_struct *find_task_by_pid_type(int type, int pid); - extern void set_special_pids(pid_t session, pid_t pgrp); - extern void __set_special_pids(pid_t session, pid_t pgrp); - - /* per-UID process charging. */ --extern struct user_struct * alloc_uid(uid_t); -+extern struct user_struct * alloc_uid(xid_t, uid_t); - static inline struct user_struct *get_uid(struct user_struct *u) - { - atomic_inc(&u->__count); -diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h -index c057f0b..e4b2803 100644 ---- a/include/linux/shmem_fs.h -+++ b/include/linux/shmem_fs.h -@@ -8,6 +8,9 @@ - - #define SHMEM_NR_DIRECT 16 - -+#define TMPFS_SUPER_MAGIC 0x01021994 -+ -+ - struct shmem_inode_info { - spinlock_t lock; - unsigned long flags; -diff --git a/include/linux/stat.h b/include/linux/stat.h -index 8ff2a12..289a968 100644 ---- a/include/linux/stat.h -+++ b/include/linux/stat.h -@@ -63,6 +63,7 @@ struct kstat { - unsigned int nlink; - uid_t uid; - gid_t gid; -+ xid_t xid; - dev_t rdev; - loff_t size; - struct timespec atime; -diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h -index be4772e..b27c818 100644 ---- a/include/linux/sunrpc/auth.h -+++ b/include/linux/sunrpc/auth.h -@@ -28,6 +28,7 @@ - struct auth_cred { - uid_t uid; - gid_t gid; -+ xid_t xid; - struct group_info *group_info; - }; - -diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h -index f147e6b..2c892da 100644 ---- a/include/linux/sunrpc/clnt.h -+++ b/include/linux/sunrpc/clnt.h -@@ -51,7 +51,8 @@ struct rpc_clnt { - cl_intr : 1,/* interruptible */ - cl_autobind : 1,/* use getport() */ - cl_oneshot : 1,/* dispose after use */ -- cl_dead : 1;/* abandoned */ -+ cl_dead : 1,/* abandoned */ -+ cl_tagxid : 1;/* do xid tagging */ - - struct rpc_rtt * cl_rtt; /* RTO estimator data */ - struct rpc_portmap * cl_pmap; /* port mapping */ -diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h -index bac61db..7e42ca6 100644 ---- a/include/linux/sysctl.h -+++ b/include/linux/sysctl.h -@@ -148,6 +148,7 @@ enum - KERN_SPIN_RETRY=70, /* int: number of spinlock retries */ - KERN_ACPI_VIDEO_FLAGS=71, /* int: flags for setting up video after ACPI sleep */ - KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */ -+ KERN_VSHELPER=73, /* string: path to vshelper policy agent */ - }; - - -@@ -882,6 +883,9 @@ typedef int ctl_handler (ctl_table *tabl - typedef int proc_handler (ctl_table *ctl, int write, struct file * filp, - void __user *buffer, size_t *lenp, loff_t *ppos); - -+typedef int virt_handler (struct ctl_table *ctl, int write, xid_t xid, -+ void **datap, size_t *lenp); -+ - extern int proc_dostring(ctl_table *, int, struct file *, - void __user *, size_t *, loff_t *); - extern int proc_dointvec(ctl_table *, int, struct file *, -@@ -963,6 +967,7 @@ struct ctl_table - mode_t mode; - ctl_table *child; - proc_handler *proc_handler; /* Callback for text formatting */ -+ virt_handler *virt_handler; /* Context virtualization */ - ctl_handler *strategy; /* Callback function for all r/w */ - struct proc_dir_entry *de; /* /proc control block */ - void *extra1; -diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h -index 392da5a..e738d80 100644 ---- a/include/linux/sysfs.h -+++ b/include/linux/sysfs.h -@@ -12,6 +12,8 @@ - - #include - -+#define SYSFS_SUPER_MAGIC 0x62656572 -+ - struct kobject; - struct module; - -diff --git a/include/linux/types.h b/include/linux/types.h -index 54ae2d5..08848a1 100644 ---- a/include/linux/types.h -+++ b/include/linux/types.h -@@ -38,6 +38,8 @@ typedef __kernel_uid32_t uid_t; - typedef __kernel_gid32_t gid_t; - typedef __kernel_uid16_t uid16_t; - typedef __kernel_gid16_t gid16_t; -+typedef unsigned int xid_t; -+typedef unsigned int nid_t; - - #ifdef CONFIG_UID16 - /* This is defined by include/asm-{arch}/posix_types.h */ -diff --git a/include/linux/vroot.h b/include/linux/vroot.h -new file mode 100644 -index 0000000..4eb6d0d ---- /dev/null -+++ b/include/linux/vroot.h -@@ -0,0 +1,51 @@ -+ -+/* -+ * include/linux/vroot.h -+ * -+ * written by Herbert Pötzl, 9/11/2002 -+ * ported to 2.6 by Herbert Pötzl, 30/12/2004 -+ * -+ * Copyright (C) 2002-2005 by Herbert Pötzl. -+ * Redistribution of this file is permitted under the -+ * GNU General Public License. -+ */ -+ -+#ifndef _LINUX_VROOT_H -+#define _LINUX_VROOT_H -+ -+ -+#ifdef __KERNEL__ -+ -+/* Possible states of device */ -+enum { -+ Vr_unbound, -+ Vr_bound, -+}; -+ -+struct vroot_device { -+ int vr_number; -+ int vr_refcnt; -+ -+ struct semaphore vr_ctl_mutex; -+ struct block_device *vr_device; -+ int vr_state; -+}; -+ -+ -+typedef struct block_device *(vroot_grb_func)(struct block_device *); -+ -+extern int register_vroot_grb(vroot_grb_func *); -+extern int unregister_vroot_grb(vroot_grb_func *); -+ -+#endif /* __KERNEL__ */ -+ -+#define MAX_VROOT_DEFAULT 8 -+ -+/* -+ * IOCTL commands --- we will commandeer 0x56 ('V') -+ */ -+ -+#define VROOT_SET_DEV 0x5600 -+#define VROOT_CLR_DEV 0x5601 -+ -+#endif /* _LINUX_VROOT_H */ -diff --git a/include/linux/vs_base.h b/include/linux/vs_base.h -new file mode 100644 -index 0000000..fa1b85e ---- /dev/null -+++ b/include/linux/vs_base.h -@@ -0,0 +1,103 @@ -+#ifndef _VX_VS_BASE_H -+#define _VX_VS_BASE_H -+ -+#include "vserver/context.h" -+ -+ -+#define vx_task_xid(t) ((t)->xid) -+ -+#define vx_current_xid() vx_task_xid(current) -+ -+#define vx_check(c,m) __vx_check(vx_current_xid(),c,m) -+ -+#define vx_weak_check(c,m) ((m) ? vx_check(c,m) : 1) -+ -+ -+/* -+ * check current context for ADMIN/WATCH and -+ * optionally against supplied argument -+ */ -+static inline int __vx_check(xid_t cid, xid_t id, unsigned int mode) -+{ -+ if (mode & VX_ARG_MASK) { -+ if ((mode & VX_IDENT) && -+ (id == cid)) -+ return 1; -+ } -+ if (mode & VX_ATR_MASK) { -+ if ((mode & VX_DYNAMIC) && -+ (id >= MIN_D_CONTEXT) && -+ (id <= MAX_S_CONTEXT)) -+ return 1; -+ if ((mode & VX_STATIC) && -+ (id > 1) && (id < MIN_D_CONTEXT)) -+ return 1; -+ } -+ return (((mode & VX_ADMIN) && (cid == 0)) || -+ ((mode & VX_WATCH) && (cid == 1)) || -+ ((mode & VX_HOSTID) && (id == 0))); -+} -+ -+ -+#define __vx_state(v) ((v) ? ((v)->vx_state) : 0) -+ -+#define vx_info_state(v,m) (__vx_state(v) & (m)) -+ -+ -+/* generic flag merging */ -+ -+#define vx_check_flags(v,m,f) (((v) & (m)) ^ (f)) -+ -+#define vx_mask_flags(v,f,m) (((v) & ~(m)) | ((f) & (m))) -+ -+#define vx_mask_mask(v,f,m) (((v) & ~(m)) | ((v) & (f) & (m))) -+ -+#define vx_check_bit(v,n) ((v) & (1LL << (n))) -+ -+ -+/* context flags */ -+ -+#define __vx_flags(v) ((v) ? (v)->vx_flags : 0) -+ -+#define vx_current_flags() __vx_flags(current->vx_info) -+ -+#define vx_info_flags(v,m,f) \ -+ vx_check_flags(__vx_flags(v),(m),(f)) -+ -+#define task_vx_flags(t,m,f) \ -+ ((t) && vx_info_flags((t)->vx_info, (m), (f))) -+ -+#define vx_flags(m,f) vx_info_flags(current->vx_info,(m),(f)) -+ -+ -+/* context caps */ -+ -+#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0) -+ -+#define vx_current_ccaps() __vx_ccaps(current->vx_info) -+ -+#define vx_info_ccaps(v,c) (__vx_ccaps(v) & (c)) -+ -+#define vx_ccaps(c) vx_info_ccaps(current->vx_info,(c)) -+ -+ -+#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 ) -+ -+#define vx_info_mcaps(v,c) (__vx_mcaps(v) & (c)) -+ -+#define vx_mcaps(c) vx_info_mcaps(current->vx_info,(c)) -+ -+ -+#define vx_current_bcaps() \ -+ (((current->vx_info) && !vx_flags(VXF_STATE_SETUP, 0)) ? \ -+ current->vx_info->vx_bcaps : cap_bset) -+ -+ -+#define vx_current_initpid(n) \ -+ (current->vx_info && \ -+ (current->vx_info->vx_initpid == (n))) -+ -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vs_context.h b/include/linux/vs_context.h -new file mode 100644 -index 0000000..24bb245 ---- /dev/null -+++ b/include/linux/vs_context.h -@@ -0,0 +1,198 @@ -+#ifndef _VX_VS_CONTEXT_H -+#define _VX_VS_CONTEXT_H -+ -+#include -+#include "vserver/debug.h" -+ -+ -+#define get_vx_info(i) __get_vx_info(i,__FILE__,__LINE__,__HERE__) -+ -+static inline struct vx_info *__get_vx_info(struct vx_info *vxi, -+ const char *_file, int _line, void *_here) -+{ -+ if (!vxi) -+ return NULL; -+ -+ vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])", -+ vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0, -+ _file, _line); -+ __vxh_get_vx_info(vxi, _here); -+ -+ atomic_inc(&vxi->vx_usecnt); -+ return vxi; -+} -+ -+ -+extern void free_vx_info(struct vx_info *); -+ -+#define put_vx_info(i) __put_vx_info(i,__FILE__,__LINE__,__HERE__) -+ -+static inline void __put_vx_info(struct vx_info *vxi, -+ const char *_file, int _line, void *_here) -+{ -+ if (!vxi) -+ return; -+ -+ vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])", -+ vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0, -+ _file, _line); -+ __vxh_put_vx_info(vxi, _here); -+ -+ if (atomic_dec_and_test(&vxi->vx_usecnt)) -+ free_vx_info(vxi); -+} -+ -+ -+#define init_vx_info(p,i) __init_vx_info(p,i,__FILE__,__LINE__,__HERE__) -+ -+static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi, -+ const char *_file, int _line, void *_here) -+{ -+ if (vxi) { -+ vxlprintk(VXD_CBIT(xid, 3), -+ "init_vx_info(%p[#%d.%d])", -+ vxi, vxi?vxi->vx_id:0, -+ vxi?atomic_read(&vxi->vx_usecnt):0, -+ _file, _line); -+ __vxh_init_vx_info(vxi, vxp, _here); -+ -+ atomic_inc(&vxi->vx_usecnt); -+ } -+ *vxp = vxi; -+} -+ -+ -+#define set_vx_info(p,i) __set_vx_info(p,i,__FILE__,__LINE__,__HERE__) -+ -+static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi, -+ const char *_file, int _line, void *_here) -+{ -+ struct vx_info *vxo; -+ -+ if (!vxi) -+ return; -+ -+ vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])", -+ vxi, vxi?vxi->vx_id:0, -+ vxi?atomic_read(&vxi->vx_usecnt):0, -+ _file, _line); -+ __vxh_set_vx_info(vxi, vxp, _here); -+ -+ atomic_inc(&vxi->vx_usecnt); -+ vxo = xchg(vxp, vxi); -+ BUG_ON(vxo); -+} -+ -+ -+#define clr_vx_info(p) __clr_vx_info(p,__FILE__,__LINE__,__HERE__) -+ -+static inline void __clr_vx_info(struct vx_info **vxp, -+ const char *_file, int _line, void *_here) -+{ -+ struct vx_info *vxo; -+ -+ vxo = xchg(vxp, NULL); -+ if (!vxo) -+ return; -+ -+ vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])", -+ vxo, vxo?vxo->vx_id:0, -+ vxo?atomic_read(&vxo->vx_usecnt):0, -+ _file, _line); -+ __vxh_clr_vx_info(vxo, vxp, _here); -+ -+ if (atomic_dec_and_test(&vxo->vx_usecnt)) -+ free_vx_info(vxo); -+} -+ -+ -+#define claim_vx_info(v,p) \ -+ __claim_vx_info(v,p,__FILE__,__LINE__,__HERE__) -+ -+static inline void __claim_vx_info(struct vx_info *vxi, -+ struct task_struct *task, -+ const char *_file, int _line, void *_here) -+{ -+ vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p", -+ vxi, vxi?vxi->vx_id:0, -+ vxi?atomic_read(&vxi->vx_usecnt):0, -+ vxi?atomic_read(&vxi->vx_tasks):0, -+ task, _file, _line); -+ __vxh_claim_vx_info(vxi, task, _here); -+ -+ atomic_inc(&vxi->vx_tasks); -+} -+ -+ -+extern void unhash_vx_info(struct vx_info *); -+ -+#define release_vx_info(v,p) \ -+ __release_vx_info(v,p,__FILE__,__LINE__,__HERE__) -+ -+static inline void __release_vx_info(struct vx_info *vxi, -+ struct task_struct *task, -+ const char *_file, int _line, void *_here) -+{ -+ vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p", -+ vxi, vxi?vxi->vx_id:0, -+ vxi?atomic_read(&vxi->vx_usecnt):0, -+ vxi?atomic_read(&vxi->vx_tasks):0, -+ task, _file, _line); -+ __vxh_release_vx_info(vxi, task, _here); -+ -+ might_sleep(); -+ -+ if (atomic_dec_and_test(&vxi->vx_tasks)) -+ unhash_vx_info(vxi); -+} -+ -+ -+#define task_get_vx_info(p) \ -+ __task_get_vx_info(p,__FILE__,__LINE__,__HERE__) -+ -+static inline struct vx_info *__task_get_vx_info(struct task_struct *p, -+ const char *_file, int _line, void *_here) -+{ -+ struct vx_info *vxi; -+ -+ task_lock(p); -+ vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)", -+ p, _file, _line); -+ vxi = __get_vx_info(p->vx_info, _file, _line, _here); -+ task_unlock(p); -+ return vxi; -+} -+ -+ -+static inline void __wakeup_vx_info(struct vx_info *vxi) -+{ -+ if (waitqueue_active(&vxi->vx_wait)) -+ wake_up_interruptible(&vxi->vx_wait); -+} -+ -+extern void exit_vx_info(struct task_struct *); -+ -+static inline -+struct task_struct *vx_child_reaper(struct task_struct *p) -+{ -+ struct vx_info *vxi = p->vx_info; -+ struct task_struct *reaper = child_reaper; -+ -+ if (!vxi) -+ goto out; -+ -+ BUG_ON(!p->vx_info->vx_reaper); -+ -+ /* child reaper for the guest reaper */ -+ if (vxi->vx_reaper == p) -+ goto out; -+ -+ reaper = vxi->vx_reaper; -+out: -+ return reaper; -+} -+ -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vs_cvirt.h b/include/linux/vs_cvirt.h -new file mode 100644 -index 0000000..0901e73 ---- /dev/null -+++ b/include/linux/vs_cvirt.h -@@ -0,0 +1,108 @@ -+#ifndef _VX_VS_CVIRT_H -+#define _VX_VS_CVIRT_H -+ -+#include "vserver/cvirt.h" -+#include "vserver/debug.h" -+ -+ -+/* utsname virtualization */ -+ -+static inline struct new_utsname *vx_new_utsname(void) -+{ -+ if (current->vx_info) -+ return ¤t->vx_info->cvirt.utsname; -+ return &system_utsname; -+} -+ -+#define vx_new_uts(x) ((vx_new_utsname())->x) -+ -+ -+/* pid faking stuff */ -+ -+ -+#define vx_info_map_pid(v,p) \ -+ __vx_info_map_pid((v), (p), __FUNC__, __FILE__, __LINE__) -+#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p) -+#define vx_map_pid(p) vx_info_map_pid(current->vx_info, p) -+#define vx_map_tgid(p) vx_map_pid(p) -+ -+static inline int __vx_info_map_pid(struct vx_info *vxi, int pid, -+ const char *func, const char *file, int line) -+{ -+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) { -+ vxfprintk(VXD_CBIT(cvirt, 2), -+ "vx_map_tgid: %p/%llx: %d -> %d", -+ vxi, (long long)vxi->vx_flags, pid, -+ (pid && pid == vxi->vx_initpid)?1:pid, -+ func, file, line); -+ if (pid == 0) -+ return 0; -+ if (pid == vxi->vx_initpid) -+ return 1; -+ } -+ return pid; -+} -+ -+#define vx_info_rmap_pid(v,p) \ -+ __vx_info_rmap_pid((v), (p), __FUNC__, __FILE__, __LINE__) -+#define vx_rmap_pid(p) vx_info_rmap_pid(current->vx_info, p) -+#define vx_rmap_tgid(p) vx_rmap_pid(p) -+ -+static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid, -+ const char *func, const char *file, int line) -+{ -+ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) { -+ vxfprintk(VXD_CBIT(cvirt, 2), -+ "vx_rmap_tgid: %p/%llx: %d -> %d", -+ vxi, (long long)vxi->vx_flags, pid, -+ (pid == 1)?vxi->vx_initpid:pid, -+ func, file, line); -+ if ((pid == 1) && vxi->vx_initpid) -+ return vxi->vx_initpid; -+ if (pid == vxi->vx_initpid) -+ return ~0U; -+ } -+ return pid; -+} -+ -+ -+static inline void vx_activate_task(struct task_struct *p) -+{ -+ struct vx_info *vxi; -+ -+ if ((vxi = p->vx_info)) { -+ vx_update_load(vxi); -+ atomic_inc(&vxi->cvirt.nr_running); -+ } -+} -+ -+static inline void vx_deactivate_task(struct task_struct *p) -+{ -+ struct vx_info *vxi; -+ -+ if ((vxi = p->vx_info)) { -+ vx_update_load(vxi); -+ atomic_dec(&vxi->cvirt.nr_running); -+ } -+} -+ -+static inline void vx_uninterruptible_inc(struct task_struct *p) -+{ -+ struct vx_info *vxi; -+ -+ if ((vxi = p->vx_info)) -+ atomic_inc(&vxi->cvirt.nr_uninterruptible); -+} -+ -+static inline void vx_uninterruptible_dec(struct task_struct *p) -+{ -+ struct vx_info *vxi; -+ -+ if ((vxi = p->vx_info)) -+ atomic_dec(&vxi->cvirt.nr_uninterruptible); -+} -+ -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vs_dlimit.h b/include/linux/vs_dlimit.h -new file mode 100644 -index 0000000..674262d ---- /dev/null -+++ b/include/linux/vs_dlimit.h -@@ -0,0 +1,213 @@ -+#ifndef _VX_VS_DLIMIT_H -+#define _VX_VS_DLIMIT_H -+ -+#include "vserver/dlimit.h" -+#include "vserver/debug.h" -+ -+ -+#define get_dl_info(i) __get_dl_info(i,__FILE__,__LINE__) -+ -+static inline struct dl_info *__get_dl_info(struct dl_info *dli, -+ const char *_file, int _line) -+{ -+ if (!dli) -+ return NULL; -+ vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])", -+ dli, dli?dli->dl_xid:0, dli?atomic_read(&dli->dl_usecnt):0, -+ _file, _line); -+ atomic_inc(&dli->dl_usecnt); -+ return dli; -+} -+ -+ -+#define free_dl_info(i) \ -+ call_rcu(&i->dl_rcu, rcu_free_dl_info); -+ -+#define put_dl_info(i) __put_dl_info(i,__FILE__,__LINE__) -+ -+static inline void __put_dl_info(struct dl_info *dli, -+ const char *_file, int _line) -+{ -+ if (!dli) -+ return; -+ vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])", -+ dli, dli?dli->dl_xid:0, dli?atomic_read(&dli->dl_usecnt):0, -+ _file, _line); -+ if (atomic_dec_and_test(&dli->dl_usecnt)) -+ free_dl_info(dli); -+} -+ -+ -+#define __dlimit_char(d) ((d)?'*':' ') -+ -+static inline int __dl_alloc_space(struct super_block *sb, -+ xid_t xid, dlsize_t nr, const char *file, int line) -+{ -+ struct dl_info *dli = NULL; -+ int ret = 0; -+ -+ if (nr == 0) -+ goto out; -+ dli = locate_dl_info(sb, xid); -+ if (!dli) -+ goto out; -+ -+ spin_lock(&dli->dl_lock); -+ ret = (dli->dl_space_used + nr > dli->dl_space_total); -+ if (!ret) -+ dli->dl_space_used += nr; -+ spin_unlock(&dli->dl_lock); -+ put_dl_info(dli); -+out: -+ vxlprintk(VXD_CBIT(dlim, 1), -+ "ALLOC (%p,#%d)%c %lld bytes (%d)", -+ sb, xid, __dlimit_char(dli), (long long)nr, -+ ret, file, line); -+ return ret; -+} -+ -+static inline void __dl_free_space(struct super_block *sb, -+ xid_t xid, dlsize_t nr, const char *_file, int _line) -+{ -+ struct dl_info *dli = NULL; -+ -+ if (nr == 0) -+ goto out; -+ dli = locate_dl_info(sb, xid); -+ if (!dli) -+ goto out; -+ -+ spin_lock(&dli->dl_lock); -+ if (dli->dl_space_used > nr) -+ dli->dl_space_used -= nr; -+ else -+ dli->dl_space_used = 0; -+ spin_unlock(&dli->dl_lock); -+ put_dl_info(dli); -+out: -+ vxlprintk(VXD_CBIT(dlim, 1), -+ "FREE (%p,#%d)%c %lld bytes", -+ sb, xid, __dlimit_char(dli), (long long)nr, -+ _file, _line); -+} -+ -+static inline int __dl_alloc_inode(struct super_block *sb, -+ xid_t xid, const char *_file, int _line) -+{ -+ struct dl_info *dli; -+ int ret = 0; -+ -+ dli = locate_dl_info(sb, xid); -+ if (!dli) -+ goto out; -+ -+ spin_lock(&dli->dl_lock); -+ ret = (dli->dl_inodes_used >= dli->dl_inodes_total); -+ if (!ret) -+ dli->dl_inodes_used++; -+#if 0 -+ else -+ vxwprintk("DLIMIT hit (%p,#%d), inode %d>=%d @ %s:%d", -+ sb, xid, -+ dli->dl_inodes_used, dli->dl_inodes_total, -+ file, line); -+#endif -+ spin_unlock(&dli->dl_lock); -+ put_dl_info(dli); -+out: -+ vxlprintk(VXD_CBIT(dlim, 0), -+ "ALLOC (%p,#%d)%c inode (%d)", -+ sb, xid, __dlimit_char(dli), ret, _file, _line); -+ return ret; -+} -+ -+static inline void __dl_free_inode(struct super_block *sb, -+ xid_t xid, const char *_file, int _line) -+{ -+ struct dl_info *dli; -+ -+ dli = locate_dl_info(sb, xid); -+ if (!dli) -+ goto out; -+ -+ spin_lock(&dli->dl_lock); -+ if (dli->dl_inodes_used > 1) -+ dli->dl_inodes_used--; -+ else -+ dli->dl_inodes_used = 0; -+ spin_unlock(&dli->dl_lock); -+ put_dl_info(dli); -+out: -+ vxlprintk(VXD_CBIT(dlim, 0), -+ "FREE (%p,#%d)%c inode", -+ sb, xid, __dlimit_char(dli), _file, _line); -+} -+ -+static inline void __dl_adjust_block(struct super_block *sb, xid_t xid, -+ unsigned int *free_blocks, unsigned int *root_blocks, -+ const char *_file, int _line) -+{ -+ struct dl_info *dli; -+ uint64_t broot, bfree; -+ -+ dli = locate_dl_info(sb, xid); -+ if (!dli) -+ return; -+ -+ spin_lock(&dli->dl_lock); -+ broot = (dli->dl_space_total - -+ (dli->dl_space_total >> 10) * dli->dl_nrlmult) -+ >> sb->s_blocksize_bits; -+ bfree = (dli->dl_space_total - dli->dl_space_used) -+ >> sb->s_blocksize_bits; -+ spin_unlock(&dli->dl_lock); -+ -+ vxlprintk(VXD_CBIT(dlim, 2), -+ "ADJUST: %lld,%lld on %d,%d [mult=%d]", -+ (long long)bfree, (long long)broot, -+ *free_blocks, *root_blocks, dli->dl_nrlmult, -+ _file, _line); -+ if (free_blocks) { -+ if (*free_blocks > bfree) -+ *free_blocks = bfree; -+ } -+ if (root_blocks) { -+ if (*root_blocks > broot) -+ *root_blocks = broot; -+ } -+ put_dl_info(dli); -+} -+ -+#define DLIMIT_ALLOC_SPACE(in, bytes) \ -+ __dl_alloc_space((in)->i_sb, (in)->i_xid, (dlsize_t)(bytes), \ -+ __FILE__, __LINE__ ) -+ -+#define DLIMIT_FREE_SPACE(in, bytes) \ -+ __dl_free_space((in)->i_sb, (in)->i_xid, (dlsize_t)(bytes), \ -+ __FILE__, __LINE__ ) -+ -+#define DLIMIT_ALLOC_BLOCK(in, nr) \ -+ __dl_alloc_space((in)->i_sb, (in)->i_xid, \ -+ ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \ -+ __FILE__, __LINE__ ) -+ -+#define DLIMIT_FREE_BLOCK(in, nr) \ -+ __dl_free_space((in)->i_sb, (in)->i_xid, \ -+ ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \ -+ __FILE__, __LINE__ ) -+ -+ -+#define DLIMIT_ALLOC_INODE(in) \ -+ __dl_alloc_inode((in)->i_sb, (in)->i_xid, __FILE__, __LINE__ ) -+ -+#define DLIMIT_FREE_INODE(in) \ -+ __dl_free_inode((in)->i_sb, (in)->i_xid, __FILE__, __LINE__ ) -+ -+ -+#define DLIMIT_ADJUST_BLOCK(sb, xid, fb, rb) \ -+ __dl_adjust_block(sb, xid, fb, rb, __FILE__, __LINE__ ) -+ -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vs_limit.h b/include/linux/vs_limit.h -new file mode 100644 -index 0000000..d1304bd ---- /dev/null -+++ b/include/linux/vs_limit.h -@@ -0,0 +1,107 @@ -+#ifndef _VX_VS_LIMIT_H -+#define _VX_VS_LIMIT_H -+ -+#include "vserver/limit.h" -+#include "vserver/debug.h" -+#include "vserver/limit_int.h" -+ -+ -+#define vx_acc_cres(v,d,p,r) \ -+ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__) -+ -+#define vx_acc_cres_cond(x,d,p,r) \ -+ __vx_acc_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \ -+ r, d, p, __FILE__, __LINE__) -+ -+ -+#define vx_add_cres(v,a,p,r) \ -+ __vx_add_cres(v, r, a, p, __FILE__, __LINE__) -+#define vx_sub_cres(v,a,p,r) vx_add_cres(v,-(a),p,r) -+ -+#define vx_add_cres_cond(x,a,p,r) \ -+ __vx_add_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \ -+ r, a, p, __FILE__, __LINE__) -+#define vx_sub_cres_cond(x,a,p,r) vx_add_cres_cond(x,-(a),p,r) -+ -+ -+/* process and file limits */ -+ -+#define vx_nproc_inc(p) \ -+ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC) -+ -+#define vx_nproc_dec(p) \ -+ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC) -+ -+#define vx_files_inc(f) \ -+ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE) -+ -+#define vx_files_dec(f) \ -+ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE) -+ -+#define vx_locks_inc(l) \ -+ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS) -+ -+#define vx_locks_dec(l) \ -+ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS) -+ -+#define vx_openfd_inc(f) \ -+ vx_acc_cres(current->vx_info, 1, (void *)(long)(f), VLIMIT_OPENFD) -+ -+#define vx_openfd_dec(f) \ -+ vx_acc_cres(current->vx_info,-1, (void *)(long)(f), VLIMIT_OPENFD) -+ -+ -+#define vx_cres_avail(v,n,r) \ -+ __vx_cres_avail(v, r, n, __FILE__, __LINE__) -+ -+ -+#define vx_nproc_avail(n) \ -+ vx_cres_avail(current->vx_info, n, RLIMIT_NPROC) -+ -+#define vx_files_avail(n) \ -+ vx_cres_avail(current->vx_info, n, RLIMIT_NOFILE) -+ -+#define vx_locks_avail(n) \ -+ vx_cres_avail(current->vx_info, n, RLIMIT_LOCKS) -+ -+#define vx_openfd_avail(n) \ -+ vx_cres_avail(current->vx_info, n, VLIMIT_OPENFD) -+ -+ -+/* socket limits */ -+ -+#define vx_sock_inc(s) \ -+ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK) -+ -+#define vx_sock_dec(s) \ -+ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK) -+ -+#define vx_sock_avail(n) \ -+ vx_cres_avail(current->vx_info, n, VLIMIT_NSOCK) -+ -+ -+/* ipc resource limits */ -+ -+#define vx_ipcmsg_add(v,u,a) \ -+ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE) -+ -+#define vx_ipcmsg_sub(v,u,a) \ -+ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE) -+ -+#define vx_ipcmsg_avail(v,a) \ -+ vx_cres_avail(v, a, RLIMIT_MSGQUEUE) -+ -+ -+#define vx_ipcshm_add(v,k,a) \ -+ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM) -+ -+#define vx_ipcshm_sub(v,k,a) \ -+ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM) -+ -+#define vx_ipcshm_avail(v,a) \ -+ vx_cres_avail(v, a, VLIMIT_SHMEM) -+ -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vs_memory.h b/include/linux/vs_memory.h -new file mode 100644 -index 0000000..b19afb0 ---- /dev/null -+++ b/include/linux/vs_memory.h -@@ -0,0 +1,108 @@ -+#ifndef _VX_VS_MEMORY_H -+#define _VX_VS_MEMORY_H -+ -+#include -+#include "vserver/limit.h" -+#include "vserver/debug.h" -+#include "vserver/limit_int.h" -+ -+ -+#define __vx_add_long(a,v) (*(v) += (a)) -+#define __vx_inc_long(v) (++*(v)) -+#define __vx_dec_long(v) (--*(v)) -+ -+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS -+#define __vx_add_value(a,v) atomic_long_add(a,v) -+#define __vx_inc_value(v) atomic_long_inc(v) -+#define __vx_dec_value(v) atomic_long_dec(v) -+#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ -+#define __vx_add_value(a,v) __vx_add_long(a,v) -+#define __vx_inc_value(v) __vx_inc_long(v) -+#define __vx_dec_value(v) __vx_dec_long(v) -+#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ -+ -+ -+#define vx_acc_page(m,d,v,r) do { \ -+ if ((d) > 0) \ -+ __vx_inc_long(&(m->v)); \ -+ else \ -+ __vx_dec_long(&(m->v)); \ -+ __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \ -+} while (0) -+ -+#define vx_acc_page_atomic(m,d,v,r) do { \ -+ if ((d) > 0) \ -+ __vx_inc_value(&(m->v)); \ -+ else \ -+ __vx_dec_value(&(m->v)); \ -+ __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \ -+} while (0) -+ -+ -+#define vx_acc_pages(m,p,v,r) do { \ -+ unsigned long __p = (p); \ -+ __vx_add_long(__p, &(m->v)); \ -+ __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \ -+} while (0) -+ -+#define vx_acc_pages_atomic(m,p,v,r) do { \ -+ unsigned long __p = (p); \ -+ __vx_add_value(__p, &(m->v)); \ -+ __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \ -+} while (0) -+ -+ -+ -+#define vx_acc_vmpage(m,d) \ -+ vx_acc_page(m, d, total_vm, RLIMIT_AS) -+#define vx_acc_vmlpage(m,d) \ -+ vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK) -+#define vx_acc_file_rsspage(m,d) \ -+ vx_acc_page_atomic(m, d, _file_rss, RLIMIT_RSS) -+#define vx_acc_anon_rsspage(m,d) \ -+ vx_acc_page_atomic(m, d, _anon_rss, VLIMIT_ANON) -+ -+#define vx_acc_vmpages(m,p) \ -+ vx_acc_pages(m, p, total_vm, RLIMIT_AS) -+#define vx_acc_vmlpages(m,p) \ -+ vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK) -+#define vx_acc_file_rsspages(m,p) \ -+ vx_acc_pages_atomic(m, p, _file_rss, RLIMIT_RSS) -+#define vx_acc_anon_rsspages(m,p) \ -+ vx_acc_pages_atomic(m, p, _anon_rss, VLIMIT_ANON) -+ -+#define vx_pages_add(s,r,p) __vx_add_cres(s, r, p, 0, __FILE__, __LINE__) -+#define vx_pages_sub(s,r,p) vx_pages_add(s, r, -(p)) -+ -+#define vx_vmpages_inc(m) vx_acc_vmpage(m, 1) -+#define vx_vmpages_dec(m) vx_acc_vmpage(m,-1) -+#define vx_vmpages_add(m,p) vx_acc_vmpages(m, p) -+#define vx_vmpages_sub(m,p) vx_acc_vmpages(m,-(p)) -+ -+#define vx_vmlocked_inc(m) vx_acc_vmlpage(m, 1) -+#define vx_vmlocked_dec(m) vx_acc_vmlpage(m,-1) -+#define vx_vmlocked_add(m,p) vx_acc_vmlpages(m, p) -+#define vx_vmlocked_sub(m,p) vx_acc_vmlpages(m,-(p)) -+ -+#define vx_file_rsspages_inc(m) vx_acc_file_rsspage(m, 1) -+#define vx_file_rsspages_dec(m) vx_acc_file_rsspage(m,-1) -+#define vx_file_rsspages_add(m,p) vx_acc_file_rsspages(m, p) -+#define vx_file_rsspages_sub(m,p) vx_acc_file_rsspages(m,-(p)) -+ -+#define vx_anon_rsspages_inc(m) vx_acc_anon_rsspage(m, 1) -+#define vx_anon_rsspages_dec(m) vx_acc_anon_rsspage(m,-1) -+#define vx_anon_rsspages_add(m,p) vx_acc_anon_rsspages(m, p) -+#define vx_anon_rsspages_sub(m,p) vx_acc_anon_rsspages(m,-(p)) -+ -+ -+#define vx_pages_avail(m,p,r) \ -+ __vx_cres_avail((m)->mm_vx_info, r, p, __FILE__, __LINE__) -+ -+#define vx_vmpages_avail(m,p) vx_pages_avail(m, p, RLIMIT_AS) -+#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK) -+#define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS) -+#define vx_anonpages_avail(m,p) vx_pages_avail(m, p, VLIMIT_ANON) -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vs_network.h b/include/linux/vs_network.h -new file mode 100644 -index 0000000..28fa781 ---- /dev/null -+++ b/include/linux/vs_network.h -@@ -0,0 +1,215 @@ -+#ifndef _NX_VS_NETWORK_H -+#define _NX_VS_NETWORK_H -+ -+#include "vserver/network.h" -+#include "vserver/debug.h" -+ -+ -+#define get_nx_info(i) __get_nx_info(i,__FILE__,__LINE__) -+ -+static inline struct nx_info *__get_nx_info(struct nx_info *nxi, -+ const char *_file, int _line) -+{ -+ if (!nxi) -+ return NULL; -+ -+ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])", -+ nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0, -+ _file, _line); -+ -+ atomic_inc(&nxi->nx_usecnt); -+ return nxi; -+} -+ -+ -+extern void free_nx_info(struct nx_info *); -+ -+#define put_nx_info(i) __put_nx_info(i,__FILE__,__LINE__) -+ -+static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line) -+{ -+ if (!nxi) -+ return; -+ -+ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])", -+ nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0, -+ _file, _line); -+ -+ if (atomic_dec_and_test(&nxi->nx_usecnt)) -+ free_nx_info(nxi); -+} -+ -+ -+#define init_nx_info(p,i) __init_nx_info(p,i,__FILE__,__LINE__) -+ -+static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi, -+ const char *_file, int _line) -+{ -+ if (nxi) { -+ vxlprintk(VXD_CBIT(nid, 3), -+ "init_nx_info(%p[#%d.%d])", -+ nxi, nxi?nxi->nx_id:0, -+ nxi?atomic_read(&nxi->nx_usecnt):0, -+ _file, _line); -+ -+ atomic_inc(&nxi->nx_usecnt); -+ } -+ *nxp = nxi; -+} -+ -+ -+#define set_nx_info(p,i) __set_nx_info(p,i,__FILE__,__LINE__) -+ -+static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi, -+ const char *_file, int _line) -+{ -+ struct nx_info *nxo; -+ -+ if (!nxi) -+ return; -+ -+ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])", -+ nxi, nxi?nxi->nx_id:0, -+ nxi?atomic_read(&nxi->nx_usecnt):0, -+ _file, _line); -+ -+ atomic_inc(&nxi->nx_usecnt); -+ nxo = xchg(nxp, nxi); -+ BUG_ON(nxo); -+} -+ -+#define clr_nx_info(p) __clr_nx_info(p,__FILE__,__LINE__) -+ -+static inline void __clr_nx_info(struct nx_info **nxp, -+ const char *_file, int _line) -+{ -+ struct nx_info *nxo; -+ -+ nxo = xchg(nxp, NULL); -+ if (!nxo) -+ return; -+ -+ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])", -+ nxo, nxo?nxo->nx_id:0, -+ nxo?atomic_read(&nxo->nx_usecnt):0, -+ _file, _line); -+ -+ if (atomic_dec_and_test(&nxo->nx_usecnt)) -+ free_nx_info(nxo); -+} -+ -+ -+#define claim_nx_info(v,p) __claim_nx_info(v,p,__FILE__,__LINE__) -+ -+static inline void __claim_nx_info(struct nx_info *nxi, -+ struct task_struct *task, const char *_file, int _line) -+{ -+ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p", -+ nxi, nxi?nxi->nx_id:0, -+ nxi?atomic_read(&nxi->nx_usecnt):0, -+ nxi?atomic_read(&nxi->nx_tasks):0, -+ task, _file, _line); -+ -+ atomic_inc(&nxi->nx_tasks); -+} -+ -+ -+extern void unhash_nx_info(struct nx_info *); -+ -+#define release_nx_info(v,p) __release_nx_info(v,p,__FILE__,__LINE__) -+ -+static inline void __release_nx_info(struct nx_info *nxi, -+ struct task_struct *task, const char *_file, int _line) -+{ -+ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p", -+ nxi, nxi?nxi->nx_id:0, -+ nxi?atomic_read(&nxi->nx_usecnt):0, -+ nxi?atomic_read(&nxi->nx_tasks):0, -+ task, _file, _line); -+ -+ might_sleep(); -+ -+ if (atomic_dec_and_test(&nxi->nx_tasks)) -+ unhash_nx_info(nxi); -+} -+ -+ -+#define task_get_nx_info(i) __task_get_nx_info(i,__FILE__,__LINE__) -+ -+static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p, -+ const char *_file, int _line) -+{ -+ struct nx_info *nxi; -+ -+ task_lock(p); -+ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)", -+ p, _file, _line); -+ nxi = __get_nx_info(p->nx_info, _file, _line); -+ task_unlock(p); -+ return nxi; -+} -+ -+ -+#define nx_task_nid(t) ((t)->nid) -+ -+#define nx_current_nid() nx_task_nid(current) -+ -+#define nx_check(c,m) __nx_check(nx_current_nid(),c,m) -+ -+#define nx_weak_check(c,m) ((m) ? nx_check(c,m) : 1) -+ -+ -+#define __nx_state(v) ((v) ? ((v)->nx_state) : 0) -+ -+#define nx_info_state(v,m) (__nx_state(v) & (m)) -+ -+ -+#define __nx_flags(v) ((v) ? (v)->nx_flags : 0) -+ -+#define nx_current_flags() __nx_flags(current->nx_info) -+ -+#define nx_info_flags(v,m,f) \ -+ vx_check_flags(__nx_flags(v),(m),(f)) -+ -+#define task_nx_flags(t,m,f) \ -+ ((t) && nx_info_flags((t)->nx_info, (m), (f))) -+ -+#define nx_flags(m,f) nx_info_flags(current->nx_info,(m),(f)) -+ -+ -+/* context caps */ -+ -+#define __nx_ncaps(v) ((v) ? (v)->nx_ncaps : 0) -+ -+#define nx_current_ncaps() __nx_ncaps(current->nx_info) -+ -+#define nx_info_ncaps(v,c) (__nx_ncaps(v) & (c)) -+ -+#define nx_ncaps(c) nx_info_ncaps(current->nx_info,(c)) -+ -+ -+static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr) -+{ -+ int n,i; -+ -+ if (!nxi) -+ return 1; -+ -+ n = nxi->nbipv4; -+ for (i=0; iipv4[i] == addr) -+ return 1; -+ } -+ return 0; -+} -+ -+static inline void exit_nx_info(struct task_struct *p) -+{ -+ if (p->nx_info) -+ release_nx_info(p->nx_info, p); -+} -+ -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vs_sched.h b/include/linux/vs_sched.h -new file mode 100644 -index 0000000..fd345f7 ---- /dev/null -+++ b/include/linux/vs_sched.h -@@ -0,0 +1,93 @@ -+#ifndef _VX_VS_SCHED_H -+#define _VX_VS_SCHED_H -+ -+#include -+#include "vserver/sched.h" -+ -+ -+#define VAVAVOOM_RATIO 50 -+ -+#define MAX_PRIO_BIAS 20 -+#define MIN_PRIO_BIAS -20 -+ -+ -+static inline int vx_tokens_avail(struct vx_info *vxi) -+{ -+ return atomic_read(&vxi->sched.tokens); -+} -+ -+static inline void vx_consume_token(struct vx_info *vxi) -+{ -+ atomic_dec(&vxi->sched.tokens); -+} -+ -+static inline int vx_need_resched(struct task_struct *p) -+{ -+#ifdef CONFIG_VSERVER_HARDCPU -+ struct vx_info *vxi = p->vx_info; -+#endif -+ int slice = --p->time_slice; -+ -+#ifdef CONFIG_VSERVER_HARDCPU -+ if (vxi) { -+ int tokens; -+ -+ if ((tokens = vx_tokens_avail(vxi)) > 0) -+ vx_consume_token(vxi); -+ /* for tokens > 0, one token was consumed */ -+ if (tokens < 2) -+ return 1; -+ } -+#endif -+ return (slice == 0); -+} -+ -+ -+static inline void vx_onhold_inc(struct vx_info *vxi) -+{ -+ int onhold = atomic_read(&vxi->cvirt.nr_onhold); -+ -+ atomic_inc(&vxi->cvirt.nr_onhold); -+ if (!onhold) -+ vxi->cvirt.onhold_last = jiffies; -+} -+ -+static inline void __vx_onhold_update(struct vx_info *vxi) -+{ -+ int cpu = smp_processor_id(); -+ uint32_t now = jiffies; -+ uint32_t delta = now - vxi->cvirt.onhold_last; -+ -+ vxi->cvirt.onhold_last = now; -+ vxi->sched.cpu[cpu].hold_ticks += delta; -+} -+ -+static inline void vx_onhold_dec(struct vx_info *vxi) -+{ -+ if (atomic_dec_and_test(&vxi->cvirt.nr_onhold)) -+ __vx_onhold_update(vxi); -+} -+ -+static inline void vx_account_user(struct vx_info *vxi, -+ cputime_t cputime, int nice) -+{ -+ int cpu = smp_processor_id(); -+ -+ if (!vxi) -+ return; -+ vxi->sched.cpu[cpu].user_ticks += cputime; -+} -+ -+static inline void vx_account_system(struct vx_info *vxi, -+ cputime_t cputime, int idle) -+{ -+ int cpu = smp_processor_id(); -+ -+ if (!vxi) -+ return; -+ vxi->sched.cpu[cpu].sys_ticks += cputime; -+} -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vs_socket.h b/include/linux/vs_socket.h -new file mode 100644 -index 0000000..9173bfe ---- /dev/null -+++ b/include/linux/vs_socket.h -@@ -0,0 +1,57 @@ -+#ifndef _VX_VS_SOCKET_H -+#define _VX_VS_SOCKET_H -+ -+#include "vserver/debug.h" -+ -+ -+/* socket accounting */ -+ -+#include -+ -+static inline int vx_sock_type(int family) -+{ -+ int type = 4; -+ -+ if (family > 0 && family < 3) -+ type = family; -+ else if (family == PF_INET6) -+ type = 3; -+ return type; -+} -+ -+#define vx_acc_sock(v,f,p,s) \ -+ __vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__) -+ -+static inline void __vx_acc_sock(struct vx_info *vxi, -+ int family, int pos, int size, char *file, int line) -+{ -+ if (vxi) { -+ int type = vx_sock_type(family); -+ -+ atomic_inc(&vxi->cacct.sock[type][pos].count); -+ atomic_add(size, &vxi->cacct.sock[type][pos].total); -+ } -+} -+ -+#define vx_sock_recv(sk,s) \ -+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s)) -+#define vx_sock_send(sk,s) \ -+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s)) -+#define vx_sock_fail(sk,s) \ -+ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s)) -+ -+ -+#define sock_vx_init(s) do { \ -+ (s)->sk_xid = 0; \ -+ (s)->sk_vx_info = NULL; \ -+ } while (0) -+ -+#define sock_nx_init(s) do { \ -+ (s)->sk_nid = 0; \ -+ (s)->sk_nx_info = NULL; \ -+ } while (0) -+ -+ -+#else -+#warning duplicate inclusion -+#endif -diff --git a/include/linux/vserver/context.h b/include/linux/vserver/context.h -new file mode 100644 -index 0000000..24c7a93 ---- /dev/null -+++ b/include/linux/vserver/context.h -@@ -0,0 +1,170 @@ -+#ifndef _VX_CONTEXT_H -+#define _VX_CONTEXT_H -+ -+#include -+#include -+ -+ -+#define MAX_S_CONTEXT 65535 /* Arbitrary limit */ -+#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */ -+ -+#define VX_DYNAMIC_ID ((uint32_t)-1) /* id for dynamic context */ -+ -+/* context flags */ -+ -+#define VXF_INFO_LOCK 0x00000001 -+#define VXF_INFO_SCHED 0x00000002 -+#define VXF_INFO_NPROC 0x00000004 -+#define VXF_INFO_PRIVATE 0x00000008 -+ -+#define VXF_INFO_INIT 0x00000010 -+#define VXF_INFO_HIDE 0x00000020 -+#define VXF_INFO_ULIMIT 0x00000040 -+#define VXF_INFO_NSPACE 0x00000080 -+ -+#define VXF_SCHED_HARD 0x00000100 -+#define VXF_SCHED_PRIO 0x00000200 -+#define VXF_SCHED_PAUSE 0x00000400 -+ -+#define VXF_VIRT_MEM 0x00010000 -+#define VXF_VIRT_UPTIME 0x00020000 -+#define VXF_VIRT_CPU 0x00040000 -+#define VXF_VIRT_LOAD 0x00080000 -+ -+#define VXF_HIDE_MOUNT 0x01000000 -+#define VXF_HIDE_NETIF 0x02000000 -+ -+#define VXF_STATE_SETUP (1ULL<<32) -+#define VXF_STATE_INIT (1ULL<<33) -+ -+#define VXF_SC_HELPER (1ULL<<36) -+#define VXF_REBOOT_KILL (1ULL<<37) -+#define VXF_PERSISTENT (1ULL<<38) -+ -+#define VXF_FORK_RSS (1ULL<<48) -+#define VXF_PROLIFIC (1ULL<<49) -+ -+#define VXF_IGNEG_NICE (1ULL<<52) -+ -+#define VXF_ONE_TIME (0x0003ULL<<32) -+ -+#define VXF_INIT_SET (VXF_STATE_SETUP|VXF_STATE_INIT) -+ -+ -+/* context migration */ -+ -+#define VXM_SET_INIT 0x00000001 -+#define VXM_SET_REAPER 0x00000002 -+ -+/* context caps */ -+ -+#define VXC_CAP_MASK 0x00000000 -+ -+#define VXC_SET_UTSNAME 0x00000001 -+#define VXC_SET_RLIMIT 0x00000002 -+ -+#define VXC_RAW_ICMP 0x00000100 -+#define VXC_SYSLOG 0x00001000 -+ -+#define VXC_SECURE_MOUNT 0x00010000 -+#define VXC_SECURE_REMOUNT 0x00020000 -+#define VXC_BINARY_MOUNT 0x00040000 -+ -+#define VXC_QUOTA_CTL 0x00100000 -+ -+ -+/* context state changes */ -+ -+enum { -+ VSC_STARTUP = 1, -+ VSC_SHUTDOWN, -+ -+ VSC_NETUP, -+ VSC_NETDOWN, -+}; -+ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+ -+#include "limit_def.h" -+#include "sched_def.h" -+#include "cvirt_def.h" -+ -+struct vx_info { -+ struct hlist_node vx_hlist; /* linked list of contexts */ -+ xid_t vx_id; /* context id */ -+ atomic_t vx_usecnt; /* usage count */ -+ atomic_t vx_tasks; /* tasks count */ -+ struct vx_info *vx_parent; /* parent context */ -+ int vx_state; /* context state */ -+ -+ struct namespace *vx_namespace; /* private namespace */ -+ struct fs_struct *vx_fs; /* private namespace fs */ -+ uint64_t vx_flags; /* context flags */ -+ uint64_t vx_bcaps; /* bounding caps (system) */ -+ uint64_t vx_ccaps; /* context caps (vserver) */ -+ -+ struct task_struct *vx_reaper; /* guest reaper process */ -+ pid_t vx_initpid; /* PID of guest init */ -+ -+ wait_queue_head_t vx_wait; /* context exit waitqueue */ -+ -+ struct _vx_limit limit; /* vserver limits */ -+ struct _vx_sched sched; /* vserver scheduler */ -+ struct _vx_cvirt cvirt; /* virtual/bias stuff */ -+ struct _vx_cacct cacct; /* context accounting */ -+ -+ char vx_name[65]; /* vserver name */ -+}; -+ -+ -+/* status flags */ -+ -+#define VXS_HASHED 0x0001 -+#define VXS_PAUSED 0x0010 -+#define VXS_ONHOLD 0x0020 -+#define VXS_SHUTDOWN 0x0100 -+#define VXS_RELEASED 0x8000 -+ -+/* check conditions */ -+ -+#define VX_ADMIN 0x0001 -+#define VX_WATCH 0x0002 -+#define VX_HIDE 0x0004 -+#define VX_HOSTID 0x0008 -+ -+#define VX_IDENT 0x0010 -+#define VX_EQUIV 0x0020 -+#define VX_PARENT 0x0040 -+#define VX_CHILD 0x0080 -+ -+#define VX_ARG_MASK 0x00F0 -+ -+#define VX_DYNAMIC 0x0100 -+#define VX_STATIC 0x0200 -+ -+#define VX_ATR_MASK 0x0F00 -+ -+ -+extern void claim_vx_info(struct vx_info *, struct task_struct *); -+extern void release_vx_info(struct vx_info *, struct task_struct *); -+ -+extern struct vx_info *lookup_vx_info(int); -+extern struct vx_info *lookup_or_create_vx_info(int); -+ -+extern int get_xid_list(int, unsigned int *, int); -+extern int xid_is_hashed(xid_t); -+ -+extern int vx_migrate_task(struct task_struct *, struct vx_info *); -+ -+extern long vs_state_change(struct vx_info *, unsigned int); -+ -+ -+#endif /* __KERNEL__ */ -+#else /* _VX_CONTEXT_H */ -+#warning duplicate inclusion -+#endif /* _VX_CONTEXT_H */ -diff --git a/include/linux/vserver/context_cmd.h b/include/linux/vserver/context_cmd.h -new file mode 100644 -index 0000000..5a3195f ---- /dev/null -+++ b/include/linux/vserver/context_cmd.h -@@ -0,0 +1,84 @@ -+#ifndef _VX_CONTEXT_CMD_H -+#define _VX_CONTEXT_CMD_H -+ -+ -+/* vinfo commands */ -+ -+#define VCMD_task_xid VC_CMD(VINFO, 1, 0) -+ -+#ifdef __KERNEL__ -+extern int vc_task_xid(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+ -+#define VCMD_vx_info VC_CMD(VINFO, 5, 0) -+ -+struct vcmd_vx_info_v0 { -+ uint32_t xid; -+ uint32_t initpid; -+ /* more to come */ -+}; -+ -+#ifdef __KERNEL__ -+extern int vc_vx_info(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+ -+ -+/* context commands */ -+ -+#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0) -+#define VCMD_ctx_create VC_CMD(VPROC, 1, 1) -+ -+struct vcmd_ctx_create { -+ uint64_t flagword; -+}; -+ -+#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0) -+#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1) -+ -+struct vcmd_ctx_migrate { -+ uint64_t flagword; -+}; -+ -+#ifdef __KERNEL__ -+extern int vc_ctx_create(uint32_t, void __user *); -+extern int vc_ctx_migrate(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+ -+ -+/* flag commands */ -+ -+#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0) -+#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0) -+ -+struct vcmd_ctx_flags_v0 { -+ uint64_t flagword; -+ uint64_t mask; -+}; -+ -+#ifdef __KERNEL__ -+extern int vc_get_cflags(uint32_t, void __user *); -+extern int vc_set_cflags(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+ -+ -+/* context caps commands */ -+ -+#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 0) -+#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 0) -+ -+struct vcmd_ctx_caps_v0 { -+ uint64_t bcaps; -+ uint64_t ccaps; -+ uint64_t cmask; -+}; -+ -+#ifdef __KERNEL__ -+extern int vc_get_ccaps(uint32_t, void __user *); -+extern int vc_set_ccaps(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_CONTEXT_CMD_H */ -diff --git a/include/linux/vserver/cvirt.h b/include/linux/vserver/cvirt.h -new file mode 100644 -index 0000000..204db79 ---- /dev/null -+++ b/include/linux/vserver/cvirt.h -@@ -0,0 +1,26 @@ -+#ifndef _VX_CVIRT_H -+#define _VX_CVIRT_H -+ -+ -+#ifdef __KERNEL__ -+ -+struct timespec; -+ -+void vx_vsi_uptime(struct timespec *, struct timespec *); -+ -+ -+struct vx_info; -+ -+void vx_update_load(struct vx_info *); -+ -+ -+int vx_uts_virt_handler(struct ctl_table *ctl, int write, xid_t xid, -+ void **datap, size_t *lenp); -+ -+ -+int vx_do_syslog(int, char __user *, int); -+ -+#endif /* __KERNEL__ */ -+#else /* _VX_CVIRT_H */ -+#warning duplicate inclusion -+#endif /* _VX_CVIRT_H */ -diff --git a/include/linux/vserver/cvirt_cmd.h b/include/linux/vserver/cvirt_cmd.h -new file mode 100644 -index 0000000..6720469 ---- /dev/null -+++ b/include/linux/vserver/cvirt_cmd.h -@@ -0,0 +1,35 @@ -+#ifndef _VX_CVIRT_CMD_H -+#define _VX_CVIRT_CMD_H -+ -+ -+/* virtual host info name commands */ -+ -+#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0) -+#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0) -+ -+struct vcmd_vhi_name_v0 { -+ uint32_t field; -+ char name[65]; -+}; -+ -+ -+enum vhi_name_field { -+ VHIN_CONTEXT=0, -+ VHIN_SYSNAME, -+ VHIN_NODENAME, -+ VHIN_RELEASE, -+ VHIN_VERSION, -+ VHIN_MACHINE, -+ VHIN_DOMAINNAME, -+}; -+ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+extern int vc_set_vhi_name(uint32_t, void __user *); -+extern int vc_get_vhi_name(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_CVIRT_CMD_H */ -diff --git a/include/linux/vserver/cvirt_def.h b/include/linux/vserver/cvirt_def.h -new file mode 100644 -index 0000000..eae2ec2 ---- /dev/null -+++ b/include/linux/vserver/cvirt_def.h -@@ -0,0 +1,78 @@ -+#ifndef _VX_CVIRT_DEF_H -+#define _VX_CVIRT_DEF_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+struct _vx_usage_stat { -+ uint64_t user; -+ uint64_t nice; -+ uint64_t system; -+ uint64_t softirq; -+ uint64_t irq; -+ uint64_t idle; -+ uint64_t iowait; -+}; -+ -+struct _vx_syslog { -+ wait_queue_head_t log_wait; -+ spinlock_t logbuf_lock; /* lock for the log buffer */ -+ -+ unsigned long log_start; /* next char to be read by syslog() */ -+ unsigned long con_start; /* next char to be sent to consoles */ -+ unsigned long log_end; /* most-recently-written-char + 1 */ -+ unsigned long logged_chars; /* #chars since last read+clear operation */ -+ -+ char log_buf[1024]; -+}; -+ -+ -+/* context sub struct */ -+ -+struct _vx_cvirt { -+ int max_threads; /* maximum allowed threads */ -+ atomic_t nr_threads; /* number of current threads */ -+ atomic_t nr_running; /* number of running threads */ -+ atomic_t nr_uninterruptible; /* number of uninterruptible threads */ -+ -+ atomic_t nr_onhold; /* processes on hold */ -+ uint32_t onhold_last; /* jiffies when put on hold */ -+ -+ struct timespec bias_idle; -+ struct timespec bias_uptime; /* context creation point */ -+ uint64_t bias_clock; /* offset in clock_t */ -+ -+ struct new_utsname utsname; -+ -+ spinlock_t load_lock; /* lock for the load averages */ -+ atomic_t load_updates; /* nr of load updates done so far */ -+ uint32_t load_last; /* last time load was cacled */ -+ uint32_t load[3]; /* load averages 1,5,15 */ -+ -+ atomic_t total_forks; /* number of forks so far */ -+ -+ struct _vx_usage_stat cpustat[NR_CPUS]; -+ -+ struct _vx_syslog syslog; -+}; -+ -+struct _vx_sock_acc { -+ atomic_t count; -+ atomic_t total; -+}; -+ -+/* context sub struct */ -+ -+struct _vx_cacct { -+ unsigned long total_forks; -+ -+ struct _vx_sock_acc sock[5][3]; -+}; -+ -+#endif /* _VX_CVIRT_DEF_H */ -diff --git a/include/linux/vserver/debug.h b/include/linux/vserver/debug.h -new file mode 100644 -index 0000000..3defb65 ---- /dev/null -+++ b/include/linux/vserver/debug.h -@@ -0,0 +1,297 @@ -+#ifndef _VX_DEBUG_H -+#define _VX_DEBUG_H -+ -+#include -+ -+ -+#define VXD_CBIT(n,m) (vx_debug_ ## n & (1 << (m))) -+#define VXD_CMIN(n,m) (vx_debug_ ## n > (m)) -+#define VXD_MASK(n,m) (vx_debug_ ## n & (m)) -+ -+#define VXD_QPOS(v,p) (((uint32_t)(v) >> ((p)*8)) & 0xFF) -+#define VXD_QUAD(v) VXD_QPOS(v,0), VXD_QPOS(v,1), \ -+ VXD_QPOS(v,2), VXD_QPOS(v,3) -+#define VXF_QUAD "%u.%u.%u.%u" -+ -+#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \ -+ imajor((d)->bd_inode), iminor((d)->bd_inode) -+#define VXF_DEV "%p[%lu,%d:%d]" -+ -+ -+#define __FUNC__ __func__ -+ -+ -+#ifdef CONFIG_VSERVER_DEBUG -+ -+extern unsigned int vx_debug_switch; -+extern unsigned int vx_debug_xid; -+extern unsigned int vx_debug_nid; -+extern unsigned int vx_debug_net; -+extern unsigned int vx_debug_limit; -+extern unsigned int vx_debug_cres; -+extern unsigned int vx_debug_dlim; -+extern unsigned int vx_debug_cvirt; -+extern unsigned int vx_debug_misc; -+ -+ -+#define VX_LOGLEVEL "vxD: " -+#define VX_WARNLEVEL KERN_WARNING "vxW: " -+ -+#define vxdprintk(c,f,x...) \ -+ do { \ -+ if (c) \ -+ printk(VX_LOGLEVEL f "\n" , ##x); \ -+ } while (0) -+ -+#define vxlprintk(c,f,x...) \ -+ do { \ -+ if (c) \ -+ printk(VX_LOGLEVEL f " @%s:%d\n", x); \ -+ } while (0) -+ -+#define vxfprintk(c,f,x...) \ -+ do { \ -+ if (c) \ -+ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \ -+ } while (0) -+ -+ -+#define vxwprintk(c,f,x...) \ -+ do { \ -+ if (c) \ -+ printk(VX_WARNLEVEL f "\n" , ##x); \ -+ } while (0) -+ -+ -+#define vxd_path(d,m) \ -+ ({ static char _buffer[PATH_MAX]; \ -+ d_path((d), (m), _buffer, sizeof(_buffer)); }) -+ -+#else /* CONFIG_VSERVER_DEBUG */ -+ -+#define vx_debug_switch 0 -+#define vx_debug_xid 0 -+#define vx_debug_nid 0 -+#define vx_debug_net 0 -+#define vx_debug_limit 0 -+#define vx_debug_cres 0 -+#define vx_debug_dlim 0 -+#define vx_debug_cvirt 0 -+ -+#define vxdprintk(x...) do { } while (0) -+#define vxlprintk(x...) do { } while (0) -+#define vxfprintk(x...) do { } while (0) -+#define vxwprintk(x...) do { } while (0) -+ -+#define vxd_path "" -+ -+#endif /* CONFIG_VSERVER_DEBUG */ -+ -+ -+/* history stuff */ -+ -+#ifdef CONFIG_VSERVER_HISTORY -+ -+ -+extern unsigned volatile int vxh_active; -+ -+struct _vxhe_vxi { -+ struct vx_info *ptr; -+ unsigned xid; -+ unsigned usecnt; -+ unsigned tasks; -+}; -+ -+struct _vxhe_set_clr { -+ void *data; -+}; -+ -+struct _vxhe_loc_lookup { -+ unsigned arg; -+}; -+ -+enum { -+ VXH_UNUSED=0, -+ VXH_THROW_OOPS=1, -+ -+ VXH_GET_VX_INFO, -+ VXH_PUT_VX_INFO, -+ VXH_INIT_VX_INFO, -+ VXH_SET_VX_INFO, -+ VXH_CLR_VX_INFO, -+ VXH_CLAIM_VX_INFO, -+ VXH_RELEASE_VX_INFO, -+ VXH_ALLOC_VX_INFO, -+ VXH_DEALLOC_VX_INFO, -+ VXH_HASH_VX_INFO, -+ VXH_UNHASH_VX_INFO, -+ VXH_LOC_VX_INFO, -+ VXH_LOOKUP_VX_INFO, -+ VXH_CREATE_VX_INFO, -+}; -+ -+struct _vx_hist_entry { -+ void *loc; -+ unsigned short seq; -+ unsigned short type; -+ struct _vxhe_vxi vxi; -+ union { -+ struct _vxhe_set_clr sc; -+ struct _vxhe_loc_lookup ll; -+ }; -+}; -+ -+struct _vx_hist_entry *vxh_advance(void *loc); -+ -+ -+static inline -+void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi) -+{ -+ entry->vxi.ptr = vxi; -+ if (vxi) { -+ entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt); -+ entry->vxi.tasks = atomic_read(&vxi->vx_tasks); -+ entry->vxi.xid = vxi->vx_id; -+ } -+} -+ -+ -+#define __HERE__ current_text_addr() -+ -+#define __VXH_BODY(__type, __data, __here) \ -+ struct _vx_hist_entry *entry; \ -+ \ -+ preempt_disable(); \ -+ entry = vxh_advance(__here); \ -+ __data; \ -+ entry->type = __type; \ -+ preempt_enable(); -+ -+ -+ /* pass vxi only */ -+ -+#define __VXH_SMPL \ -+ __vxh_copy_vxi(entry, vxi) -+ -+static inline -+void __vxh_smpl(struct vx_info *vxi, int __type, void *__here) -+{ -+ __VXH_BODY(__type, __VXH_SMPL, __here) -+} -+ -+ /* pass vxi and data (void *) */ -+ -+#define __VXH_DATA \ -+ __vxh_copy_vxi(entry, vxi); \ -+ entry->sc.data = data -+ -+static inline -+void __vxh_data(struct vx_info *vxi, void *data, -+ int __type, void *__here) -+{ -+ __VXH_BODY(__type, __VXH_DATA, __here) -+} -+ -+ /* pass vxi and arg (long) */ -+ -+#define __VXH_LONG \ -+ __vxh_copy_vxi(entry, vxi); \ -+ entry->ll.arg = arg -+ -+static inline -+void __vxh_long(struct vx_info *vxi, long arg, -+ int __type, void *__here) -+{ -+ __VXH_BODY(__type, __VXH_LONG, __here) -+} -+ -+ -+static inline -+void __vxh_throw_oops(void *__here) -+{ -+ __VXH_BODY(VXH_THROW_OOPS, {}, __here); -+ /* prevent further acquisition */ -+ vxh_active = 0; -+} -+ -+ -+#define vxh_throw_oops() __vxh_throw_oops(__HERE__); -+ -+#define __vxh_get_vx_info(v,h) __vxh_smpl(v, VXH_GET_VX_INFO, h); -+#define __vxh_put_vx_info(v,h) __vxh_smpl(v, VXH_PUT_VX_INFO, h); -+ -+#define __vxh_init_vx_info(v,d,h) \ -+ __vxh_data(v,d, VXH_INIT_VX_INFO, h); -+#define __vxh_set_vx_info(v,d,h) \ -+ __vxh_data(v,d, VXH_SET_VX_INFO, h); -+#define __vxh_clr_vx_info(v,d,h) \ -+ __vxh_data(v,d, VXH_CLR_VX_INFO, h); -+ -+#define __vxh_claim_vx_info(v,d,h) \ -+ __vxh_data(v,d, VXH_CLAIM_VX_INFO, h); -+#define __vxh_release_vx_info(v,d,h) \ -+ __vxh_data(v,d, VXH_RELEASE_VX_INFO, h); -+ -+#define vxh_alloc_vx_info(v) \ -+ __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__); -+#define vxh_dealloc_vx_info(v) \ -+ __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__); -+ -+#define vxh_hash_vx_info(v) \ -+ __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__); -+#define vxh_unhash_vx_info(v) \ -+ __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__); -+ -+#define vxh_loc_vx_info(v,l) \ -+ __vxh_long(v,l, VXH_LOC_VX_INFO, __HERE__); -+#define vxh_lookup_vx_info(v,l) \ -+ __vxh_long(v,l, VXH_LOOKUP_VX_INFO, __HERE__); -+#define vxh_create_vx_info(v,l) \ -+ __vxh_long(v,l, VXH_CREATE_VX_INFO, __HERE__); -+ -+extern void vxh_dump_history(void); -+ -+ -+#else /* CONFIG_VSERVER_HISTORY */ -+ -+#define __HERE__ 0 -+ -+#define vxh_throw_oops() do { } while (0) -+ -+#define __vxh_get_vx_info(v,h) do { } while (0) -+#define __vxh_put_vx_info(v,h) do { } while (0) -+ -+#define __vxh_init_vx_info(v,d,h) do { } while (0) -+#define __vxh_set_vx_info(v,d,h) do { } while (0) -+#define __vxh_clr_vx_info(v,d,h) do { } while (0) -+ -+#define __vxh_claim_vx_info(v,d,h) do { } while (0) -+#define __vxh_release_vx_info(v,d,h) do { } while (0) -+ -+#define vxh_alloc_vx_info(v) do { } while (0) -+#define vxh_dealloc_vx_info(v) do { } while (0) -+ -+#define vxh_hash_vx_info(v) do { } while (0) -+#define vxh_unhash_vx_info(v) do { } while (0) -+ -+#define vxh_loc_vx_info(a,v) do { } while (0) -+#define vxh_lookup_vx_info(a,v) do { } while (0) -+#define vxh_create_vx_info(a,v) do { } while (0) -+ -+#define vxh_dump_history() do { } while (0) -+ -+ -+#endif /* CONFIG_VSERVER_HISTORY */ -+ -+ -+#ifdef CONFIG_VSERVER_DEBUG -+#define vxd_assert_lock(l) assert_spin_locked(l) -+#define vxd_assert(c,f,x...) vxlprintk(!(c), \ -+ "assertion [" f "] failed.", ##x, __FILE__, __LINE__) -+#else -+#define vxd_assert_lock(l) do { } while (0) -+#define vxd_assert(c,f,x...) do { } while (0) -+#endif -+ -+ -+#endif /* _VX_DEBUG_H */ -diff --git a/include/linux/vserver/debug_cmd.h b/include/linux/vserver/debug_cmd.h -new file mode 100644 -index 0000000..c0cbd08 ---- /dev/null -+++ b/include/linux/vserver/debug_cmd.h -@@ -0,0 +1,14 @@ -+#ifndef _VX_DEBUG_CMD_H -+#define _VX_DEBUG_CMD_H -+ -+ -+/* debug commands */ -+ -+#define VCMD_dump_history VC_CMD(DEBUG, 1, 0) -+ -+#ifdef __KERNEL__ -+ -+extern int vc_dump_history(uint32_t); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_DEBUG_CMD_H */ -diff --git a/include/linux/vserver/dlimit.h b/include/linux/vserver/dlimit.h -new file mode 100644 -index 0000000..99c2240 ---- /dev/null -+++ b/include/linux/vserver/dlimit.h -@@ -0,0 +1,53 @@ -+#ifndef _VX_DLIMIT_H -+#define _VX_DLIMIT_H -+ -+#include "switch.h" -+ -+#define CDLIM_UNSET (0ULL) -+#define CDLIM_INFINITY (~0ULL) -+#define CDLIM_KEEP (~1ULL) -+ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct super_block; -+ -+struct dl_info { -+ struct hlist_node dl_hlist; /* linked list of contexts */ -+ struct rcu_head dl_rcu; /* the rcu head */ -+ xid_t dl_xid; /* context id */ -+ atomic_t dl_usecnt; /* usage count */ -+ atomic_t dl_refcnt; /* reference count */ -+ -+ struct super_block *dl_sb; /* associated superblock */ -+ -+ spinlock_t dl_lock; /* protect the values */ -+ -+ uint64_t dl_space_used; /* used space in bytes */ -+ uint64_t dl_space_total; /* maximum space in bytes */ -+ uint32_t dl_inodes_used; /* used inodes */ -+ uint32_t dl_inodes_total; /* maximum inodes */ -+ -+ unsigned int dl_nrlmult; /* non root limit mult */ -+}; -+ -+struct rcu_head; -+ -+extern void rcu_free_dl_info(struct rcu_head *); -+extern void unhash_dl_info(struct dl_info *); -+ -+extern struct dl_info *locate_dl_info(struct super_block *, xid_t); -+ -+ -+struct kstatfs; -+ -+extern void vx_vsi_statfs(struct super_block *, struct kstatfs *); -+ -+typedef uint64_t dlsize_t; -+ -+#endif /* __KERNEL__ */ -+#else /* _VX_DLIMIT_H */ -+#warning duplicate inclusion -+#endif /* _VX_DLIMIT_H */ -diff --git a/include/linux/vserver/dlimit_cmd.h b/include/linux/vserver/dlimit_cmd.h -new file mode 100644 -index 0000000..cc7f779 ---- /dev/null -+++ b/include/linux/vserver/dlimit_cmd.h -@@ -0,0 +1,71 @@ -+#ifndef _VX_DLIMIT_CMD_H -+#define _VX_DLIMIT_CMD_H -+ -+#include -+ -+ -+/* dlimit vserver commands */ -+ -+#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0) -+#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0) -+ -+#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0) -+#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0) -+ -+struct vcmd_ctx_dlimit_base_v0 { -+ const char __user *name; -+ uint32_t flags; -+}; -+ -+struct vcmd_ctx_dlimit_v0 { -+ const char __user *name; -+ uint32_t space_used; /* used space in kbytes */ -+ uint32_t space_total; /* maximum space in kbytes */ -+ uint32_t inodes_used; /* used inodes */ -+ uint32_t inodes_total; /* maximum inodes */ -+ uint32_t reserved; /* reserved for root in % */ -+ uint32_t flags; -+}; -+ -+ -+#ifdef __KERNEL__ -+ -+#ifdef CONFIG_COMPAT -+ -+struct vcmd_ctx_dlimit_base_v0_x32 { -+ compat_uptr_t name_ptr; -+ uint32_t flags; -+}; -+ -+struct vcmd_ctx_dlimit_v0_x32 { -+ compat_uptr_t name_ptr; -+ uint32_t space_used; /* used space in kbytes */ -+ uint32_t space_total; /* maximum space in kbytes */ -+ uint32_t inodes_used; /* used inodes */ -+ uint32_t inodes_total; /* maximum inodes */ -+ uint32_t reserved; /* reserved for root in % */ -+ uint32_t flags; -+}; -+ -+#endif /* CONFIG_COMPAT */ -+ -+#include -+ -+extern int vc_add_dlimit(uint32_t, void __user *); -+extern int vc_rem_dlimit(uint32_t, void __user *); -+ -+extern int vc_set_dlimit(uint32_t, void __user *); -+extern int vc_get_dlimit(uint32_t, void __user *); -+ -+#ifdef CONFIG_COMPAT -+ -+extern int vc_add_dlimit_x32(uint32_t, void __user *); -+extern int vc_rem_dlimit_x32(uint32_t, void __user *); -+ -+extern int vc_set_dlimit_x32(uint32_t, void __user *); -+extern int vc_get_dlimit_x32(uint32_t, void __user *); -+ -+#endif /* CONFIG_COMPAT */ -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_DLIMIT_CMD_H */ -diff --git a/include/linux/vserver/inode.h b/include/linux/vserver/inode.h -new file mode 100644 -index 0000000..a6f60f5 ---- /dev/null -+++ b/include/linux/vserver/inode.h -@@ -0,0 +1,40 @@ -+#ifndef _VX_INODE_H -+#define _VX_INODE_H -+ -+ -+#define IATTR_XID 0x01000000 -+ -+#define IATTR_ADMIN 0x00000001 -+#define IATTR_WATCH 0x00000002 -+#define IATTR_HIDE 0x00000004 -+#define IATTR_FLAGS 0x00000007 -+ -+#define IATTR_BARRIER 0x00010000 -+#define IATTR_IUNLINK 0x00020000 -+#define IATTR_IMMUTABLE 0x00040000 -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+ -+#ifdef CONFIG_VSERVER_PROC_SECURE -+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE ) -+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN ) -+#else -+#define IATTR_PROC_DEFAULT ( IATTR_ADMIN ) -+#define IATTR_PROC_SYMLINK ( IATTR_ADMIN ) -+#endif -+ -+#define vx_hide_check(c,m) (((m) & IATTR_HIDE) ? vx_check(c,m) : 1) -+ -+#endif /* __KERNEL__ */ -+ -+/* inode ioctls */ -+ -+#define FIOC_GETXFLG _IOR('x', 5, long) -+#define FIOC_SETXFLG _IOW('x', 6, long) -+ -+#else /* _VX_INODE_H */ -+#warning duplicate inclusion -+#endif /* _VX_INODE_H */ -diff --git a/include/linux/vserver/inode_cmd.h b/include/linux/vserver/inode_cmd.h -new file mode 100644 -index 0000000..70d56a8 ---- /dev/null -+++ b/include/linux/vserver/inode_cmd.h -@@ -0,0 +1,61 @@ -+#ifndef _VX_INODE_CMD_H -+#define _VX_INODE_CMD_H -+ -+ -+/* inode vserver commands */ -+ -+#define VCMD_get_iattr_v0 VC_CMD(INODE, 1, 0) -+#define VCMD_set_iattr_v0 VC_CMD(INODE, 2, 0) -+ -+#define VCMD_get_iattr VC_CMD(INODE, 1, 1) -+#define VCMD_set_iattr VC_CMD(INODE, 2, 1) -+ -+struct vcmd_ctx_iattr_v0 { -+ /* device handle in id */ -+ uint64_t ino; -+ uint32_t xid; -+ uint32_t flags; -+ uint32_t mask; -+}; -+ -+struct vcmd_ctx_iattr_v1 { -+ const char __user *name; -+ uint32_t xid; -+ uint32_t flags; -+ uint32_t mask; -+}; -+ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+ -+#ifdef CONFIG_COMPAT -+ -+struct vcmd_ctx_iattr_v1_x32 { -+ compat_uptr_t name_ptr; -+ uint32_t xid; -+ uint32_t flags; -+ uint32_t mask; -+}; -+ -+#endif /* CONFIG_COMPAT */ -+ -+#include -+ -+extern int vc_get_iattr_v0(uint32_t, void __user *); -+extern int vc_set_iattr_v0(uint32_t, void __user *); -+ -+extern int vc_get_iattr(uint32_t, void __user *); -+extern int vc_set_iattr(uint32_t, void __user *); -+ -+#ifdef CONFIG_COMPAT -+ -+extern int vc_get_iattr_x32(uint32_t, void __user *); -+extern int vc_set_iattr_x32(uint32_t, void __user *); -+ -+#endif /* CONFIG_COMPAT */ -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_INODE_CMD_H */ -diff --git a/include/linux/vserver/legacy.h b/include/linux/vserver/legacy.h -new file mode 100644 -index 0000000..41afbd9 ---- /dev/null -+++ b/include/linux/vserver/legacy.h -@@ -0,0 +1,49 @@ -+#ifndef _VX_LEGACY_H -+#define _VX_LEGACY_H -+ -+#include "switch.h" -+ -+ -+/* compatibiliy vserver commands */ -+ -+#define VCMD_new_s_context VC_CMD(COMPAT, 1, 1) -+#define VCMD_set_ipv4root VC_CMD(COMPAT, 2, 3) -+ -+#define VCMD_create_context VC_CMD(VSETUP, 1, 0) -+ -+/* compatibiliy vserver arguments */ -+ -+struct vcmd_new_s_context_v1 { -+ uint32_t remove_cap; -+ uint32_t flags; -+}; -+ -+struct vcmd_set_ipv4root_v3 { -+ /* number of pairs in id */ -+ uint32_t broadcast; -+ struct { -+ uint32_t ip; -+ uint32_t mask; -+ } nx_mask_pair[NB_IPV4ROOT]; -+}; -+ -+ -+#define VX_INFO_LOCK 1 /* Can't request a new vx_id */ -+#define VX_INFO_NPROC 4 /* Limit number of processes in a context */ -+#define VX_INFO_PRIVATE 8 /* Noone can join this security context */ -+#define VX_INFO_INIT 16 /* This process wants to become the */ -+ /* logical process 1 of the security */ -+ /* context */ -+#define VX_INFO_HIDEINFO 32 /* Hide some information in /proc */ -+#define VX_INFO_ULIMIT 64 /* Use ulimit of the current process */ -+ /* to become the global limits */ -+ /* of the context */ -+#define VX_INFO_NAMESPACE 128 /* save private namespace */ -+ -+ -+#ifdef __KERNEL__ -+extern int vc_new_s_context(uint32_t, void __user *); -+extern int vc_set_ipv4root(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_LEGACY_H */ -diff --git a/include/linux/vserver/limit.h b/include/linux/vserver/limit.h -new file mode 100644 -index 0000000..aaaee11 ---- /dev/null -+++ b/include/linux/vserver/limit.h -@@ -0,0 +1,20 @@ -+#ifndef _VX_LIMIT_H -+#define _VX_LIMIT_H -+ -+ -+#define VLIMIT_NSOCK 16 -+#define VLIMIT_OPENFD 17 -+#define VLIMIT_ANON 18 -+#define VLIMIT_SHMEM 19 -+ -+#ifdef __KERNEL__ -+ -+struct sysinfo; -+ -+void vx_vsi_meminfo(struct sysinfo *); -+void vx_vsi_swapinfo(struct sysinfo *); -+ -+#define NUM_LIMITS 24 -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_LIMIT_H */ -diff --git a/include/linux/vserver/limit_cmd.h b/include/linux/vserver/limit_cmd.h -new file mode 100644 -index 0000000..b67a309 ---- /dev/null -+++ b/include/linux/vserver/limit_cmd.h -@@ -0,0 +1,37 @@ -+#ifndef _VX_LIMIT_CMD_H -+#define _VX_LIMIT_CMD_H -+ -+ -+/* rlimit vserver commands */ -+ -+#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0) -+#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0) -+#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0) -+ -+struct vcmd_ctx_rlimit_v0 { -+ uint32_t id; -+ uint64_t minimum; -+ uint64_t softlimit; -+ uint64_t maximum; -+}; -+ -+struct vcmd_ctx_rlimit_mask_v0 { -+ uint32_t minimum; -+ uint32_t softlimit; -+ uint32_t maximum; -+}; -+ -+#define CRLIM_UNSET (0ULL) -+#define CRLIM_INFINITY (~0ULL) -+#define CRLIM_KEEP (~1ULL) -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+extern int vc_get_rlimit(uint32_t, void __user *); -+extern int vc_set_rlimit(uint32_t, void __user *); -+extern int vc_get_rlimit_mask(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_LIMIT_CMD_H */ -diff --git a/include/linux/vserver/limit_def.h b/include/linux/vserver/limit_def.h -new file mode 100644 -index 0000000..a154334 ---- /dev/null -+++ b/include/linux/vserver/limit_def.h -@@ -0,0 +1,23 @@ -+#ifndef _VX_LIMIT_DEF_H -+#define _VX_LIMIT_DEF_H -+ -+#include -+#include -+#include -+ -+#include "limit.h" -+ -+ -+/* context sub struct */ -+ -+struct _vx_limit { -+ atomic_t ticks; -+ -+ unsigned long rlim[NUM_LIMITS]; /* Context limit */ -+ unsigned long rmax[NUM_LIMITS]; /* Context maximum */ -+ atomic_t rcur[NUM_LIMITS]; /* Current value */ -+ atomic_t lhit[NUM_LIMITS]; /* Limit hits */ -+}; -+ -+ -+#endif /* _VX_LIMIT_DEF_H */ -diff --git a/include/linux/vserver/limit_int.h b/include/linux/vserver/limit_int.h -new file mode 100644 -index 0000000..a48d242 ---- /dev/null -+++ b/include/linux/vserver/limit_int.h -@@ -0,0 +1,76 @@ -+#ifndef _VX_LIMIT_INT_H -+#define _VX_LIMIT_INT_H -+ -+ -+#ifdef __KERNEL__ -+ -+#define VXD_RCRES(r) VXD_CBIT(cres, (r)) -+#define VXD_RLIMIT(r) VXD_CBIT(limit, (r)) -+ -+extern const char *vlimit_name[NUM_LIMITS]; -+ -+static inline void __vx_acc_cres(struct vx_info *vxi, -+ int res, int dir, void *_data, char *_file, int _line) -+{ -+ if (VXD_RCRES(res)) -+ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5d%s (%p)", -+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res, -+ (vxi ? atomic_read(&vxi->limit.rcur[res]) : 0), -+ (dir > 0) ? "++" : "--", _data, _file, _line); -+ if (!vxi) -+ return; -+ -+ if (dir > 0) -+ atomic_inc(&vxi->limit.rcur[res]); -+ else -+ atomic_dec(&vxi->limit.rcur[res]); -+} -+ -+static inline void __vx_add_cres(struct vx_info *vxi, -+ int res, int amount, void *_data, char *_file, int _line) -+{ -+ if (VXD_RCRES(res)) -+ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5d += %5d (%p)", -+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res, -+ (vxi ? atomic_read(&vxi->limit.rcur[res]) : 0), -+ amount, _data, _file, _line); -+ if (amount == 0) -+ return; -+ if (!vxi) -+ return; -+ atomic_add(amount, &vxi->limit.rcur[res]); -+} -+ -+static inline int __vx_cres_avail(struct vx_info *vxi, -+ int res, int num, char *_file, int _line) -+{ -+ unsigned long value; -+ -+ if (VXD_RLIMIT(res)) -+ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d", -+ (vxi ? vxi->vx_id : -1), vlimit_name[res], res, -+ (vxi ? vxi->limit.rlim[res] : 1), -+ (vxi ? atomic_read(&vxi->limit.rcur[res]) : 0), -+ num, _file, _line); -+ if (num == 0) -+ return 1; -+ if (!vxi) -+ return 1; -+ -+ value = atomic_read(&vxi->limit.rcur[res]); -+ -+ if (value > vxi->limit.rmax[res]) -+ vxi->limit.rmax[res] = value; -+ -+ if (vxi->limit.rlim[res] == RLIM_INFINITY) -+ return 1; -+ -+ if (value + num <= vxi->limit.rlim[res]) -+ return 1; -+ -+ atomic_inc(&vxi->limit.lhit[res]); -+ return 0; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_LIMIT_H */ -diff --git a/include/linux/vserver/namespace.h b/include/linux/vserver/namespace.h -new file mode 100644 -index 0000000..fb6cdd1 ---- /dev/null -+++ b/include/linux/vserver/namespace.h -@@ -0,0 +1,15 @@ -+#ifndef _VX_NAMESPACE_H -+#define _VX_NAMESPACE_H -+ -+ -+#include -+ -+struct vx_info; -+struct namespace; -+struct fs_struct; -+ -+extern int vx_set_namespace(struct vx_info *, struct namespace *, struct fs_struct *); -+ -+#else /* _VX_NAMESPACE_H */ -+#warning duplicate inclusion -+#endif /* _VX_NAMESPACE_H */ -diff --git a/include/linux/vserver/namespace_cmd.h b/include/linux/vserver/namespace_cmd.h -new file mode 100644 -index 0000000..0b3239a ---- /dev/null -+++ b/include/linux/vserver/namespace_cmd.h -@@ -0,0 +1,19 @@ -+#ifndef _VX_NAMESPACE_CMD_H -+#define _VX_NAMESPACE_CMD_H -+ -+ -+#define VCMD_enter_namespace VC_CMD(PROCALT, 1, 0) -+#define VCMD_cleanup_namespace VC_CMD(PROCALT, 2, 0) -+ -+#define VCMD_set_namespace_v0 VC_CMD(PROCALT, 3, 0) -+#define VCMD_set_namespace VC_CMD(PROCALT, 3, 1) -+ -+ -+#ifdef __KERNEL__ -+ -+extern int vc_enter_namespace(uint32_t, void __user *); -+extern int vc_cleanup_namespace(uint32_t, void __user *); -+extern int vc_set_namespace(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_NAMESPACE_CMD_H */ -diff --git a/include/linux/vserver/network.h b/include/linux/vserver/network.h -new file mode 100644 -index 0000000..1722b16 ---- /dev/null -+++ b/include/linux/vserver/network.h -@@ -0,0 +1,119 @@ -+#ifndef _VX_NETWORK_H -+#define _VX_NETWORK_H -+ -+#include -+ -+ -+#define MAX_N_CONTEXT 65535 /* Arbitrary limit */ -+ -+#define NX_DYNAMIC_ID ((uint32_t)-1) /* id for dynamic context */ -+ -+#define NB_IPV4ROOT 16 -+ -+ -+/* network flags */ -+ -+#define NXF_STATE_SETUP (1ULL<<32) -+ -+#define NXF_SC_HELPER (1ULL<<36) -+#define NXF_PERSISTENT (1ULL<<38) -+ -+#define NXF_ONE_TIME (0x0001ULL<<32) -+ -+#define NXF_INIT_SET (0) -+ -+ -+/* address types */ -+ -+#define NXA_TYPE_IPV4 1 -+#define NXA_TYPE_IPV6 2 -+ -+#define NXA_MOD_BCAST (1<<8) -+ -+#define NXA_TYPE_ANY (~0) -+ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+ -+ -+struct nx_info { -+ struct hlist_node nx_hlist; /* linked list of nxinfos */ -+ nid_t nx_id; /* vnet id */ -+ atomic_t nx_usecnt; /* usage count */ -+ atomic_t nx_tasks; /* tasks count */ -+ int nx_state; /* context state */ -+ -+ uint64_t nx_flags; /* network flag word */ -+ uint64_t nx_ncaps; /* network capabilities */ -+ -+ int nbipv4; -+ __u32 ipv4[NB_IPV4ROOT]; /* Process can only bind to these IPs */ -+ /* The first one is used to connect */ -+ /* and for bind any service */ -+ /* The other must be used explicity */ -+ __u32 mask[NB_IPV4ROOT]; /* Netmask for each ipv4 */ -+ /* Used to select the proper source */ -+ /* address for sockets */ -+ __u32 v4_bcast; /* Broadcast address to receive UDP */ -+ -+ char nx_name[65]; /* network context name */ -+}; -+ -+ -+/* status flags */ -+ -+#define NXS_HASHED 0x0001 -+#define NXS_SHUTDOWN 0x0100 -+#define NXS_RELEASED 0x8000 -+ -+extern struct nx_info *lookup_nx_info(int); -+ -+extern int get_nid_list(int, unsigned int *, int); -+extern int nid_is_hashed(nid_t); -+ -+extern int nx_migrate_task(struct task_struct *, struct nx_info *); -+ -+extern long vs_net_change(struct nx_info *, unsigned int); -+ -+struct in_ifaddr; -+struct net_device; -+ -+#ifdef CONFIG_INET -+int ifa_in_nx_info(struct in_ifaddr *, struct nx_info *); -+int dev_in_nx_info(struct net_device *, struct nx_info *); -+ -+#else /* CONFIG_INET */ -+static inline -+int ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n) -+{ -+ return 1; -+} -+ -+static inline -+int dev_in_nx_info(struct net_device *d, struct nx_info *n) -+{ -+ return 1; -+} -+#endif /* CONFIG_INET */ -+ -+struct sock; -+ -+#ifdef CONFIG_INET -+int nx_addr_conflict(struct nx_info *, uint32_t, struct sock *); -+#else /* CONFIG_INET */ -+static inline -+int nx_addr_conflict(struct nx_info *n, uint32_t a, struct sock *s) -+{ -+ return 1; -+} -+#endif /* CONFIG_INET */ -+ -+#endif /* __KERNEL__ */ -+#else /* _VX_NETWORK_H */ -+#warning duplicate inclusion -+#endif /* _VX_NETWORK_H */ -diff --git a/include/linux/vserver/network_cmd.h b/include/linux/vserver/network_cmd.h -new file mode 100644 -index 0000000..d9802fe ---- /dev/null -+++ b/include/linux/vserver/network_cmd.h -@@ -0,0 +1,89 @@ -+#ifndef _VX_NETWORK_CMD_H -+#define _VX_NETWORK_CMD_H -+ -+ -+/* vinfo commands */ -+ -+#define VCMD_task_nid VC_CMD(VINFO, 2, 0) -+ -+#ifdef __KERNEL__ -+extern int vc_task_nid(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+ -+#define VCMD_nx_info VC_CMD(VINFO, 6, 0) -+ -+struct vcmd_nx_info_v0 { -+ uint32_t nid; -+ /* more to come */ -+}; -+ -+#ifdef __KERNEL__ -+extern int vc_nx_info(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+ -+#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0) -+#define VCMD_net_create VC_CMD(VNET, 1, 1) -+ -+struct vcmd_net_create { -+ uint64_t flagword; -+}; -+ -+#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0) -+ -+#define VCMD_net_add VC_CMD(NETALT, 1, 0) -+#define VCMD_net_remove VC_CMD(NETALT, 2, 0) -+ -+struct vcmd_net_addr_v0 { -+ uint16_t type; -+ uint16_t count; -+ uint32_t ip[4]; -+ uint32_t mask[4]; -+ /* more to come */ -+}; -+ -+ -+#ifdef __KERNEL__ -+extern int vc_net_create(uint32_t, void __user *); -+extern int vc_net_migrate(uint32_t, void __user *); -+ -+extern int vc_net_add(uint32_t, void __user *); -+extern int vc_net_remove(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+ -+ -+/* flag commands */ -+ -+#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0) -+#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0) -+ -+struct vcmd_net_flags_v0 { -+ uint64_t flagword; -+ uint64_t mask; -+}; -+ -+#ifdef __KERNEL__ -+extern int vc_get_nflags(uint32_t, void __user *); -+extern int vc_set_nflags(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+ -+ -+/* network caps commands */ -+ -+#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0) -+#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0) -+ -+struct vcmd_net_caps_v0 { -+ uint64_t ncaps; -+ uint64_t cmask; -+}; -+ -+#ifdef __KERNEL__ -+extern int vc_get_ncaps(uint32_t, void __user *); -+extern int vc_set_ncaps(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_CONTEXT_CMD_H */ -diff --git a/include/linux/vserver/sched.h b/include/linux/vserver/sched.h -new file mode 100644 -index 0000000..2ef4b99 ---- /dev/null -+++ b/include/linux/vserver/sched.h -@@ -0,0 +1,26 @@ -+#ifndef _VX_SCHED_H -+#define _VX_SCHED_H -+ -+ -+#ifdef __KERNEL__ -+ -+struct timespec; -+ -+void vx_vsi_uptime(struct timespec *, struct timespec *); -+ -+ -+struct vx_info; -+ -+void vx_update_load(struct vx_info *); -+ -+ -+struct task_struct; -+ -+int vx_effective_vavavoom(struct vx_info *, int); -+ -+int vx_tokens_recalc(struct vx_info *); -+ -+#endif /* __KERNEL__ */ -+#else /* _VX_SCHED_H */ -+#warning duplicate inclusion -+#endif /* _VX_SCHED_H */ -diff --git a/include/linux/vserver/sched_cmd.h b/include/linux/vserver/sched_cmd.h -new file mode 100644 -index 0000000..b9e8ac1 ---- /dev/null -+++ b/include/linux/vserver/sched_cmd.h -@@ -0,0 +1,48 @@ -+#ifndef _VX_SCHED_CMD_H -+#define _VX_SCHED_CMD_H -+ -+ -+/* sched vserver commands */ -+ -+#define VCMD_set_sched_v2 VC_CMD(SCHED, 1, 2) -+#define VCMD_set_sched VC_CMD(SCHED, 1, 3) -+ -+struct vcmd_set_sched_v2 { -+ int32_t fill_rate; -+ int32_t interval; -+ int32_t tokens; -+ int32_t tokens_min; -+ int32_t tokens_max; -+ uint64_t cpu_mask; -+}; -+ -+struct vcmd_set_sched_v3 { -+ uint32_t set_mask; -+ int32_t fill_rate; -+ int32_t interval; -+ int32_t tokens; -+ int32_t tokens_min; -+ int32_t tokens_max; -+ int32_t priority_bias; -+}; -+ -+ -+#define VXSM_FILL_RATE 0x0001 -+#define VXSM_INTERVAL 0x0002 -+#define VXSM_TOKENS 0x0010 -+#define VXSM_TOKENS_MIN 0x0020 -+#define VXSM_TOKENS_MAX 0x0040 -+#define VXSM_PRIO_BIAS 0x0100 -+ -+#define SCHED_KEEP (-2) -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+extern int vc_set_sched_v1(uint32_t, void __user *); -+extern int vc_set_sched_v2(uint32_t, void __user *); -+extern int vc_set_sched(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_SCHED_CMD_H */ -diff --git a/include/linux/vserver/sched_def.h b/include/linux/vserver/sched_def.h -new file mode 100644 -index 0000000..ee69c9b ---- /dev/null -+++ b/include/linux/vserver/sched_def.h -@@ -0,0 +1,39 @@ -+#ifndef _VX_SCHED_DEF_H -+#define _VX_SCHED_DEF_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+struct _vx_ticks { -+ uint64_t user_ticks; /* token tick events */ -+ uint64_t sys_ticks; /* token tick events */ -+ uint64_t hold_ticks; /* token ticks paused */ -+ uint64_t unused[5]; /* cacheline ? */ -+}; -+ -+/* context sub struct */ -+ -+struct _vx_sched { -+ atomic_t tokens; /* number of CPU tokens */ -+ spinlock_t tokens_lock; /* lock for token bucket */ -+ -+ int fill_rate; /* Fill rate: add X tokens... */ -+ int interval; /* Divisor: per Y jiffies */ -+ int tokens_min; /* Limit: minimum for unhold */ -+ int tokens_max; /* Limit: no more than N tokens */ -+ uint32_t jiffies; /* last time accounted */ -+ -+ int priority_bias; /* bias offset for priority */ -+ int vavavoom; /* last calculated vavavoom */ -+ -+ cpumask_t cpus_allowed; /* cpu mask for context */ -+ -+ struct _vx_ticks cpu[NR_CPUS]; -+}; -+ -+#endif /* _VX_SCHED_DEF_H */ -diff --git a/include/linux/vserver/signal.h b/include/linux/vserver/signal.h -new file mode 100644 -index 0000000..690168e ---- /dev/null -+++ b/include/linux/vserver/signal.h -@@ -0,0 +1,14 @@ -+#ifndef _VX_SIGNAL_H -+#define _VX_SIGNAL_H -+ -+ -+#ifdef __KERNEL__ -+ -+struct vx_info; -+ -+int vx_info_kill(struct vx_info *, int, int); -+ -+#endif /* __KERNEL__ */ -+#else /* _VX_SIGNAL_H */ -+#warning duplicate inclusion -+#endif /* _VX_SIGNAL_H */ -diff --git a/include/linux/vserver/signal_cmd.h b/include/linux/vserver/signal_cmd.h -new file mode 100644 -index 0000000..a1c71eb ---- /dev/null -+++ b/include/linux/vserver/signal_cmd.h -@@ -0,0 +1,26 @@ -+#ifndef _VX_SIGNAL_CMD_H -+#define _VX_SIGNAL_CMD_H -+ -+ -+/* signalling vserver commands */ -+ -+#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0) -+#define VCMD_wait_exit VC_CMD(EVENT, 99, 0) -+ -+struct vcmd_ctx_kill_v0 { -+ int32_t pid; -+ int32_t sig; -+}; -+ -+struct vcmd_wait_exit_v0 { -+ int32_t a; -+ int32_t b; -+}; -+ -+#ifdef __KERNEL__ -+ -+extern int vc_ctx_kill(uint32_t, void __user *); -+extern int vc_wait_exit(uint32_t, void __user *); -+ -+#endif /* __KERNEL__ */ -+#endif /* _VX_SIGNAL_CMD_H */ -diff --git a/include/linux/vserver/switch.h b/include/linux/vserver/switch.h -new file mode 100644 -index 0000000..ddfba94 ---- /dev/null -+++ b/include/linux/vserver/switch.h -@@ -0,0 +1,98 @@ -+#ifndef _VX_SWITCH_H -+#define _VX_SWITCH_H -+ -+#include -+ -+ -+#define VC_CATEGORY(c) (((c) >> 24) & 0x3F) -+#define VC_COMMAND(c) (((c) >> 16) & 0xFF) -+#define VC_VERSION(c) ((c) & 0xFFF) -+ -+#define VC_CMD(c,i,v) ((((VC_CAT_ ## c) & 0x3F) << 24) \ -+ | (((i) & 0xFF) << 16) | ((v) & 0xFFF)) -+ -+/* -+ -+ Syscall Matrix V2.8 -+ -+ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL| -+ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | | -+ |INFO |SETUP | |MOVE | | | | | | -+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ -+ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICES| | -+ HOST | 00| 01| 02| 03| 04| 05| | 06| 07| -+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ -+ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | | -+ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15| -+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ -+ MEMORY | | | | | | | |SWAP | | -+ | 16| 17| 18| 19| 20| 21| | 22| 23| -+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ -+ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | | -+ | 24| 25| 26| 27| 28| 29| | 30| 31| -+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ -+ DISK | | | | |DLIMIT | | |INODE | | -+ VFS | 32| 33| 34| 35| 36| 37| | 38| 39| -+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ -+ OTHER | | | | | | | |VINFO | | -+ | 40| 41| 42| 43| 44| 45| | 46| 47| -+ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+ -+ SPECIAL|EVENT | | | |FLAGS | | | | | -+ | 48| 49| 50| 51| 52| 53| | 54| 55| -+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ -+ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT | -+ | 56| 57| 58| 59| 60|TEST 61| | 62| 63| -+ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ -+ -+*/ -+ -+#define VC_CAT_VERSION 0 -+ -+#define VC_CAT_VSETUP 1 -+#define VC_CAT_VHOST 2 -+ -+#define VC_CAT_VPROC 9 -+#define VC_CAT_PROCALT 10 -+#define VC_CAT_PROCMIG 11 -+#define VC_CAT_PROCTRL 12 -+ -+#define VC_CAT_SCHED 14 -+ -+#define VC_CAT_VNET 25 -+#define VC_CAT_NETALT 26 -+#define VC_CAT_NETMIG 27 -+#define VC_CAT_NETCTRL 28 -+ -+#define VC_CAT_DLIMIT 36 -+#define VC_CAT_INODE 38 -+ -+#define VC_CAT_VINFO 46 -+#define VC_CAT_EVENT 48 -+ -+#define VC_CAT_FLAGS 52 -+#define VC_CAT_DEBUG 56 -+#define VC_CAT_RLIMIT 60 -+ -+#define VC_CAT_SYSTEST 61 -+#define VC_CAT_COMPAT 63 -+ -+/* interface version */ -+ -+#define VCI_VERSION 0x00020001 -+#define VCI_LEGACY_VERSION 0x000100FF -+ -+/* query version */ -+ -+#define VCMD_get_version VC_CMD(VERSION, 0, 0) -+ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+ -+#else /* __KERNEL__ */ -+#define __user -+#endif /* __KERNEL__ */ -+ -+#endif /* _VX_SWITCH_H */ -diff --git a/include/linux/vserver/xid.h b/include/linux/vserver/xid.h -new file mode 100644 -index 0000000..2e4349e ---- /dev/null -+++ b/include/linux/vserver/xid.h -@@ -0,0 +1,146 @@ -+#ifndef _VX_XID_H -+#define _VX_XID_H -+ -+#include -+ -+ -+#define XID_TAG(in) (IS_TAGXID(in)) -+ -+ -+#ifdef CONFIG_XID_TAG_NFSD -+#define XID_TAG_NFSD 1 -+#else -+#define XID_TAG_NFSD 0 -+#endif -+ -+ -+#ifdef CONFIG_INOXID_NONE -+ -+#define MAX_UID 0xFFFFFFFF -+#define MAX_GID 0xFFFFFFFF -+ -+#define INOXID_XID(tag, uid, gid, xid) (0) -+ -+#define XIDINO_UID(tag, uid, xid) (uid) -+#define XIDINO_GID(tag, gid, xid) (gid) -+ -+#endif -+ -+ -+#ifdef CONFIG_INOXID_GID16 -+ -+#define MAX_UID 0xFFFFFFFF -+#define MAX_GID 0x0000FFFF -+ -+#define INOXID_XID(tag, uid, gid, xid) \ -+ ((tag) ? (((gid) >> 16) & 0xFFFF) : 0) -+ -+#define XIDINO_UID(tag, uid, xid) (uid) -+#define XIDINO_GID(tag, gid, xid) \ -+ ((tag) ? (((gid) & 0xFFFF) | ((xid) << 16)) : (gid)) -+ -+#endif -+ -+ -+#ifdef CONFIG_INOXID_UGID24 -+ -+#define MAX_UID 0x00FFFFFF -+#define MAX_GID 0x00FFFFFF -+ -+#define INOXID_XID(tag, uid, gid, xid) \ -+ ((tag) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0) -+ -+#define XIDINO_UID(tag, uid, xid) \ -+ ((tag) ? (((uid) & 0xFFFFFF) | (((xid) & 0xFF00) << 16)) : (uid)) -+#define XIDINO_GID(tag, gid, xid) \ -+ ((tag) ? (((gid) & 0xFFFFFF) | (((xid) & 0x00FF) << 24)) : (gid)) -+ -+#endif -+ -+ -+#ifdef CONFIG_INOXID_UID16 -+ -+#define MAX_UID 0x0000FFFF -+#define MAX_GID 0xFFFFFFFF -+ -+#define INOXID_XID(tag, uid, gid, xid) \ -+ ((tag) ? (((uid) >> 16) & 0xFFFF) : 0) -+ -+#define XIDINO_UID(tag, uid, xid) \ -+ ((tag) ? (((uid) & 0xFFFF) | ((xid) << 16)) : (uid)) -+#define XIDINO_GID(tag, gid, xid) (gid) -+ -+#endif -+ -+ -+#ifdef CONFIG_INOXID_INTERN -+ -+#define MAX_UID 0xFFFFFFFF -+#define MAX_GID 0xFFFFFFFF -+ -+#define INOXID_XID(tag, uid, gid, xid) \ -+ ((tag) ? (xid) : 0) -+ -+#define XIDINO_UID(tag, uid, xid) (uid) -+#define XIDINO_GID(tag, gid, xid) (gid) -+ -+#endif -+ -+ -+#ifdef CONFIG_INOXID_RUNTIME -+ -+#define MAX_UID 0xFFFFFFFF -+#define MAX_GID 0xFFFFFFFF -+ -+#define INOXID_XID(tag, uid, gid, xid) (0) -+ -+#define XIDINO_UID(tag, uid, xid) (uid) -+#define XIDINO_GID(tag, gid, xid) (gid) -+ -+#endif -+ -+ -+#ifndef CONFIG_INOXID_NONE -+#define vx_current_fsxid(sb) \ -+ ((sb)->s_flags & MS_TAGXID ? current->xid : 0) -+#else -+#define vx_current_fsxid(sb) (0) -+#endif -+ -+#ifndef CONFIG_INOXID_INTERN -+#define XIDINO_XID(tag, xid) (0) -+#else -+#define XIDINO_XID(tag, xid) ((tag) ? (xid) : 0) -+#endif -+ -+#define INOXID_UID(tag, uid, gid) \ -+ ((tag) ? ((uid) & MAX_UID) : (uid)) -+#define INOXID_GID(tag, uid, gid) \ -+ ((tag) ? ((gid) & MAX_GID) : (gid)) -+ -+ -+static inline uid_t vx_map_uid(uid_t uid) -+{ -+ if ((uid > MAX_UID) && (uid != -1)) -+ uid = -2; -+ return (uid & MAX_UID); -+} -+ -+static inline gid_t vx_map_gid(gid_t gid) -+{ -+ if ((gid > MAX_GID) && (gid != -1)) -+ gid = -2; -+ return (gid & MAX_GID); -+} -+ -+ -+#ifdef CONFIG_VSERVER_LEGACY -+#define FIOC_GETXID _IOR('x', 1, long) -+#define FIOC_SETXID _IOW('x', 2, long) -+#define FIOC_SETXIDJ _IOW('x', 3, long) -+#endif -+ -+int vx_parse_xid(char *string, xid_t *xid, int remove); -+void vx_propagate_xid(struct nameidata *nd, struct inode *inode); -+ -+#endif /* _VX_XID_H */ -diff --git a/include/net/af_unix.h b/include/net/af_unix.h -index bfc1779..9dd2fac 100644 ---- a/include/net/af_unix.h -+++ b/include/net/af_unix.h -@@ -17,9 +17,9 @@ extern spinlock_t unix_table_lock; - - extern atomic_t unix_tot_inflight; - --static inline struct sock *first_unix_socket(int *i) -+static inline struct sock *next_unix_socket_table(int *i) - { -- for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) { -+ for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) { - if (!hlist_empty(&unix_socket_table[*i])) - return __sk_head(&unix_socket_table[*i]); - } -@@ -28,16 +28,19 @@ static inline struct sock *first_unix_so - - static inline struct sock *next_unix_socket(int *i, struct sock *s) - { -- struct sock *next = sk_next(s); -- /* More in this chain? */ -- if (next) -- return next; -- /* Look for next non-empty chain. */ -- for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) { -- if (!hlist_empty(&unix_socket_table[*i])) -- return __sk_head(&unix_socket_table[*i]); -- } -- return NULL; -+ do { -+ if (s) -+ s = sk_next(s); -+ if (!s) -+ s = next_unix_socket_table(i); -+ } while (s && !vx_check(s->sk_xid, VX_IDENT|VX_WATCH)); -+ return s; -+} -+ -+static inline struct sock *first_unix_socket(int *i) -+{ -+ *i = 0; -+ return next_unix_socket(i, NULL); - } - - #define forall_unix_sockets(i, s) \ -diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h -index 135d80f..1a80498 100644 ---- a/include/net/inet_hashtables.h -+++ b/include/net/inet_hashtables.h -@@ -272,6 +272,25 @@ static inline int inet_iif(const struct - return ((struct rtable *)skb->dst)->rt_iif; - } - -+/* -+ * Check if a given address matches for an inet socket -+ * -+ * nxi: the socket's nx_info if any -+ * addr: to be verified address -+ * saddr: socket addresses -+ */ -+static inline int inet_addr_match ( -+ struct nx_info *nxi, -+ uint32_t addr, -+ uint32_t saddr) -+{ -+ if (addr && (saddr == addr)) -+ return 1; -+ if (!saddr) -+ return addr_in_nx_info(nxi, addr); -+ return 0; -+} -+ - extern struct sock *__inet_lookup_listener(const struct hlist_head *head, - const u32 daddr, - const unsigned short hnum, -@@ -292,7 +311,7 @@ static inline struct sock * - const struct inet_sock *inet = inet_sk((sk = __sk_head(head))); - - if (inet->num == hnum && !sk->sk_node.next && -- (!inet->rcv_saddr || inet->rcv_saddr == daddr) && -+ inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) && - (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && - !sk->sk_bound_dev_if) - goto sherry_cache; -diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h -index 883eb52..4824254 100644 ---- a/include/net/inet_sock.h -+++ b/include/net/inet_sock.h -@@ -115,6 +115,7 @@ struct inet_sock { - /* Socket demultiplex comparisons on incoming packets. */ - __u32 daddr; - __u32 rcv_saddr; -+ __u32 rcv_saddr2; /* Second bound ipv4 addr, for ipv4root */ - __u16 dport; - __u16 num; - __u32 saddr; -diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h -index 1da294c..4f9f2b0 100644 ---- a/include/net/inet_timewait_sock.h -+++ b/include/net/inet_timewait_sock.h -@@ -116,6 +116,10 @@ struct inet_timewait_sock { - #define tw_refcnt __tw_common.skc_refcnt - #define tw_hash __tw_common.skc_hash - #define tw_prot __tw_common.skc_prot -+#define tw_xid __tw_common.skc_xid -+#define tw_vx_info __tw_common.skc_vx_info -+#define tw_nid __tw_common.skc_nid -+#define tw_nx_info __tw_common.skc_nx_info - volatile unsigned char tw_substate; - /* 3 bits hole, try to pack */ - unsigned char tw_rcv_wscale; -diff --git a/include/net/route.h b/include/net/route.h -index 9c04f15..e9ba7a4 100644 ---- a/include/net/route.h -+++ b/include/net/route.h -@@ -28,11 +28,14 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include -+#include -+#include - - #ifndef __KERNEL__ - #warning This file is not supposed to be used outside of kernel. -@@ -144,6 +147,59 @@ static inline char rt_tos2priority(u8 to - return ip_tos2prio[IPTOS_TOS(tos)>>1]; - } - -+#define IPI_LOOPBACK htonl(INADDR_LOOPBACK) -+ -+static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl) -+{ -+ int err; -+ int i, n = nxi->nbipv4; -+ u32 ipv4root = nxi->ipv4[0]; -+ -+ if (ipv4root == 0) -+ return 0; -+ -+ if (fl->fl4_src == 0) { -+ if (n > 1) { -+ u32 foundsrc; -+ -+ err = __ip_route_output_key(rp, fl); -+ if (err) { -+ fl->fl4_src = ipv4root; -+ err = __ip_route_output_key(rp, fl); -+ } -+ if (err) -+ return err; -+ -+ foundsrc = (*rp)->rt_src; -+ ip_rt_put(*rp); -+ -+ for (i=0; imask[i]; -+ u32 ipv4 = nxi->ipv4[i]; -+ u32 net4 = ipv4 & mask; -+ -+ if (foundsrc == ipv4) { -+ fl->fl4_src = ipv4; -+ break; -+ } -+ if (!fl->fl4_src && (foundsrc & mask) == net4) -+ fl->fl4_src = ipv4; -+ } -+ } -+ if (fl->fl4_src == 0) -+ fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK) -+ ? IPI_LOOPBACK : ipv4root; -+ } else { -+ for (i=0; iipv4[i] == fl->fl4_src) -+ break; -+ } -+ if (i == n) -+ return -EPERM; -+ } -+ return 0; -+} -+ - static inline int ip_route_connect(struct rtable **rp, u32 dst, - u32 src, u32 tos, int oif, u8 protocol, - u16 sport, u16 dport, struct sock *sk) -@@ -158,7 +214,23 @@ static inline int ip_route_connect(struc - .dport = dport } } }; - - int err; -- if (!dst || !src) { -+ struct nx_info *nx_info = current->nx_info; -+ -+ if (sk) -+ nx_info = sk->sk_nx_info; -+ vxdprintk(VXD_CBIT(net, 4), -+ "ip_route_connect(%p) %p,%p;%lx", -+ sk, nx_info, sk->sk_socket, -+ (sk->sk_socket?sk->sk_socket->flags:0)); -+ -+ if (nx_info) { -+ err = ip_find_src(nx_info, rp, &fl); -+ if (err) -+ return err; -+ if (fl.fl4_dst == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) -+ fl.fl4_dst = nx_info->ipv4[0]; -+ } -+ if (!fl.fl4_dst || !fl.fl4_src) { - err = __ip_route_output_key(rp, &fl); - if (err) - return err; -diff --git a/include/net/sock.h b/include/net/sock.h -index 3075803..bcdf50d 100644 ---- a/include/net/sock.h -+++ b/include/net/sock.h -@@ -115,6 +115,10 @@ struct sock_common { - atomic_t skc_refcnt; - unsigned int skc_hash; - struct proto *skc_prot; -+ xid_t skc_xid; -+ struct vx_info *skc_vx_info; -+ nid_t skc_nid; -+ struct nx_info *skc_nx_info; - }; - - /** -@@ -189,6 +193,10 @@ struct sock { - #define sk_refcnt __sk_common.skc_refcnt - #define sk_hash __sk_common.skc_hash - #define sk_prot __sk_common.skc_prot -+#define sk_xid __sk_common.skc_xid -+#define sk_vx_info __sk_common.skc_vx_info -+#define sk_nid __sk_common.skc_nid -+#define sk_nx_info __sk_common.skc_nx_info - unsigned char sk_shutdown : 2, - sk_no_check : 2, - sk_userlocks : 4; -diff --git a/ipc/mqueue.c b/ipc/mqueue.c -index fd2e26b..6fc128e 100644 ---- a/ipc/mqueue.c -+++ b/ipc/mqueue.c -@@ -25,6 +25,8 @@ - #include - #include - #include -+#include -+#include - #include - #include "util.h" - -@@ -148,17 +150,20 @@ static struct inode *mqueue_get_inode(st - spin_lock(&mq_lock); - if (u->mq_bytes + mq_bytes < u->mq_bytes || - u->mq_bytes + mq_bytes > -- p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) { -+ p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur || -+ !vx_ipcmsg_avail(p->vx_info, mq_bytes)) { - spin_unlock(&mq_lock); - goto out_inode; - } - u->mq_bytes += mq_bytes; -+ vx_ipcmsg_add(p->vx_info, u, mq_bytes); - spin_unlock(&mq_lock); - - info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); - if (!info->messages) { - spin_lock(&mq_lock); - u->mq_bytes -= mq_bytes; -+ vx_ipcmsg_sub(p->vx_info, u, mq_bytes); - spin_unlock(&mq_lock); - goto out_inode; - } -@@ -256,10 +261,14 @@ static void mqueue_delete_inode(struct i - (info->attr.mq_maxmsg * info->attr.mq_msgsize)); - user = info->user; - if (user) { -+ struct vx_info *vxi = lookup_vx_info(user->xid); -+ - spin_lock(&mq_lock); - user->mq_bytes -= mq_bytes; -+ vx_ipcmsg_sub(vxi, user, mq_bytes); - queues_count--; - spin_unlock(&mq_lock); -+ put_vx_info(vxi); - free_uid(user); - } - } -@@ -738,7 +747,7 @@ asmlinkage long sys_mq_unlink(const char - if (inode) - atomic_inc(&inode->i_count); - -- err = vfs_unlink(dentry->d_parent->d_inode, dentry); -+ err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL); - out_err: - dput(dentry); - -diff --git a/ipc/msg.c b/ipc/msg.c -index fbf7570..10459e8 100644 ---- a/ipc/msg.c -+++ b/ipc/msg.c -@@ -100,6 +100,7 @@ static int newque (key_t key, int msgflg - - msq->q_perm.mode = (msgflg & S_IRWXUGO); - msq->q_perm.key = key; -+ msq->q_perm.xid = vx_current_xid(); - - msq->q_perm.security = NULL; - retval = security_msg_queue_alloc(msq); -@@ -815,6 +816,9 @@ static int sysvipc_msg_proc_show(struct - { - struct msg_queue *msq = it; - -+ if (!vx_check(msq->q_perm.xid, VX_IDENT)) -+ return 0; -+ - return seq_printf(s, - "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", - msq->q_perm.key, -diff --git a/ipc/sem.c b/ipc/sem.c -index 31fd402..1a68338 100644 ---- a/ipc/sem.c -+++ b/ipc/sem.c -@@ -179,6 +179,7 @@ static int newary (key_t key, int nsems, - - sma->sem_perm.mode = (semflg & S_IRWXUGO); - sma->sem_perm.key = key; -+ sma->sem_perm.xid = vx_current_xid(); - - sma->sem_perm.security = NULL; - retval = security_sem_alloc(sma); -@@ -1337,6 +1338,9 @@ static int sysvipc_sem_proc_show(struct - { - struct sem_array *sma = it; - -+ if (!vx_check(sma->sem_perm.xid, VX_IDENT)) -+ return 0; -+ - return seq_printf(s, - "%10d %10d %4o %10lu %5u %5u %5u %5u %10lu %10lu\n", - sma->sem_perm.key, -diff --git a/ipc/shm.c b/ipc/shm.c -index 9162123..918b2ff 100644 ---- a/ipc/shm.c -+++ b/ipc/shm.c -@@ -30,6 +30,8 @@ - #include - #include - #include -+#include -+#include - - #include - -@@ -114,7 +116,12 @@ static void shm_open (struct vm_area_str - */ - static void shm_destroy (struct shmid_kernel *shp) - { -- shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid); -+ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ -+ vx_ipcshm_sub(vxi, shp, numpages); -+ shm_tot -= numpages; -+ - shm_rmid (shp->id); - shm_unlock(shp); - if (!is_file_hugepages(shp->shm_file)) -@@ -124,6 +131,7 @@ static void shm_destroy (struct shmid_ke - shp->mlock_user); - fput (shp->shm_file); - security_shm_free(shp); -+ put_vx_info(vxi); - ipc_rcu_putref(shp); - } - -@@ -198,12 +206,15 @@ static int newseg (key_t key, int shmflg - - if (shm_tot + numpages >= shm_ctlall) - return -ENOSPC; -+ if (!vx_ipcshm_avail(current->vx_info, numpages)) -+ return -ENOSPC; - - shp = ipc_rcu_alloc(sizeof(*shp)); - if (!shp) - return -ENOMEM; - - shp->shm_perm.key = key; -+ shp->shm_perm.xid = vx_current_xid(); - shp->shm_perm.mode = (shmflg & S_IRWXUGO); - shp->mlock_user = NULL; - -@@ -254,6 +265,7 @@ static int newseg (key_t key, int shmflg - file->f_op = &shm_file_operations; - - shm_tot += numpages; -+ vx_ipcshm_add(current->vx_info, key, numpages); - shm_unlock(shp); - return shp->id; - -@@ -895,6 +907,9 @@ static int sysvipc_shm_proc_show(struct - #define SMALL_STRING "%10d %10d %4o %10u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n" - #define BIG_STRING "%10d %10d %4o %21u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n" - -+ if (!vx_check(shp->shm_perm.xid, VX_IDENT)) -+ return 0; -+ - if (sizeof(size_t) <= sizeof(int)) - format = SMALL_STRING; - else -diff --git a/ipc/util.c b/ipc/util.c -index 8626219..9de6620 100644 ---- a/ipc/util.c -+++ b/ipc/util.c -@@ -154,7 +154,9 @@ int ipc_findkey(struct ipc_ids* ids, key - */ - for (id = 0; id <= max_id; id++) { - p = ids->entries->p[id]; -- if(p==NULL) -+ if (p==NULL) -+ continue; -+ if (!vx_check(p->xid, VX_IDENT)) - continue; - if (key == p->key) - return id; -@@ -468,6 +470,8 @@ int ipcperms (struct kern_ipc_perm *ipcp - { /* flag will most probably be 0 or S_...UGO from */ - int requested_mode, granted_mode; - -+ if (!vx_check(ipcp->xid, VX_ADMIN|VX_IDENT)) /* maybe just VX_IDENT? */ -+ return -1; - requested_mode = (flag >> 6) | (flag >> 3) | flag; - granted_mode = ipcp->mode; - if (current->euid == ipcp->cuid || current->euid == ipcp->uid) -diff --git a/kernel/Makefile b/kernel/Makefile -index 4ae0fbd..2d89af0 100644 ---- a/kernel/Makefile -+++ b/kernel/Makefile -@@ -10,6 +10,8 @@ obj-y = sched.o fork.o exec_domain.o - kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ - hrtimer.o - -+obj-y += vserver/ -+ - obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o - obj-$(CONFIG_FUTEX) += futex.o - obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o -diff --git a/kernel/capability.c b/kernel/capability.c -index bfa3c92..08e5fe7 100644 ---- a/kernel/capability.c -+++ b/kernel/capability.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - - unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ -diff --git a/kernel/cpuset.c b/kernel/cpuset.c -index 12815d3..b6c29ae 100644 ---- a/kernel/cpuset.c -+++ b/kernel/cpuset.c -@@ -50,6 +50,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/kernel/exit.c b/kernel/exit.c -index 531aadc..7428f48 100644 ---- a/kernel/exit.c -+++ b/kernel/exit.c -@@ -31,6 +31,10 @@ - #include - #include - #include -+#include -+#include -+#include -+#include - - #include - #include -@@ -237,6 +241,7 @@ static void reparent_to_init(void) - ptrace_unlink(current); - /* Reparent to init */ - REMOVE_LINKS(current); -+ /* FIXME: handle vchild_reaper/initpid */ - current->parent = child_reaper; - current->real_parent = child_reaper; - SET_LINKS(current); -@@ -396,6 +401,7 @@ static void close_files(struct files_str - struct file * file = xchg(&fdt->fd[i], NULL); - if (file) - filp_close(file, files); -+ vx_openfd_dec(i); - } - i++; - set >>= 1; -@@ -536,7 +542,7 @@ static void exit_mm(struct task_struct * - mmput(mm); - } - --static inline void choose_new_parent(task_t *p, task_t *reaper, task_t *child_reaper) -+static inline void choose_new_parent(task_t *p, task_t *reaper) - { - /* - * Make sure we're not reparenting to ourselves and that -@@ -616,10 +622,11 @@ static void forget_original_parent(struc - struct task_struct *p, *reaper = father; - struct list_head *_p, *_n; - -+ /* FIXME: handle vchild_reaper/initpid */ - do { - reaper = next_thread(reaper); - if (reaper == father) { -- reaper = child_reaper; -+ reaper = vx_child_reaper(father); - break; - } - } while (reaper->exit_state); -@@ -643,7 +650,7 @@ static void forget_original_parent(struc - - if (father == p->real_parent) { - /* reparent with a reaper, real father it's us */ -- choose_new_parent(p, reaper, child_reaper); -+ choose_new_parent(p, vx_child_reaper(p)); - reparent_thread(p, father, 0); - } else { - /* reparent ptraced task to its real parent */ -@@ -664,7 +671,11 @@ static void forget_original_parent(struc - } - list_for_each_safe(_p, _n, &father->ptrace_children) { - p = list_entry(_p,struct task_struct,ptrace_list); -- choose_new_parent(p, reaper, child_reaper); -+ -+ /* check for reaper context */ -+ BUG_ON(p->xid != reaper->xid); -+ -+ choose_new_parent(p, reaper); - reparent_thread(p, father, 1); - } - } -@@ -858,6 +869,8 @@ fastcall NORET_TYPE void do_exit(long co - __exit_files(tsk); - __exit_fs(tsk); - exit_namespace(tsk); -+ exit_vx_info(tsk); -+ exit_nx_info(tsk); - exit_thread(); - cpuset_exit(tsk); - exit_keys(tsk); -diff --git a/kernel/fork.c b/kernel/fork.c -index a8eab86..c6a2ba4 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -44,6 +44,10 @@ - #include - #include - #include -+#include -+#include -+#include -+#include - - #include - #include -@@ -104,6 +108,8 @@ static kmem_cache_t *mm_cachep; - void free_task(struct task_struct *tsk) - { - free_thread_info(tsk->thread_info); -+ clr_vx_info(&tsk->vx_info); -+ clr_nx_info(&tsk->nx_info); - free_task_struct(tsk); - } - EXPORT_SYMBOL(free_task); -@@ -203,6 +209,8 @@ static inline int dup_mmap(struct mm_str - mm->free_area_cache = oldmm->mmap_base; - mm->cached_hole_size = ~0UL; - mm->map_count = 0; -+ __set_mm_counter(mm, file_rss, 0); -+ __set_mm_counter(mm, anon_rss, 0); - cpus_clear(mm->cpu_vm_mask); - mm->mm_rb = RB_ROOT; - rb_link = &mm->mm_rb.rb_node; -@@ -214,7 +222,7 @@ static inline int dup_mmap(struct mm_str - - if (mpnt->vm_flags & VM_DONTCOPY) { - long pages = vma_pages(mpnt); -- mm->total_vm -= pages; -+ vx_vmpages_sub(mm, pages); - vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file, - -pages); - continue; -@@ -321,8 +329,6 @@ static struct mm_struct * mm_init(struct - INIT_LIST_HEAD(&mm->mmlist); - mm->core_waiters = 0; - mm->nr_ptes = 0; -- set_mm_counter(mm, file_rss, 0); -- set_mm_counter(mm, anon_rss, 0); - spin_lock_init(&mm->page_table_lock); - rwlock_init(&mm->ioctx_list_lock); - mm->ioctx_list = NULL; -@@ -331,6 +337,7 @@ static struct mm_struct * mm_init(struct - - if (likely(!mm_alloc_pgd(mm))) { - mm->def_flags = 0; -+ set_vx_info(&mm->mm_vx_info, current->vx_info); - return mm; - } - free_mm(mm); -@@ -362,6 +369,7 @@ void fastcall __mmdrop(struct mm_struct - BUG_ON(mm == &init_mm); - mm_free_pgd(mm); - destroy_context(mm); -+ clr_vx_info(&mm->mm_vx_info); - free_mm(mm); - } - -@@ -465,6 +473,7 @@ static struct mm_struct *dup_mm(struct t - goto fail_nomem; - - memcpy(mm, oldmm, sizeof(*mm)); -+ mm->mm_vx_info = NULL; - - if (!mm_init(mm)) - goto fail_nomem; -@@ -492,6 +501,7 @@ fail_nocontext: - * If init_new_context() failed, we cannot use mmput() to free the mm - * because it calls destroy_context() - */ -+ clr_vx_info(&mm->mm_vx_info); - mm_free_pgd(mm); - free_mm(mm); - return NULL; -@@ -685,6 +695,8 @@ static struct files_struct *dup_fd(struc - struct file *f = *old_fds++; - if (f) { - get_file(f); -+ /* FIXME: sum it first for check and performance */ -+ vx_openfd_inc(open_files - i); - } else { - /* - * The fd may be claimed in the fd bitmap but not yet -@@ -917,6 +929,8 @@ static task_t *copy_process(unsigned lon - { - int retval; - struct task_struct *p = NULL; -+ struct vx_info *vxi; -+ struct nx_info *nxi; - - if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) - return ERR_PTR(-EINVAL); -@@ -945,12 +959,30 @@ static task_t *copy_process(unsigned lon - if (!p) - goto fork_out; - -+ init_vx_info(&p->vx_info, current->vx_info); -+ init_nx_info(&p->nx_info, current->nx_info); -+ -+ /* check vserver memory */ -+ if (p->mm && !(clone_flags & CLONE_VM)) { -+ if (vx_vmpages_avail(p->mm, p->mm->total_vm)) -+ vx_pages_add(p->vx_info, RLIMIT_AS, p->mm->total_vm); -+ else -+ goto bad_fork_free; -+ } -+ if (p->mm && vx_flags(VXF_FORK_RSS, 0)) { -+ if (!vx_rsspages_avail(p->mm, get_mm_counter(p->mm, file_rss))) -+ goto bad_fork_cleanup_vm; -+ } -+ - retval = -EAGAIN; -+ if (!vx_nproc_avail(1)) -+ goto bad_fork_cleanup_vm; -+ - if (atomic_read(&p->user->processes) >= - p->signal->rlim[RLIMIT_NPROC].rlim_cur) { - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && - p->user != &root_user) -- goto bad_fork_free; -+ goto bad_fork_cleanup_vm; - } - - atomic_inc(&p->user->__count); -@@ -1190,6 +1222,18 @@ static task_t *copy_process(unsigned lon - nr_threads++; - total_forks++; - spin_unlock(¤t->sighand->siglock); -+ -+ /* p is copy of current */ -+ vxi = p->vx_info; -+ if (vxi) { -+ claim_vx_info(vxi, p); -+ atomic_inc(&vxi->cvirt.nr_threads); -+ atomic_inc(&vxi->cvirt.total_forks); -+ vx_nproc_inc(p); -+ } -+ nxi = p->nx_info; -+ if (nxi) -+ claim_nx_info(nxi, p); - write_unlock_irq(&tasklist_lock); - proc_fork_connector(p); - return p; -@@ -1230,6 +1274,9 @@ bad_fork_cleanup_count: - put_group_info(p->group_info); - atomic_dec(&p->user->processes); - free_uid(p->user); -+bad_fork_cleanup_vm: -+ if (p->mm && !(clone_flags & CLONE_VM)) -+ vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm); - bad_fork_free: - free_task(p); - fork_out: -diff --git a/kernel/kthread.c b/kernel/kthread.c -index e75950a..c848b20 100644 ---- a/kernel/kthread.c -+++ b/kernel/kthread.c -@@ -114,7 +114,7 @@ static void keventd_create_kthread(void - create->result = ERR_PTR(pid); - } else { - wait_for_completion(&create->started); -- create->result = find_task_by_pid(pid); -+ create->result = find_task_by_real_pid(pid); - } - complete(&create->done); - } -diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c -index 520f6c5..96d7046 100644 ---- a/kernel/posix-cpu-timers.c -+++ b/kernel/posix-cpu-timers.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - static int check_clock(const clockid_t which_clock) - { -diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c -index 216f574..33e4b92 100644 ---- a/kernel/posix-timers.c -+++ b/kernel/posix-timers.c -@@ -47,6 +47,7 @@ - #include - #include - #include -+#include - - /* - * Management arrays for POSIX timers. Timers are kept in slab memory -@@ -306,9 +307,10 @@ int posix_timer_event(struct k_itimer *t - - if (timr->it_sigev_notify & SIGEV_THREAD_ID) { - struct task_struct *leader; -- int ret = send_sigqueue(timr->it_sigev_signo, timr->sigq, -- timr->it_process); -+ int ret; - -+ ret = send_sigqueue(timr->it_sigev_signo, timr->sigq, -+ timr->it_process); - if (likely(ret >= 0)) - return ret; - -@@ -365,7 +367,7 @@ static struct task_struct * good_sigeven - struct task_struct *rtn = current->group_leader; - - if ((event->sigev_notify & SIGEV_THREAD_ID ) && -- (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) || -+ (!(rtn = find_task_by_real_pid(event->sigev_notify_thread_id)) || - rtn->tgid != current->tgid || - (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL)) - return NULL; -diff --git a/kernel/printk.c b/kernel/printk.c -index 13ced0f..bbff973 100644 ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - - #include - -@@ -221,18 +222,13 @@ int do_syslog(int type, char __user *buf - unsigned long i, j, limit, count; - int do_clear = 0; - char c; -- int error = 0; -+ int error; - - error = security_syslog(type); - if (error) - return error; - -- switch (type) { -- case 0: /* Close log */ -- break; -- case 1: /* Open log */ -- break; -- case 2: /* Read from log */ -+ if ((type >= 2) && (type <= 4)) { - error = -EINVAL; - if (!buf || len < 0) - goto out; -@@ -243,6 +239,16 @@ int do_syslog(int type, char __user *buf - error = -EFAULT; - goto out; - } -+ } -+ if (!vx_check(0, VX_ADMIN|VX_WATCH)) -+ return vx_do_syslog(type, buf, len); -+ -+ switch (type) { -+ case 0: /* Close log */ -+ break; -+ case 1: /* Open log */ -+ break; -+ case 2: /* Read from log */ - error = wait_event_interruptible(log_wait, - (log_start - log_end)); - if (error) -@@ -267,16 +273,6 @@ int do_syslog(int type, char __user *buf - do_clear = 1; - /* FALL THRU */ - case 3: /* Read last kernel messages */ -- error = -EINVAL; -- if (!buf || len < 0) -- goto out; -- error = 0; -- if (!len) -- goto out; -- if (!access_ok(VERIFY_WRITE, buf, len)) { -- error = -EFAULT; -- goto out; -- } - count = len; - if (count > log_buf_len) - count = log_buf_len; -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index d95a72c..220f567 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -489,6 +490,10 @@ asmlinkage long sys_ptrace(long request, - goto out; - } - -+ ret = -EPERM; -+ if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) -+ goto out_put_task_struct; -+ - if (request == PTRACE_ATTACH) { - ret = ptrace_attach(child); - goto out_put_task_struct; -diff --git a/kernel/sched.c b/kernel/sched.c -index 4d46e90..545c80b 100644 ---- a/kernel/sched.c -+++ b/kernel/sched.c -@@ -52,6 +52,9 @@ - #include - - #include -+#include -+#include -+#include - - /* - * Convert user-nice values [ -20 ... 0 ... 19 ] -@@ -238,6 +241,10 @@ - struct list_head migration_queue; - int cpu; - #endif -+#ifdef CONFIG_VSERVER_HARDCPU -+ struct list_head hold_queue; -+ int idle_tokens; -+#endif - - #ifdef CONFIG_SCHEDSTATS - /* latency stats */ -@@ -598,6 +605,7 @@ static inline void sched_info_switch(tas - */ - static void dequeue_task(struct task_struct *p, prio_array_t *array) - { -+ BUG_ON(p->state & TASK_ONHOLD); - array->nr_active--; - list_del(&p->run_list); - if (list_empty(array->queue + p->prio)) -@@ -606,6 +614,7 @@ static void dequeue_task(struct task_str - - static void enqueue_task(struct task_struct *p, prio_array_t *array) - { -+ BUG_ON(p->state & TASK_ONHOLD); - sched_info_queued(p); - list_add_tail(&p->run_list, array->queue + p->prio); - __set_bit(p->prio, array->bitmap); -@@ -619,11 +628,13 @@ static void enqueue_task(struct task_str - */ - static void requeue_task(struct task_struct *p, prio_array_t *array) - { -+ BUG_ON(p->state & TASK_ONHOLD); - list_move_tail(&p->run_list, array->queue + p->prio); - } - - static inline void enqueue_task_head(struct task_struct *p, prio_array_t *array) - { -+ BUG_ON(p->state & TASK_ONHOLD); - list_add(&p->run_list, array->queue + p->prio); - __set_bit(p->prio, array->bitmap); - array->nr_active++; -@@ -647,6 +658,7 @@ static inline void enqueue_task_head(str - static int effective_prio(task_t *p) - { - int bonus, prio; -+ struct vx_info *vxi; - - if (rt_task(p)) - return p->prio; -@@ -654,6 +666,11 @@ static int effective_prio(task_t *p) - bonus = CURRENT_BONUS(p) - MAX_BONUS / 2; - - prio = p->static_prio - bonus; -+ -+ if ((vxi = p->vx_info) && -+ vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) -+ prio += vx_effective_vavavoom(vxi, MAX_USER_PRIO); -+ - if (prio < MAX_RT_PRIO) - prio = MAX_RT_PRIO; - if (prio > MAX_PRIO-1) -@@ -792,19 +809,77 @@ static void activate_task(task_t *p, run - } - p->timestamp = now; - -+ vx_activate_task(p); - __activate_task(p, rq); - } - - /* - * deactivate_task - remove a task from the runqueue. - */ --static void deactivate_task(struct task_struct *p, runqueue_t *rq) -+static void __deactivate_task(struct task_struct *p, runqueue_t *rq) - { - rq->nr_running--; - dequeue_task(p, p->array); - p->array = NULL; - } - -+static inline -+void deactivate_task(struct task_struct *p, runqueue_t *rq) -+{ -+ vx_deactivate_task(p); -+ __deactivate_task(p, rq); -+} -+ -+ -+#ifdef CONFIG_VSERVER_HARDCPU -+/* -+ * vx_hold_task - put a task on the hold queue -+ */ -+static inline -+void vx_hold_task(struct vx_info *vxi, -+ struct task_struct *p, runqueue_t *rq) -+{ -+ __deactivate_task(p, rq); -+ p->state |= TASK_ONHOLD; -+ /* a new one on hold */ -+ vx_onhold_inc(vxi); -+ list_add_tail(&p->run_list, &rq->hold_queue); -+} -+ -+/* -+ * vx_unhold_task - put a task back to the runqueue -+ */ -+static inline -+void vx_unhold_task(struct vx_info *vxi, -+ struct task_struct *p, runqueue_t *rq) -+{ -+ list_del(&p->run_list); -+ /* one less waiting */ -+ vx_onhold_dec(vxi); -+ p->state &= ~TASK_ONHOLD; -+ enqueue_task(p, rq->expired); -+ rq->nr_running++; -+ -+ if (p->static_prio < rq->best_expired_prio) -+ rq->best_expired_prio = p->static_prio; -+} -+#else -+static inline -+void vx_hold_task(struct vx_info *vxi, -+ struct task_struct *p, runqueue_t *rq) -+{ -+ return; -+} -+ -+static inline -+void vx_unhold_task(struct vx_info *vxi, -+ struct task_struct *p, runqueue_t *rq) -+{ -+ return; -+} -+#endif /* CONFIG_VSERVER_HARDCPU */ -+ -+ - /* - * resched_task - mark a task 'to be rescheduled now'. - * -@@ -1168,6 +1243,12 @@ static int try_to_wake_up(task_t *p, uns - - rq = task_rq_lock(p, &flags); - old_state = p->state; -+ -+ /* we need to unhold suspended tasks */ -+ if (old_state & TASK_ONHOLD) { -+ vx_unhold_task(p->vx_info, p, rq); -+ old_state = p->state; -+ } - if (!(old_state & state)) - goto out; - -@@ -1284,10 +1365,16 @@ out_activate: - * sleep is handled in a priority-neutral manner, no priority - * boost and no penalty.) - */ -- if (old_state & TASK_NONINTERACTIVE) -+ if (old_state & TASK_NONINTERACTIVE) { -+ vx_activate_task(p); - __activate_task(p, rq); -- else -+ } else - activate_task(p, rq, cpu == this_cpu); -+ -+ /* this is to get the accounting behind the load update */ -+ if (old_state & TASK_UNINTERRUPTIBLE) -+ vx_uninterruptible_dec(p); -+ - /* - * Sync wakeups (i.e. those types of wakeups where the waker - * has indicated that it will leave the CPU in short order) -@@ -1411,6 +1498,7 @@ void fastcall wake_up_new_task(task_t *p - - p->prio = effective_prio(p); - -+ vx_activate_task(p); - if (likely(cpu == this_cpu)) { - if (!(clone_flags & CLONE_VM)) { - /* -@@ -1422,6 +1510,7 @@ void fastcall wake_up_new_task(task_t *p - __activate_task(p, rq); - else { - p->prio = current->prio; -+ BUG_ON(p->state & TASK_ONHOLD); - list_add_tail(&p->run_list, ¤t->run_list); - p->array = current->array; - p->array->nr_active++; -@@ -2485,13 +2574,16 @@ unsigned long long current_sched_time(co - void account_user_time(struct task_struct *p, cputime_t cputime) - { - struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; -+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */ - cputime64_t tmp; -+ int nice = (TASK_NICE(p) > 0); - - p->utime = cputime_add(p->utime, cputime); -+ vx_account_user(vxi, cputime, nice); - - /* Add user time to cpustat. */ - tmp = cputime_to_cputime64(cputime); -- if (TASK_NICE(p) > 0) -+ if (nice) - cpustat->nice = cputime64_add(cpustat->nice, tmp); - else - cpustat->user = cputime64_add(cpustat->user, tmp); -@@ -2507,10 +2599,12 @@ void account_system_time(struct task_str - cputime_t cputime) - { - struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; -+ struct vx_info *vxi = p->vx_info; /* p is _always_ current */ - runqueue_t *rq = this_rq(); - cputime64_t tmp; - - p->stime = cputime_add(p->stime, cputime); -+ vx_account_system(vxi, cputime, (p == rq->idle)); - - /* Add system time to cpustat. */ - tmp = cputime_to_cputime64(cputime); -@@ -2570,6 +2664,10 @@ void scheduler_tick(void) - if (p == rq->idle) { - if (wake_priority_sleeper(rq)) - goto out; -+#ifdef CONFIG_VSERVER_HARDCPU_IDLE -+ if (!--rq->idle_tokens && !list_empty(&rq->hold_queue)) -+ set_need_resched(); -+#endif - rebalance_tick(cpu, rq, SCHED_IDLE); - return; - } -@@ -2602,7 +2700,7 @@ void scheduler_tick(void) - } - goto out_unlock; - } -- if (!--p->time_slice) { -+ if (vx_need_resched(p)) { - dequeue_task(p, rq->active); - set_tsk_need_resched(p); - p->prio = effective_prio(p); -@@ -2867,6 +2965,10 @@ asmlinkage void __sched schedule(void) - unsigned long long now; - unsigned long run_time; - int cpu, idx, new_prio; -+ struct vx_info *vxi; -+#ifdef CONFIG_VSERVER_HARDCPU -+ int maxidle = -HZ; -+#endif - - /* - * Test if we are atomic. Since do_exit() needs to call into -@@ -2926,12 +3028,41 @@ need_resched_nonpreemptible: - unlikely(signal_pending(prev)))) - prev->state = TASK_RUNNING; - else { -- if (prev->state == TASK_UNINTERRUPTIBLE) -+ if (prev->state == TASK_UNINTERRUPTIBLE) { - rq->nr_uninterruptible++; -+ vx_uninterruptible_inc(prev); -+ } - deactivate_task(prev, rq); - } - } - -+#ifdef CONFIG_VSERVER_HARDCPU -+ if (!list_empty(&rq->hold_queue)) { -+ struct list_head *l, *n; -+ int ret; -+ -+ vxi = NULL; -+ list_for_each_safe(l, n, &rq->hold_queue) { -+ next = list_entry(l, task_t, run_list); -+ if (vxi == next->vx_info) -+ continue; -+ -+ vxi = next->vx_info; -+ ret = vx_tokens_recalc(vxi); -+ -+ if (ret > 0) { -+ vx_unhold_task(vxi, next, rq); -+ break; -+ } -+ if ((ret < 0) && (maxidle < ret)) -+ maxidle = ret; -+ } -+ } -+ rq->idle_tokens = -maxidle; -+ -+pick_next: -+#endif -+ - cpu = smp_processor_id(); - if (unlikely(!rq->nr_running)) { - go_idle: -@@ -2979,6 +3110,22 @@ go_idle: - queue = array->queue + idx; - next = list_entry(queue->next, task_t, run_list); - -+ vxi = next->vx_info; -+#ifdef CONFIG_VSERVER_HARDCPU -+ if (vx_info_flags(vxi, VXF_SCHED_PAUSE|VXF_SCHED_HARD, 0)) { -+ int ret = vx_tokens_recalc(vxi); -+ -+ if (unlikely(ret <= 0)) { -+ if (ret && (rq->idle_tokens > -ret)) -+ rq->idle_tokens = -ret; -+ vx_hold_task(vxi, next, rq); -+ goto pick_next; -+ } -+ } else /* well, looks ugly but not as ugly as the ifdef-ed version */ -+#endif -+ if (vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) -+ vx_tokens_recalc(vxi); -+ - if (!rt_task(next) && next->activated > 0) { - unsigned long long delta = now - next->timestamp; - if (unlikely((long long)(now - next->timestamp) < 0)) -@@ -3534,7 +3681,7 @@ asmlinkage long sys_nice(int increment) - nice = 19; - - if (increment < 0 && !can_nice(current, nice)) -- return -EPERM; -+ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM; - - retval = security_task_setnice(current, nice); - if (retval) -@@ -3694,6 +3841,7 @@ recheck: - oldprio = p->prio; - __setscheduler(p, policy, param->sched_priority); - if (array) { -+ vx_activate_task(p); - __activate_task(p, rq); - /* - * Reschedule if we are currently running on this runqueue and -@@ -6037,6 +6185,9 @@ void __init sched_init(void) - INIT_LIST_HEAD(&rq->migration_queue); - #endif - atomic_set(&rq->nr_iowait, 0); -+#ifdef CONFIG_VSERVER_HARDCPU -+ INIT_LIST_HEAD(&rq->hold_queue); -+#endif - - for (j = 0; j < 2; j++) { - array = rq->arrays + j; -@@ -6106,6 +6257,7 @@ void normalize_rt_tasks(void) - deactivate_task(p, task_rq(p)); - __setscheduler(p, SCHED_NORMAL, 0); - if (array) { -+ vx_activate_task(p); - __activate_task(p, task_rq(p)); - resched_task(rq->curr); - } -diff --git a/kernel/signal.c b/kernel/signal.c -index ea15410..4f5185f 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -676,18 +677,27 @@ static int rm_from_queue(unsigned long m - static int check_kill_permission(int sig, struct siginfo *info, - struct task_struct *t) - { -+ int user; - int error = -EINVAL; -+ - if (!valid_signal(sig)) - return error; -+ -+ user = ((info == SEND_SIG_NOINFO) || -+ (!is_si_special(info) && SI_FROMUSER(info))); -+ - error = -EPERM; -- if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info))) -- && ((sig != SIGCONT) || -+ if (user && ((sig != SIGCONT) || - (current->signal->session != t->signal->session)) - && (current->euid ^ t->suid) && (current->euid ^ t->uid) - && (current->uid ^ t->suid) && (current->uid ^ t->uid) - && !capable(CAP_KILL)) - return error; - -+ error = -ESRCH; -+ if (user && !vx_check(vx_task_xid(t), VX_ADMIN|VX_IDENT)) -+ return error; -+ - error = security_task_kill(t, info, sig); - if (!error) - audit_signal_info(sig, t); /* Let audit system see the signal */ -@@ -1991,6 +2001,11 @@ relock: - if (current->pid == 1) - continue; - -+ /* virtual init is protected against user signals */ -+ if ((info->si_code == SI_USER) && -+ vx_current_initpid(current->pid)) -+ continue; -+ - if (sig_kernel_stop(signr)) { - /* - * The default action is to stop all threads in -diff --git a/kernel/sys.c b/kernel/sys.c -index f91218a..6084bf4 100644 ---- a/kernel/sys.c -+++ b/kernel/sys.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -30,6 +31,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -227,6 +229,8 @@ EXPORT_SYMBOL(unregister_reboot_notifier - #ifndef CONFIG_SECURITY - int capable(int cap) - { -+ if (vx_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap)) -+ return 0; - if (cap_raised(current->cap_effective, cap)) { - current->flags |= PF_SUPERPRIV; - return 1; -@@ -246,7 +250,10 @@ static int set_one_prio(struct task_stru - goto out; - } - if (niceval < task_nice(p) && !can_nice(p, niceval)) { -- error = -EACCES; -+ if (vx_flags(VXF_IGNEG_NICE, 0)) -+ error = 0; -+ else -+ error = -EACCES; - goto out; - } - no_nice = security_task_setnice(p, niceval); -@@ -298,7 +305,8 @@ asmlinkage long sys_setpriority(int whic - if (!who) - who = current->uid; - else -- if ((who != current->uid) && !(user = find_user(who))) -+ if ((who != current->uid) && -+ !(user = find_user(vx_current_xid(), who))) - goto out_unlock; /* No processes for this user */ - - do_each_thread(g, p) -@@ -356,7 +364,8 @@ asmlinkage long sys_getpriority(int whic - if (!who) - who = current->uid; - else -- if ((who != current->uid) && !(user = find_user(who))) -+ if ((who != current->uid) && -+ !(user = find_user(vx_current_xid(), who))) - goto out_unlock; /* No processes for this user */ - - do_each_thread(g, p) -@@ -473,6 +482,9 @@ void kernel_power_off(void) - machine_power_off(); - } - EXPORT_SYMBOL_GPL(kernel_power_off); -+ -+long vs_reboot(unsigned int, void *); -+ - /* - * Reboot system call: for obvious reasons only root may call it, - * and even root needs to set up some magic numbers in the registers -@@ -503,6 +515,9 @@ asmlinkage long sys_reboot(int magic1, i - if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off) - cmd = LINUX_REBOOT_CMD_HALT; - -+ if (!vx_check(0, VX_ADMIN|VX_WATCH)) -+ return vs_reboot(cmd, arg); -+ - lock_kernel(); - switch (cmd) { - case LINUX_REBOOT_CMD_RESTART: -@@ -690,7 +705,7 @@ static int set_user(uid_t new_ruid, int - { - struct user_struct *new_user; - -- new_user = alloc_uid(new_ruid); -+ new_user = alloc_uid(vx_current_xid(), new_ruid); - if (!new_user) - return -EAGAIN; - -@@ -1099,15 +1114,18 @@ asmlinkage long sys_setpgid(pid_t pid, p - { - struct task_struct *p; - struct task_struct *group_leader = current->group_leader; -+ pid_t rpgid; - int err = -EINVAL; - - if (!pid) -- pid = group_leader->pid; -+ pid = vx_map_pid(group_leader->pid); - if (!pgid) - pgid = pid; - if (pgid < 0) - return -EINVAL; - -+ rpgid = vx_rmap_pid(pgid); -+ - /* From this point forward we keep holding onto the tasklist lock - * so that our parent does not change from under us. -DaveM - */ -@@ -1142,22 +1160,22 @@ asmlinkage long sys_setpgid(pid_t pid, p - if (pgid != pid) { - struct task_struct *p; - -- do_each_task_pid(pgid, PIDTYPE_PGID, p) { -+ do_each_task_pid(rpgid, PIDTYPE_PGID, p) { - if (p->signal->session == group_leader->signal->session) - goto ok_pgid; -- } while_each_task_pid(pgid, PIDTYPE_PGID, p); -+ } while_each_task_pid(rpgid, PIDTYPE_PGID, p); - goto out; - } - - ok_pgid: -- err = security_task_setpgid(p, pgid); -+ err = security_task_setpgid(p, rpgid); - if (err) - goto out; - -- if (process_group(p) != pgid) { -+ if (process_group(p) != rpgid) { - detach_pid(p, PIDTYPE_PGID); -- p->signal->pgrp = pgid; -- attach_pid(p, PIDTYPE_PGID, pgid); -+ p->signal->pgrp = rpgid; -+ attach_pid(p, PIDTYPE_PGID, rpgid); - } - - err = 0; -@@ -1170,7 +1188,7 @@ out: - asmlinkage long sys_getpgid(pid_t pid) - { - if (!pid) { -- return process_group(current); -+ return vx_rmap_pid(process_group(current)); - } else { - int retval; - struct task_struct *p; -@@ -1182,7 +1200,7 @@ asmlinkage long sys_getpgid(pid_t pid) - if (p) { - retval = security_task_getpgid(p); - if (!retval) -- retval = process_group(p); -+ retval = vx_rmap_pid(process_group(p)); - } - read_unlock(&tasklist_lock); - return retval; -@@ -1518,7 +1536,7 @@ asmlinkage long sys_newuname(struct new_ - int errno = 0; - - down_read(&uts_sem); -- if (copy_to_user(name,&system_utsname,sizeof *name)) -+ if (copy_to_user(name, vx_new_utsname(), sizeof *name)) - errno = -EFAULT; - up_read(&uts_sem); - return errno; -@@ -1529,15 +1547,17 @@ asmlinkage long sys_sethostname(char __u - int errno; - char tmp[__NEW_UTS_LEN]; - -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME)) - return -EPERM; - if (len < 0 || len > __NEW_UTS_LEN) - return -EINVAL; - down_write(&uts_sem); - errno = -EFAULT; - if (!copy_from_user(tmp, name, len)) { -- memcpy(system_utsname.nodename, tmp, len); -- system_utsname.nodename[len] = 0; -+ char *ptr = vx_new_uts(nodename); -+ -+ memcpy(ptr, tmp, len); -+ ptr[len] = 0; - errno = 0; - } - up_write(&uts_sem); -@@ -1549,15 +1569,17 @@ asmlinkage long sys_sethostname(char __u - asmlinkage long sys_gethostname(char __user *name, int len) - { - int i, errno; -+ char *ptr; - - if (len < 0) - return -EINVAL; - down_read(&uts_sem); -- i = 1 + strlen(system_utsname.nodename); -+ ptr = vx_new_uts(nodename); -+ i = 1 + strlen(ptr); - if (i > len) - i = len; - errno = 0; -- if (copy_to_user(name, system_utsname.nodename, i)) -+ if (copy_to_user(name, ptr, i)) - errno = -EFAULT; - up_read(&uts_sem); - return errno; -@@ -1574,7 +1596,7 @@ asmlinkage long sys_setdomainname(char _ - int errno; - char tmp[__NEW_UTS_LEN]; - -- if (!capable(CAP_SYS_ADMIN)) -+ if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME)) - return -EPERM; - if (len < 0 || len > __NEW_UTS_LEN) - return -EINVAL; -@@ -1582,8 +1604,10 @@ asmlinkage long sys_setdomainname(char _ - down_write(&uts_sem); - errno = -EFAULT; - if (!copy_from_user(tmp, name, len)) { -- memcpy(system_utsname.domainname, tmp, len); -- system_utsname.domainname[len] = 0; -+ char *ptr = vx_new_uts(domainname); -+ -+ memcpy(ptr, tmp, len); -+ ptr[len] = 0; - errno = 0; - } - up_write(&uts_sem); -@@ -1640,7 +1664,7 @@ asmlinkage long sys_setrlimit(unsigned i - return -EINVAL; - old_rlim = current->signal->rlim + resource; - if ((new_rlim.rlim_max > old_rlim->rlim_max) && -- !capable(CAP_SYS_RESOURCE)) -+ !capable(CAP_SYS_RESOURCE) && !vx_ccaps(VXC_SET_RLIMIT)) - return -EPERM; - if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN) - return -EPERM; -diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index 32b48e8..f81b394 100644 ---- a/kernel/sysctl.c -+++ b/kernel/sysctl.c -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -89,6 +90,7 @@ static int ngroups_max = NGROUPS_MAX; - #ifdef CONFIG_KMOD - extern char modprobe_path[]; - #endif -+extern char vshelper_path[]; - #ifdef CONFIG_CHR_DEV_SG - extern int sg_big_buff; - #endif -@@ -237,6 +239,7 @@ static ctl_table kern_table[] = { - .maxlen = sizeof(system_utsname.sysname), - .mode = 0444, - .proc_handler = &proc_doutsstring, -+ .virt_handler = &vx_uts_virt_handler, - .strategy = &sysctl_string, - }, - { -@@ -246,6 +249,7 @@ static ctl_table kern_table[] = { - .maxlen = sizeof(system_utsname.release), - .mode = 0444, - .proc_handler = &proc_doutsstring, -+ .virt_handler = &vx_uts_virt_handler, - .strategy = &sysctl_string, - }, - { -@@ -255,6 +259,7 @@ static ctl_table kern_table[] = { - .maxlen = sizeof(system_utsname.version), - .mode = 0444, - .proc_handler = &proc_doutsstring, -+ .virt_handler = &vx_uts_virt_handler, - .strategy = &sysctl_string, - }, - { -@@ -264,6 +269,7 @@ static ctl_table kern_table[] = { - .maxlen = sizeof(system_utsname.nodename), - .mode = 0644, - .proc_handler = &proc_doutsstring, -+ .virt_handler = &vx_uts_virt_handler, - .strategy = &sysctl_string, - }, - { -@@ -273,6 +279,7 @@ static ctl_table kern_table[] = { - .maxlen = sizeof(system_utsname.domainname), - .mode = 0644, - .proc_handler = &proc_doutsstring, -+ .virt_handler = &vx_uts_virt_handler, - .strategy = &sysctl_string, - }, - { -@@ -409,6 +416,15 @@ static ctl_table kern_table[] = { - .strategy = &sysctl_string, - }, - #endif -+ { -+ .ctl_name = KERN_VSHELPER, -+ .procname = "vshelper", -+ .data = &vshelper_path, -+ .maxlen = 256, -+ .mode = 0644, -+ .proc_handler = &proc_dostring, -+ .strategy = &sysctl_string, -+ }, - #ifdef CONFIG_CHR_DEV_SG - { - .ctl_name = KERN_SG_BIG_BUFF, -@@ -1564,16 +1580,20 @@ static ssize_t proc_writesys(struct file - int proc_dostring(ctl_table *table, int write, struct file *filp, - void __user *buffer, size_t *lenp, loff_t *ppos) - { -- size_t len; -+ size_t len, maxlen; - char __user *p; - char c; -+ void *data; -+ -+ data = table->data; -+ maxlen = table->maxlen; -+ -+ if (!data || !maxlen || !*lenp || (*ppos && !write)) -+ return (*lenp = 0); - -- if (!table->data || !table->maxlen || !*lenp || -- (*ppos && !write)) { -- *lenp = 0; -- return 0; -- } -- -+ if (table->virt_handler) -+ table->virt_handler(table, write, filp->f_xid, &data, &maxlen); -+ - if (write) { - len = 0; - p = buffer; -@@ -1584,20 +1604,20 @@ int proc_dostring(ctl_table *table, int - break; - len++; - } -- if (len >= table->maxlen) -- len = table->maxlen-1; -- if(copy_from_user(table->data, buffer, len)) -+ if (len >= maxlen) -+ len = maxlen-1; -+ if(copy_from_user(data, buffer, len)) - return -EFAULT; -- ((char *) table->data)[len] = 0; -+ ((char *) data)[len] = 0; - *ppos += *lenp; - } else { -- len = strlen(table->data); -- if (len > table->maxlen) -- len = table->maxlen; -+ len = strlen(data); -+ if (len > maxlen) -+ len = maxlen; - if (len > *lenp) - len = *lenp; - if (len) -- if(copy_to_user(buffer, table->data, len)) -+ if(copy_to_user(buffer, data, len)) - return -EFAULT; - if (len < *lenp) { - if(put_user('\n', ((char __user *) buffer) + len)) -diff --git a/kernel/timer.c b/kernel/timer.c -index bf7c419..a709b8a 100644 ---- a/kernel/timer.c -+++ b/kernel/timer.c -@@ -34,6 +34,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -972,12 +974,6 @@ asmlinkage unsigned long sys_alarm(unsig - - #endif - --#ifndef __alpha__ -- --/* -- * The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this -- * should be moved into arch/i386 instead? -- */ - - /** - * sys_getpid - return the thread group id of the current process -@@ -990,7 +986,7 @@ asmlinkage unsigned long sys_alarm(unsig - */ - asmlinkage long sys_getpid(void) - { -- return current->tgid; -+ return vx_map_tgid(current->tgid); - } - - /* -@@ -1034,9 +1030,23 @@ asmlinkage long sys_getppid(void) - #endif - break; - } -- return pid; -+ return vx_map_pid(pid); - } - -+#ifdef __alpha__ -+ -+/* -+ * The Alpha uses getxpid, getxuid, and getxgid instead. -+ */ -+ -+asmlinkage long do_getxpid(long *ppid) -+{ -+ *ppid = sys_getppid(); -+ return sys_getpid(); -+} -+ -+#else /* _alpha_ */ -+ - asmlinkage long sys_getuid(void) - { - /* Only we change this so SMP safe */ -@@ -1197,6 +1207,8 @@ asmlinkage long sys_sysinfo(struct sysin - tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC; - tp.tv_sec++; - } -+ if (vx_flags(VXF_VIRT_UPTIME, 0)) -+ vx_vsi_uptime(&tp, NULL); - val.uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); - - val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); -diff --git a/kernel/user.c b/kernel/user.c -index d9deae4..155084e 100644 ---- a/kernel/user.c -+++ b/kernel/user.c -@@ -23,8 +23,8 @@ - #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8) - #define UIDHASH_SZ (1 << UIDHASH_BITS) - #define UIDHASH_MASK (UIDHASH_SZ - 1) --#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK) --#define uidhashentry(uid) (uidhash_table + __uidhashfn((uid))) -+#define __uidhashfn(xid,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK) -+#define uidhashentry(xid,uid) (uidhash_table + __uidhashfn((xid),(uid))) - - static kmem_cache_t *uid_cachep; - static struct list_head uidhash_table[UIDHASH_SZ]; -@@ -66,7 +66,7 @@ static inline void uid_hash_remove(struc - list_del(&up->uidhash_list); - } - --static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *hashent) -+static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent) - { - struct list_head *up; - -@@ -75,7 +75,7 @@ static inline struct user_struct *uid_ha - - user = list_entry(up, struct user_struct, uidhash_list); - -- if(user->uid == uid) { -+ if(user->uid == uid && user->xid == xid) { - atomic_inc(&user->__count); - return user; - } -@@ -90,13 +90,13 @@ static inline struct user_struct *uid_ha - * - * If the user_struct could not be found, return NULL. - */ --struct user_struct *find_user(uid_t uid) -+struct user_struct *find_user(xid_t xid, uid_t uid) - { - struct user_struct *ret; - unsigned long flags; - - spin_lock_irqsave(&uidhash_lock, flags); -- ret = uid_hash_find(uid, uidhashentry(uid)); -+ ret = uid_hash_find(xid, uid, uidhashentry(xid, uid)); - spin_unlock_irqrestore(&uidhash_lock, flags); - return ret; - } -@@ -116,13 +116,13 @@ void free_uid(struct user_struct *up) - local_irq_restore(flags); - } - --struct user_struct * alloc_uid(uid_t uid) -+struct user_struct * alloc_uid(xid_t xid, uid_t uid) - { -- struct list_head *hashent = uidhashentry(uid); -+ struct list_head *hashent = uidhashentry(xid, uid); - struct user_struct *up; - - spin_lock_irq(&uidhash_lock); -- up = uid_hash_find(uid, hashent); -+ up = uid_hash_find(xid, uid, hashent); - spin_unlock_irq(&uidhash_lock); - - if (!up) { -@@ -132,6 +132,7 @@ struct user_struct * alloc_uid(uid_t uid - if (!new) - return NULL; - new->uid = uid; -+ new->xid = xid; - atomic_set(&new->__count, 1); - atomic_set(&new->processes, 0); - atomic_set(&new->files, 0); -@@ -154,7 +155,7 @@ struct user_struct * alloc_uid(uid_t uid - * on adding the same user already.. - */ - spin_lock_irq(&uidhash_lock); -- up = uid_hash_find(uid, hashent); -+ up = uid_hash_find(xid, uid, hashent); - if (up) { - key_put(new->uid_keyring); - key_put(new->session_keyring); -@@ -200,7 +201,7 @@ static int __init uid_cache_init(void) - - /* Insert the root user immediately (init already runs as root) */ - spin_lock_irq(&uidhash_lock); -- uid_hash_insert(&root_user, uidhashentry(0)); -+ uid_hash_insert(&root_user, uidhashentry(0,0)); - spin_unlock_irq(&uidhash_lock); - - return 0; -diff --git a/kernel/vserver/Kconfig b/kernel/vserver/Kconfig -new file mode 100644 -index 0000000..2658bc7 ---- /dev/null -+++ b/kernel/vserver/Kconfig -@@ -0,0 +1,179 @@ -+# -+# Linux VServer configuration -+# -+ -+config VSERVER -+ bool -+ default y -+ -+config VSERVER_SECURITY -+ bool -+ depends on SECURITY -+ default y -+ select SECURITY_CAPABILITIES -+ -+config VSERVER_LEGACYNET -+ bool -+ depends on !VSERVER_NGNET -+ default y -+ -+menu "Linux VServer" -+ -+config VSERVER_LEGACY -+ bool "Enable Legacy Kernel API" -+ default y -+ help -+ This enables the legacy API used in vs1.xx, maintaining -+ compatibility with older vserver tools, and guest images -+ that are configured using the legacy method. This is -+ probably a good idea for now, for migration purposes. -+ -+ Note that some tools have not yet been altered to use -+ this API, so disabling this option may reduce some -+ functionality. -+ -+config VSERVER_LEGACY_VERSION -+ bool "Show a Legacy Version ID" -+ depends on VSERVER_LEGACY -+ default n -+ help -+ This shows a special legacy version to very old tools -+ which do not handle the current version correctly. -+ -+ This will probably disable some features of newer tools -+ so better avoid it, unless you really, really need it -+ for backwards compatibility. -+ -+config VSERVER_NGNET -+ bool "Disable Legacy Networking Kernel API" -+ depends on EXPERIMENTAL -+ default n -+ help -+ This disables the legacy networking API which is required -+ by the chbind tool. Do not disable it unless you exactly -+ know what you are doing. -+ -+config VSERVER_PROC_SECURE -+ bool "Enable Proc Security" -+ depends on PROC_FS -+ default y -+ help -+ This configures ProcFS security to initially hide -+ non-process entries for all contexts except the main and -+ spectator context (i.e. for all guests), which is a secure -+ default. -+ -+ (note: on 1.2x the entries were visible by default) -+ -+config VSERVER_HARDCPU -+ bool "Enable Hard CPU Limits" -+ depends on EXPERIMENTAL -+ default n -+ help -+ Activate the Hard CPU Limits -+ -+ This will compile in code that allows the Token Bucket -+ Scheduler to put processes on hold when a context's -+ tokens are depleted (provided that its per-context -+ sched_hard flag is set). -+ -+ Processes belonging to that context will not be able -+ to consume CPU resources again until a per-context -+ configured minimum of tokens has been reached. -+ -+config VSERVER_HARDCPU_IDLE -+ bool "Limit the IDLE task" -+ depends on VSERVER_HARDCPU -+ default n -+ help -+ Limit the idle slices, so the the next context -+ will be scheduled as soon as possible. -+ -+ This might improve interactivity and latency, but -+ will also marginally increase scheduling overhead. -+ -+choice -+ prompt "Persistent Inode Context Tagging" -+ default INOXID_UGID24 -+ help -+ This adds persistent context information to filesystems -+ mounted with the tagxid option. Tagging is a requirement -+ for per-context disk limits and per-context quota. -+ -+ -+config INOXID_NONE -+ bool "Disabled" -+ help -+ do not store per-context information in inodes. -+ -+config INOXID_UID16 -+ bool "UID16/GID32" -+ help -+ reduces UID to 16 bit, but leaves GID at 32 bit. -+ -+config INOXID_GID16 -+ bool "UID32/GID16" -+ help -+ reduces GID to 16 bit, but leaves UID at 32 bit. -+ -+config INOXID_UGID24 -+ bool "UID24/GID24" -+ help -+ uses the upper 8bit from UID and GID for XID tagging -+ which leaves 24bit for UID/GID each, which should be -+ more than sufficient for normal use. -+ -+config INOXID_INTERN -+ bool "UID32/GID32" -+ help -+ this uses otherwise reserved inode fields in the on -+ disk representation, which limits the use to a few -+ filesystems (currently ext2 and ext3) -+ -+config INOXID_RUNTIME -+ bool "Runtime" -+ depends on EXPERIMENTAL -+ help -+ inodes are tagged when first accessed, this doesn't -+ require any persistant information, but might give -+ funny results for mixed access. -+ -+endchoice -+ -+config XID_TAG_NFSD -+ bool "Tag NFSD User Auth and Files" -+ default n -+ help -+ Enable this if you do want the in-kernel NFS -+ Server to use the xid tagging specified above. -+ (will require patched clients too) -+ -+config VSERVER_DEBUG -+ bool "VServer Debugging Code" -+ default n -+ help -+ Set this to yes if you want to be able to activate -+ debugging output at runtime. It adds a probably small -+ overhead to all vserver related functions and -+ increases the kernel size by about 20k. -+ -+config VSERVER_HISTORY -+ bool "VServer History Tracing" -+ depends on VSERVER_DEBUG -+ default n -+ help -+ Set this to yes if you want to record the history of -+ linux-vserver activities, so they can be replayed in -+ the event of a kernel panic or oops. -+ -+config VSERVER_HISTORY_SIZE -+ int "Per-CPU History Size (32-65536)" -+ depends on VSERVER_HISTORY -+ range 32 65536 -+ default 64 -+ help -+ This allows you to specify the number of entries in -+ the per-CPU history buffer. -+ -+endmenu -+ -diff --git a/kernel/vserver/Makefile b/kernel/vserver/Makefile -new file mode 100644 -index 0000000..19cd988 ---- /dev/null -+++ b/kernel/vserver/Makefile -@@ -0,0 +1,16 @@ -+# -+# Makefile for the Linux vserver routines. -+# -+ -+ -+obj-y += vserver.o -+ -+vserver-y := switch.o context.o namespace.o sched.o network.o inode.o \ -+ limit.o cvirt.o signal.o helper.o init.o dlimit.o -+ -+vserver-$(CONFIG_PROC_FS) += proc.o -+vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o -+vserver-$(CONFIG_VSERVER_LEGACY) += legacy.o -+vserver-$(CONFIG_VSERVER_LEGACYNET) += legacynet.o -+vserver-$(CONFIG_VSERVER_HISTORY) += history.o -+ -diff --git a/kernel/vserver/context.c b/kernel/vserver/context.c -new file mode 100644 -index 0000000..3542996 ---- /dev/null -+++ b/kernel/vserver/context.c -@@ -0,0 +1,889 @@ -+/* -+ * linux/kernel/vserver/context.c -+ * -+ * Virtual Server: Context Support -+ * -+ * Copyright (C) 2003-2005 Herbert Pötzl -+ * -+ * V0.01 context helper -+ * V0.02 vx_ctx_kill syscall command -+ * V0.03 replaced context_info calls -+ * V0.04 redesign of struct (de)alloc -+ * V0.05 rlimit basic implementation -+ * V0.06 task_xid and info commands -+ * V0.07 context flags and caps -+ * V0.08 switch to RCU based hash -+ * V0.09 revert to non RCU for now -+ * V0.10 and back to working RCU hash -+ * V0.11 and back to locking again -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "cvirt_init.h" -+#include "limit_init.h" -+#include "sched_init.h" -+ -+ -+/* __alloc_vx_info() -+ -+ * allocate an initialized vx_info struct -+ * doesn't make it visible (hash) */ -+ -+static struct vx_info *__alloc_vx_info(xid_t xid) -+{ -+ struct vx_info *new = NULL; -+ -+ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid); -+ -+ /* would this benefit from a slab cache? */ -+ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL); -+ if (!new) -+ return 0; -+ -+ memset (new, 0, sizeof(struct vx_info)); -+ new->vx_id = xid; -+ INIT_HLIST_NODE(&new->vx_hlist); -+ atomic_set(&new->vx_usecnt, 0); -+ atomic_set(&new->vx_tasks, 0); -+ new->vx_parent = NULL; -+ new->vx_state = 0; -+ init_waitqueue_head(&new->vx_wait); -+ -+ /* prepare reaper */ -+ get_task_struct(child_reaper); -+ new->vx_reaper = child_reaper; -+ -+ /* rest of init goes here */ -+ vx_info_init_limit(&new->limit); -+ vx_info_init_sched(&new->sched); -+ vx_info_init_cvirt(&new->cvirt); -+ vx_info_init_cacct(&new->cacct); -+ -+ new->vx_flags = VXF_INIT_SET; -+ new->vx_bcaps = CAP_INIT_EFF_SET; -+ new->vx_ccaps = 0; -+ -+ vxdprintk(VXD_CBIT(xid, 0), -+ "alloc_vx_info(%d) = %p", xid, new); -+ vxh_alloc_vx_info(new); -+ return new; -+} -+ -+/* __dealloc_vx_info() -+ -+ * final disposal of vx_info */ -+ -+static void __dealloc_vx_info(struct vx_info *vxi) -+{ -+ vxdprintk(VXD_CBIT(xid, 0), -+ "dealloc_vx_info(%p)", vxi); -+ vxh_dealloc_vx_info(vxi); -+ -+ vxi->vx_hlist.next = LIST_POISON1; -+ vxi->vx_id = -1; -+ -+ vx_info_exit_limit(&vxi->limit); -+ vx_info_exit_sched(&vxi->sched); -+ vx_info_exit_cvirt(&vxi->cvirt); -+ vx_info_exit_cacct(&vxi->cacct); -+ -+ vxi->vx_state |= VXS_RELEASED; -+ kfree(vxi); -+} -+ -+static void __shutdown_vx_info(struct vx_info *vxi) -+{ -+ struct namespace *namespace; -+ struct fs_struct *fs; -+ -+ might_sleep(); -+ -+ vxi->vx_state |= VXS_SHUTDOWN; -+ vs_state_change(vxi, VSC_SHUTDOWN); -+ -+ namespace = xchg(&vxi->vx_namespace, NULL); -+ if (namespace) -+ put_namespace(namespace); -+ -+ fs = xchg(&vxi->vx_fs, NULL); -+ if (fs) -+ put_fs_struct(fs); -+} -+ -+/* exported stuff */ -+ -+void free_vx_info(struct vx_info *vxi) -+{ -+ /* context shutdown is mandatory */ -+ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN)); -+ -+ BUG_ON(atomic_read(&vxi->vx_usecnt)); -+ BUG_ON(atomic_read(&vxi->vx_tasks)); -+ -+ BUG_ON(vx_info_state(vxi, VXS_HASHED)); -+ -+ BUG_ON(vxi->vx_namespace); -+ BUG_ON(vxi->vx_fs); -+ -+ __dealloc_vx_info(vxi); -+} -+ -+ -+/* hash table for vx_info hash */ -+ -+#define VX_HASH_SIZE 13 -+ -+struct hlist_head vx_info_hash[VX_HASH_SIZE]; -+ -+static spinlock_t vx_info_hash_lock = SPIN_LOCK_UNLOCKED; -+ -+ -+static inline unsigned int __hashval(xid_t xid) -+{ -+ return (xid % VX_HASH_SIZE); -+} -+ -+ -+ -+/* __hash_vx_info() -+ -+ * add the vxi to the global hash table -+ * requires the hash_lock to be held */ -+ -+static inline void __hash_vx_info(struct vx_info *vxi) -+{ -+ struct hlist_head *head; -+ -+ vxd_assert_lock(&vx_info_hash_lock); -+ vxdprintk(VXD_CBIT(xid, 4), -+ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id); -+ vxh_hash_vx_info(vxi); -+ -+ /* context must not be hashed */ -+ BUG_ON(vx_info_state(vxi, VXS_HASHED)); -+ -+ vxi->vx_state |= VXS_HASHED; -+ head = &vx_info_hash[__hashval(vxi->vx_id)]; -+ hlist_add_head(&vxi->vx_hlist, head); -+} -+ -+/* __unhash_vx_info() -+ -+ * remove the vxi from the global hash table -+ * requires the hash_lock to be held */ -+ -+static inline void __unhash_vx_info(struct vx_info *vxi) -+{ -+ vxd_assert_lock(&vx_info_hash_lock); -+ vxdprintk(VXD_CBIT(xid, 4), -+ "__unhash_vx_info: %p[#%d]", vxi, vxi->vx_id); -+ vxh_unhash_vx_info(vxi); -+ -+ /* context must be hashed */ -+ BUG_ON(!vx_info_state(vxi, VXS_HASHED)); -+ -+ vxi->vx_state &= ~VXS_HASHED; -+ hlist_del(&vxi->vx_hlist); -+} -+ -+ -+/* __lookup_vx_info() -+ -+ * requires the hash_lock to be held -+ * doesn't increment the vx_refcnt */ -+ -+static inline struct vx_info *__lookup_vx_info(xid_t xid) -+{ -+ struct hlist_head *head = &vx_info_hash[__hashval(xid)]; -+ struct hlist_node *pos; -+ struct vx_info *vxi; -+ -+ vxd_assert_lock(&vx_info_hash_lock); -+ hlist_for_each(pos, head) { -+ vxi = hlist_entry(pos, struct vx_info, vx_hlist); -+ -+ if (vxi->vx_id == xid) -+ goto found; -+ } -+ vxi = NULL; -+found: -+ vxdprintk(VXD_CBIT(xid, 0), -+ "__lookup_vx_info(#%u): %p[#%u]", -+ xid, vxi, vxi?vxi->vx_id:0); -+ vxh_lookup_vx_info(vxi, xid); -+ return vxi; -+} -+ -+ -+/* __vx_dynamic_id() -+ -+ * find unused dynamic xid -+ * requires the hash_lock to be held */ -+ -+static inline xid_t __vx_dynamic_id(void) -+{ -+ static xid_t seq = MAX_S_CONTEXT; -+ xid_t barrier = seq; -+ -+ vxd_assert_lock(&vx_info_hash_lock); -+ do { -+ if (++seq > MAX_S_CONTEXT) -+ seq = MIN_D_CONTEXT; -+ if (!__lookup_vx_info(seq)) { -+ vxdprintk(VXD_CBIT(xid, 4), -+ "__vx_dynamic_id: [#%d]", seq); -+ return seq; -+ } -+ } while (barrier != seq); -+ return 0; -+} -+ -+#ifdef CONFIG_VSERVER_LEGACY -+ -+/* __loc_vx_info() -+ -+ * locate or create the requested context -+ * get() it and if new hash it */ -+ -+static struct vx_info * __loc_vx_info(int id, int *err) -+{ -+ struct vx_info *new, *vxi = NULL; -+ -+ vxdprintk(VXD_CBIT(xid, 1), "loc_vx_info(%d)*", id); -+ -+ if (!(new = __alloc_vx_info(id))) { -+ *err = -ENOMEM; -+ return NULL; -+ } -+ -+ /* required to make dynamic xids unique */ -+ spin_lock(&vx_info_hash_lock); -+ -+ /* dynamic context requested */ -+ if (id == VX_DYNAMIC_ID) { -+ id = __vx_dynamic_id(); -+ if (!id) { -+ printk(KERN_ERR "no dynamic context available.\n"); -+ goto out_unlock; -+ } -+ new->vx_id = id; -+ } -+ /* existing context requested */ -+ else if ((vxi = __lookup_vx_info(id))) { -+ /* context in setup is not available */ -+ if (vxi->vx_flags & VXF_STATE_SETUP) { -+ vxdprintk(VXD_CBIT(xid, 0), -+ "loc_vx_info(%d) = %p (not available)", id, vxi); -+ vxi = NULL; -+ *err = -EBUSY; -+ } else { -+ vxdprintk(VXD_CBIT(xid, 0), -+ "loc_vx_info(%d) = %p (found)", id, vxi); -+ get_vx_info(vxi); -+ *err = 0; -+ } -+ goto out_unlock; -+ } -+ -+ /* new context requested */ -+ vxdprintk(VXD_CBIT(xid, 0), -+ "loc_vx_info(%d) = %p (new)", id, new); -+ __hash_vx_info(get_vx_info(new)); -+ vxi = new, new = NULL; -+ *err = 1; -+ -+out_unlock: -+ spin_unlock(&vx_info_hash_lock); -+ vxh_loc_vx_info(vxi, id); -+ if (new) -+ __dealloc_vx_info(new); -+ return vxi; -+} -+ -+#endif -+ -+/* __create_vx_info() -+ -+ * create the requested context -+ * get() and hash it */ -+ -+static struct vx_info * __create_vx_info(int id) -+{ -+ struct vx_info *new, *vxi = NULL; -+ -+ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id); -+ -+ if (!(new = __alloc_vx_info(id))) -+ return ERR_PTR(-ENOMEM); -+ -+ /* required to make dynamic xids unique */ -+ spin_lock(&vx_info_hash_lock); -+ -+ /* dynamic context requested */ -+ if (id == VX_DYNAMIC_ID) { -+ id = __vx_dynamic_id(); -+ if (!id) { -+ printk(KERN_ERR "no dynamic context available.\n"); -+ vxi = ERR_PTR(-EAGAIN); -+ goto out_unlock; -+ } -+ new->vx_id = id; -+ } -+ /* static context requested */ -+ else if ((vxi = __lookup_vx_info(id))) { -+ vxdprintk(VXD_CBIT(xid, 0), -+ "create_vx_info(%d) = %p (already there)", id, vxi); -+ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0)) -+ vxi = ERR_PTR(-EBUSY); -+ else -+ vxi = ERR_PTR(-EEXIST); -+ goto out_unlock; -+ } -+ /* dynamic xid creation blocker */ -+ else if (id >= MIN_D_CONTEXT) { -+ vxdprintk(VXD_CBIT(xid, 0), -+ "create_vx_info(%d) (dynamic rejected)", id); -+ vxi = ERR_PTR(-EINVAL); -+ goto out_unlock; -+ } -+ -+ /* new context */ -+ vxdprintk(VXD_CBIT(xid, 0), -+ "create_vx_info(%d) = %p (new)", id, new); -+ __hash_vx_info(get_vx_info(new)); -+ vxi = new, new = NULL; -+ -+out_unlock: -+ spin_unlock(&vx_info_hash_lock); -+ vxh_create_vx_info(IS_ERR(vxi)?NULL:vxi, id); -+ if (new) -+ __dealloc_vx_info(new); -+ return vxi; -+} -+ -+ -+/* exported stuff */ -+ -+ -+void unhash_vx_info(struct vx_info *vxi) -+{ -+ __shutdown_vx_info(vxi); -+ spin_lock(&vx_info_hash_lock); -+ __unhash_vx_info(vxi); -+ spin_unlock(&vx_info_hash_lock); -+ __wakeup_vx_info(vxi); -+} -+ -+ -+/* lookup_vx_info() -+ -+ * search for a vx_info and get() it -+ * negative id means current */ -+ -+struct vx_info *lookup_vx_info(int id) -+{ -+ struct vx_info *vxi = NULL; -+ -+ if (id < 0) { -+ vxi = get_vx_info(current->vx_info); -+ } else if (id > 1) { -+ spin_lock(&vx_info_hash_lock); -+ vxi = get_vx_info(__lookup_vx_info(id)); -+ spin_unlock(&vx_info_hash_lock); -+ } -+ return vxi; -+} -+ -+/* xid_is_hashed() -+ -+ * verify that xid is still hashed */ -+ -+int xid_is_hashed(xid_t xid) -+{ -+ int hashed; -+ -+ spin_lock(&vx_info_hash_lock); -+ hashed = (__lookup_vx_info(xid) != NULL); -+ spin_unlock(&vx_info_hash_lock); -+ return hashed; -+} -+ -+#ifdef CONFIG_VSERVER_LEGACY -+ -+struct vx_info *lookup_or_create_vx_info(int id) -+{ -+ int err; -+ -+ return __loc_vx_info(id, &err); -+} -+ -+#endif -+ -+#ifdef CONFIG_PROC_FS -+ -+int get_xid_list(int index, unsigned int *xids, int size) -+{ -+ int hindex, nr_xids = 0; -+ -+ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) { -+ struct hlist_head *head = &vx_info_hash[hindex]; -+ struct hlist_node *pos; -+ -+ spin_lock(&vx_info_hash_lock); -+ hlist_for_each(pos, head) { -+ struct vx_info *vxi; -+ -+ if (--index > 0) -+ continue; -+ -+ vxi = hlist_entry(pos, struct vx_info, vx_hlist); -+ xids[nr_xids] = vxi->vx_id; -+ if (++nr_xids >= size) { -+ spin_unlock(&vx_info_hash_lock); -+ goto out; -+ } -+ } -+ /* keep the lock time short */ -+ spin_unlock(&vx_info_hash_lock); -+ } -+out: -+ return nr_xids; -+} -+#endif -+ -+ -+int vx_migrate_user(struct task_struct *p, struct vx_info *vxi) -+{ -+ struct user_struct *new_user, *old_user; -+ -+ if (!p || !vxi) -+ BUG(); -+ new_user = alloc_uid(vxi->vx_id, p->uid); -+ if (!new_user) -+ return -ENOMEM; -+ -+ old_user = p->user; -+ if (new_user != old_user) { -+ atomic_inc(&new_user->processes); -+ atomic_dec(&old_user->processes); -+ p->user = new_user; -+ } -+ free_uid(old_user); -+ return 0; -+} -+ -+void vx_mask_bcaps(struct vx_info *vxi, struct task_struct *p) -+{ -+ p->cap_effective &= vxi->vx_bcaps; -+ p->cap_inheritable &= vxi->vx_bcaps; -+ p->cap_permitted &= vxi->vx_bcaps; -+} -+ -+ -+#include -+ -+static int vx_openfd_task(struct task_struct *tsk) -+{ -+ struct files_struct *files = tsk->files; -+ struct fdtable *fdt; -+ const unsigned long *bptr; -+ int count, total; -+ -+ /* no rcu_read_lock() because of spin_lock() */ -+ spin_lock(&files->file_lock); -+ fdt = files_fdtable(files); -+ bptr = fdt->open_fds->fds_bits; -+ count = fdt->max_fds / (sizeof(unsigned long) * 8); -+ for (total = 0; count > 0; count--) { -+ if (*bptr) -+ total += hweight_long(*bptr); -+ bptr++; -+ } -+ spin_unlock(&files->file_lock); -+ return total; -+} -+ -+/* -+ * migrate task to new context -+ * gets vxi, puts old_vxi on change -+ */ -+ -+int vx_migrate_task(struct task_struct *p, struct vx_info *vxi) -+{ -+ struct vx_info *old_vxi; -+ int ret = 0; -+ -+ if (!p || !vxi) -+ BUG(); -+ -+ old_vxi = task_get_vx_info(p); -+ if (old_vxi == vxi) -+ goto out; -+ -+ vxdprintk(VXD_CBIT(xid, 5), -+ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi, -+ vxi->vx_id, atomic_read(&vxi->vx_usecnt)); -+ -+ if (!(ret = vx_migrate_user(p, vxi))) { -+ int openfd; -+ -+ task_lock(p); -+ openfd = vx_openfd_task(p); -+ -+ if (old_vxi) { -+ atomic_dec(&old_vxi->cvirt.nr_threads); -+ atomic_dec(&old_vxi->cvirt.nr_running); -+ atomic_dec(&old_vxi->limit.rcur[RLIMIT_NPROC]); -+ /* FIXME: what about the struct files here? */ -+ atomic_sub(openfd, &old_vxi->limit.rcur[VLIMIT_OPENFD]); -+ } -+ atomic_inc(&vxi->cvirt.nr_threads); -+ atomic_inc(&vxi->cvirt.nr_running); -+ atomic_inc(&vxi->limit.rcur[RLIMIT_NPROC]); -+ /* FIXME: what about the struct files here? */ -+ atomic_add(openfd, &vxi->limit.rcur[VLIMIT_OPENFD]); -+ -+ if (old_vxi) { -+ release_vx_info(old_vxi, p); -+ clr_vx_info(&p->vx_info); -+ } -+ claim_vx_info(vxi, p); -+ set_vx_info(&p->vx_info, vxi); -+ p->xid = vxi->vx_id; -+ -+ vxdprintk(VXD_CBIT(xid, 5), -+ "moved task %p into vxi:%p[#%d]", -+ p, vxi, vxi->vx_id); -+ -+ vx_mask_bcaps(vxi, p); -+ task_unlock(p); -+ } -+out: -+ put_vx_info(old_vxi); -+ return ret; -+} -+ -+int vx_set_reaper(struct vx_info *vxi, struct task_struct *p) -+{ -+ struct task_struct *old_reaper; -+ -+ if (!vxi) -+ return -EINVAL; -+ -+ vxdprintk(VXD_CBIT(xid, 6), -+ "vx_set_reaper(%p[#%d],%p[#%d,%d])", -+ vxi, vxi->vx_id, p, p->xid, p->pid); -+ -+ old_reaper = vxi->vx_reaper; -+ if (old_reaper == p) -+ return 0; -+ -+ /* set new child reaper */ -+ get_task_struct(p); -+ vxi->vx_reaper = p; -+ put_task_struct(old_reaper); -+ return 0; -+} -+ -+int vx_set_init(struct vx_info *vxi, struct task_struct *p) -+{ -+ if (!vxi) -+ return -EINVAL; -+ -+ vxdprintk(VXD_CBIT(xid, 6), -+ "vx_set_init(%p[#%d],%p[#%d,%d,%d])", -+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid); -+ -+ vxi->vx_initpid = p->tgid; -+ return 0; -+} -+ -+void vx_exit_init(struct vx_info *vxi, struct task_struct *p) -+{ -+ vxdprintk(VXD_CBIT(xid, 6), -+ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])", -+ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid); -+ -+ vxi->vx_initpid = 0; -+} -+ -+void vx_set_persistent(struct vx_info *vxi) -+{ -+ vxdprintk(VXD_CBIT(xid, 6), -+ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id); -+ -+ if (vx_info_flags(vxi, VXF_PERSISTENT, 0)) { -+ get_vx_info(vxi); -+ claim_vx_info(vxi, current); -+ } else { -+ release_vx_info(vxi, current); -+ put_vx_info(vxi); -+ } -+} -+ -+ -+/* task must be current or locked */ -+ -+void exit_vx_info(struct task_struct *p) -+{ -+ struct vx_info *vxi = p->vx_info; -+ -+ if (vxi) { -+ atomic_dec(&vxi->cvirt.nr_threads); -+ vx_nproc_dec(p); -+ -+ if (vxi->vx_initpid == p->tgid) -+ vx_exit_init(vxi, p); -+ if (vxi->vx_reaper == p) -+ vx_set_reaper(vxi, child_reaper); -+ release_vx_info(vxi, p); -+ } -+} -+ -+ -+/* vserver syscall commands below here */ -+ -+/* taks xid and vx_info functions */ -+ -+#include -+ -+ -+int vc_task_xid(uint32_t id, void __user *data) -+{ -+ xid_t xid; -+ -+ if (id) { -+ struct task_struct *tsk; -+ -+ if (!vx_check(0, VX_ADMIN|VX_WATCH)) -+ return -EPERM; -+ -+ read_lock(&tasklist_lock); -+ tsk = find_task_by_real_pid(id); -+ xid = (tsk) ? tsk->xid : -ESRCH; -+ read_unlock(&tasklist_lock); -+ } -+ else -+ xid = vx_current_xid(); -+ return xid; -+} -+ -+ -+int vc_vx_info(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_vx_info_v0 vc_data; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) -+ return -EPERM; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ vc_data.xid = vxi->vx_id; -+ vc_data.initpid = vxi->vx_initpid; -+ put_vx_info(vxi); -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+ -+/* context functions */ -+ -+int vc_ctx_create(uint32_t xid, void __user *data) -+{ -+ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET }; -+ struct vx_info *new_vxi; -+ int ret; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ if ((xid > MAX_S_CONTEXT) && (xid != VX_DYNAMIC_ID)) -+ return -EINVAL; -+ if (xid < 2) -+ return -EINVAL; -+ -+ new_vxi = __create_vx_info(xid); -+ if (IS_ERR(new_vxi)) -+ return PTR_ERR(new_vxi); -+ -+ /* initial flags */ -+ new_vxi->vx_flags = vc_data.flagword; -+ -+ /* get a reference for persistent contexts */ -+ if ((vc_data.flagword & VXF_PERSISTENT)) -+ vx_set_persistent(new_vxi); -+ -+ vs_state_change(new_vxi, VSC_STARTUP); -+ ret = new_vxi->vx_id; -+ vx_migrate_task(current, new_vxi); -+ /* if this fails, we might end up with a hashed vx_info */ -+ put_vx_info(new_vxi); -+ return ret; -+} -+ -+ -+int vc_ctx_migrate(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_migrate vc_data = { .flagword = 0 }; -+ struct vx_info *vxi; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ /* dirty hack until Spectator becomes a cap */ -+ if (id == 1) { -+ current->xid = 1; -+ return 0; -+ } -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ vx_migrate_task(current, vxi); -+ if (vc_data.flagword & VXM_SET_INIT) -+ vx_set_init(vxi, current); -+ if (vc_data.flagword & VXM_SET_REAPER) -+ vx_set_reaper(vxi, current); -+ put_vx_info(vxi); -+ return 0; -+} -+ -+ -+int vc_get_cflags(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_ctx_flags_v0 vc_data; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ vc_data.flagword = vxi->vx_flags; -+ -+ /* special STATE flag handling */ -+ vc_data.mask = vx_mask_flags(~0UL, vxi->vx_flags, VXF_ONE_TIME); -+ -+ put_vx_info(vxi); -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+int vc_set_cflags(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_ctx_flags_v0 vc_data; -+ uint64_t mask, trigger; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ /* special STATE flag handling */ -+ mask = vx_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME); -+ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword); -+ -+ if (vxi == current->vx_info) { -+ if (trigger & VXF_STATE_SETUP) -+ vx_mask_bcaps(vxi, current); -+ if (trigger & VXF_STATE_INIT) { -+ vx_set_init(vxi, current); -+ vx_set_reaper(vxi, current); -+ } -+ } -+ -+ vxi->vx_flags = vx_mask_flags(vxi->vx_flags, -+ vc_data.flagword, mask); -+ if (trigger & VXF_PERSISTENT) -+ vx_set_persistent(vxi); -+ -+ put_vx_info(vxi); -+ return 0; -+} -+ -+int vc_get_ccaps(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_ctx_caps_v0 vc_data; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ vc_data.bcaps = vxi->vx_bcaps; -+ vc_data.ccaps = vxi->vx_ccaps; -+ vc_data.cmask = ~0UL; -+ put_vx_info(vxi); -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+int vc_set_ccaps(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_ctx_caps_v0 vc_data; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ vxi->vx_bcaps &= vc_data.bcaps; -+ vxi->vx_ccaps = vx_mask_flags(vxi->vx_ccaps, -+ vc_data.ccaps, vc_data.cmask); -+ put_vx_info(vxi); -+ return 0; -+} -+ -+#include -+ -+EXPORT_SYMBOL_GPL(free_vx_info); -+ -diff --git a/kernel/vserver/cvirt.c b/kernel/vserver/cvirt.c -new file mode 100644 -index 0000000..4805303 ---- /dev/null -+++ b/kernel/vserver/cvirt.c -@@ -0,0 +1,259 @@ -+/* -+ * linux/kernel/vserver/cvirt.c -+ * -+ * Virtual Server: Context Virtualization -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 broken out from limit.c -+ * V0.02 added utsname stuff -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle) -+{ -+ struct vx_info *vxi = current->vx_info; -+ -+ set_normalized_timespec(uptime, -+ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec, -+ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec); -+ if (!idle) -+ return; -+ set_normalized_timespec(idle, -+ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec, -+ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec); -+ return; -+} -+ -+uint64_t vx_idle_jiffies(void) -+{ -+ return init_task.utime + init_task.stime; -+} -+ -+ -+ -+static inline uint32_t __update_loadavg(uint32_t load, -+ int wsize, int delta, int n) -+{ -+ unsigned long long calc, prev; -+ -+ /* just set it to n */ -+ if (unlikely(delta >= wsize)) -+ return (n << FSHIFT); -+ -+ calc = delta * n; -+ calc <<= FSHIFT; -+ prev = (wsize - delta); -+ prev *= load; -+ calc += prev; -+ do_div(calc, wsize); -+ return calc; -+} -+ -+ -+void vx_update_load(struct vx_info *vxi) -+{ -+ uint32_t now, last, delta; -+ unsigned int nr_running, nr_uninterruptible; -+ unsigned int total; -+ -+ spin_lock(&vxi->cvirt.load_lock); -+ -+ now = jiffies; -+ last = vxi->cvirt.load_last; -+ delta = now - last; -+ -+ if (delta < 5*HZ) -+ goto out; -+ -+ nr_running = atomic_read(&vxi->cvirt.nr_running); -+ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible); -+ total = nr_running + nr_uninterruptible; -+ -+ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0], -+ 60*HZ, delta, total); -+ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1], -+ 5*60*HZ, delta, total); -+ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2], -+ 15*60*HZ, delta, total); -+ -+ vxi->cvirt.load_last = now; -+out: -+ atomic_inc(&vxi->cvirt.load_updates); -+ spin_unlock(&vxi->cvirt.load_lock); -+} -+ -+ -+int vx_uts_virt_handler(struct ctl_table *ctl, int write, xid_t xid, -+ void **datap, size_t *lenp) -+{ -+ switch (ctl->ctl_name) { -+ case KERN_OSTYPE: -+ *datap = vx_new_uts(sysname); -+ break; -+ case KERN_OSRELEASE: -+ *datap = vx_new_uts(release); -+ break; -+ case KERN_VERSION: -+ *datap = vx_new_uts(version); -+ break; -+ case KERN_NODENAME: -+ *datap = vx_new_uts(nodename); -+ break; -+ case KERN_DOMAINNAME: -+ *datap = vx_new_uts(domainname); -+ break; -+ } -+ -+ return 0; -+} -+ -+ -+ -+/* -+ * Commands to do_syslog: -+ * -+ * 0 -- Close the log. Currently a NOP. -+ * 1 -- Open the log. Currently a NOP. -+ * 2 -- Read from the log. -+ * 3 -- Read all messages remaining in the ring buffer. -+ * 4 -- Read and clear all messages remaining in the ring buffer -+ * 5 -- Clear ring buffer. -+ * 6 -- Disable printk's to console -+ * 7 -- Enable printk's to console -+ * 8 -- Set level of messages printed to console -+ * 9 -- Return number of unread characters in the log buffer -+ * 10 -- Return size of the log buffer -+ */ -+int vx_do_syslog(int type, char __user *buf, int len) -+{ -+ int error = 0; -+ int do_clear = 0; -+ struct vx_info *vxi = current->vx_info; -+ struct _vx_syslog *log; -+ -+ if (!vxi) -+ return -EINVAL; -+ log = &vxi->cvirt.syslog; -+ -+ switch (type) { -+ case 0: /* Close log */ -+ case 1: /* Open log */ -+ break; -+ case 2: /* Read from log */ -+ error = wait_event_interruptible(log->log_wait, -+ (log->log_start - log->log_end)); -+ if (error) -+ break; -+ spin_lock_irq(&log->logbuf_lock); -+ spin_unlock_irq(&log->logbuf_lock); -+ break; -+ case 4: /* Read/clear last kernel messages */ -+ do_clear = 1; -+ /* fall through */ -+ case 3: /* Read last kernel messages */ -+ return 0; -+ -+ case 5: /* Clear ring buffer */ -+ return 0; -+ -+ case 6: /* Disable logging to console */ -+ case 7: /* Enable logging to console */ -+ case 8: /* Set level of messages printed to console */ -+ break; -+ -+ case 9: /* Number of chars in the log buffer */ -+ return 0; -+ case 10: /* Size of the log buffer */ -+ return 0; -+ default: -+ error = -EINVAL; -+ break; -+ } -+ return error; -+} -+ -+ -+/* virtual host info names */ -+ -+static char * vx_vhi_name(struct vx_info *vxi, int id) -+{ -+ switch (id) { -+ case VHIN_CONTEXT: -+ return vxi->vx_name; -+ case VHIN_SYSNAME: -+ return vxi->cvirt.utsname.sysname; -+ case VHIN_NODENAME: -+ return vxi->cvirt.utsname.nodename; -+ case VHIN_RELEASE: -+ return vxi->cvirt.utsname.release; -+ case VHIN_VERSION: -+ return vxi->cvirt.utsname.version; -+ case VHIN_MACHINE: -+ return vxi->cvirt.utsname.machine; -+ case VHIN_DOMAINNAME: -+ return vxi->cvirt.utsname.domainname; -+ default: -+ return NULL; -+ } -+ return NULL; -+} -+ -+int vc_set_vhi_name(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_vhi_name_v0 vc_data; -+ char *name; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ name = vx_vhi_name(vxi, vc_data.field); -+ if (name) -+ memcpy(name, vc_data.name, 65); -+ put_vx_info(vxi); -+ return (name ? 0 : -EFAULT); -+} -+ -+int vc_get_vhi_name(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_vhi_name_v0 vc_data; -+ char *name; -+ -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ name = vx_vhi_name(vxi, vc_data.field); -+ if (!name) -+ goto out_put; -+ -+ memcpy(vc_data.name, name, 65); -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+out_put: -+ put_vx_info(vxi); -+ return (name ? 0 : -EFAULT); -+} -diff --git a/kernel/vserver/cvirt_init.h b/kernel/vserver/cvirt_init.h -new file mode 100644 -index 0000000..d2e6d47 ---- /dev/null -+++ b/kernel/vserver/cvirt_init.h -@@ -0,0 +1,83 @@ -+ -+#include -+ -+ -+#include -+ -+ -+extern uint64_t vx_idle_jiffies(void); -+ -+static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt) -+{ -+ uint64_t idle_jiffies = vx_idle_jiffies(); -+ uint64_t nsuptime; -+ -+ do_posix_clock_monotonic_gettime(&cvirt->bias_uptime); -+ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec -+ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec; -+ cvirt->bias_clock = nsec_to_clock_t(nsuptime); -+ -+ jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle); -+ atomic_set(&cvirt->nr_threads, 0); -+ atomic_set(&cvirt->nr_running, 0); -+ atomic_set(&cvirt->nr_uninterruptible, 0); -+ atomic_set(&cvirt->nr_onhold, 0); -+ -+ down_read(&uts_sem); -+ cvirt->utsname = system_utsname; -+ up_read(&uts_sem); -+ -+ spin_lock_init(&cvirt->load_lock); -+ cvirt->load_last = jiffies; -+ atomic_set(&cvirt->load_updates, 0); -+ cvirt->load[0] = 0; -+ cvirt->load[1] = 0; -+ cvirt->load[2] = 0; -+ atomic_set(&cvirt->total_forks, 0); -+ -+ spin_lock_init(&cvirt->syslog.logbuf_lock); -+ init_waitqueue_head(&cvirt->syslog.log_wait); -+ cvirt->syslog.log_start = 0; -+ cvirt->syslog.log_end = 0; -+ cvirt->syslog.con_start = 0; -+ cvirt->syslog.logged_chars = 0; -+} -+ -+static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt) -+{ -+#ifdef CONFIG_VSERVER_DEBUG -+ int value; -+ -+ vxwprintk((value = atomic_read(&cvirt->nr_threads)), -+ "!!! cvirt: %p[nr_threads] = %d on exit.", -+ cvirt, value); -+ vxwprintk((value = atomic_read(&cvirt->nr_running)), -+ "!!! cvirt: %p[nr_running] = %d on exit.", -+ cvirt, value); -+ vxwprintk((value = atomic_read(&cvirt->nr_uninterruptible)), -+ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.", -+ cvirt, value); -+ vxwprintk((value = atomic_read(&cvirt->nr_onhold)), -+ "!!! cvirt: %p[nr_onhold] = %d on exit.", -+ cvirt, value); -+#endif -+ return; -+} -+ -+static inline void vx_info_init_cacct(struct _vx_cacct *cacct) -+{ -+ int i,j; -+ -+ for (i=0; i<5; i++) { -+ for (j=0; j<3; j++) { -+ atomic_set(&cacct->sock[i][j].count, 0); -+ atomic_set(&cacct->sock[i][j].total, 0); -+ } -+ } -+} -+ -+static inline void vx_info_exit_cacct(struct _vx_cacct *cacct) -+{ -+ return; -+} -+ -diff --git a/kernel/vserver/cvirt_proc.h b/kernel/vserver/cvirt_proc.h -new file mode 100644 -index 0000000..9143c2d ---- /dev/null -+++ b/kernel/vserver/cvirt_proc.h -@@ -0,0 +1,92 @@ -+#ifndef _VX_CVIRT_PROC_H -+#define _VX_CVIRT_PROC_H -+ -+#include -+ -+ -+#define LOAD_INT(x) ((x) >> FSHIFT) -+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) -+ -+static inline int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer) -+{ -+ int length = 0; -+ int a, b, c; -+ -+ length += sprintf(buffer + length, -+ "BiasUptime:\t%lu.%02lu\n", -+ (unsigned long)cvirt->bias_uptime.tv_sec, -+ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100))); -+ length += sprintf(buffer + length, -+ "SysName:\t%.*s\n" -+ "NodeName:\t%.*s\n" -+ "Release:\t%.*s\n" -+ "Version:\t%.*s\n" -+ "Machine:\t%.*s\n" -+ "DomainName:\t%.*s\n" -+ ,__NEW_UTS_LEN, cvirt->utsname.sysname -+ ,__NEW_UTS_LEN, cvirt->utsname.nodename -+ ,__NEW_UTS_LEN, cvirt->utsname.release -+ ,__NEW_UTS_LEN, cvirt->utsname.version -+ ,__NEW_UTS_LEN, cvirt->utsname.machine -+ ,__NEW_UTS_LEN, cvirt->utsname.domainname -+ ); -+ -+ a = cvirt->load[0] + (FIXED_1/200); -+ b = cvirt->load[1] + (FIXED_1/200); -+ c = cvirt->load[2] + (FIXED_1/200); -+ length += sprintf(buffer + length, -+ "nr_threads:\t%d\n" -+ "nr_running:\t%d\n" -+ "nr_unintr:\t%d\n" -+ "nr_onhold:\t%d\n" -+ "load_updates:\t%d\n" -+ "loadavg:\t%d.%02d %d.%02d %d.%02d\n" -+ "total_forks:\t%d\n" -+ ,atomic_read(&cvirt->nr_threads) -+ ,atomic_read(&cvirt->nr_running) -+ ,atomic_read(&cvirt->nr_uninterruptible) -+ ,atomic_read(&cvirt->nr_onhold) -+ ,atomic_read(&cvirt->load_updates) -+ ,LOAD_INT(a), LOAD_FRAC(a) -+ ,LOAD_INT(b), LOAD_FRAC(b) -+ ,LOAD_INT(c), LOAD_FRAC(c) -+ ,atomic_read(&cvirt->total_forks) -+ ); -+ return length; -+} -+ -+ -+static inline long vx_sock_count(struct _vx_cacct *cacct, int type, int pos) -+{ -+ return atomic_read(&cacct->sock[type][pos].count); -+} -+ -+ -+static inline long vx_sock_total(struct _vx_cacct *cacct, int type, int pos) -+{ -+ return atomic_read(&cacct->sock[type][pos].total); -+} -+ -+static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer) -+{ -+ int i,j, length = 0; -+ static char *type[] = { "UNSPEC", "UNIX", "INET", "INET6", "OTHER" }; -+ -+ for (i=0; i<5; i++) { -+ length += sprintf(buffer + length, -+ "%s:", type[i]); -+ for (j=0; j<3; j++) { -+ length += sprintf(buffer + length, -+ "\t%12lu/%-12lu" -+ ,vx_sock_count(cacct, i, j) -+ ,vx_sock_total(cacct, i, j) -+ ); -+ } -+ buffer[length++] = '\n'; -+ } -+ length += sprintf(buffer + length, -+ "forks:\t%lu\n", cacct->total_forks); -+ return length; -+} -+ -+#endif /* _VX_CVIRT_PROC_H */ -diff --git a/kernel/vserver/dlimit.c b/kernel/vserver/dlimit.c -new file mode 100644 -index 0000000..6978817 ---- /dev/null -+++ b/kernel/vserver/dlimit.c -@@ -0,0 +1,552 @@ -+/* -+ * linux/kernel/vserver/dlimit.c -+ * -+ * Virtual Server: Context Disk Limits -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 initial version -+ * V0.02 compat32 splitup -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/* __alloc_dl_info() -+ -+ * allocate an initialized dl_info struct -+ * doesn't make it visible (hash) */ -+ -+static struct dl_info *__alloc_dl_info(struct super_block *sb, xid_t xid) -+{ -+ struct dl_info *new = NULL; -+ -+ vxdprintk(VXD_CBIT(dlim, 5), -+ "alloc_dl_info(%p,%d)*", sb, xid); -+ -+ /* would this benefit from a slab cache? */ -+ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL); -+ if (!new) -+ return 0; -+ -+ memset (new, 0, sizeof(struct dl_info)); -+ new->dl_xid = xid; -+ new->dl_sb = sb; -+ INIT_RCU_HEAD(&new->dl_rcu); -+ INIT_HLIST_NODE(&new->dl_hlist); -+ spin_lock_init(&new->dl_lock); -+ atomic_set(&new->dl_refcnt, 0); -+ atomic_set(&new->dl_usecnt, 0); -+ -+ /* rest of init goes here */ -+ -+ vxdprintk(VXD_CBIT(dlim, 4), -+ "alloc_dl_info(%p,%d) = %p", sb, xid, new); -+ return new; -+} -+ -+/* __dealloc_dl_info() -+ -+ * final disposal of dl_info */ -+ -+static void __dealloc_dl_info(struct dl_info *dli) -+{ -+ vxdprintk(VXD_CBIT(dlim, 4), -+ "dealloc_dl_info(%p)", dli); -+ -+ dli->dl_hlist.next = LIST_POISON1; -+ dli->dl_xid = -1; -+ dli->dl_sb = 0; -+ -+ BUG_ON(atomic_read(&dli->dl_usecnt)); -+ BUG_ON(atomic_read(&dli->dl_refcnt)); -+ -+ kfree(dli); -+} -+ -+ -+/* hash table for dl_info hash */ -+ -+#define DL_HASH_SIZE 13 -+ -+struct hlist_head dl_info_hash[DL_HASH_SIZE]; -+ -+static spinlock_t dl_info_hash_lock = SPIN_LOCK_UNLOCKED; -+ -+ -+static inline unsigned int __hashval(struct super_block *sb, xid_t xid) -+{ -+ return ((xid ^ (unsigned long)sb) % DL_HASH_SIZE); -+} -+ -+ -+ -+/* __hash_dl_info() -+ -+ * add the dli to the global hash table -+ * requires the hash_lock to be held */ -+ -+static inline void __hash_dl_info(struct dl_info *dli) -+{ -+ struct hlist_head *head; -+ -+ vxdprintk(VXD_CBIT(dlim, 6), -+ "__hash_dl_info: %p[#%d]", dli, dli->dl_xid); -+ get_dl_info(dli); -+ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_xid)]; -+ hlist_add_head_rcu(&dli->dl_hlist, head); -+} -+ -+/* __unhash_dl_info() -+ -+ * remove the dli from the global hash table -+ * requires the hash_lock to be held */ -+ -+static inline void __unhash_dl_info(struct dl_info *dli) -+{ -+ vxdprintk(VXD_CBIT(dlim, 6), -+ "__unhash_dl_info: %p[#%d]", dli, dli->dl_xid); -+ hlist_del_rcu(&dli->dl_hlist); -+ put_dl_info(dli); -+} -+ -+ -+/* __lookup_dl_info() -+ -+ * requires the rcu_read_lock() -+ * doesn't increment the dl_refcnt */ -+ -+static inline struct dl_info *__lookup_dl_info(struct super_block *sb, xid_t xid) -+{ -+ struct hlist_head *head = &dl_info_hash[__hashval(sb, xid)]; -+ struct hlist_node *pos; -+ struct dl_info *dli; -+ -+ hlist_for_each_entry_rcu(dli, pos, head, dl_hlist) { -+// hlist_for_each_rcu(pos, head) { -+// struct dl_info *dli = -+// hlist_entry(pos, struct dl_info, dl_hlist); -+ -+ if (dli->dl_xid == xid && dli->dl_sb == sb) { -+ return dli; -+ } -+ } -+ return NULL; -+} -+ -+ -+struct dl_info *locate_dl_info(struct super_block *sb, xid_t xid) -+{ -+ struct dl_info *dli; -+ -+ rcu_read_lock(); -+ dli = get_dl_info(__lookup_dl_info(sb, xid)); -+ vxdprintk(VXD_CBIT(dlim, 7), -+ "locate_dl_info(%p,#%d) = %p", sb, xid, dli); -+ rcu_read_unlock(); -+ return dli; -+} -+ -+void rcu_free_dl_info(struct rcu_head *head) -+{ -+ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu); -+ int usecnt, refcnt; -+ -+ BUG_ON(!dli || !head); -+ -+ usecnt = atomic_read(&dli->dl_usecnt); -+ BUG_ON(usecnt < 0); -+ -+ refcnt = atomic_read(&dli->dl_refcnt); -+ BUG_ON(refcnt < 0); -+ -+ vxdprintk(VXD_CBIT(dlim, 3), -+ "rcu_free_dl_info(%p)", dli); -+ if (!usecnt) -+ __dealloc_dl_info(dli); -+ else -+ printk("!!! rcu didn't free\n"); -+} -+ -+ -+ -+ -+int do_addrem_dlimit(uint32_t id, const char __user *name, -+ uint32_t flags, int add) -+{ -+ struct nameidata nd; -+ int ret; -+ -+ ret = user_path_walk_link(name, &nd); -+ if (!ret) { -+ struct super_block *sb; -+ struct dl_info *dli; -+ -+ ret = -EINVAL; -+ if (!nd.dentry->d_inode) -+ goto out_release; -+ if (!(sb = nd.dentry->d_inode->i_sb)) -+ goto out_release; -+ -+ if (add) { -+ dli = __alloc_dl_info(sb, id); -+ spin_lock(&dl_info_hash_lock); -+ -+ ret = -EEXIST; -+ if (__lookup_dl_info(sb, id)) -+ goto out_unlock; -+ __hash_dl_info(dli); -+ dli = NULL; -+ } else { -+ spin_lock(&dl_info_hash_lock); -+ dli = __lookup_dl_info(sb, id); -+ -+ ret = -ESRCH; -+ if (!dli) -+ goto out_unlock; -+ __unhash_dl_info(dli); -+ } -+ ret = 0; -+ out_unlock: -+ spin_unlock(&dl_info_hash_lock); -+ if (add && dli) -+ __dealloc_dl_info(dli); -+ out_release: -+ path_release(&nd); -+ } -+ return ret; -+} -+ -+int vc_add_dlimit(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_dlimit_base_v0 vc_data; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1); -+} -+ -+int vc_rem_dlimit(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_dlimit_base_v0 vc_data; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0); -+} -+ -+#ifdef CONFIG_COMPAT -+ -+int vc_add_dlimit_x32(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ return do_addrem_dlimit(id, -+ compat_ptr(vc_data.name_ptr), vc_data.flags, 1); -+} -+ -+int vc_rem_dlimit_x32(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_dlimit_base_v0_x32 vc_data; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ return do_addrem_dlimit(id, -+ compat_ptr(vc_data.name_ptr), vc_data.flags, 0); -+} -+ -+#endif /* CONFIG_COMPAT */ -+ -+ -+static inline -+int do_set_dlimit(uint32_t id, const char __user *name, -+ uint32_t space_used, uint32_t space_total, -+ uint32_t inodes_used, uint32_t inodes_total, -+ uint32_t reserved, uint32_t flags) -+{ -+ struct nameidata nd; -+ int ret; -+ -+ ret = user_path_walk_link(name, &nd); -+ if (!ret) { -+ struct super_block *sb; -+ struct dl_info *dli; -+ -+ ret = -EINVAL; -+ if (!nd.dentry->d_inode) -+ goto out_release; -+ if (!(sb = nd.dentry->d_inode->i_sb)) -+ goto out_release; -+ if ((reserved != (uint32_t)CDLIM_KEEP && -+ reserved > 100) || -+ (inodes_used != (uint32_t)CDLIM_KEEP && -+ inodes_used > inodes_total) || -+ (space_used != (uint32_t)CDLIM_KEEP && -+ space_used > space_total)) -+ goto out_release; -+ -+ ret = -ESRCH; -+ dli = locate_dl_info(sb, id); -+ if (!dli) -+ goto out_release; -+ -+ spin_lock(&dli->dl_lock); -+ -+ if (inodes_used != (uint32_t)CDLIM_KEEP) -+ dli->dl_inodes_used = inodes_used; -+ if (inodes_total != (uint32_t)CDLIM_KEEP) -+ dli->dl_inodes_total = inodes_total; -+ if (space_used != (uint32_t)CDLIM_KEEP) { -+ dli->dl_space_used = space_used; -+ dli->dl_space_used <<= 10; -+ } -+ if (space_total == (uint32_t)CDLIM_INFINITY) -+ dli->dl_space_total = (uint64_t)CDLIM_INFINITY; -+ else if (space_total != (uint32_t)CDLIM_KEEP) { -+ dli->dl_space_total = space_total; -+ dli->dl_space_total <<= 10; -+ } -+ if (reserved != (uint32_t)CDLIM_KEEP) -+ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100; -+ -+ spin_unlock(&dli->dl_lock); -+ -+ put_dl_info(dli); -+ ret = 0; -+ -+ out_release: -+ path_release(&nd); -+ } -+ return ret; -+} -+ -+int vc_set_dlimit(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_dlimit_v0 vc_data; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ return do_set_dlimit(id, vc_data.name, -+ vc_data.space_used, vc_data.space_total, -+ vc_data.inodes_used, vc_data.inodes_total, -+ vc_data.reserved, vc_data.flags); -+} -+ -+#ifdef CONFIG_COMPAT -+ -+int vc_set_dlimit_x32(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_dlimit_v0_x32 vc_data; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr), -+ vc_data.space_used, vc_data.space_total, -+ vc_data.inodes_used, vc_data.inodes_total, -+ vc_data.reserved, vc_data.flags); -+} -+ -+#endif /* CONFIG_COMPAT */ -+ -+ -+static inline -+int do_get_dlimit(uint32_t id, const char __user *name, -+ uint32_t *space_used, uint32_t *space_total, -+ uint32_t *inodes_used, uint32_t *inodes_total, -+ uint32_t *reserved, uint32_t *flags) -+{ -+ struct nameidata nd; -+ int ret; -+ -+ ret = user_path_walk_link(name, &nd); -+ if (!ret) { -+ struct super_block *sb; -+ struct dl_info *dli; -+ -+ ret = -EINVAL; -+ if (!nd.dentry->d_inode) -+ goto out_release; -+ if (!(sb = nd.dentry->d_inode->i_sb)) -+ goto out_release; -+ -+ ret = -ESRCH; -+ dli = locate_dl_info(sb, id); -+ if (!dli) -+ goto out_release; -+ -+ spin_lock(&dli->dl_lock); -+ *inodes_used = dli->dl_inodes_used; -+ *inodes_total = dli->dl_inodes_total; -+ *space_used = dli->dl_space_used >> 10; -+ if (dli->dl_space_total == (uint64_t)CDLIM_INFINITY) -+ *space_total = (uint32_t)CDLIM_INFINITY; -+ else -+ *space_total = dli->dl_space_total >> 10; -+ -+ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10); -+ spin_unlock(&dli->dl_lock); -+ -+ put_dl_info(dli); -+ ret = -EFAULT; -+ -+ ret = 0; -+ out_release: -+ path_release(&nd); -+ } -+ return ret; -+} -+ -+ -+int vc_get_dlimit(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_dlimit_v0 vc_data; -+ int ret; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ ret = do_get_dlimit(id, vc_data.name, -+ &vc_data.space_used, &vc_data.space_total, -+ &vc_data.inodes_used, &vc_data.inodes_total, -+ &vc_data.reserved, &vc_data.flags); -+ if (ret) -+ return ret; -+ -+ if (copy_to_user(data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+#ifdef CONFIG_COMPAT -+ -+int vc_get_dlimit_x32(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_dlimit_v0_x32 vc_data; -+ int ret; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr), -+ &vc_data.space_used, &vc_data.space_total, -+ &vc_data.inodes_used, &vc_data.inodes_total, -+ &vc_data.reserved, &vc_data.flags); -+ if (ret) -+ return ret; -+ -+ if (copy_to_user(data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+#endif /* CONFIG_COMPAT */ -+ -+ -+void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf) -+{ -+ struct dl_info *dli; -+ __u64 blimit, bfree, bavail; -+ __u32 ifree; -+ -+ dli = locate_dl_info(sb, vx_current_xid()); -+ if (!dli) -+ return; -+ -+ spin_lock(&dli->dl_lock); -+ if (dli->dl_inodes_total == (uint32_t)CDLIM_INFINITY) -+ goto no_ilim; -+ -+ /* reduce max inodes available to limit */ -+ if (buf->f_files > dli->dl_inodes_total) -+ buf->f_files = dli->dl_inodes_total; -+ -+ /* inode hack for reiserfs */ -+ if ((buf->f_files == 0) && (dli->dl_inodes_total > 0)) { -+ buf->f_files = dli->dl_inodes_total; -+ buf->f_ffree = dli->dl_inodes_total; -+ } -+ -+ ifree = dli->dl_inodes_total - dli->dl_inodes_used; -+ /* reduce free inodes to min */ -+ if (ifree < buf->f_ffree) -+ buf->f_ffree = ifree; -+ -+no_ilim: -+ if (dli->dl_space_total == (uint64_t)CDLIM_INFINITY) -+ goto no_blim; -+ -+ blimit = dli->dl_space_total >> sb->s_blocksize_bits; -+ -+ if (dli->dl_space_total < dli->dl_space_used) -+ bfree = 0; -+ else -+ bfree = (dli->dl_space_total - dli->dl_space_used) -+ >> sb->s_blocksize_bits; -+ -+ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult); -+ if (bavail < dli->dl_space_used) -+ bavail = 0; -+ else -+ bavail = (bavail - dli->dl_space_used) -+ >> sb->s_blocksize_bits; -+ -+ /* reduce max space available to limit */ -+ if (buf->f_blocks > blimit) -+ buf->f_blocks = blimit; -+ -+ /* reduce free space to min */ -+ if (bfree < buf->f_bfree) -+ buf->f_bfree = bfree; -+ -+ /* reduce avail space to min */ -+ if (bavail < buf->f_bavail) -+ buf->f_bavail = bavail; -+ -+no_blim: -+ spin_unlock(&dli->dl_lock); -+ put_dl_info(dli); -+ -+ return; -+} -+ -+#include -+ -+EXPORT_SYMBOL_GPL(locate_dl_info); -+EXPORT_SYMBOL_GPL(rcu_free_dl_info); -+ -diff --git a/kernel/vserver/helper.c b/kernel/vserver/helper.c -new file mode 100644 -index 0000000..d9a38be ---- /dev/null -+++ b/kernel/vserver/helper.c -@@ -0,0 +1,200 @@ -+/* -+ * linux/kernel/vserver/helper.c -+ * -+ * Virtual Context Support -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 basic helper -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+char vshelper_path[255] = "/sbin/vshelper"; -+ -+ -+int do_vshelper(char *name, char *argv[], char *envp[], int sync) -+{ -+ int ret; -+ -+ if ((ret = call_usermodehelper(name, argv, envp, sync))) { -+ printk( KERN_WARNING -+ "%s: (%s %s) returned %s with %d\n", -+ name, argv[1], argv[2], -+ sync?"sync":"async", ret); -+ } -+ vxdprintk(VXD_CBIT(switch, 4), -+ "%s: (%s %s) returned %s with %d", -+ name, argv[1], argv[2], sync?"sync":"async", ret); -+ return ret; -+} -+ -+/* -+ * vshelper path is set via /proc/sys -+ * invoked by vserver sys_reboot(), with -+ * the following arguments -+ * -+ * argv [0] = vshelper_path; -+ * argv [1] = action: "restart", "halt", "poweroff", ... -+ * argv [2] = context identifier -+ * -+ * envp [*] = type-specific parameters -+ */ -+ -+long vs_reboot_helper(struct vx_info *vxi, int cmd, void *arg) -+{ -+ char id_buf[8], cmd_buf[16]; -+ char uid_buf[16], pid_buf[16]; -+ int ret; -+ -+ char *argv[] = {vshelper_path, NULL, id_buf, 0}; -+ char *envp[] = {"HOME=/", "TERM=linux", -+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", -+ uid_buf, pid_buf, cmd_buf, 0}; -+ -+ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id); -+ -+ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd); -+ snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid); -+ snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid); -+ -+ switch (cmd) { -+ case LINUX_REBOOT_CMD_RESTART: -+ argv[1] = "restart"; -+ break; -+ -+ case LINUX_REBOOT_CMD_HALT: -+ argv[1] = "halt"; -+ break; -+ -+ case LINUX_REBOOT_CMD_POWER_OFF: -+ argv[1] = "poweroff"; -+ break; -+ -+ case LINUX_REBOOT_CMD_SW_SUSPEND: -+ argv[1] = "swsusp"; -+ break; -+ -+ default: -+ return 0; -+ } -+ -+#ifndef CONFIG_VSERVER_LEGACY -+ ret = do_vshelper(vshelper_path, argv, envp, 1); -+#else -+ ret = do_vshelper(vshelper_path, argv, envp, 0); -+#endif -+ return (ret) ? -EPERM : 0; -+} -+ -+ -+long vs_reboot(unsigned int cmd, void * arg) -+{ -+ struct vx_info *vxi = current->vx_info; -+ long ret = 0; -+ -+ vxdprintk(VXD_CBIT(misc, 5), -+ "vs_reboot(%p[#%d],%d)", -+ vxi, vxi?vxi->vx_id:0, cmd); -+ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) { -+ switch (cmd) { -+ case LINUX_REBOOT_CMD_RESTART: -+ case LINUX_REBOOT_CMD_HALT: -+ case LINUX_REBOOT_CMD_POWER_OFF: -+ vx_info_kill(vxi, 0, SIGKILL); -+ vx_info_kill(vxi, 1, SIGKILL); -+ default: -+ break; -+ } -+ } else { -+ ret = vs_reboot_helper(vxi, cmd, arg); -+ } -+ return ret; -+} -+ -+ -+/* -+ * argv [0] = vshelper_path; -+ * argv [1] = action: "startup", "shutdown" -+ * argv [2] = context identifier -+ * -+ * envp [*] = type-specific parameters -+ */ -+ -+long vs_state_change(struct vx_info *vxi, unsigned int cmd) -+{ -+ char id_buf[8], cmd_buf[16]; -+ char *argv[] = {vshelper_path, NULL, id_buf, 0}; -+ char *envp[] = {"HOME=/", "TERM=linux", -+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0}; -+ -+ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0)) -+ return 0; -+ -+ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id); -+ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd); -+ -+ switch (cmd) { -+ case VSC_STARTUP: -+ argv[1] = "startup"; -+ break; -+ case VSC_SHUTDOWN: -+ argv[1] = "shutdown"; -+ break; -+ default: -+ return 0; -+ } -+ -+ do_vshelper(vshelper_path, argv, envp, 1); -+ return 0; -+} -+ -+ -+/* -+ * argv [0] = vshelper_path; -+ * argv [1] = action: "netup", "netdown" -+ * argv [2] = context identifier -+ * -+ * envp [*] = type-specific parameters -+ */ -+ -+long vs_net_change(struct nx_info *nxi, unsigned int cmd) -+{ -+ char id_buf[8], cmd_buf[16]; -+ char *argv[] = {vshelper_path, NULL, id_buf, 0}; -+ char *envp[] = {"HOME=/", "TERM=linux", -+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0}; -+ -+ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0)) -+ return 0; -+ -+ snprintf(id_buf, sizeof(id_buf)-1, "%d", nxi->nx_id); -+ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd); -+ -+ switch (cmd) { -+ case VSC_NETUP: -+ argv[1] = "netup"; -+ break; -+ case VSC_NETDOWN: -+ argv[1] = "netdown"; -+ break; -+ default: -+ return 0; -+ } -+ -+ do_vshelper(vshelper_path, argv, envp, 1); -+ return 0; -+} -+ -diff --git a/kernel/vserver/history.c b/kernel/vserver/history.c -new file mode 100644 -index 0000000..79610c0 ---- /dev/null -+++ b/kernel/vserver/history.c -@@ -0,0 +1,184 @@ -+/* -+ * kernel/vserver/history.c -+ * -+ * Virtual Context History Backtrace -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 basic structure -+ * V0.02 hash/unhash and trace -+ * V0.03 preemption fixes -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+ -+#ifdef CONFIG_VSERVER_HISTORY -+#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE -+#else -+#define VXH_SIZE 64 -+#endif -+ -+struct _vx_history { -+ unsigned int counter; -+ -+ struct _vx_hist_entry entry[VXH_SIZE+1]; -+}; -+ -+ -+DEFINE_PER_CPU(struct _vx_history, vx_history_buffer); -+ -+unsigned volatile int vxh_active = 1; -+ -+static atomic_t sequence = ATOMIC_INIT(0); -+ -+ -+/* vxh_advance() -+ -+ * requires disabled preemption */ -+ -+struct _vx_hist_entry *vxh_advance(void *loc) -+{ -+ unsigned int cpu = smp_processor_id(); -+ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu); -+ struct _vx_hist_entry *entry; -+ unsigned int index; -+ -+ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE; -+ entry = &hist->entry[index]; -+ -+ entry->seq = atomic_inc_return(&sequence); -+ entry->loc = loc; -+ return entry; -+} -+ -+ -+#define VXH_LOC_FMTS "(#%04x,*%d):%p" -+ -+#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc -+ -+ -+#define VXH_VXI_FMTS "%p[#%d,%d.%d]" -+ -+#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \ -+ (e)->vxi.ptr?(e)->vxi.xid:0, \ -+ (e)->vxi.ptr?(e)->vxi.usecnt:0, \ -+ (e)->vxi.ptr?(e)->vxi.tasks:0 -+ -+void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu) -+{ -+ switch (e->type) { -+ case VXH_THROW_OOPS: -+ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e)); -+ break; -+ -+ case VXH_GET_VX_INFO: -+ case VXH_PUT_VX_INFO: -+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n", -+ VXH_LOC_ARGS(e), -+ (e->type==VXH_GET_VX_INFO)?"get":"put", -+ VXH_VXI_ARGS(e)); -+ break; -+ -+ case VXH_INIT_VX_INFO: -+ case VXH_SET_VX_INFO: -+ case VXH_CLR_VX_INFO: -+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n", -+ VXH_LOC_ARGS(e), -+ (e->type==VXH_INIT_VX_INFO)?"init": -+ ((e->type==VXH_SET_VX_INFO)?"set":"clr"), -+ VXH_VXI_ARGS(e), e->sc.data); -+ break; -+ -+ case VXH_CLAIM_VX_INFO: -+ case VXH_RELEASE_VX_INFO: -+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n", -+ VXH_LOC_ARGS(e), -+ (e->type==VXH_CLAIM_VX_INFO)?"claim":"release", -+ VXH_VXI_ARGS(e), e->sc.data); -+ break; -+ -+ case VXH_ALLOC_VX_INFO: -+ case VXH_DEALLOC_VX_INFO: -+ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n", -+ VXH_LOC_ARGS(e), -+ (e->type==VXH_ALLOC_VX_INFO)?"alloc":"dealloc", -+ VXH_VXI_ARGS(e)); -+ break; -+ -+ case VXH_HASH_VX_INFO: -+ case VXH_UNHASH_VX_INFO: -+ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n", -+ VXH_LOC_ARGS(e), -+ (e->type==VXH_HASH_VX_INFO)?"hash":"unhash", -+ VXH_VXI_ARGS(e)); -+ break; -+ -+ case VXH_LOC_VX_INFO: -+ case VXH_LOOKUP_VX_INFO: -+ case VXH_CREATE_VX_INFO: -+ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n", -+ VXH_LOC_ARGS(e), -+ (e->type==VXH_CREATE_VX_INFO)?"create": -+ ((e->type==VXH_LOC_VX_INFO)?"loc":"lookup"), -+ e->ll.arg, VXH_VXI_ARGS(e)); -+ break; -+ } -+} -+ -+static void __vxh_dump_history(void) -+{ -+ unsigned int i,j; -+ -+ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n", -+ atomic_read(&sequence), NR_CPUS); -+ -+ for (i=0; i < VXH_SIZE; i++) { -+ for (j=0; j < NR_CPUS; j++) { -+ struct _vx_history *hist = -+ &per_cpu(vx_history_buffer, j); -+ unsigned int index = (hist->counter-i) % VXH_SIZE; -+ struct _vx_hist_entry *entry = &hist->entry[index]; -+ -+ vxh_dump_entry(entry, j); -+ } -+ } -+} -+ -+void vxh_dump_history(void) -+{ -+ vxh_active = 0; -+#ifdef CONFIG_SMP -+ local_irq_enable(); -+ smp_send_stop(); -+ local_irq_disable(); -+#endif -+ __vxh_dump_history(); -+} -+ -+ -+/* vserver syscall commands below here */ -+ -+ -+int vc_dump_history(uint32_t id) -+{ -+ vxh_active = 0; -+ __vxh_dump_history(); -+ vxh_active = 1; -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(vxh_advance); -+ -diff --git a/kernel/vserver/init.c b/kernel/vserver/init.c -new file mode 100644 -index 0000000..d2e300e ---- /dev/null -+++ b/kernel/vserver/init.c -@@ -0,0 +1,44 @@ -+/* -+ * linux/kernel/init.c -+ * -+ * Virtual Server Init -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 basic structure -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+int vserver_register_sysctl(void); -+void vserver_unregister_sysctl(void); -+ -+ -+static int __init init_vserver(void) -+{ -+ int ret = 0; -+ -+#ifdef CONFIG_VSERVER_DEBUG -+ vserver_register_sysctl(); -+#endif -+ return ret; -+} -+ -+ -+static void __exit exit_vserver(void) -+{ -+ -+#ifdef CONFIG_VSERVER_DEBUG -+ vserver_unregister_sysctl(); -+#endif -+ return; -+} -+ -+ -+module_init(init_vserver); -+module_exit(exit_vserver); -+ -diff --git a/kernel/vserver/inode.c b/kernel/vserver/inode.c -new file mode 100644 -index 0000000..fe7f6a5 ---- /dev/null -+++ b/kernel/vserver/inode.c -@@ -0,0 +1,369 @@ -+/* -+ * linux/kernel/vserver/inode.c -+ * -+ * Virtual Server: File System Support -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 separated from vcontext V0.05 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+static int __vc_get_iattr(struct inode *in, uint32_t *xid, uint32_t *flags, uint32_t *mask) -+{ -+ struct proc_dir_entry *entry; -+ -+ if (!in || !in->i_sb) -+ return -ESRCH; -+ -+ *flags = IATTR_XID -+ | (IS_BARRIER(in) ? IATTR_BARRIER : 0) -+ | (IS_IUNLINK(in) ? IATTR_IUNLINK : 0) -+ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0); -+ *mask = IATTR_IUNLINK | IATTR_IMMUTABLE; -+ -+ if (S_ISDIR(in->i_mode)) -+ *mask |= IATTR_BARRIER; -+ -+ if (IS_TAGXID(in)) { -+ *xid = in->i_xid; -+ *mask |= IATTR_XID; -+ } -+ -+ switch (in->i_sb->s_magic) { -+ case PROC_SUPER_MAGIC: -+ entry = PROC_I(in)->pde; -+ -+ /* check for specific inodes? */ -+ if (entry) -+ *mask |= IATTR_FLAGS; -+ if (entry) -+ *flags |= (entry->vx_flags & IATTR_FLAGS); -+ else -+ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS); -+ break; -+ -+ case DEVPTS_SUPER_MAGIC: -+ *xid = in->i_xid; -+ *mask |= IATTR_XID; -+ break; -+ -+ default: -+ break; -+ } -+ return 0; -+} -+ -+int vc_get_iattr(uint32_t id, void __user *data) -+{ -+ struct nameidata nd; -+ struct vcmd_ctx_iattr_v1 vc_data = { .xid = -1 }; -+ int ret; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ ret = user_path_walk_link(vc_data.name, &nd); -+ if (!ret) { -+ ret = __vc_get_iattr(nd.dentry->d_inode, -+ &vc_data.xid, &vc_data.flags, &vc_data.mask); -+ path_release(&nd); -+ } -+ if (ret) -+ return ret; -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ ret = -EFAULT; -+ return ret; -+} -+ -+#ifdef CONFIG_COMPAT -+ -+int vc_get_iattr_x32(uint32_t id, void __user *data) -+{ -+ struct nameidata nd; -+ struct vcmd_ctx_iattr_v1_x32 vc_data = { .xid = -1 }; -+ int ret; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd); -+ if (!ret) { -+ ret = __vc_get_iattr(nd.dentry->d_inode, -+ &vc_data.xid, &vc_data.flags, &vc_data.mask); -+ path_release(&nd); -+ } -+ if (ret) -+ return ret; -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ ret = -EFAULT; -+ return ret; -+} -+ -+#endif /* CONFIG_COMPAT */ -+ -+ -+static int __vc_set_iattr(struct dentry *de, uint32_t *xid, uint32_t *flags, uint32_t *mask) -+{ -+ struct inode *in = de->d_inode; -+ int error = 0, is_proc = 0, has_xid = 0; -+ struct iattr attr = { 0 }; -+ -+ if (!in || !in->i_sb) -+ return -ESRCH; -+ -+ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC); -+ if ((*mask & IATTR_FLAGS) && !is_proc) -+ return -EINVAL; -+ -+ has_xid = IS_TAGXID(in) || -+ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC); -+ if ((*mask & IATTR_XID) && !has_xid) -+ return -EINVAL; -+ -+ mutex_lock(&in->i_mutex); -+ if (*mask & IATTR_XID) { -+ attr.ia_xid = *xid; -+ attr.ia_valid |= ATTR_XID; -+ } -+ -+ if (*mask & IATTR_FLAGS) { -+ struct proc_dir_entry *entry = PROC_I(in)->pde; -+ unsigned int iflags = PROC_I(in)->vx_flags; -+ -+ iflags = (iflags & ~(*mask & IATTR_FLAGS)) -+ | (*flags & IATTR_FLAGS); -+ PROC_I(in)->vx_flags = iflags; -+ if (entry) -+ entry->vx_flags = iflags; -+ } -+ -+ if (*mask & (IATTR_BARRIER | IATTR_IUNLINK | IATTR_IMMUTABLE)) { -+ if (*mask & IATTR_IMMUTABLE) { -+ if (*flags & IATTR_IMMUTABLE) -+ in->i_flags |= S_IMMUTABLE; -+ else -+ in->i_flags &= ~S_IMMUTABLE; -+ } -+ if (*mask & IATTR_IUNLINK) { -+ if (*flags & IATTR_IUNLINK) -+ in->i_flags |= S_IUNLINK; -+ else -+ in->i_flags &= ~S_IUNLINK; -+ } -+ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) { -+ if (*flags & IATTR_BARRIER) -+ in->i_flags |= S_BARRIER; -+ else -+ in->i_flags &= ~S_BARRIER; -+ } -+ if (in->i_op && in->i_op->sync_flags) { -+ error = in->i_op->sync_flags(in); -+ if (error) -+ goto out; -+ } -+ } -+ -+ if (attr.ia_valid) { -+ if (in->i_op && in->i_op->setattr) -+ error = in->i_op->setattr(de, &attr); -+ else { -+ error = inode_change_ok(in, &attr); -+ if (!error) -+ error = inode_setattr(in, &attr); -+ } -+ } -+ -+out: -+ mutex_unlock(&in->i_mutex); -+ return error; -+} -+ -+int vc_set_iattr(uint32_t id, void __user *data) -+{ -+ struct nameidata nd; -+ struct vcmd_ctx_iattr_v1 vc_data; -+ int ret; -+ -+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_LINUX_IMMUTABLE)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ ret = user_path_walk_link(vc_data.name, &nd); -+ if (!ret) { -+ ret = __vc_set_iattr(nd.dentry, -+ &vc_data.xid, &vc_data.flags, &vc_data.mask); -+ path_release(&nd); -+ } -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ ret = -EFAULT; -+ return ret; -+} -+ -+#ifdef CONFIG_COMPAT -+ -+int vc_set_iattr_x32(uint32_t id, void __user *data) -+{ -+ struct nameidata nd; -+ struct vcmd_ctx_iattr_v1_x32 vc_data; -+ int ret; -+ -+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_LINUX_IMMUTABLE)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd); -+ if (!ret) { -+ ret = __vc_set_iattr(nd.dentry, -+ &vc_data.xid, &vc_data.flags, &vc_data.mask); -+ path_release(&nd); -+ } -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ ret = -EFAULT; -+ return ret; -+} -+ -+#endif /* CONFIG_COMPAT */ -+ -+#ifdef CONFIG_VSERVER_LEGACY -+ -+#define PROC_DYNAMIC_FIRST 0xF0000000UL -+ -+int vx_proc_ioctl(struct inode * inode, struct file * filp, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct proc_dir_entry *entry; -+ int error = 0; -+ int flags; -+ -+ if (inode->i_ino < PROC_DYNAMIC_FIRST) -+ return -ENOTTY; -+ -+ entry = PROC_I(inode)->pde; -+ if (!entry) -+ return -ENOTTY; -+ -+ switch(cmd) { -+ case FIOC_GETXFLG: { -+ /* fixme: if stealth, return -ENOTTY */ -+ error = -EPERM; -+ flags = entry->vx_flags; -+ if (capable(CAP_CONTEXT)) -+ error = put_user(flags, (int *) arg); -+ break; -+ } -+ case FIOC_SETXFLG: { -+ /* fixme: if stealth, return -ENOTTY */ -+ error = -EPERM; -+ if (!capable(CAP_CONTEXT)) -+ break; -+ error = -EROFS; -+ if (IS_RDONLY(inode)) -+ break; -+ error = -EFAULT; -+ if (get_user(flags, (int *) arg)) -+ break; -+ error = 0; -+ entry->vx_flags = flags; -+ break; -+ } -+ default: -+ return -ENOTTY; -+ } -+ return error; -+} -+#endif -+ -+ -+int vx_parse_xid(char *string, xid_t *xid, int remove) -+{ -+ static match_table_t tokens = { -+ {1, "xid=%u"}, -+ {0, NULL} -+ }; -+ substring_t args[MAX_OPT_ARGS]; -+ int token, option = 0; -+ -+ if (!string) -+ return 0; -+ -+ token = match_token(string, tokens, args); -+ if (token && xid && !match_int(args, &option)) -+ *xid = option; -+ -+ vxdprintk(VXD_CBIT(xid, 7), -+ "vx_parse_xid(»%s«): %d:#%d", -+ string, token, option); -+ -+ if (token && remove) { -+ char *p = strstr(string, "xid="); -+ char *q = p; -+ -+ if (p) { -+ while (*q != '\0' && *q != ',') -+ q++; -+ while (*q) -+ *p++ = *q++; -+ while (*p) -+ *p++ = '\0'; -+ } -+ } -+ return token; -+} -+ -+void vx_propagate_xid(struct nameidata *nd, struct inode *inode) -+{ -+ xid_t new_xid = 0; -+ struct vfsmount *mnt; -+ int propagate; -+ -+ if (!nd) -+ return; -+ mnt = nd->mnt; -+ if (!mnt) -+ return; -+ -+ propagate = (mnt->mnt_flags & MNT_XID); -+ if (propagate) -+ new_xid = mnt->mnt_xid; -+ -+ vxdprintk(VXD_CBIT(xid, 7), -+ "vx_propagate_xid(%p[#%lu.%d]): %d,%d", -+ inode, inode->i_ino, inode->i_xid, -+ new_xid, (propagate)?1:0); -+ -+ if (propagate) -+ inode->i_xid = new_xid; -+} -+ -+#include -+ -+EXPORT_SYMBOL_GPL(vx_propagate_xid); -+ -diff --git a/kernel/vserver/legacy.c b/kernel/vserver/legacy.c -new file mode 100644 -index 0000000..cd87ccd ---- /dev/null -+++ b/kernel/vserver/legacy.c -@@ -0,0 +1,111 @@ -+/* -+ * linux/kernel/vserver/legacy.c -+ * -+ * Virtual Server: Legacy Funtions -+ * -+ * Copyright (C) 2001-2003 Jacques Gelinas -+ * Copyright (C) 2003-2005 Herbert Pötzl -+ * -+ * V0.01 broken out from vcontext.c V0.05 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+extern int vx_set_init(struct vx_info *, struct task_struct *); -+ -+static int vx_set_initpid(struct vx_info *vxi, int pid) -+{ -+ struct task_struct *init; -+ -+ init = find_task_by_real_pid(pid); -+ if (!init) -+ return -ESRCH; -+ -+ return vx_set_init(vxi, init); -+} -+ -+int vc_new_s_context(uint32_t ctx, void __user *data) -+{ -+ int ret = -ENOMEM; -+ struct vcmd_new_s_context_v1 vc_data; -+ struct vx_info *new_vxi; -+ -+ if (copy_from_user(&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ /* legacy hack, will be removed soon */ -+ if (ctx == -2) { -+ /* assign flags and initpid */ -+ if (!current->vx_info) -+ return -EINVAL; -+ ret = 0; -+ if (vc_data.flags & VX_INFO_INIT) -+ ret = vx_set_initpid(current->vx_info, current->tgid); -+ if (ret == 0) { -+ /* We keep the same vx_id, but lower the capabilities */ -+ current->vx_info->vx_bcaps &= (~vc_data.remove_cap); -+ ret = vx_current_xid(); -+ current->vx_info->vx_flags |= vc_data.flags; -+ } -+ return ret; -+ } -+ -+ if (!vx_check(0, VX_ADMIN) || !capable(CAP_SYS_ADMIN) -+ /* might make sense in the future, or not ... */ -+ || vx_flags(VX_INFO_LOCK, 0)) -+ return -EPERM; -+ -+ /* ugly hack for Spectator */ -+ if (ctx == 1) { -+ current->xid = 1; -+ return 0; -+ } -+ -+ if (((ctx > MAX_S_CONTEXT) && (ctx != VX_DYNAMIC_ID)) || -+ (ctx == 0)) -+ return -EINVAL; -+ -+ if ((ctx == VX_DYNAMIC_ID) || (ctx < MIN_D_CONTEXT)) -+ new_vxi = lookup_or_create_vx_info(ctx); -+ else -+ new_vxi = lookup_vx_info(ctx); -+ -+ if (!new_vxi) -+ return -EINVAL; -+ -+ ret = -EPERM; -+ if (!vx_info_flags(new_vxi, VXF_STATE_SETUP, 0) && -+ vx_info_flags(new_vxi, VX_INFO_PRIVATE, 0)) -+ goto out_put; -+ -+ new_vxi->vx_flags &= ~(VXF_STATE_SETUP|VXF_STATE_INIT); -+ -+ ret = vx_migrate_task(current, new_vxi); -+ if (ret == 0) { -+ current->vx_info->vx_bcaps &= (~vc_data.remove_cap); -+ new_vxi->vx_flags |= vc_data.flags; -+ if (vc_data.flags & VX_INFO_INIT) -+ vx_set_initpid(new_vxi, current->tgid); -+ if (vc_data.flags & VX_INFO_NAMESPACE) -+ vx_set_namespace(new_vxi, -+ current->namespace, current->fs); -+ if (vc_data.flags & VX_INFO_NPROC) -+ new_vxi->limit.rlim[RLIMIT_NPROC] = -+ current->signal->rlim[RLIMIT_NPROC].rlim_max; -+ ret = new_vxi->vx_id; -+ } -+out_put: -+ put_vx_info(new_vxi); -+ return ret; -+} -+ -diff --git a/kernel/vserver/legacynet.c b/kernel/vserver/legacynet.c -new file mode 100644 -index 0000000..2df0af9 ---- /dev/null -+++ b/kernel/vserver/legacynet.c -@@ -0,0 +1,85 @@ -+ -+/* -+ * linux/kernel/vserver/legacynet.c -+ * -+ * Virtual Server: Legacy Network Funtions -+ * -+ * Copyright (C) 2001-2003 Jacques Gelinas -+ * Copyright (C) 2003-2005 Herbert Pötzl -+ * -+ * V0.01 broken out from legacy.c -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+// #include -+#include -+#include -+ -+#include -+#include -+ -+ -+extern struct nx_info *create_nx_info(void); -+ -+/* set ipv4 root (syscall) */ -+ -+int vc_set_ipv4root(uint32_t nbip, void __user *data) -+{ -+ int i, err = -EPERM; -+ struct vcmd_set_ipv4root_v3 vc_data; -+ struct nx_info *new_nxi, *nxi = current->nx_info; -+ -+ if (nbip < 0 || nbip > NB_IPV4ROOT) -+ return -EINVAL; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ if (!nxi || nxi->ipv4[0] == 0 || capable(CAP_NET_ADMIN)) -+ /* We are allowed to change everything */ -+ err = 0; -+ else if (nxi) { -+ int found = 0; -+ -+ /* We are allowed to select a subset of the currently -+ installed IP numbers. No new one are allowed -+ We can't change the broadcast address though */ -+ for (i=0; inbipv4; j++) { -+ if (nxip == nxi->ipv4[j]) { -+ found++; -+ break; -+ } -+ } -+ } -+ if ((found == nbip) && -+ (vc_data.broadcast == nxi->v4_bcast)) -+ err = 0; -+ } -+ if (err) -+ return err; -+ -+ new_nxi = create_nx_info(); -+ if (IS_ERR(new_nxi)) -+ return -EINVAL; -+ -+ new_nxi->nbipv4 = nbip; -+ for (i=0; iipv4[i] = vc_data.nx_mask_pair[i].ip; -+ new_nxi->mask[i] = vc_data.nx_mask_pair[i].mask; -+ } -+ new_nxi->v4_bcast = vc_data.broadcast; -+ if (nxi) -+ printk("!!! switching nx_info %p->%p\n", nxi, new_nxi); -+ -+ nx_migrate_task(current, new_nxi); -+ put_nx_info(new_nxi); -+ return 0; -+} -+ -+ -diff --git a/kernel/vserver/limit.c b/kernel/vserver/limit.c -new file mode 100644 -index 0000000..5a0ad11 ---- /dev/null -+++ b/kernel/vserver/limit.c -@@ -0,0 +1,177 @@ -+/* -+ * linux/kernel/vserver/limit.c -+ * -+ * Virtual Server: Context Limits -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 broken out from vcontext V0.05 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+const char *vlimit_name[NUM_LIMITS] = { -+ [RLIMIT_CPU] = "CPU", -+ [RLIMIT_RSS] = "RSS", -+ [RLIMIT_NPROC] = "NPROC", -+ [RLIMIT_NOFILE] = "NOFILE", -+ [RLIMIT_MEMLOCK] = "VML", -+ [RLIMIT_AS] = "VM", -+ [RLIMIT_LOCKS] = "LOCKS", -+ [RLIMIT_SIGPENDING] = "SIGP", -+ [RLIMIT_MSGQUEUE] = "MSGQ", -+ -+ [VLIMIT_NSOCK] = "NSOCK", -+ [VLIMIT_OPENFD] = "OPENFD", -+ [VLIMIT_ANON] = "ANON", -+ [VLIMIT_SHMEM] = "SHMEM", -+}; -+ -+EXPORT_SYMBOL_GPL(vlimit_name); -+ -+ -+static int is_valid_rlimit(int id) -+{ -+ int valid = 0; -+ -+ switch (id) { -+ case RLIMIT_RSS: -+ case RLIMIT_NPROC: -+ case RLIMIT_NOFILE: -+ case RLIMIT_MEMLOCK: -+ case RLIMIT_AS: -+ -+ case VLIMIT_NSOCK: -+ case VLIMIT_OPENFD: -+ case VLIMIT_ANON: -+ case VLIMIT_SHMEM: -+ valid = 1; -+ break; -+ } -+ return valid; -+} -+ -+static inline uint64_t vc_get_rlim(struct vx_info *vxi, int id) -+{ -+ unsigned long limit; -+ -+ limit = vxi->limit.rlim[id]; -+ if (limit == RLIM_INFINITY) -+ return CRLIM_INFINITY; -+ return limit; -+} -+ -+int vc_get_rlimit(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_ctx_rlimit_v0 vc_data; -+ -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ if (!is_valid_rlimit(vc_data.id)) -+ return -EINVAL; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ vc_data.maximum = vc_get_rlim(vxi, vc_data.id); -+ vc_data.minimum = CRLIM_UNSET; -+ vc_data.softlimit = CRLIM_UNSET; -+ put_vx_info(vxi); -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+int vc_set_rlimit(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ struct vcmd_ctx_rlimit_v0 vc_data; -+ -+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ if (!is_valid_rlimit(vc_data.id)) -+ return -EINVAL; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ if (vc_data.maximum != CRLIM_KEEP) -+ vxi->limit.rlim[vc_data.id] = vc_data.maximum; -+ put_vx_info(vxi); -+ -+ return 0; -+} -+ -+int vc_get_rlimit_mask(uint32_t id, void __user *data) -+{ -+ static struct vcmd_ctx_rlimit_mask_v0 mask = { -+ /* minimum */ -+ 0 -+ , /* softlimit */ -+ 0 -+ , /* maximum */ -+ (1 << RLIMIT_RSS) | -+ (1 << RLIMIT_NPROC) | -+ (1 << RLIMIT_NOFILE) | -+ (1 << RLIMIT_MEMLOCK) | -+ (1 << RLIMIT_LOCKS) | -+ (1 << RLIMIT_AS) | -+ (1 << VLIMIT_ANON) | -+ 0 -+ }; -+ -+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) -+ return -EPERM; -+ if (copy_to_user(data, &mask, sizeof(mask))) -+ return -EFAULT; -+ return 0; -+} -+ -+ -+void vx_vsi_meminfo(struct sysinfo *val) -+{ -+ struct vx_info *vxi = current->vx_info; -+ unsigned long v; -+ -+ v = vxi->limit.rlim[RLIMIT_RSS]; -+ if (v != RLIM_INFINITY) -+ val->totalram = min(val->totalram, v); -+ v = atomic_read(&vxi->limit.rcur[RLIMIT_RSS]); -+ val->freeram = (v < val->totalram) ? val->totalram - v : 0; -+ val->bufferram = 0; -+ val->totalhigh = 0; -+ val->freehigh = 0; -+ return; -+} -+ -+void vx_vsi_swapinfo(struct sysinfo *val) -+{ -+ struct vx_info *vxi = current->vx_info; -+ unsigned long v, w; -+ -+ v = vxi->limit.rlim[RLIMIT_RSS]; -+ w = vxi->limit.rlim[RLIMIT_AS]; -+ if (w != RLIM_INFINITY) -+ val->totalswap = min(val->totalswap, w - -+ ((v != RLIM_INFINITY) ? v : 0)); -+ w = atomic_read(&vxi->limit.rcur[RLIMIT_AS]); -+ val->freeswap = (w < val->totalswap) ? val->totalswap - w : 0; -+ return; -+} -+ -diff --git a/kernel/vserver/limit_init.h b/kernel/vserver/limit_init.h -new file mode 100644 -index 0000000..74599e9 ---- /dev/null -+++ b/kernel/vserver/limit_init.h -@@ -0,0 +1,34 @@ -+ -+#include -+ -+ -+#include -+ -+ -+static inline void vx_info_init_limit(struct _vx_limit *limit) -+{ -+ int lim; -+ -+ for (lim=0; limrlim[lim] = RLIM_INFINITY; -+ limit->rmax[lim] = 0; -+ atomic_set(&limit->rcur[lim], 0); -+ atomic_set(&limit->lhit[lim], 0); -+ } -+} -+ -+static inline void vx_info_exit_limit(struct _vx_limit *limit) -+{ -+#ifdef CONFIG_VSERVER_DEBUG -+ unsigned long value; -+ unsigned int lim; -+ -+ for (lim=0; limrcur[lim]); -+ vxwprintk(value, -+ "!!! limit: %p[%s,%d] = %ld on exit.", -+ limit, vlimit_name[lim], lim, value); -+ } -+#endif -+} -+ -diff --git a/kernel/vserver/limit_proc.h b/kernel/vserver/limit_proc.h -new file mode 100644 -index 0000000..f318277 ---- /dev/null -+++ b/kernel/vserver/limit_proc.h -@@ -0,0 +1,58 @@ -+#ifndef _VX_LIMIT_PROC_H -+#define _VX_LIMIT_PROC_H -+ -+ -+static inline void vx_limit_fixup(struct _vx_limit *limit) -+{ -+ unsigned long value; -+ unsigned int lim; -+ -+ for (lim=0; limrcur[lim]); -+ if (value > limit->rmax[lim]) -+ limit->rmax[lim] = value; -+ if (limit->rmax[lim] > limit->rlim[lim]) -+ limit->rmax[lim] = limit->rlim[lim]; -+ } -+} -+ -+#define VX_LIMIT_FMT ":\t%10d\t%10ld\t%10ld\t%6d\n" -+ -+#define VX_LIMIT_ARG(r) \ -+ ,atomic_read(&limit->rcur[r]) \ -+ ,limit->rmax[r] \ -+ ,limit->rlim[r] \ -+ ,atomic_read(&limit->lhit[r]) -+ -+static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer) -+{ -+ vx_limit_fixup(limit); -+ return sprintf(buffer, -+ "PROC" VX_LIMIT_FMT -+ "VM" VX_LIMIT_FMT -+ "VML" VX_LIMIT_FMT -+ "RSS" VX_LIMIT_FMT -+ "ANON" VX_LIMIT_FMT -+ "FILES" VX_LIMIT_FMT -+ "OFD" VX_LIMIT_FMT -+ "LOCKS" VX_LIMIT_FMT -+ "SOCK" VX_LIMIT_FMT -+ "MSGQ" VX_LIMIT_FMT -+ "SHM" VX_LIMIT_FMT -+ VX_LIMIT_ARG(RLIMIT_NPROC) -+ VX_LIMIT_ARG(RLIMIT_AS) -+ VX_LIMIT_ARG(RLIMIT_MEMLOCK) -+ VX_LIMIT_ARG(RLIMIT_RSS) -+ VX_LIMIT_ARG(VLIMIT_ANON) -+ VX_LIMIT_ARG(RLIMIT_NOFILE) -+ VX_LIMIT_ARG(VLIMIT_OPENFD) -+ VX_LIMIT_ARG(RLIMIT_LOCKS) -+ VX_LIMIT_ARG(VLIMIT_NSOCK) -+ VX_LIMIT_ARG(RLIMIT_MSGQUEUE) -+ VX_LIMIT_ARG(VLIMIT_SHMEM) -+ ); -+} -+ -+#endif /* _VX_LIMIT_PROC_H */ -+ -+ -diff --git a/kernel/vserver/namespace.c b/kernel/vserver/namespace.c -new file mode 100644 -index 0000000..a40e0e8 ---- /dev/null -+++ b/kernel/vserver/namespace.c -@@ -0,0 +1,123 @@ -+/* -+ * linux/kernel/vserver/namespace.c -+ * -+ * Virtual Server: Context Namespace Support -+ * -+ * Copyright (C) 2003-2005 Herbert Pötzl -+ * -+ * V0.01 broken out from context.c 0.07 -+ * V0.02 added task locking for namespace -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+/* namespace functions */ -+ -+#include -+ -+int vx_set_namespace(struct vx_info *vxi, struct namespace *ns, struct fs_struct *fs) -+{ -+ struct fs_struct *fs_copy; -+ -+ if (vxi->vx_namespace) -+ return -EPERM; -+ if (!ns || !fs) -+ return -EINVAL; -+ -+ fs_copy = copy_fs_struct(fs); -+ if (!fs_copy) -+ return -ENOMEM; -+ -+ get_namespace(ns); -+ vxi->vx_namespace = ns; -+ vxi->vx_fs = fs_copy; -+ return 0; -+} -+ -+int vc_enter_namespace(uint32_t id, void *data) -+{ -+ struct vx_info *vxi; -+ struct fs_struct *old_fs, *fs; -+ struct namespace *old_ns; -+ int ret = 0; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ ret = -EINVAL; -+ if (!vxi->vx_namespace) -+ goto out_put; -+ -+ ret = -ENOMEM; -+ fs = copy_fs_struct(vxi->vx_fs); -+ if (!fs) -+ goto out_put; -+ -+ ret = 0; -+ task_lock(current); -+ old_ns = current->namespace; -+ old_fs = current->fs; -+ get_namespace(vxi->vx_namespace); -+ current->namespace = vxi->vx_namespace; -+ current->fs = fs; -+ task_unlock(current); -+ -+ put_namespace(old_ns); -+ put_fs_struct(old_fs); -+out_put: -+ put_vx_info(vxi); -+ return ret; -+} -+ -+int vc_cleanup_namespace(uint32_t id, void *data) -+{ -+ // down_write(¤t->namespace->sem); -+ spin_lock(&vfsmount_lock); -+ umount_unused(current->namespace->root, current->fs); -+ spin_unlock(&vfsmount_lock); -+ // up_write(¤t->namespace->sem); -+ return 0; -+} -+ -+int vc_set_namespace(uint32_t id, void __user *data) -+{ -+ struct fs_struct *fs; -+ struct namespace *ns; -+ struct vx_info *vxi; -+ int ret; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ task_lock(current); -+ fs = current->fs; -+ atomic_inc(&fs->count); -+ ns = current->namespace; -+ get_namespace(current->namespace); -+ task_unlock(current); -+ -+ ret = vx_set_namespace(vxi, ns, fs); -+ -+ put_namespace(ns); -+ put_fs_struct(fs); -+ put_vx_info(vxi); -+ return ret; -+} -+ -diff --git a/kernel/vserver/network.c b/kernel/vserver/network.c -new file mode 100644 -index 0000000..b5f3578 ---- /dev/null -+++ b/kernel/vserver/network.c -@@ -0,0 +1,784 @@ -+/* -+ * linux/kernel/vserver/network.c -+ * -+ * Virtual Server: Network Support -+ * -+ * Copyright (C) 2003-2005 Herbert Pötzl -+ * -+ * V0.01 broken out from vcontext V0.05 -+ * V0.02 cleaned up implementation -+ * V0.03 added equiv nx commands -+ * V0.04 switch to RCU based hash -+ * V0.05 and back to locking again -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+ -+/* __alloc_nx_info() -+ -+ * allocate an initialized nx_info struct -+ * doesn't make it visible (hash) */ -+ -+static struct nx_info *__alloc_nx_info(nid_t nid) -+{ -+ struct nx_info *new = NULL; -+ -+ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid); -+ -+ /* would this benefit from a slab cache? */ -+ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL); -+ if (!new) -+ return 0; -+ -+ memset (new, 0, sizeof(struct nx_info)); -+ new->nx_id = nid; -+ INIT_HLIST_NODE(&new->nx_hlist); -+ atomic_set(&new->nx_usecnt, 0); -+ atomic_set(&new->nx_tasks, 0); -+ new->nx_state = 0; -+ -+ new->nx_flags = NXF_INIT_SET; -+ -+ /* rest of init goes here */ -+ -+ vxdprintk(VXD_CBIT(nid, 0), -+ "alloc_nx_info(%d) = %p", nid, new); -+ return new; -+} -+ -+/* __dealloc_nx_info() -+ -+ * final disposal of nx_info */ -+ -+static void __dealloc_nx_info(struct nx_info *nxi) -+{ -+ vxdprintk(VXD_CBIT(nid, 0), -+ "dealloc_nx_info(%p)", nxi); -+ -+ nxi->nx_hlist.next = LIST_POISON1; -+ nxi->nx_id = -1; -+ -+ BUG_ON(atomic_read(&nxi->nx_usecnt)); -+ BUG_ON(atomic_read(&nxi->nx_tasks)); -+ -+ nxi->nx_state |= NXS_RELEASED; -+ kfree(nxi); -+} -+ -+static void __shutdown_nx_info(struct nx_info *nxi) -+{ -+ nxi->nx_state |= NXS_SHUTDOWN; -+ vs_net_change(nxi, VSC_NETDOWN); -+} -+ -+/* exported stuff */ -+ -+void free_nx_info(struct nx_info *nxi) -+{ -+ /* context shutdown is mandatory */ -+ BUG_ON(nxi->nx_state != NXS_SHUTDOWN); -+ -+ /* context must not be hashed */ -+ BUG_ON(nxi->nx_state & NXS_HASHED); -+ -+ BUG_ON(atomic_read(&nxi->nx_usecnt)); -+ BUG_ON(atomic_read(&nxi->nx_tasks)); -+ -+ __dealloc_nx_info(nxi); -+} -+ -+ -+/* hash table for nx_info hash */ -+ -+#define NX_HASH_SIZE 13 -+ -+struct hlist_head nx_info_hash[NX_HASH_SIZE]; -+ -+static spinlock_t nx_info_hash_lock = SPIN_LOCK_UNLOCKED; -+ -+ -+static inline unsigned int __hashval(nid_t nid) -+{ -+ return (nid % NX_HASH_SIZE); -+} -+ -+ -+ -+/* __hash_nx_info() -+ -+ * add the nxi to the global hash table -+ * requires the hash_lock to be held */ -+ -+static inline void __hash_nx_info(struct nx_info *nxi) -+{ -+ struct hlist_head *head; -+ -+ vxd_assert_lock(&nx_info_hash_lock); -+ vxdprintk(VXD_CBIT(nid, 4), -+ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id); -+ -+ /* context must not be hashed */ -+ BUG_ON(nx_info_state(nxi, NXS_HASHED)); -+ -+ nxi->nx_state |= NXS_HASHED; -+ head = &nx_info_hash[__hashval(nxi->nx_id)]; -+ hlist_add_head(&nxi->nx_hlist, head); -+} -+ -+/* __unhash_nx_info() -+ -+ * remove the nxi from the global hash table -+ * requires the hash_lock to be held */ -+ -+static inline void __unhash_nx_info(struct nx_info *nxi) -+{ -+ vxd_assert_lock(&nx_info_hash_lock); -+ vxdprintk(VXD_CBIT(nid, 4), -+ "__unhash_nx_info: %p[#%d]", nxi, nxi->nx_id); -+ -+ /* context must be hashed */ -+ BUG_ON(!nx_info_state(nxi, NXS_HASHED)); -+ -+ nxi->nx_state &= ~NXS_HASHED; -+ hlist_del(&nxi->nx_hlist); -+} -+ -+ -+/* __lookup_nx_info() -+ -+ * requires the hash_lock to be held -+ * doesn't increment the nx_refcnt */ -+ -+static inline struct nx_info *__lookup_nx_info(nid_t nid) -+{ -+ struct hlist_head *head = &nx_info_hash[__hashval(nid)]; -+ struct hlist_node *pos; -+ struct nx_info *nxi; -+ -+ vxd_assert_lock(&nx_info_hash_lock); -+ hlist_for_each(pos, head) { -+ nxi = hlist_entry(pos, struct nx_info, nx_hlist); -+ -+ if (nxi->nx_id == nid) -+ goto found; -+ } -+ nxi = NULL; -+found: -+ vxdprintk(VXD_CBIT(nid, 0), -+ "__lookup_nx_info(#%u): %p[#%u]", -+ nid, nxi, nxi?nxi->nx_id:0); -+ return nxi; -+} -+ -+ -+/* __nx_dynamic_id() -+ -+ * find unused dynamic nid -+ * requires the hash_lock to be held */ -+ -+static inline nid_t __nx_dynamic_id(void) -+{ -+ static nid_t seq = MAX_N_CONTEXT; -+ nid_t barrier = seq; -+ -+ vxd_assert_lock(&nx_info_hash_lock); -+ do { -+ if (++seq > MAX_N_CONTEXT) -+ seq = MIN_D_CONTEXT; -+ if (!__lookup_nx_info(seq)) { -+ vxdprintk(VXD_CBIT(nid, 4), -+ "__nx_dynamic_id: [#%d]", seq); -+ return seq; -+ } -+ } while (barrier != seq); -+ return 0; -+} -+ -+/* __create_nx_info() -+ -+ * create the requested context -+ * get() and hash it */ -+ -+static struct nx_info * __create_nx_info(int id) -+{ -+ struct nx_info *new, *nxi = NULL; -+ -+ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id); -+ -+ if (!(new = __alloc_nx_info(id))) -+ return ERR_PTR(-ENOMEM); -+ -+ /* required to make dynamic xids unique */ -+ spin_lock(&nx_info_hash_lock); -+ -+ /* dynamic context requested */ -+ if (id == NX_DYNAMIC_ID) { -+ id = __nx_dynamic_id(); -+ if (!id) { -+ printk(KERN_ERR "no dynamic context available.\n"); -+ nxi = ERR_PTR(-EAGAIN); -+ goto out_unlock; -+ } -+ new->nx_id = id; -+ } -+ /* static context requested */ -+ else if ((nxi = __lookup_nx_info(id))) { -+ vxdprintk(VXD_CBIT(nid, 0), -+ "create_nx_info(%d) = %p (already there)", id, nxi); -+ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0)) -+ nxi = ERR_PTR(-EBUSY); -+ else -+ nxi = ERR_PTR(-EEXIST); -+ goto out_unlock; -+ } -+ /* dynamic nid creation blocker */ -+ else if (id >= MIN_D_CONTEXT) { -+ vxdprintk(VXD_CBIT(nid, 0), -+ "create_nx_info(%d) (dynamic rejected)", id); -+ nxi = ERR_PTR(-EINVAL); -+ goto out_unlock; -+ } -+ -+ /* new context */ -+ vxdprintk(VXD_CBIT(nid, 0), -+ "create_nx_info(%d) = %p (new)", id, new); -+ __hash_nx_info(get_nx_info(new)); -+ nxi = new, new = NULL; -+ -+out_unlock: -+ spin_unlock(&nx_info_hash_lock); -+ if (new) -+ __dealloc_nx_info(new); -+ return nxi; -+} -+ -+ -+ -+/* exported stuff */ -+ -+ -+void unhash_nx_info(struct nx_info *nxi) -+{ -+ __shutdown_nx_info(nxi); -+ spin_lock(&nx_info_hash_lock); -+ __unhash_nx_info(nxi); -+ spin_unlock(&nx_info_hash_lock); -+} -+ -+#ifdef CONFIG_VSERVER_LEGACYNET -+ -+struct nx_info *create_nx_info(void) -+{ -+ return __create_nx_info(NX_DYNAMIC_ID); -+} -+ -+#endif -+ -+/* lookup_nx_info() -+ -+ * search for a nx_info and get() it -+ * negative id means current */ -+ -+struct nx_info *lookup_nx_info(int id) -+{ -+ struct nx_info *nxi = NULL; -+ -+ if (id < 0) { -+ nxi = get_nx_info(current->nx_info); -+ } else if (id > 1) { -+ spin_lock(&nx_info_hash_lock); -+ nxi = get_nx_info(__lookup_nx_info(id)); -+ spin_unlock(&nx_info_hash_lock); -+ } -+ return nxi; -+} -+ -+/* nid_is_hashed() -+ -+ * verify that nid is still hashed */ -+ -+int nid_is_hashed(nid_t nid) -+{ -+ int hashed; -+ -+ spin_lock(&nx_info_hash_lock); -+ hashed = (__lookup_nx_info(nid) != NULL); -+ spin_unlock(&nx_info_hash_lock); -+ return hashed; -+} -+ -+ -+#ifdef CONFIG_PROC_FS -+ -+int get_nid_list(int index, unsigned int *nids, int size) -+{ -+ int hindex, nr_nids = 0; -+ -+ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) { -+ struct hlist_head *head = &nx_info_hash[hindex]; -+ struct hlist_node *pos; -+ -+ spin_lock(&nx_info_hash_lock); -+ hlist_for_each(pos, head) { -+ struct nx_info *nxi; -+ -+ if (--index > 0) -+ continue; -+ -+ nxi = hlist_entry(pos, struct nx_info, nx_hlist); -+ nids[nr_nids] = nxi->nx_id; -+ if (++nr_nids >= size) { -+ spin_unlock(&nx_info_hash_lock); -+ goto out; -+ } -+ } -+ /* keep the lock time short */ -+ spin_unlock(&nx_info_hash_lock); -+ } -+out: -+ return nr_nids; -+} -+#endif -+ -+ -+/* -+ * migrate task to new network -+ * gets nxi, puts old_nxi on change -+ */ -+ -+int nx_migrate_task(struct task_struct *p, struct nx_info *nxi) -+{ -+ struct nx_info *old_nxi; -+ int ret = 0; -+ -+ if (!p || !nxi) -+ BUG(); -+ -+ vxdprintk(VXD_CBIT(nid, 5), -+ "nx_migrate_task(%p,%p[#%d.%d.%d])", -+ p, nxi, nxi->nx_id, -+ atomic_read(&nxi->nx_usecnt), -+ atomic_read(&nxi->nx_tasks)); -+ -+ /* maybe disallow this completely? */ -+ old_nxi = task_get_nx_info(p); -+ if (old_nxi == nxi) -+ goto out; -+ -+ task_lock(p); -+ if (old_nxi) -+ clr_nx_info(&p->nx_info); -+ claim_nx_info(nxi, p); -+ set_nx_info(&p->nx_info, nxi); -+ p->nid = nxi->nx_id; -+ task_unlock(p); -+ -+ vxdprintk(VXD_CBIT(nid, 5), -+ "moved task %p into nxi:%p[#%d]", -+ p, nxi, nxi->nx_id); -+ -+ if (old_nxi) -+ release_nx_info(old_nxi, p); -+out: -+ put_nx_info(old_nxi); -+ return ret; -+} -+ -+ -+#ifdef CONFIG_INET -+ -+#include -+#include -+ -+int ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi) -+{ -+ if (!nxi) -+ return 1; -+ if (!ifa) -+ return 0; -+ return addr_in_nx_info(nxi, ifa->ifa_address); -+} -+ -+int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi) -+{ -+ struct in_device *in_dev; -+ struct in_ifaddr **ifap; -+ struct in_ifaddr *ifa; -+ int ret = 0; -+ -+ if (!nxi) -+ return 1; -+ -+ in_dev = in_dev_get(dev); -+ if (!in_dev) -+ goto out; -+ -+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; -+ ifap = &ifa->ifa_next) { -+ if (addr_in_nx_info(nxi, ifa->ifa_address)) { -+ ret = 1; -+ break; -+ } -+ } -+ in_dev_put(in_dev); -+out: -+ return ret; -+} -+ -+/* -+ * check if address is covered by socket -+ * -+ * sk: the socket to check against -+ * addr: the address in question (must be != 0) -+ */ -+static inline int __addr_in_socket(struct sock *sk, uint32_t addr) -+{ -+ struct nx_info *nxi = sk->sk_nx_info; -+ uint32_t saddr = inet_rcv_saddr(sk); -+ -+ vxdprintk(VXD_CBIT(net, 5), -+ "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx", -+ sk, VXD_QUAD(addr), nxi, VXD_QUAD(saddr), sk->sk_socket, -+ (sk->sk_socket?sk->sk_socket->flags:0)); -+ -+ if (saddr) { -+ /* direct address match */ -+ return (saddr == addr); -+ } else if (nxi) { -+ /* match against nx_info */ -+ return addr_in_nx_info(nxi, addr); -+ } else { -+ /* unrestricted any socket */ -+ return 1; -+ } -+} -+ -+ -+int nx_addr_conflict(struct nx_info *nxi, uint32_t addr, struct sock *sk) -+{ -+ vxdprintk(VXD_CBIT(net, 2), -+ "nx_addr_conflict(%p,%p) %d.%d,%d.%d", -+ nxi, sk, VXD_QUAD(addr)); -+ -+ if (addr) { -+ /* check real address */ -+ return __addr_in_socket(sk, addr); -+ } else if (nxi) { -+ /* check against nx_info */ -+ int i, n = nxi->nbipv4; -+ -+ for (i=0; iipv4[i])) -+ return 1; -+ return 0; -+ } else { -+ /* check against any */ -+ return 1; -+ } -+} -+ -+#endif /* CONFIG_INET */ -+ -+void nx_set_persistent(struct nx_info *nxi) -+{ -+ if (nx_info_flags(nxi, NXF_PERSISTENT, 0)) { -+ get_nx_info(nxi); -+ claim_nx_info(nxi, current); -+ } else { -+ release_nx_info(nxi, current); -+ put_nx_info(nxi); -+ } -+} -+ -+/* vserver syscall commands below here */ -+ -+/* taks nid and nx_info functions */ -+ -+#include -+ -+ -+int vc_task_nid(uint32_t id, void __user *data) -+{ -+ nid_t nid; -+ -+ if (id) { -+ struct task_struct *tsk; -+ -+ if (!vx_check(0, VX_ADMIN|VX_WATCH)) -+ return -EPERM; -+ -+ read_lock(&tasklist_lock); -+ tsk = find_task_by_real_pid(id); -+ nid = (tsk) ? tsk->nid : -ESRCH; -+ read_unlock(&tasklist_lock); -+ } -+ else -+ nid = nx_current_nid(); -+ return nid; -+} -+ -+ -+int vc_nx_info(uint32_t id, void __user *data) -+{ -+ struct nx_info *nxi; -+ struct vcmd_nx_info_v0 vc_data; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) -+ return -EPERM; -+ -+ nxi = lookup_nx_info(id); -+ if (!nxi) -+ return -ESRCH; -+ -+ vc_data.nid = nxi->nx_id; -+ put_nx_info(nxi); -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+ -+/* network functions */ -+ -+int vc_net_create(uint32_t nid, void __user *data) -+{ -+ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET }; -+ struct nx_info *new_nxi; -+ int ret; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ if ((nid > MAX_S_CONTEXT) && (nid != VX_DYNAMIC_ID)) -+ return -EINVAL; -+ if (nid < 2) -+ return -EINVAL; -+ -+ new_nxi = __create_nx_info(nid); -+ if (IS_ERR(new_nxi)) -+ return PTR_ERR(new_nxi); -+ -+ /* initial flags */ -+ new_nxi->nx_flags = vc_data.flagword; -+ -+ /* get a reference for persistent contexts */ -+ if ((vc_data.flagword & NXF_PERSISTENT)) -+ nx_set_persistent(new_nxi); -+ -+ vs_net_change(new_nxi, VSC_NETUP); -+ ret = new_nxi->nx_id; -+ nx_migrate_task(current, new_nxi); -+ /* if this fails, we might end up with a hashed nx_info */ -+ put_nx_info(new_nxi); -+ return ret; -+} -+ -+ -+int vc_net_migrate(uint32_t id, void __user *data) -+{ -+ struct nx_info *nxi; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ -+ nxi = lookup_nx_info(id); -+ if (!nxi) -+ return -ESRCH; -+ nx_migrate_task(current, nxi); -+ put_nx_info(nxi); -+ return 0; -+} -+ -+int vc_net_add(uint32_t nid, void __user *data) -+{ -+ struct vcmd_net_addr_v0 vc_data; -+ struct nx_info *nxi; -+ int index, pos, ret = 0; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ switch (vc_data.type) { -+ case NXA_TYPE_IPV4: -+ if ((vc_data.count < 1) || (vc_data.count > 4)) -+ return -EINVAL; -+ break; -+ -+ default: -+ break; -+ } -+ -+ nxi = lookup_nx_info(nid); -+ if (!nxi) -+ return -ESRCH; -+ -+ switch (vc_data.type) { -+ case NXA_TYPE_IPV4: -+ index = 0; -+ while ((index < vc_data.count) && -+ ((pos = nxi->nbipv4) < NB_IPV4ROOT)) { -+ nxi->ipv4[pos] = vc_data.ip[index]; -+ nxi->mask[pos] = vc_data.mask[index]; -+ index++; -+ nxi->nbipv4++; -+ } -+ ret = index; -+ break; -+ -+ case NXA_TYPE_IPV4|NXA_MOD_BCAST: -+ nxi->v4_bcast = vc_data.ip[0]; -+ ret = 1; -+ break; -+ -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ put_nx_info(nxi); -+ return ret; -+} -+ -+int vc_net_remove(uint32_t nid, void __user *data) -+{ -+ struct vcmd_net_addr_v0 vc_data; -+ struct nx_info *nxi; -+ int ret = 0; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ nxi = lookup_nx_info(nid); -+ if (!nxi) -+ return -ESRCH; -+ -+ switch ((unsigned)vc_data.type) { -+ case NXA_TYPE_ANY: -+ nxi->nbipv4 = 0; -+ break; -+ -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ put_nx_info(nxi); -+ return ret; -+} -+ -+int vc_get_nflags(uint32_t id, void __user *data) -+{ -+ struct nx_info *nxi; -+ struct vcmd_net_flags_v0 vc_data; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ -+ nxi = lookup_nx_info(id); -+ if (!nxi) -+ return -ESRCH; -+ -+ vc_data.flagword = nxi->nx_flags; -+ -+ /* special STATE flag handling */ -+ vc_data.mask = vx_mask_flags(~0UL, nxi->nx_flags, NXF_ONE_TIME); -+ -+ put_nx_info(nxi); -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+int vc_set_nflags(uint32_t id, void __user *data) -+{ -+ struct nx_info *nxi; -+ struct vcmd_net_flags_v0 vc_data; -+ uint64_t mask, trigger; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ nxi = lookup_nx_info(id); -+ if (!nxi) -+ return -ESRCH; -+ -+ /* special STATE flag handling */ -+ mask = vx_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME); -+ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword); -+ -+ nxi->nx_flags = vx_mask_flags(nxi->nx_flags, -+ vc_data.flagword, mask); -+ if (trigger & NXF_PERSISTENT) -+ nx_set_persistent(nxi); -+ -+ put_nx_info(nxi); -+ return 0; -+} -+ -+int vc_get_ncaps(uint32_t id, void __user *data) -+{ -+ struct nx_info *nxi; -+ struct vcmd_net_caps_v0 vc_data; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ -+ nxi = lookup_nx_info(id); -+ if (!nxi) -+ return -ESRCH; -+ -+ vc_data.ncaps = nxi->nx_ncaps; -+ vc_data.cmask = ~0UL; -+ put_nx_info(nxi); -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; -+ return 0; -+} -+ -+int vc_set_ncaps(uint32_t id, void __user *data) -+{ -+ struct nx_info *nxi; -+ struct vcmd_net_caps_v0 vc_data; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ nxi = lookup_nx_info(id); -+ if (!nxi) -+ return -ESRCH; -+ -+ nxi->nx_ncaps = vx_mask_flags(nxi->nx_ncaps, -+ vc_data.ncaps, vc_data.cmask); -+ put_nx_info(nxi); -+ return 0; -+} -+ -+ -+#include -+ -+EXPORT_SYMBOL_GPL(free_nx_info); -+EXPORT_SYMBOL_GPL(unhash_nx_info); -+ -diff --git a/kernel/vserver/proc.c b/kernel/vserver/proc.c -new file mode 100644 -index 0000000..8c196d0 ---- /dev/null -+++ b/kernel/vserver/proc.c -@@ -0,0 +1,864 @@ -+/* -+ * linux/kernel/vserver/proc.c -+ * -+ * Virtual Context Support -+ * -+ * Copyright (C) 2003-2005 Herbert Pötzl -+ * -+ * V0.01 basic structure -+ * V0.02 adaptation vs1.3.0 -+ * V0.03 proc permissions -+ * V0.04 locking/generic -+ * V0.05 next generation procfs -+ * V0.06 inode validation -+ * V0.07 generic rewrite vid -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include "cvirt_proc.h" -+#include "limit_proc.h" -+#include "sched_proc.h" -+#include "vci_config.h" -+ -+static struct proc_dir_entry *proc_virtual; -+ -+static struct proc_dir_entry *proc_vnet; -+ -+ -+enum vid_directory_inos { -+ PROC_XID_INO = 32, -+ PROC_XID_INFO, -+ PROC_XID_STATUS, -+ PROC_XID_LIMIT, -+ PROC_XID_SCHED, -+ PROC_XID_CVIRT, -+ PROC_XID_CACCT, -+ -+ PROC_NID_INO = 64, -+ PROC_NID_INFO, -+ PROC_NID_STATUS, -+}; -+ -+#define PROC_VID_MASK 0x60 -+ -+ -+/* first the actual feeds */ -+ -+ -+static int proc_virtual_info(int vid, char *buffer) -+{ -+ return sprintf(buffer, -+ "VCIVersion:\t%04x:%04x\n" -+ "VCISyscall:\t%d\n" -+ "VCIKernel:\t%08x\n" -+ ,VCI_VERSION >> 16 -+ ,VCI_VERSION & 0xFFFF -+ ,__NR_vserver -+ ,vci_kernel_config() -+ ); -+} -+ -+ -+int proc_xid_info (int vid, char *buffer) -+{ -+ struct vx_info *vxi; -+ int length; -+ -+ vxi = lookup_vx_info(vid); -+ if (!vxi) -+ return 0; -+ length = sprintf(buffer, -+ "ID:\t%d\n" -+ "Info:\t%p\n" -+ "Init:\t%d\n" -+ ,vxi->vx_id -+ ,vxi -+ ,vxi->vx_initpid -+ ); -+ put_vx_info(vxi); -+ return length; -+} -+ -+int proc_xid_status (int vid, char *buffer) -+{ -+ struct vx_info *vxi; -+ int length; -+ -+ vxi = lookup_vx_info(vid); -+ if (!vxi) -+ return 0; -+ length = sprintf(buffer, -+ "UseCnt:\t%d\n" -+ "Tasks:\t%d\n" -+ "Flags:\t%016llx\n" -+ "BCaps:\t%016llx\n" -+ "CCaps:\t%016llx\n" -+ "Ticks:\t%d\n" -+ ,atomic_read(&vxi->vx_usecnt) -+ ,atomic_read(&vxi->vx_tasks) -+ ,(unsigned long long)vxi->vx_flags -+ ,(unsigned long long)vxi->vx_bcaps -+ ,(unsigned long long)vxi->vx_ccaps -+ ,atomic_read(&vxi->limit.ticks) -+ ); -+ put_vx_info(vxi); -+ return length; -+} -+ -+int proc_xid_limit (int vid, char *buffer) -+{ -+ struct vx_info *vxi; -+ int length; -+ -+ vxi = lookup_vx_info(vid); -+ if (!vxi) -+ return 0; -+ length = vx_info_proc_limit(&vxi->limit, buffer); -+ put_vx_info(vxi); -+ return length; -+} -+ -+int proc_xid_sched (int vid, char *buffer) -+{ -+ struct vx_info *vxi; -+ int length; -+ -+ vxi = lookup_vx_info(vid); -+ if (!vxi) -+ return 0; -+ length = vx_info_proc_sched(&vxi->sched, buffer); -+ put_vx_info(vxi); -+ return length; -+} -+ -+int proc_xid_cvirt (int vid, char *buffer) -+{ -+ struct vx_info *vxi; -+ int length; -+ -+ vxi = lookup_vx_info(vid); -+ if (!vxi) -+ return 0; -+ vx_update_load(vxi); -+ length = vx_info_proc_cvirt(&vxi->cvirt, buffer); -+ put_vx_info(vxi); -+ return length; -+} -+ -+int proc_xid_cacct (int vid, char *buffer) -+{ -+ struct vx_info *vxi; -+ int length; -+ -+ vxi = lookup_vx_info(vid); -+ if (!vxi) -+ return 0; -+ length = vx_info_proc_cacct(&vxi->cacct, buffer); -+ put_vx_info(vxi); -+ return length; -+} -+ -+ -+static int proc_vnet_info(int vid, char *buffer) -+{ -+ return sprintf(buffer, -+ "VCIVersion:\t%04x:%04x\n" -+ "VCISyscall:\t%d\n" -+ ,VCI_VERSION >> 16 -+ ,VCI_VERSION & 0xFFFF -+ ,__NR_vserver -+ ); -+} -+ -+#define atoquad(a) \ -+ (((a)>>0) & 0xff), (((a)>>8) & 0xff), \ -+ (((a)>>16) & 0xff), (((a)>>24) & 0xff) -+ -+int proc_nid_info (int vid, char *buffer) -+{ -+ struct nx_info *nxi; -+ int length, i; -+ -+ nxi = lookup_nx_info(vid); -+ if (!nxi) -+ return 0; -+ length = sprintf(buffer, -+ "ID:\t%d\n" -+ "Info:\t%p\n" -+ ,nxi->nx_id -+ ,nxi -+ ); -+ for (i=0; inbipv4; i++) { -+ length += sprintf(buffer + length, -+ "%d:\t%d.%d.%d.%d/%d.%d.%d.%d\n", i, -+ atoquad(nxi->ipv4[i]), -+ atoquad(nxi->mask[i])); -+ } -+ put_nx_info(nxi); -+ return length; -+} -+ -+int proc_nid_status (int vid, char *buffer) -+{ -+ struct nx_info *nxi; -+ int length; -+ -+ nxi = lookup_nx_info(vid); -+ if (!nxi) -+ return 0; -+ length = sprintf(buffer, -+ "UseCnt:\t%d\n" -+ "Tasks:\t%d\n" -+ ,atomic_read(&nxi->nx_usecnt) -+ ,atomic_read(&nxi->nx_tasks) -+ ); -+ put_nx_info(nxi); -+ return length; -+} -+ -+/* here the inode helpers */ -+ -+ -+#define fake_ino(id,nr) (((nr) & 0xFFFF) | \ -+ (((id) & 0xFFFF) << 16)) -+ -+#define inode_vid(i) (((i)->i_ino >> 16) & 0xFFFF) -+#define inode_type(i) ((i)->i_ino & 0xFFFF) -+ -+#define MAX_MULBY10 ((~0U-9)/10) -+ -+ -+static struct inode *proc_vid_make_inode(struct super_block * sb, -+ int vid, int ino) -+{ -+ struct inode *inode = new_inode(sb); -+ -+ if (!inode) -+ goto out; -+ -+ inode->i_mtime = inode->i_atime = -+ inode->i_ctime = CURRENT_TIME; -+ inode->i_ino = fake_ino(vid, ino); -+ -+ inode->i_uid = 0; -+ inode->i_gid = 0; -+out: -+ return inode; -+} -+ -+static int proc_vid_revalidate(struct dentry * dentry, struct nameidata *nd) -+{ -+ struct inode * inode = dentry->d_inode; -+ int vid, hashed=0; -+ -+ vid = inode_vid(inode); -+ switch (inode_type(inode) & PROC_VID_MASK) { -+ case PROC_XID_INO: -+ hashed = xid_is_hashed(vid); -+ break; -+ case PROC_NID_INO: -+ hashed = nid_is_hashed(vid); -+ break; -+ } -+ if (hashed) -+ return 1; -+ d_drop(dentry); -+ return 0; -+} -+ -+ -+#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024) -+ -+static ssize_t proc_vid_info_read(struct file * file, char * buf, -+ size_t count, loff_t *ppos) -+{ -+ struct inode * inode = file->f_dentry->d_inode; -+ unsigned long page; -+ ssize_t length; -+ int vid; -+ -+ if (count > PROC_BLOCK_SIZE) -+ count = PROC_BLOCK_SIZE; -+ if (!(page = __get_free_page(GFP_KERNEL))) -+ return -ENOMEM; -+ -+ vid = inode_vid(inode); -+ length = PROC_I(inode)->op.proc_vid_read(vid, (char*)page); -+ -+ if (length >= 0) -+ length = simple_read_from_buffer(buf, count, ppos, -+ (char *)page, length); -+ free_page(page); -+ return length; -+} -+ -+ -+ -+ -+ -+/* here comes the lower level (vid) */ -+ -+static struct file_operations proc_vid_info_file_operations = { -+ read: proc_vid_info_read, -+}; -+ -+static struct dentry_operations proc_vid_dentry_operations = { -+ d_revalidate: proc_vid_revalidate, -+}; -+ -+ -+struct vid_entry { -+ int type; -+ int len; -+ char *name; -+ mode_t mode; -+}; -+ -+#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)} -+ -+static struct vid_entry vx_base_stuff[] = { -+ E(PROC_XID_INFO, "info", S_IFREG|S_IRUGO), -+ E(PROC_XID_STATUS, "status", S_IFREG|S_IRUGO), -+ E(PROC_XID_LIMIT, "limit", S_IFREG|S_IRUGO), -+ E(PROC_XID_SCHED, "sched", S_IFREG|S_IRUGO), -+ E(PROC_XID_CVIRT, "cvirt", S_IFREG|S_IRUGO), -+ E(PROC_XID_CACCT, "cacct", S_IFREG|S_IRUGO), -+ {0,0,NULL,0} -+}; -+ -+static struct vid_entry vn_base_stuff[] = { -+ E(PROC_NID_INFO, "info", S_IFREG|S_IRUGO), -+ E(PROC_NID_STATUS, "status", S_IFREG|S_IRUGO), -+ {0,0,NULL,0} -+}; -+ -+ -+ -+static struct dentry *proc_vid_lookup(struct inode *dir, -+ struct dentry *dentry, struct nameidata *nd) -+{ -+ struct inode *inode; -+ struct vid_entry *p; -+ int error; -+ -+ error = -ENOENT; -+ inode = NULL; -+ -+ switch (inode_type(dir)) { -+ case PROC_XID_INO: -+ p = vx_base_stuff; -+ break; -+ case PROC_NID_INO: -+ p = vn_base_stuff; -+ break; -+ default: -+ goto out; -+ } -+ -+ for (; p->name; p++) { -+ if (p->len != dentry->d_name.len) -+ continue; -+ if (!memcmp(dentry->d_name.name, p->name, p->len)) -+ break; -+ } -+ if (!p->name) -+ goto out; -+ -+ error = -EINVAL; -+ inode = proc_vid_make_inode(dir->i_sb, inode_vid(dir), p->type); -+ if (!inode) -+ goto out; -+ -+ switch(p->type) { -+ case PROC_XID_INFO: -+ PROC_I(inode)->op.proc_vid_read = proc_xid_info; -+ break; -+ case PROC_XID_STATUS: -+ PROC_I(inode)->op.proc_vid_read = proc_xid_status; -+ break; -+ case PROC_XID_LIMIT: -+ PROC_I(inode)->op.proc_vid_read = proc_xid_limit; -+ break; -+ case PROC_XID_SCHED: -+ PROC_I(inode)->op.proc_vid_read = proc_xid_sched; -+ break; -+ case PROC_XID_CVIRT: -+ PROC_I(inode)->op.proc_vid_read = proc_xid_cvirt; -+ break; -+ case PROC_XID_CACCT: -+ PROC_I(inode)->op.proc_vid_read = proc_xid_cacct; -+ break; -+ -+ case PROC_NID_INFO: -+ PROC_I(inode)->op.proc_vid_read = proc_nid_info; -+ break; -+ case PROC_NID_STATUS: -+ PROC_I(inode)->op.proc_vid_read = proc_nid_status; -+ break; -+ -+ default: -+ printk("procfs: impossible type (%d)",p->type); -+ iput(inode); -+ return ERR_PTR(-EINVAL); -+ } -+ inode->i_mode = p->mode; -+ inode->i_fop = &proc_vid_info_file_operations; -+ inode->i_nlink = 1; -+ inode->i_flags|=S_IMMUTABLE; -+ -+ dentry->d_op = &proc_vid_dentry_operations; -+ d_add(dentry, inode); -+ error = 0; -+out: -+ return ERR_PTR(error); -+} -+ -+ -+static int proc_vid_readdir(struct file * filp, -+ void * dirent, filldir_t filldir) -+{ -+ int i, size; -+ struct inode *inode = filp->f_dentry->d_inode; -+ struct vid_entry *p; -+ -+ i = filp->f_pos; -+ switch (i) { -+ case 0: -+ if (filldir(dirent, ".", 1, i, -+ inode->i_ino, DT_DIR) < 0) -+ return 0; -+ i++; -+ filp->f_pos++; -+ /* fall through */ -+ case 1: -+ if (filldir(dirent, "..", 2, i, -+ PROC_ROOT_INO, DT_DIR) < 0) -+ return 0; -+ i++; -+ filp->f_pos++; -+ /* fall through */ -+ default: -+ i -= 2; -+ switch (inode_type(inode)) { -+ case PROC_XID_INO: -+ size = sizeof(vx_base_stuff); -+ p = vx_base_stuff + i; -+ break; -+ case PROC_NID_INO: -+ size = sizeof(vn_base_stuff); -+ p = vn_base_stuff + i; -+ break; -+ default: -+ return 1; -+ } -+ if (i >= size/sizeof(struct vid_entry)) -+ return 1; -+ while (p->name) { -+ if (filldir(dirent, p->name, p->len, -+ filp->f_pos, fake_ino(inode_vid(inode), -+ p->type), p->mode >> 12) < 0) -+ return 0; -+ filp->f_pos++; -+ p++; -+ } -+ } -+ return 1; -+} -+ -+ -+ -+ -+/* now the upper level (virtual) */ -+ -+static struct file_operations proc_vid_file_operations = { -+ read: generic_read_dir, -+ readdir: proc_vid_readdir, -+}; -+ -+static struct inode_operations proc_vid_inode_operations = { -+ lookup: proc_vid_lookup, -+}; -+ -+ -+ -+static __inline__ int atovid(const char *str, int len) -+{ -+ int vid, c; -+ -+ vid = 0; -+ while (len-- > 0) { -+ c = *str - '0'; -+ str++; -+ if (c > 9) -+ return -1; -+ if (vid >= MAX_MULBY10) -+ return -1; -+ vid *= 10; -+ vid += c; -+ if (!vid) -+ return -1; -+ } -+ return vid; -+} -+ -+ -+struct dentry *proc_virtual_lookup(struct inode *dir, -+ struct dentry * dentry, struct nameidata *nd) -+{ -+ int xid, len, ret; -+ struct vx_info *vxi; -+ const char *name; -+ struct inode *inode; -+ -+ name = dentry->d_name.name; -+ len = dentry->d_name.len; -+ ret = -ENOMEM; -+ -+ if (len == 7 && !memcmp(name, "current", 7)) { -+ inode = new_inode(dir->i_sb); -+ if (!inode) -+ goto out; -+ inode->i_mtime = inode->i_atime = -+ inode->i_ctime = CURRENT_TIME; -+ inode->i_ino = fake_ino(1, PROC_XID_INO); -+ inode->i_mode = S_IFLNK|S_IRWXUGO; -+ inode->i_uid = inode->i_gid = 0; -+ d_add(dentry, inode); -+ return NULL; -+ } -+ if (len == 4 && !memcmp(name, "info", 4)) { -+ inode = proc_vid_make_inode(dir->i_sb, 0, PROC_XID_INFO); -+ if (!inode) -+ goto out; -+ inode->i_fop = &proc_vid_info_file_operations; -+ PROC_I(inode)->op.proc_vid_read = proc_virtual_info; -+ inode->i_mode = S_IFREG|S_IRUGO; -+ d_add(dentry, inode); -+ return NULL; -+ } -+ -+ ret = -ENOENT; -+ xid = atovid(name, len); -+ if (xid < 0) -+ goto out; -+ vxi = lookup_vx_info(xid); -+ if (!vxi) -+ goto out; -+ -+ inode = NULL; -+ if (vx_check(xid, VX_ADMIN|VX_WATCH|VX_IDENT)) -+ inode = proc_vid_make_inode(dir->i_sb, -+ vxi->vx_id, PROC_XID_INO); -+ if (!inode) -+ goto out_release; -+ -+ inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; -+ inode->i_op = &proc_vid_inode_operations; -+ inode->i_fop = &proc_vid_file_operations; -+ inode->i_nlink = 2; -+ inode->i_flags|=S_IMMUTABLE; -+ -+ dentry->d_op = &proc_vid_dentry_operations; -+ d_add(dentry, inode); -+ ret = 0; -+ -+out_release: -+ put_vx_info(vxi); -+out: -+ return ERR_PTR(ret); -+} -+ -+ -+struct dentry *proc_vnet_lookup(struct inode *dir, -+ struct dentry * dentry, struct nameidata *nd) -+{ -+ int nid, len, ret; -+ struct nx_info *nxi; -+ const char *name; -+ struct inode *inode; -+ -+ name = dentry->d_name.name; -+ len = dentry->d_name.len; -+ ret = -ENOMEM; -+ if (len == 7 && !memcmp(name, "current", 7)) { -+ inode = new_inode(dir->i_sb); -+ if (!inode) -+ goto out; -+ inode->i_mtime = inode->i_atime = -+ inode->i_ctime = CURRENT_TIME; -+ inode->i_ino = fake_ino(1, PROC_NID_INO); -+ inode->i_mode = S_IFLNK|S_IRWXUGO; -+ inode->i_uid = inode->i_gid = 0; -+ d_add(dentry, inode); -+ return NULL; -+ } -+ if (len == 4 && !memcmp(name, "info", 4)) { -+ inode = proc_vid_make_inode(dir->i_sb, 0, PROC_NID_INFO); -+ if (!inode) -+ goto out; -+ inode->i_fop = &proc_vid_info_file_operations; -+ PROC_I(inode)->op.proc_vid_read = proc_vnet_info; -+ inode->i_mode = S_IFREG|S_IRUGO; -+ d_add(dentry, inode); -+ return NULL; -+ } -+ -+ ret = -ENOENT; -+ nid = atovid(name, len); -+ if (nid < 0) -+ goto out; -+ nxi = lookup_nx_info(nid); -+ if (!nxi) -+ goto out; -+ -+ inode = NULL; -+ if (1) -+ inode = proc_vid_make_inode(dir->i_sb, -+ nxi->nx_id, PROC_NID_INO); -+ if (!inode) -+ goto out_release; -+ -+ inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; -+ inode->i_op = &proc_vid_inode_operations; -+ inode->i_fop = &proc_vid_file_operations; -+ inode->i_nlink = 2; -+ inode->i_flags|=S_IMMUTABLE; -+ -+ dentry->d_op = &proc_vid_dentry_operations; -+ d_add(dentry, inode); -+ ret = 0; -+ -+out_release: -+ put_nx_info(nxi); -+out: -+ return ERR_PTR(ret); -+} -+ -+ -+ -+ -+#define PROC_NUMBUF 10 -+#define PROC_MAXVIDS 32 -+ -+int proc_virtual_readdir(struct file * filp, -+ void * dirent, filldir_t filldir) -+{ -+ unsigned int xid_array[PROC_MAXVIDS]; -+ char buf[PROC_NUMBUF]; -+ unsigned int nr = filp->f_pos-3; -+ unsigned int nr_xids, i; -+ ino_t ino; -+ -+ switch ((long)filp->f_pos) { -+ case 0: -+ ino = fake_ino(0, PROC_XID_INO); -+ if (filldir(dirent, ".", 1, -+ filp->f_pos, ino, DT_DIR) < 0) -+ return 0; -+ filp->f_pos++; -+ /* fall through */ -+ case 1: -+ ino = filp->f_dentry->d_parent->d_inode->i_ino; -+ if (filldir(dirent, "..", 2, -+ filp->f_pos, ino, DT_DIR) < 0) -+ return 0; -+ filp->f_pos++; -+ /* fall through */ -+ case 2: -+ ino = fake_ino(0, PROC_XID_INFO); -+ if (filldir(dirent, "info", 4, -+ filp->f_pos, ino, DT_LNK) < 0) -+ return 0; -+ filp->f_pos++; -+ /* fall through */ -+ case 3: -+ if (vx_current_xid() > 1) { -+ ino = fake_ino(1, PROC_XID_INO); -+ if (filldir(dirent, "current", 7, -+ filp->f_pos, ino, DT_LNK) < 0) -+ return 0; -+ } -+ filp->f_pos++; -+ } -+ -+ nr_xids = get_xid_list(nr, xid_array, PROC_MAXVIDS); -+ for (i = 0; i < nr_xids; i++) { -+ int xid = xid_array[i]; -+ ino_t ino = fake_ino(xid, PROC_XID_INO); -+ unsigned int j = PROC_NUMBUF; -+ -+ do buf[--j] = '0' + (xid % 10); while (xid/=10); -+ -+ if (filldir(dirent, buf+j, PROC_NUMBUF-j, -+ filp->f_pos, ino, DT_DIR) < 0) -+ break; -+ filp->f_pos++; -+ } -+ return 0; -+} -+ -+ -+static struct file_operations proc_virtual_dir_operations = { -+ read: generic_read_dir, -+ readdir: proc_virtual_readdir, -+}; -+ -+static struct inode_operations proc_virtual_dir_inode_operations = { -+ lookup: proc_virtual_lookup, -+}; -+ -+ -+int proc_vnet_readdir(struct file * filp, -+ void * dirent, filldir_t filldir) -+{ -+ unsigned int nid_array[PROC_MAXVIDS]; -+ char buf[PROC_NUMBUF]; -+ unsigned int nr = filp->f_pos-2; -+ unsigned int nr_nids, i; -+ ino_t ino; -+ -+ switch ((long)filp->f_pos) { -+ case 0: -+ ino = fake_ino(0, PROC_NID_INO); -+ if (filldir(dirent, ".", 1, -+ filp->f_pos, ino, DT_DIR) < 0) -+ return 0; -+ filp->f_pos++; -+ /* fall through */ -+ case 1: -+ ino = filp->f_dentry->d_parent->d_inode->i_ino; -+ if (filldir(dirent, "..", 2, -+ filp->f_pos, ino, DT_DIR) < 0) -+ return 0; -+ filp->f_pos++; -+ /* fall through */ -+ case 2: -+ ino = fake_ino(0, PROC_NID_INFO); -+ if (filldir(dirent, "info", 4, -+ filp->f_pos, ino, DT_REG) < 0) -+ return 0; -+ filp->f_pos++; -+ /* fall through */ -+ } -+ -+ nr_nids = get_nid_list(nr, nid_array, PROC_MAXVIDS); -+ for (i = 0; i < nr_nids; i++) { -+ int nid = nid_array[i]; -+ ino_t ino = fake_ino(nid, PROC_NID_INO); -+ unsigned long j = PROC_NUMBUF; -+ -+ do buf[--j] = '0' + (nid % 10); while (nid/=10); -+ -+ if (filldir(dirent, buf+j, PROC_NUMBUF-j, -+ filp->f_pos, ino, DT_DIR) < 0) -+ break; -+ filp->f_pos++; -+ } -+ return 0; -+} -+ -+ -+static struct file_operations proc_vnet_dir_operations = { -+ read: generic_read_dir, -+ readdir: proc_vnet_readdir, -+}; -+ -+static struct inode_operations proc_vnet_dir_inode_operations = { -+ lookup: proc_vnet_lookup, -+}; -+ -+ -+ -+void proc_vx_init(void) -+{ -+ struct proc_dir_entry *ent; -+ -+ ent = proc_mkdir("virtual", 0); -+ if (ent) { -+ ent->proc_fops = &proc_virtual_dir_operations; -+ ent->proc_iops = &proc_virtual_dir_inode_operations; -+ } -+ proc_virtual = ent; -+ -+ ent = proc_mkdir("virtnet", 0); -+ if (ent) { -+ ent->proc_fops = &proc_vnet_dir_operations; -+ ent->proc_iops = &proc_vnet_dir_inode_operations; -+ } -+ proc_vnet = ent; -+} -+ -+ -+ -+ -+/* per pid info */ -+ -+ -+int proc_pid_vx_info(struct task_struct *p, char *buffer) -+{ -+ struct vx_info *vxi; -+ char * orig = buffer; -+ -+ buffer += sprintf (buffer,"XID:\t%d\n", vx_task_xid(p)); -+ if (vx_flags(VXF_INFO_HIDE, 0)) -+ goto out; -+ -+ vxi = task_get_vx_info(p); -+ if (!vxi) -+ goto out; -+ -+ buffer += sprintf (buffer,"BCaps:\t%016llx\n" -+ ,(unsigned long long)vxi->vx_bcaps); -+ buffer += sprintf (buffer,"CCaps:\t%016llx\n" -+ ,(unsigned long long)vxi->vx_ccaps); -+ buffer += sprintf (buffer,"CFlags:\t%016llx\n" -+ ,(unsigned long long)vxi->vx_flags); -+ buffer += sprintf (buffer,"CIPid:\t%d\n" -+ ,vxi->vx_initpid); -+ -+ put_vx_info(vxi); -+out: -+ return buffer - orig; -+} -+ -+ -+int proc_pid_nx_info(struct task_struct *p, char *buffer) -+{ -+ struct nx_info *nxi; -+ char * orig = buffer; -+ int i; -+ -+ buffer += sprintf (buffer,"NID:\t%d\n", nx_task_nid(p)); -+ if (vx_flags(VXF_INFO_HIDE, 0)) -+ goto out; -+ nxi = task_get_nx_info(p); -+ if (!nxi) -+ goto out; -+ -+ for (i=0; inbipv4; i++){ -+ buffer += sprintf (buffer, -+ "V4Root[%d]:\t%d.%d.%d.%d/%d.%d.%d.%d\n", i -+ ,NIPQUAD(nxi->ipv4[i]) -+ ,NIPQUAD(nxi->mask[i])); -+ } -+ buffer += sprintf (buffer, -+ "V4Root[bcast]:\t%d.%d.%d.%d\n" -+ ,NIPQUAD(nxi->v4_bcast)); -+ -+ put_nx_info(nxi); -+out: -+ return buffer - orig; -+} -+ -diff --git a/kernel/vserver/sched.c b/kernel/vserver/sched.c -new file mode 100644 -index 0000000..50d5c0b ---- /dev/null -+++ b/kernel/vserver/sched.c -@@ -0,0 +1,218 @@ -+/* -+ * linux/kernel/vserver/sched.c -+ * -+ * Virtual Server: Scheduler Support -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 adapted Sam Vilains version to 2.6.3 -+ * V0.02 removed legacy interface -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+/* -+ * recalculate the context's scheduling tokens -+ * -+ * ret > 0 : number of tokens available -+ * ret = 0 : context is paused -+ * ret < 0 : number of jiffies until new tokens arrive -+ * -+ */ -+int vx_tokens_recalc(struct vx_info *vxi) -+{ -+ long delta, tokens = 0; -+ -+ if (vx_info_flags(vxi, VXF_SCHED_PAUSE, 0)) -+ /* we are paused */ -+ return 0; -+ -+ delta = jiffies - vxi->sched.jiffies; -+ -+ if (delta >= vxi->sched.interval) { -+ /* lockdown scheduler info */ -+ spin_lock(&vxi->sched.tokens_lock); -+ -+ /* calc integral token part */ -+ delta = jiffies - vxi->sched.jiffies; -+ tokens = delta / vxi->sched.interval; -+ delta = tokens * vxi->sched.interval; -+ tokens *= vxi->sched.fill_rate; -+ -+ atomic_add(tokens, &vxi->sched.tokens); -+ vxi->sched.jiffies += delta; -+ tokens = atomic_read(&vxi->sched.tokens); -+ -+ if (tokens > vxi->sched.tokens_max) { -+ tokens = vxi->sched.tokens_max; -+ atomic_set(&vxi->sched.tokens, tokens); -+ } -+ spin_unlock(&vxi->sched.tokens_lock); -+ } else { -+ /* no new tokens */ -+ tokens = vx_tokens_avail(vxi); -+ if (tokens <= 0) -+ vxi->vx_state |= VXS_ONHOLD; -+ if (tokens < vxi->sched.tokens_min) { -+ /* enough tokens will be available in */ -+ if (vxi->sched.tokens_min == 0) -+ return delta - vxi->sched.interval; -+ return delta - vxi->sched.interval * -+ vxi->sched.tokens_min / vxi->sched.fill_rate; -+ } -+ } -+ -+ /* we have some tokens left */ -+ if (vx_info_state(vxi, VXS_ONHOLD) && -+ (tokens >= vxi->sched.tokens_min)) -+ vxi->vx_state &= ~VXS_ONHOLD; -+ if (vx_info_state(vxi, VXS_ONHOLD)) -+ tokens -= vxi->sched.tokens_min; -+ -+ return tokens; -+} -+ -+/* -+ * effective_prio - return the priority that is based on the static -+ * priority but is modified by bonuses/penalties. -+ * -+ * We scale the actual sleep average [0 .... MAX_SLEEP_AVG] -+ * into a -4 ... 0 ... +4 bonus/penalty range. -+ * -+ * Additionally, we scale another amount based on the number of -+ * CPU tokens currently held by the context, if the process is -+ * part of a context (and the appropriate SCHED flag is set). -+ * This ranges from -5 ... 0 ... +15, quadratically. -+ * -+ * So, the total bonus is -9 .. 0 .. +19 -+ * We use ~50% of the full 0...39 priority range so that: -+ * -+ * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs. -+ * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks. -+ * unless that context is far exceeding its CPU allocation. -+ * -+ * Both properties are important to certain workloads. -+ */ -+int vx_effective_vavavoom(struct vx_info *vxi, int max_prio) -+{ -+ int vavavoom, max; -+ -+ /* lots of tokens = lots of vavavoom -+ * no tokens = no vavavoom */ -+ if ((vavavoom = atomic_read(&vxi->sched.tokens)) >= 0) { -+ max = vxi->sched.tokens_max; -+ vavavoom = max - vavavoom; -+ max = max * max; -+ vavavoom = max_prio * VAVAVOOM_RATIO / 100 -+ * (vavavoom*vavavoom - (max >> 2)) / max; -+ } else -+ vavavoom = 0; -+ -+ vxi->sched.vavavoom = vavavoom; -+ return vavavoom; -+} -+ -+ -+int vc_set_sched_v2(uint32_t xid, void __user *data) -+{ -+ struct vcmd_set_sched_v2 vc_data; -+ struct vx_info *vxi; -+ -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ vxi = lookup_vx_info(xid); -+ if (!vxi) -+ return -EINVAL; -+ -+ spin_lock(&vxi->sched.tokens_lock); -+ -+ if (vc_data.interval != SCHED_KEEP) -+ vxi->sched.interval = vc_data.interval; -+ if (vc_data.fill_rate != SCHED_KEEP) -+ vxi->sched.fill_rate = vc_data.fill_rate; -+ if (vc_data.tokens_min != SCHED_KEEP) -+ vxi->sched.tokens_min = vc_data.tokens_min; -+ if (vc_data.tokens_max != SCHED_KEEP) -+ vxi->sched.tokens_max = vc_data.tokens_max; -+ if (vc_data.tokens != SCHED_KEEP) -+ atomic_set(&vxi->sched.tokens, vc_data.tokens); -+ -+ /* Sanity check the resultant values */ -+ if (vxi->sched.fill_rate <= 0) -+ vxi->sched.fill_rate = 1; -+ if (vxi->sched.interval <= 0) -+ vxi->sched.interval = HZ; -+ if (vxi->sched.tokens_max == 0) -+ vxi->sched.tokens_max = 1; -+ if (atomic_read(&vxi->sched.tokens) > vxi->sched.tokens_max) -+ atomic_set(&vxi->sched.tokens, vxi->sched.tokens_max); -+ if (vxi->sched.tokens_min > vxi->sched.tokens_max) -+ vxi->sched.tokens_min = vxi->sched.tokens_max; -+ -+ spin_unlock(&vxi->sched.tokens_lock); -+ put_vx_info(vxi); -+ return 0; -+} -+ -+ -+int vc_set_sched(uint32_t xid, void __user *data) -+{ -+ struct vcmd_set_sched_v3 vc_data; -+ struct vx_info *vxi; -+ unsigned int set_mask; -+ -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ vxi = lookup_vx_info(xid); -+ if (!vxi) -+ return -EINVAL; -+ -+ set_mask = vc_data.set_mask; -+ -+ spin_lock(&vxi->sched.tokens_lock); -+ -+ if (set_mask & VXSM_FILL_RATE) -+ vxi->sched.fill_rate = vc_data.fill_rate; -+ if (set_mask & VXSM_INTERVAL) -+ vxi->sched.interval = vc_data.interval; -+ if (set_mask & VXSM_TOKENS) -+ atomic_set(&vxi->sched.tokens, vc_data.tokens); -+ if (set_mask & VXSM_TOKENS_MIN) -+ vxi->sched.tokens_min = vc_data.tokens_min; -+ if (set_mask & VXSM_TOKENS_MAX) -+ vxi->sched.tokens_max = vc_data.tokens_max; -+ if (set_mask & VXSM_PRIO_BIAS) -+ vxi->sched.priority_bias = vc_data.priority_bias; -+ -+ /* Sanity check the resultant values */ -+ if (vxi->sched.fill_rate <= 0) -+ vxi->sched.fill_rate = 1; -+ if (vxi->sched.interval <= 0) -+ vxi->sched.interval = HZ; -+ if (vxi->sched.tokens_max == 0) -+ vxi->sched.tokens_max = 1; -+ if (atomic_read(&vxi->sched.tokens) > vxi->sched.tokens_max) -+ atomic_set(&vxi->sched.tokens, vxi->sched.tokens_max); -+ if (vxi->sched.tokens_min > vxi->sched.tokens_max) -+ vxi->sched.tokens_min = vxi->sched.tokens_max; -+ if (vxi->sched.priority_bias > MAX_PRIO_BIAS) -+ vxi->sched.priority_bias = MAX_PRIO_BIAS; -+ if (vxi->sched.priority_bias < MIN_PRIO_BIAS) -+ vxi->sched.priority_bias = MIN_PRIO_BIAS; -+ -+ spin_unlock(&vxi->sched.tokens_lock); -+ put_vx_info(vxi); -+ return 0; -+} -+ -diff --git a/kernel/vserver/sched_init.h b/kernel/vserver/sched_init.h -new file mode 100644 -index 0000000..90d1396 ---- /dev/null -+++ b/kernel/vserver/sched_init.h -@@ -0,0 +1,30 @@ -+ -+static inline void vx_info_init_sched(struct _vx_sched *sched) -+{ -+ int i; -+ -+ /* scheduling; hard code starting values as constants */ -+ sched->fill_rate = 1; -+ sched->interval = 4; -+ sched->tokens_min = HZ >> 4; -+ sched->tokens_max = HZ >> 1; -+ sched->jiffies = jiffies; -+ sched->tokens_lock = SPIN_LOCK_UNLOCKED; -+ -+ atomic_set(&sched->tokens, HZ >> 2); -+ sched->cpus_allowed = CPU_MASK_ALL; -+ sched->priority_bias = 0; -+ sched->vavavoom = 0; -+ -+ for_each_cpu(i) { -+ sched->cpu[i].user_ticks = 0; -+ sched->cpu[i].sys_ticks = 0; -+ sched->cpu[i].hold_ticks = 0; -+ } -+} -+ -+static inline void vx_info_exit_sched(struct _vx_sched *sched) -+{ -+ return; -+} -+ -diff --git a/kernel/vserver/sched_proc.h b/kernel/vserver/sched_proc.h -new file mode 100644 -index 0000000..e65a3df ---- /dev/null -+++ b/kernel/vserver/sched_proc.h -@@ -0,0 +1,40 @@ -+#ifndef _VX_SCHED_PROC_H -+#define _VX_SCHED_PROC_H -+ -+ -+static inline int vx_info_proc_sched(struct _vx_sched *sched, char *buffer) -+{ -+ int length = 0; -+ int i; -+ -+ length += sprintf(buffer, -+ "Token:\t\t%8d\n" -+ "FillRate:\t%8d\n" -+ "Interval:\t%8d\n" -+ "TokensMin:\t%8d\n" -+ "TokensMax:\t%8d\n" -+ "PrioBias:\t%8d\n" -+ "VaVaVoom:\t%8d\n" -+ ,atomic_read(&sched->tokens) -+ ,sched->fill_rate -+ ,sched->interval -+ ,sched->tokens_min -+ ,sched->tokens_max -+ ,sched->priority_bias -+ ,sched->vavavoom -+ ); -+ -+ for_each_online_cpu(i) { -+ length += sprintf(buffer + length, -+ "cpu %d: %lld %lld %lld\n" -+ ,i -+ ,(long long)sched->cpu[i].user_ticks -+ ,(long long)sched->cpu[i].sys_ticks -+ ,(long long)sched->cpu[i].hold_ticks -+ ); -+ } -+ -+ return length; -+} -+ -+#endif /* _VX_SCHED_PROC_H */ -diff --git a/kernel/vserver/signal.c b/kernel/vserver/signal.c -new file mode 100644 -index 0000000..2406b9d ---- /dev/null -+++ b/kernel/vserver/signal.c -@@ -0,0 +1,132 @@ -+/* -+ * linux/kernel/vserver/signal.c -+ * -+ * Virtual Server: Signal Support -+ * -+ * Copyright (C) 2003-2005 Herbert Pötzl -+ * -+ * V0.01 broken out from vcontext V0.05 -+ * -+ */ -+ -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+ -+int vx_info_kill(struct vx_info *vxi, int pid, int sig) -+{ -+ int retval, count=0; -+ struct task_struct *p; -+ unsigned long priv = 0; -+ -+ retval = -ESRCH; -+ vxdprintk(VXD_CBIT(misc, 4), -+ "vx_info_kill(%p[#%d],%d,%d)*", -+ vxi, vxi->vx_id, pid, sig); -+ read_lock(&tasklist_lock); -+ switch (pid) { -+ case 0: -+ priv = 1; -+ case -1: -+ for_each_process(p) { -+ int err = 0; -+ -+ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 || -+ (pid && vxi->vx_initpid == p->pid)) -+ continue; -+ -+ err = group_send_sig_info(sig, (void*)priv, p); -+ ++count; -+ if (err != -EPERM) -+ retval = err; -+ } -+ break; -+ -+ case 1: -+ if (vxi->vx_initpid) { -+ pid = vxi->vx_initpid; -+ priv = 1; -+ } -+ /* fallthrough */ -+ default: -+ p = find_task_by_real_pid(pid); -+ if (p) { -+ if (vx_task_xid(p) == vxi->vx_id) -+ retval = group_send_sig_info(sig, -+ (void*)priv, p); -+ } -+ break; -+ } -+ read_unlock(&tasklist_lock); -+ vxdprintk(VXD_CBIT(misc, 4), -+ "vx_info_kill(%p[#%d],%d,%d) = %d", -+ vxi, vxi->vx_id, pid, sig, retval); -+ return retval; -+} -+ -+int vc_ctx_kill(uint32_t id, void __user *data) -+{ -+ int retval; -+ struct vcmd_ctx_kill_v0 vc_data; -+ struct vx_info *vxi; -+ -+ if (!vx_check(0, VX_ADMIN)) -+ return -ENOSYS; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ retval = vx_info_kill(vxi, vc_data.pid, vc_data.sig); -+ put_vx_info(vxi); -+ return retval; -+} -+ -+ -+static int __wait_exit(struct vx_info *vxi) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ int ret = 0; -+ -+ add_wait_queue(&vxi->vx_wait, &wait); -+ set_current_state(TASK_INTERRUPTIBLE); -+ -+wait: -+ if (vx_info_state(vxi, VXS_SHUTDOWN|VXS_HASHED) == VXS_SHUTDOWN) -+ goto out; -+ if (signal_pending(current)) { -+ ret = -ERESTARTSYS; -+ goto out; -+ } -+ schedule(); -+ goto wait; -+ -+out: -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&vxi->vx_wait, &wait); -+ return ret; -+} -+ -+ -+ -+int vc_wait_exit(uint32_t id, void __user *data) -+{ -+ struct vx_info *vxi; -+ int ret; -+ -+ vxi = lookup_vx_info(id); -+ if (!vxi) -+ return -ESRCH; -+ -+ ret = __wait_exit(vxi); -+ put_vx_info(vxi); -+ return ret; -+} -+ -diff --git a/kernel/vserver/switch.c b/kernel/vserver/switch.c -new file mode 100644 -index 0000000..035c995 ---- /dev/null -+++ b/kernel/vserver/switch.c -@@ -0,0 +1,264 @@ -+/* -+ * linux/kernel/vserver/switch.c -+ * -+ * Virtual Server: Syscall Switch -+ * -+ * Copyright (C) 2003-2005 Herbert Pötzl -+ * -+ * V0.01 syscall switch -+ * V0.02 added signal to context -+ * V0.03 added rlimit functions -+ * V0.04 added iattr, task/xid functions -+ * V0.05 added debug/history stuff -+ * V0.06 added compat32 layer -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+ -+static inline -+int vc_get_version(uint32_t id) -+{ -+#ifdef CONFIG_VSERVER_LEGACY_VERSION -+ if (id == 63) -+ return VCI_LEGACY_VERSION; -+#endif -+ return VCI_VERSION; -+} -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+ -+#ifdef CONFIG_COMPAT -+#define __COMPAT(name, id, data, compat) \ -+ (compat) ? name ## _x32 (id, data) : name (id, data) -+#else -+#define __COMPAT(name, id, data, compat) \ -+ name (id, data) -+#endif -+ -+ -+static inline -+long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat) -+{ -+ vxdprintk(VXD_CBIT(switch, 0), -+ "vc: VCMD_%02d_%d[%d], %d,%p,%d", -+ VC_CATEGORY(cmd), VC_COMMAND(cmd), -+ VC_VERSION(cmd), id, data, compat); -+ -+#ifdef CONFIG_VSERVER_LEGACY -+ if (!capable(CAP_CONTEXT) && -+ /* dirty hack for capremove */ -+ !(cmd==VCMD_new_s_context && id==-2)) -+ return -EPERM; -+#else -+ if (!capable(CAP_CONTEXT)) -+ return -EPERM; -+#endif -+ -+ switch (cmd) { -+ case VCMD_get_version: -+ return vc_get_version(id); -+ -+ case VCMD_dump_history: -+#ifdef CONFIG_VSERVER_HISTORY -+ return vc_dump_history(id); -+#else -+ return -ENOSYS; -+#endif -+ -+#ifdef CONFIG_VSERVER_LEGACY -+ case VCMD_new_s_context: -+ return vc_new_s_context(id, data); -+#endif -+#ifdef CONFIG_VSERVER_LEGACYNET -+ case VCMD_set_ipv4root: -+ return vc_set_ipv4root(id, data); -+#endif -+ -+ case VCMD_task_xid: -+ return vc_task_xid(id, data); -+ case VCMD_vx_info: -+ return vc_vx_info(id, data); -+ -+ case VCMD_task_nid: -+ return vc_task_nid(id, data); -+ case VCMD_nx_info: -+ return vc_nx_info(id, data); -+ -+ case VCMD_set_namespace_v0: -+ return vc_set_namespace(-1, data); -+ case VCMD_set_namespace: -+ return vc_set_namespace(id, data); -+ case VCMD_cleanup_namespace: -+ return vc_cleanup_namespace(id, data); -+ } -+ -+ /* those are allowed while in setup too */ -+ if (!vx_check(0, VX_ADMIN|VX_WATCH) && -+ !vx_flags(VXF_STATE_SETUP,0)) -+ return -EPERM; -+ -+#ifdef CONFIG_VSERVER_LEGACY -+ switch (cmd) { -+ case VCMD_set_cflags: -+ case VCMD_set_ccaps: -+ if (vx_check(0, VX_WATCH)) -+ return 0; -+ } -+#endif -+ -+ switch (cmd) { -+ case VCMD_get_rlimit: -+ return vc_get_rlimit(id, data); -+ case VCMD_set_rlimit: -+ return vc_set_rlimit(id, data); -+ case VCMD_get_rlimit_mask: -+ return vc_get_rlimit_mask(id, data); -+ -+ case VCMD_get_vhi_name: -+ return vc_get_vhi_name(id, data); -+ case VCMD_set_vhi_name: -+ return vc_set_vhi_name(id, data); -+ -+ case VCMD_set_cflags: -+ return vc_set_cflags(id, data); -+ case VCMD_get_cflags: -+ return vc_get_cflags(id, data); -+ -+ case VCMD_set_ccaps: -+ return vc_set_ccaps(id, data); -+ case VCMD_get_ccaps: -+ return vc_get_ccaps(id, data); -+ -+ case VCMD_set_nflags: -+ return vc_set_nflags(id, data); -+ case VCMD_get_nflags: -+ return vc_get_nflags(id, data); -+ -+ case VCMD_set_ncaps: -+ return vc_set_ncaps(id, data); -+ case VCMD_get_ncaps: -+ return vc_get_ncaps(id, data); -+ -+ case VCMD_set_sched_v2: -+ return vc_set_sched_v2(id, data); -+ /* this is version 3 */ -+ case VCMD_set_sched: -+ return vc_set_sched(id, data); -+ -+ case VCMD_add_dlimit: -+ return __COMPAT(vc_add_dlimit, id, data, compat); -+ case VCMD_rem_dlimit: -+ return __COMPAT(vc_rem_dlimit, id, data, compat); -+ case VCMD_set_dlimit: -+ return __COMPAT(vc_set_dlimit, id, data, compat); -+ case VCMD_get_dlimit: -+ return __COMPAT(vc_get_dlimit, id, data, compat); -+ } -+ -+ /* below here only with VX_ADMIN */ -+ if (!vx_check(0, VX_ADMIN|VX_WATCH)) -+ return -EPERM; -+ -+ switch (cmd) { -+ case VCMD_ctx_kill: -+ return vc_ctx_kill(id, data); -+ -+ case VCMD_wait_exit: -+ return vc_wait_exit(id, data); -+ -+ case VCMD_create_context: -+#ifdef CONFIG_VSERVER_LEGACY -+ return vc_ctx_create(id, NULL); -+#else -+ return -ENOSYS; -+#endif -+ -+ case VCMD_get_iattr: -+ return __COMPAT(vc_get_iattr, id, data, compat); -+ case VCMD_set_iattr: -+ return __COMPAT(vc_set_iattr, id, data, compat); -+ -+ case VCMD_enter_namespace: -+ return vc_enter_namespace(id, data); -+ -+ case VCMD_ctx_create_v0: -+#ifdef CONFIG_VSERVER_LEGACY -+ if (id == 1) { -+ current->xid = 1; -+ return 1; -+ } -+#endif -+ return vc_ctx_create(id, NULL); -+ case VCMD_ctx_create: -+ return vc_ctx_create(id, data); -+ case VCMD_ctx_migrate_v0: -+ return vc_ctx_migrate(id, NULL); -+ case VCMD_ctx_migrate: -+ return vc_ctx_migrate(id, data); -+ -+ case VCMD_net_create_v0: -+ return vc_net_create(id, NULL); -+ case VCMD_net_create: -+ return vc_net_create(id, data); -+ case VCMD_net_migrate: -+ return vc_net_migrate(id, data); -+ case VCMD_net_add: -+ return vc_net_add(id, data); -+ case VCMD_net_remove: -+ return vc_net_remove(id, data); -+ -+ } -+ return -ENOSYS; -+} -+ -+extern asmlinkage long -+sys_vserver(uint32_t cmd, uint32_t id, void __user *data) -+{ -+ long ret = do_vserver(cmd, id, data, 0); -+ -+ vxdprintk(VXD_CBIT(switch, 1), -+ "vc: VCMD_%02d_%d[%d] = %08lx(%ld)", -+ VC_CATEGORY(cmd), VC_COMMAND(cmd), -+ VC_VERSION(cmd), ret, ret); -+ return ret; -+} -+ -+#ifdef CONFIG_COMPAT -+ -+extern asmlinkage long -+sys32_vserver(uint32_t cmd, uint32_t id, void __user *data) -+{ -+ long ret = do_vserver(cmd, id, data, 1); -+ -+ vxdprintk(VXD_CBIT(switch, 1), -+ "vc: VCMD_%02d_%d[%d] = %08lx(%ld)", -+ VC_CATEGORY(cmd), VC_COMMAND(cmd), -+ VC_VERSION(cmd), ret, ret); -+ return ret; -+} -+ -+#endif /* CONFIG_COMPAT */ -diff --git a/kernel/vserver/sysctl.c b/kernel/vserver/sysctl.c -new file mode 100644 -index 0000000..d233b1f ---- /dev/null -+++ b/kernel/vserver/sysctl.c -@@ -0,0 +1,227 @@ -+/* -+ * kernel/vserver/sysctl.c -+ * -+ * Virtual Context Support -+ * -+ * Copyright (C) 2004-2005 Herbert Pötzl -+ * -+ * V0.01 basic structure -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+ -+#define CTL_VSERVER 4242 /* unused? */ -+ -+enum { -+ CTL_DEBUG_ERROR = 0, -+ CTL_DEBUG_SWITCH = 1, -+ CTL_DEBUG_XID, -+ CTL_DEBUG_NID, -+ CTL_DEBUG_NET, -+ CTL_DEBUG_LIMIT, -+ CTL_DEBUG_CRES, -+ CTL_DEBUG_DLIM, -+ CTL_DEBUG_CVIRT, -+ CTL_DEBUG_MISC, -+}; -+ -+ -+unsigned int vx_debug_switch = 0; -+unsigned int vx_debug_xid = 0; -+unsigned int vx_debug_nid = 0; -+unsigned int vx_debug_net = 0; -+unsigned int vx_debug_limit = 0; -+unsigned int vx_debug_cres = 0; -+unsigned int vx_debug_dlim = 0; -+unsigned int vx_debug_cvirt = 0; -+unsigned int vx_debug_misc = 0; -+ -+ -+static struct ctl_table_header *vserver_table_header; -+static ctl_table vserver_table[]; -+ -+ -+void vserver_register_sysctl(void) -+{ -+ if (!vserver_table_header) { -+ vserver_table_header = register_sysctl_table(vserver_table, 1); -+ } -+ -+} -+ -+void vserver_unregister_sysctl(void) -+{ -+ if (vserver_table_header) { -+ unregister_sysctl_table(vserver_table_header); -+ vserver_table_header = NULL; -+ } -+} -+ -+ -+static int proc_dodebug(ctl_table *table, int write, -+ struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) -+{ -+ char tmpbuf[20], *p, c; -+ unsigned int value; -+ size_t left, len; -+ -+ if ((*ppos && !write) || !*lenp) { -+ *lenp = 0; -+ return 0; -+ } -+ -+ left = *lenp; -+ -+ if (write) { -+ if (!access_ok(VERIFY_READ, buffer, left)) -+ return -EFAULT; -+ p = (char *) buffer; -+ while (left && __get_user(c, p) >= 0 && isspace(c)) -+ left--, p++; -+ if (!left) -+ goto done; -+ -+ if (left > sizeof(tmpbuf) - 1) -+ return -EINVAL; -+ if (copy_from_user(tmpbuf, p, left)) -+ return -EFAULT; -+ tmpbuf[left] = '\0'; -+ -+ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--) -+ value = 10 * value + (*p - '0'); -+ if (*p && !isspace(*p)) -+ return -EINVAL; -+ while (left && isspace(*p)) -+ left--, p++; -+ *(unsigned int *) table->data = value; -+ } else { -+ if (!access_ok(VERIFY_WRITE, buffer, left)) -+ return -EFAULT; -+ len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data); -+ if (len > left) -+ len = left; -+ if (__copy_to_user(buffer, tmpbuf, len)) -+ return -EFAULT; -+ if ((left -= len) > 0) { -+ if (put_user('\n', (char *)buffer + len)) -+ return -EFAULT; -+ left--; -+ } -+ } -+ -+done: -+ *lenp -= left; -+ *ppos += *lenp; -+ return 0; -+} -+ -+ -+ -+static ctl_table debug_table[] = { -+ { -+ .ctl_name = CTL_DEBUG_SWITCH, -+ .procname = "debug_switch", -+ .data = &vx_debug_switch, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { -+ .ctl_name = CTL_DEBUG_XID, -+ .procname = "debug_xid", -+ .data = &vx_debug_xid, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { -+ .ctl_name = CTL_DEBUG_NID, -+ .procname = "debug_nid", -+ .data = &vx_debug_nid, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { -+ .ctl_name = CTL_DEBUG_NET, -+ .procname = "debug_net", -+ .data = &vx_debug_net, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { -+ .ctl_name = CTL_DEBUG_LIMIT, -+ .procname = "debug_limit", -+ .data = &vx_debug_limit, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { -+ .ctl_name = CTL_DEBUG_CRES, -+ .procname = "debug_cres", -+ .data = &vx_debug_cres, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { -+ .ctl_name = CTL_DEBUG_DLIM, -+ .procname = "debug_dlim", -+ .data = &vx_debug_dlim, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { -+ .ctl_name = CTL_DEBUG_CVIRT, -+ .procname = "debug_cvirt", -+ .data = &vx_debug_cvirt, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { -+ .ctl_name = CTL_DEBUG_MISC, -+ .procname = "debug_misc", -+ .data = &vx_debug_misc, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dodebug -+ }, -+ { .ctl_name = 0 } -+}; -+ -+static ctl_table vserver_table[] = { -+ { -+ .ctl_name = CTL_VSERVER, -+ .procname = "vserver", -+ .mode = 0555, -+ .child = debug_table -+ }, -+ { .ctl_name = 0 } -+}; -+ -+ -+EXPORT_SYMBOL_GPL(vx_debug_switch); -+EXPORT_SYMBOL_GPL(vx_debug_xid); -+EXPORT_SYMBOL_GPL(vx_debug_nid); -+EXPORT_SYMBOL_GPL(vx_debug_net); -+EXPORT_SYMBOL_GPL(vx_debug_limit); -+EXPORT_SYMBOL_GPL(vx_debug_cres); -+EXPORT_SYMBOL_GPL(vx_debug_dlim); -+EXPORT_SYMBOL_GPL(vx_debug_cvirt); -+EXPORT_SYMBOL_GPL(vx_debug_misc); -+ -diff --git a/kernel/vserver/vci_config.h b/kernel/vserver/vci_config.h -new file mode 100644 -index 0000000..1f3b17b ---- /dev/null -+++ b/kernel/vserver/vci_config.h -@@ -0,0 +1,73 @@ -+ -+#include -+ -+ -+enum { -+ VCI_KCBIT_LEGACY = 1, -+ VCI_KCBIT_LEGACYNET, -+ VCI_KCBIT_NGNET, -+ -+ VCI_KCBIT_PROC_SECURE, -+ VCI_KCBIT_HARDCPU, -+ VCI_KCBIT_HARDCPU_IDLE, -+ -+ VCI_KCBIT_LEGACY_VERSION = 15, -+ -+ VCI_KCBIT_DEBUG = 16, -+ VCI_KCBIT_HISTORY = 20, -+ VCI_KCBIT_TAGXID = 24, -+}; -+ -+ -+static inline uint32_t vci_kernel_config(void) -+{ -+ return -+ /* various legacy options */ -+#ifdef CONFIG_VSERVER_LEGACY -+ (1 << VCI_KCBIT_LEGACY) | -+#endif -+#ifdef CONFIG_VSERVER_LEGACYNET -+ (1 << VCI_KCBIT_LEGACYNET) | -+#endif -+#ifdef CONFIG_VSERVER_LEGACY_VERSION -+ (1 << VCI_KCBIT_LEGACY_VERSION) | -+#endif -+ -+ /* configured features */ -+#ifdef CONFIG_VSERVER_PROC_SECURE -+ (1 << VCI_KCBIT_PROC_SECURE) | -+#endif -+#ifdef CONFIG_VSERVER_HARDCPU -+ (1 << VCI_KCBIT_HARDCPU) | -+#endif -+#ifdef CONFIG_VSERVER_HARDCPU_IDLE -+ (1 << VCI_KCBIT_HARDCPU_IDLE) | -+#endif -+ -+ /* debug options */ -+#ifdef CONFIG_VSERVER_DEBUG -+ (1 << VCI_KCBIT_DEBUG) | -+#endif -+#ifdef CONFIG_VSERVER_HISTORY -+ (1 << VCI_KCBIT_HISTORY) | -+#endif -+ -+ /* inode xid tagging */ -+#if defined(CONFIG_INOXID_NONE) -+ (0 << VCI_KCBIT_TAGXID) | -+#elif defined(CONFIG_INOXID_UID16) -+ (1 << VCI_KCBIT_TAGXID) | -+#elif defined(CONFIG_INOXID_GID16) -+ (2 << VCI_KCBIT_TAGXID) | -+#elif defined(CONFIG_INOXID_UGID24) -+ (3 << VCI_KCBIT_TAGXID) | -+#elif defined(CONFIG_INOXID_INTERN) -+ (4 << VCI_KCBIT_TAGXID) | -+#elif defined(CONFIG_INOXID_RUNTIME) -+ (5 << VCI_KCBIT_TAGXID) | -+#else -+ (7 << VCI_KCBIT_TAGXID) | -+#endif -+ 0; -+} -+ -diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c -index b960ac8..0c27759 100644 ---- a/mm/filemap_xip.c -+++ b/mm/filemap_xip.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include "filemap.h" - -diff --git a/mm/fremap.c b/mm/fremap.c -index 9f381e5..a7538bd 100644 ---- a/mm/fremap.c -+++ b/mm/fremap.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -35,6 +36,7 @@ static int zap_pte(struct mm_struct *mm, - set_page_dirty(page); - page_remove_rmap(page); - page_cache_release(page); -+ // dec_mm_counter(mm, file_rss); - } - } else { - if (!pte_file(pte)) -@@ -74,6 +76,8 @@ int install_page(struct mm_struct *mm, s - err = -ENOMEM; - if (page_mapcount(page) > INT_MAX/2) - goto unlock; -+ if (!vx_rsspages_avail(mm, 1)) -+ goto unlock; - - if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte)) - inc_mm_counter(mm, file_rss); -diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index 5087077..f1b2c19 100644 ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -18,6 +18,7 @@ - #include - - #include -+#include - - const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; - static unsigned long nr_huge_pages, free_huge_pages; -diff --git a/mm/memory.c b/mm/memory.c -index 9abc600..520b66e 100644 ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -1903,6 +1903,10 @@ again: - grab_swap_token(); - } - -+ if (!vx_rsspages_avail(mm, 1)) { -+ ret = VM_FAULT_OOM; -+ goto out; -+ } - mark_page_accessed(page); - lock_page(page); - if (!PageSwapCache(page)) { -@@ -1980,6 +1984,8 @@ static int do_anonymous_page(struct mm_s - /* Allocate our own private page. */ - pte_unmap(page_table); - -+ if (!vx_rsspages_avail(mm, 1)) -+ goto oom; - if (unlikely(anon_vma_prepare(vma))) - goto oom; - page = alloc_zeroed_user_highpage(vma, address); -@@ -2058,6 +2064,9 @@ static int do_no_page(struct mm_struct * - smp_rmb(); /* serializes i_size against truncate_count */ - } - retry: -+ /* FIXME: is that check useful here? */ -+ if (!vx_rsspages_avail(mm, 1)) -+ return VM_FAULT_OOM; - new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret); - /* - * No smp_rmb is needed here as long as there's a full -diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index 954981b..6319c51 100644 ---- a/mm/mempolicy.c -+++ b/mm/mempolicy.c -@@ -86,6 +86,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/mm/mlock.c b/mm/mlock.c -index b90c595..6ea2ee0 100644 ---- a/mm/mlock.c -+++ b/mm/mlock.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - - static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev, -@@ -65,7 +66,7 @@ success: - ret = make_pages_present(start, end); - } - -- vma->vm_mm->locked_vm -= pages; -+ vx_vmlocked_sub(vma->vm_mm, pages); - out: - if (ret == -ENOMEM) - ret = -EAGAIN; -@@ -123,7 +124,7 @@ static int do_mlock(unsigned long start, - - asmlinkage long sys_mlock(unsigned long start, size_t len) - { -- unsigned long locked; -+ unsigned long locked, grow; - unsigned long lock_limit; - int error = -ENOMEM; - -@@ -134,8 +135,10 @@ asmlinkage long sys_mlock(unsigned long - len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); - start &= PAGE_MASK; - -- locked = len >> PAGE_SHIFT; -- locked += current->mm->locked_vm; -+ grow = len >> PAGE_SHIFT; -+ if (!vx_vmlocked_avail(current->mm, grow)) -+ goto out; -+ locked = current->mm->locked_vm + grow; - - lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; - lock_limit >>= PAGE_SHIFT; -@@ -143,6 +146,7 @@ asmlinkage long sys_mlock(unsigned long - /* check against resource limits */ - if ((locked <= lock_limit) || capable(CAP_IPC_LOCK)) - error = do_mlock(start, len, 1); -+out: - up_write(¤t->mm->mmap_sem); - return error; - } -@@ -202,6 +206,8 @@ asmlinkage long sys_mlockall(int flags) - lock_limit >>= PAGE_SHIFT; - - ret = -ENOMEM; -+ if (!vx_vmlocked_avail(current->mm, current->mm->total_vm)) -+ goto out; - if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) || - capable(CAP_IPC_LOCK)) - ret = do_mlockall(flags); -diff --git a/mm/mmap.c b/mm/mmap.c -index 47556d2..fe5f116 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -1116,10 +1116,10 @@ munmap_back: - kmem_cache_free(vm_area_cachep, vma); - } - out: -- mm->total_vm += len >> PAGE_SHIFT; -+ vx_vmpages_add(mm, len >> PAGE_SHIFT); - vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); - if (vm_flags & VM_LOCKED) { -- mm->locked_vm += len >> PAGE_SHIFT; -+ vx_vmlocked_add(mm, len >> PAGE_SHIFT); - make_pages_present(addr, addr + len); - } - if (flags & MAP_POPULATE) { -@@ -1479,9 +1479,9 @@ static int acct_stack_growth(struct vm_a - return -ENOMEM; - - /* Ok, everything looks good - let it rip */ -- mm->total_vm += grow; -+ vx_vmpages_add(mm, grow); - if (vma->vm_flags & VM_LOCKED) -- mm->locked_vm += grow; -+ vx_vmlocked_add(mm, grow); - vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow); - return 0; - } -@@ -1634,9 +1634,9 @@ static void remove_vma_list(struct mm_st - do { - long nrpages = vma_pages(vma); - -- mm->total_vm -= nrpages; -+ vx_vmpages_sub(mm, nrpages); - if (vma->vm_flags & VM_LOCKED) -- mm->locked_vm -= nrpages; -+ vx_vmlocked_sub(mm, nrpages); - vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); - vma = remove_vma(vma); - } while (vma); -@@ -1865,6 +1865,8 @@ unsigned long do_brk(unsigned long addr, - lock_limit >>= PAGE_SHIFT; - if (locked > lock_limit && !capable(CAP_IPC_LOCK)) - return -EAGAIN; -+ if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT)) -+ return -ENOMEM; - } - - /* -@@ -1891,7 +1893,8 @@ unsigned long do_brk(unsigned long addr, - if (mm->map_count > sysctl_max_map_count) - return -ENOMEM; - -- if (security_vm_enough_memory(len >> PAGE_SHIFT)) -+ if (security_vm_enough_memory(len >> PAGE_SHIFT) || -+ !vx_vmpages_avail(mm, len >> PAGE_SHIFT)) - return -ENOMEM; - - flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; -@@ -1919,9 +1922,9 @@ unsigned long do_brk(unsigned long addr, - vma->vm_page_prot = protection_map[flags & 0x0f]; - vma_link(mm, vma, prev, rb_link, rb_parent); - out: -- mm->total_vm += len >> PAGE_SHIFT; -+ vx_vmpages_add(mm, len >> PAGE_SHIFT); - if (flags & VM_LOCKED) { -- mm->locked_vm += len >> PAGE_SHIFT; -+ vx_vmlocked_add(mm, len >> PAGE_SHIFT); - make_pages_present(addr, addr + len); - } - return addr; -@@ -1947,6 +1950,11 @@ void exit_mmap(struct mm_struct *mm) - free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0); - tlb_finish_mmu(tlb, 0, end); - -+ set_mm_counter(mm, file_rss, 0); -+ set_mm_counter(mm, anon_rss, 0); -+ vx_vmpages_sub(mm, mm->total_vm); -+ vx_vmlocked_sub(mm, mm->locked_vm); -+ - /* - * Walk the list again, actually closing and freeing it, - * with preemption enabled, without holding any MM locks. -@@ -1986,7 +1994,8 @@ int insert_vm_struct(struct mm_struct * - if (__vma && __vma->vm_start < vma->vm_end) - return -ENOMEM; - if ((vma->vm_flags & VM_ACCOUNT) && -- security_vm_enough_memory(vma_pages(vma))) -+ (security_vm_enough_memory(vma_pages(vma)) || -+ !vx_vmpages_avail(mm, vma_pages(vma)))) - return -ENOMEM; - vma_link(mm, vma, prev, rb_link, rb_parent); - return 0; -@@ -2059,5 +2068,7 @@ int may_expand_vm(struct mm_struct *mm, - - if (cur + npages > lim) - return 0; -+ if (!vx_vmpages_avail(mm, npages)) -+ return 0; - return 1; - } -diff --git a/mm/mremap.c b/mm/mremap.c -index 1903bdf..25a9433 100644 ---- a/mm/mremap.c -+++ b/mm/mremap.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -211,7 +212,7 @@ static unsigned long move_vma(struct vm_ - * If this were a serious issue, we'd add a flag to do_munmap(). - */ - hiwater_vm = mm->hiwater_vm; -- mm->total_vm += new_len >> PAGE_SHIFT; -+ vx_vmpages_add(mm, new_len >> PAGE_SHIFT); - vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT); - - if (do_munmap(mm, old_addr, old_len) < 0) { -@@ -229,7 +230,7 @@ static unsigned long move_vma(struct vm_ - } - - if (vm_flags & VM_LOCKED) { -- mm->locked_vm += new_len >> PAGE_SHIFT; -+ vx_vmlocked_add(mm, new_len >> PAGE_SHIFT); - if (new_len > old_len) - make_pages_present(new_addr + old_len, - new_addr + new_len); -@@ -336,6 +337,9 @@ unsigned long do_mremap(unsigned long ad - ret = -EAGAIN; - if (locked > lock_limit && !capable(CAP_IPC_LOCK)) - goto out; -+ if (!vx_vmlocked_avail(current->mm, -+ (new_len - old_len) >> PAGE_SHIFT)) -+ goto out; - } - if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) { - ret = -ENOMEM; -@@ -364,10 +368,10 @@ unsigned long do_mremap(unsigned long ad - vma_adjust(vma, vma->vm_start, - addr + new_len, vma->vm_pgoff, NULL); - -- mm->total_vm += pages; -+ vx_vmpages_add(mm, pages); - vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages); - if (vma->vm_flags & VM_LOCKED) { -- mm->locked_vm += pages; -+ vx_vmlocked_add(mm, pages); - make_pages_present(addr + old_len, - addr + new_len); - } -diff --git a/mm/nommu.c b/mm/nommu.c -index 4951f47..c61677b 100644 ---- a/mm/nommu.c -+++ b/mm/nommu.c -@@ -820,7 +820,7 @@ unsigned long do_mmap_pgoff(struct file - realalloc += kobjsize(vma); - askedalloc += sizeof(*vma); - -- current->mm->total_vm += len >> PAGE_SHIFT; -+ vx_vmpages_add(current->mm, len >> PAGE_SHIFT); - - add_nommu_vma(vma); - -@@ -937,7 +937,7 @@ int do_munmap(struct mm_struct *mm, unsi - kfree(vml); - - update_hiwater_vm(mm); -- mm->total_vm -= len >> PAGE_SHIFT; -+ vx_vmpages_sub(mm, len >> PAGE_SHIFT); - - #ifdef DEBUG - show_process_blocks(); -@@ -956,7 +956,7 @@ void exit_mmap(struct mm_struct * mm) - printk("Exit_mmap:\n"); - #endif - -- mm->total_vm = 0; -+ vx_vmpages_sub(mm, mm->total_vm); - - while ((tmp = mm->context.vmlist)) { - mm->context.vmlist = tmp->next; -diff --git a/mm/oom_kill.c b/mm/oom_kill.c -index 78747af..f2479c9 100644 ---- a/mm/oom_kill.c -+++ b/mm/oom_kill.c -@@ -55,6 +55,7 @@ unsigned long badness(struct task_struct - * The memory size of the process is the basis for the badness. - */ - points = p->mm->total_vm; -+ /* FIXME: add vserver badness ;) */ - - /* - * Processes which fork a lot of child processes are likely -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index 234bd48..557a64f 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include "internal.h" -@@ -1350,6 +1351,8 @@ void si_meminfo(struct sysinfo *val) - val->freehigh = 0; - #endif - val->mem_unit = PAGE_SIZE; -+ if (vx_flags(VXF_VIRT_MEM, 0)) -+ vx_vsi_meminfo(val); - } - - EXPORT_SYMBOL(si_meminfo); -@@ -1364,6 +1367,8 @@ void si_meminfo_node(struct sysinfo *val - val->totalhigh = pgdat->node_zones[ZONE_HIGHMEM].present_pages; - val->freehigh = pgdat->node_zones[ZONE_HIGHMEM].free_pages; - val->mem_unit = PAGE_SIZE; -+ if (vx_flags(VXF_VIRT_MEM, 0)) -+ vx_vsi_meminfo(val); - } - #endif - -diff --git a/mm/rmap.c b/mm/rmap.c -index 67f0e20..c0da121 100644 ---- a/mm/rmap.c -+++ b/mm/rmap.c -@@ -53,6 +53,7 @@ - #include - #include - #include -+#include - - #include - -diff --git a/mm/shmem.c b/mm/shmem.c -index 7c455fb..d1b4192 100644 ---- a/mm/shmem.c -+++ b/mm/shmem.c -@@ -51,7 +51,6 @@ - #include - - /* This magic number is used in glibc for posix shared memory */ --#define TMPFS_MAGIC 0x01021994 - - #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long)) - #define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE) -@@ -1656,7 +1655,7 @@ static int shmem_statfs(struct super_blo - { - struct shmem_sb_info *sbinfo = SHMEM_SB(sb); - -- buf->f_type = TMPFS_MAGIC; -+ buf->f_type = TMPFS_SUPER_MAGIC; - buf->f_bsize = PAGE_CACHE_SIZE; - buf->f_namelen = NAME_MAX; - spin_lock(&sbinfo->stat_lock); -@@ -2098,7 +2097,7 @@ static int shmem_fill_super(struct super - sb->s_maxbytes = SHMEM_MAX_BYTES; - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; -- sb->s_magic = TMPFS_MAGIC; -+ sb->s_magic = TMPFS_SUPER_MAGIC; - sb->s_op = &shmem_ops; - - inode = shmem_get_inode(sb, S_IFDIR | mode, 0); -diff --git a/mm/swapfile.c b/mm/swapfile.c -index 1f9cf0d..7fab939 100644 ---- a/mm/swapfile.c -+++ b/mm/swapfile.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - DEFINE_SPINLOCK(swap_lock); - unsigned int nr_swapfiles; -@@ -1634,6 +1635,8 @@ void si_swapinfo(struct sysinfo *val) - val->freeswap = nr_swap_pages + nr_to_be_unused; - val->totalswap = total_swap_pages + nr_to_be_unused; - spin_unlock(&swap_lock); -+ if (vx_flags(VXF_VIRT_MEM, 0)) -+ vx_vsi_swapinfo(val); - } - - /* -diff --git a/mm/vmscan.c b/mm/vmscan.c -index 7ccf763..b28865d 100644 ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -1826,7 +1826,7 @@ static int __init kswapd_init(void) - swap_setup(); - for_each_pgdat(pgdat) - pgdat->kswapd -- = find_task_by_pid(kernel_thread(kswapd, pgdat, CLONE_KERNEL)); -+ = find_task_by_real_pid(kernel_thread(kswapd, pgdat, CLONE_KERNEL)); - total_memory = nr_free_pagecache_pages(); - hotcpu_notifier(cpu_callback, 0); - return 0; -diff --git a/net/core/dev.c b/net/core/dev.c -index 2afb0de..407124c 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -114,6 +114,7 @@ - #include /* Note : will define WIRELESS_EXT */ - #include - #endif /* CONFIG_NET_RADIO */ -+#include - #include - - /* -@@ -1848,6 +1849,9 @@ static int dev_ifconf(char __user *arg) - - total = 0; - for (dev = dev_base; dev; dev = dev->next) { -+ if (vx_flags(VXF_HIDE_NETIF, 0) && -+ !dev_in_nx_info(dev, current->nx_info)) -+ continue; - for (i = 0; i < NPROTO; i++) { - if (gifconf_list[i]) { - int done; -@@ -1908,6 +1912,10 @@ void dev_seq_stop(struct seq_file *seq, - - static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev) - { -+ struct nx_info *nxi = current->nx_info; -+ -+ if (vx_flags(VXF_HIDE_NETIF, 0) && !dev_in_nx_info(dev, nxi)) -+ return; - if (dev->get_stats) { - struct net_device_stats *stats = dev->get_stats(dev); - -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index eca2976..8e3a809 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -278,6 +278,9 @@ static int rtnetlink_dump_ifinfo(struct - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { - if (idx < s_idx) - continue; -+ if (vx_info_flags(skb->sk->sk_vx_info, VXF_HIDE_NETIF, 0) && -+ !dev_in_nx_info(dev, skb->sk->sk_nx_info)) -+ continue; - if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, 0, -@@ -451,6 +454,9 @@ void rtmsg_ifinfo(int type, struct net_d - sizeof(struct rtnl_link_ifmap) + - sizeof(struct rtnl_link_stats) + 128); - -+ if (vx_flags(VXF_HIDE_NETIF, 0) && -+ !dev_in_nx_info(dev, current->nx_info)) -+ return; - skb = alloc_skb(size, GFP_KERNEL); - if (!skb) - return; -diff --git a/net/core/sock.c b/net/core/sock.c -index 6e00811..ddb6738 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -125,6 +125,9 @@ - #include - - #include -+#include -+#include -+#include - - #ifdef CONFIG_INET - #include -@@ -660,6 +663,8 @@ struct sock *sk_alloc(int family, gfp_t - sk->sk_prot = sk->sk_prot_creator = prot; - sock_lock_init(sk); - } -+ sock_vx_init(sk); -+ sock_nx_init(sk); - - if (security_sk_alloc(sk, family, priority)) - goto out_free; -@@ -698,6 +703,11 @@ void sk_free(struct sock *sk) - __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); - - security_sk_free(sk); -+ vx_sock_dec(sk); -+ clr_vx_info(&sk->sk_vx_info); -+ sk->sk_xid = -1; -+ clr_nx_info(&sk->sk_nx_info); -+ sk->sk_nid = -1; - if (sk->sk_prot_creator->slab != NULL) - kmem_cache_free(sk->sk_prot_creator->slab, sk); - else -@@ -715,6 +725,8 @@ struct sock *sk_clone(const struct sock - memcpy(newsk, sk, sk->sk_prot->obj_size); - - /* SANITY */ -+ sock_vx_init(newsk); -+ sock_nx_init(newsk); - sk_node_init(&newsk->sk_node); - sock_lock_init(newsk); - bh_lock_sock(newsk); -@@ -755,6 +767,12 @@ struct sock *sk_clone(const struct sock - newsk->sk_priority = 0; - atomic_set(&newsk->sk_refcnt, 2); - -+ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info); -+ newsk->sk_xid = sk->sk_xid; -+ vx_sock_inc(newsk); -+ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info); -+ newsk->sk_nid = sk->sk_nid; -+ - /* - * Increment the counter in the same struct proto as the master - * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that -@@ -1319,6 +1337,11 @@ void sock_init_data(struct socket *sock, - sk->sk_stamp.tv_sec = -1L; - sk->sk_stamp.tv_usec = -1L; - -+ set_vx_info(&sk->sk_vx_info, current->vx_info); -+ sk->sk_xid = vx_current_xid(); -+ vx_sock_inc(sk); -+ set_nx_info(&sk->sk_nx_info, current->nx_info); -+ sk->sk_nid = nx_current_nid(); - atomic_set(&sk->sk_refcnt, 1); - } - -diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index 97c276f..fef25db 100644 ---- a/net/ipv4/af_inet.c -+++ b/net/ipv4/af_inet.c -@@ -114,6 +114,7 @@ - #ifdef CONFIG_IP_MROUTE - #include - #endif -+#include - - DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly; - -@@ -282,9 +283,11 @@ lookup_protocol: - } - - err = -EPERM; -+ if ((protocol == IPPROTO_ICMP) && vx_ccaps(VXC_RAW_ICMP)) -+ goto override; - if (answer->capability > 0 && !capable(answer->capability)) - goto out_rcu_unlock; -- -+override: - sock->ops = answer->ops; - answer_prot = answer->prot; - answer_no_check = answer->no_check; -@@ -401,6 +404,10 @@ int inet_bind(struct socket *sock, struc - unsigned short snum; - int chk_addr_ret; - int err; -+ __u32 s_addr; /* Address used for validation */ -+ __u32 s_addr1; /* Address used for socket */ -+ __u32 s_addr2; /* Broadcast address for the socket */ -+ struct nx_info *nxi = sk->sk_nx_info; - - /* If the socket has its own bind function then use it. (RAW) */ - if (sk->sk_prot->bind) { -@@ -411,7 +418,40 @@ int inet_bind(struct socket *sock, struc - if (addr_len < sizeof(struct sockaddr_in)) - goto out; - -- chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr); -+ s_addr = addr->sin_addr.s_addr; -+ s_addr1 = s_addr; -+ s_addr2 = 0xffffffffl; -+ -+ vxdprintk(VXD_CBIT(net, 3), -+ "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d", -+ sk, sk->sk_nx_info, sk->sk_socket, -+ (sk->sk_socket?sk->sk_socket->flags:0), -+ VXD_QUAD(s_addr)); -+ if (nxi) { -+ __u32 v4_bcast = nxi->v4_bcast; -+ __u32 ipv4root = nxi->ipv4[0]; -+ int nbipv4 = nxi->nbipv4; -+ -+ if (s_addr == 0) { -+ /* bind to any for 1-n */ -+ s_addr = ipv4root; -+ s_addr1 = (nbipv4 > 1) ? 0 : s_addr; -+ s_addr2 = v4_bcast; -+ } else if (s_addr == IPI_LOOPBACK) { -+ /* rewrite localhost to ipv4root */ -+ s_addr = ipv4root; -+ s_addr1 = ipv4root; -+ } else if (s_addr != v4_bcast) { -+ /* normal address bind */ -+ if (!addr_in_nx_info(nxi, s_addr)) -+ return -EADDRNOTAVAIL; -+ } -+ } -+ chk_addr_ret = inet_addr_type(s_addr); -+ -+ vxdprintk(VXD_CBIT(net, 3), -+ "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d", -+ sk, VXD_QUAD(s_addr), VXD_QUAD(s_addr1), VXD_QUAD(s_addr2)); - - /* Not specified by any standard per-se, however it breaks too - * many applications when removed. It is unfortunate since -@@ -423,7 +463,7 @@ int inet_bind(struct socket *sock, struc - err = -EADDRNOTAVAIL; - if (!sysctl_ip_nonlocal_bind && - !inet->freebind && -- addr->sin_addr.s_addr != INADDR_ANY && -+ s_addr != INADDR_ANY && - chk_addr_ret != RTN_LOCAL && - chk_addr_ret != RTN_MULTICAST && - chk_addr_ret != RTN_BROADCAST) -@@ -448,7 +488,8 @@ int inet_bind(struct socket *sock, struc - if (sk->sk_state != TCP_CLOSE || inet->num) - goto out_release_sock; - -- inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; -+ inet->rcv_saddr = inet->saddr = s_addr1; -+ inet->rcv_saddr2 = s_addr2; - if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) - inet->saddr = 0; /* Use device */ - -diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c -index 3ffa60d..ea91fd3 100644 ---- a/net/ipv4/devinet.c -+++ b/net/ipv4/devinet.c -@@ -529,6 +529,33 @@ static __inline__ int inet_abc_len(u32 a - return rc; - } - -+/* -+ Check that a device is not member of the ipv4root assigned to the process -+ Return true if this is the case -+ -+ If the process is not bound to specific IP, then it returns 0 (all -+ interface are fine). -+*/ -+static inline int devinet_notiproot (struct in_ifaddr *ifa) -+{ -+ int ret = 0; -+ struct nx_info *nxi; -+ -+ if ((nxi = current->nx_info)) { -+ int i; -+ int nbip = nxi->nbipv4; -+ __u32 addr = ifa->ifa_local; -+ ret = 1; -+ for (i=0; iipv4[i] == addr) { -+ ret = 0; -+ break; -+ } -+ } -+ } -+ return ret; -+} -+ - - int devinet_ioctl(unsigned int cmd, void __user *arg) - { -@@ -636,6 +663,9 @@ int devinet_ioctl(unsigned int cmd, void - ret = -EADDRNOTAVAIL; - if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) - goto done; -+ if (vx_flags(VXF_HIDE_NETIF, 0) && -+ !ifa_in_nx_info(ifa, current->nx_info)) -+ goto done; - - switch(cmd) { - case SIOCGIFADDR: /* Get interface address */ -@@ -780,6 +810,9 @@ static int inet_gifconf(struct net_devic - goto out; - - for (; ifa; ifa = ifa->ifa_next) { -+ if (vx_flags(VXF_HIDE_NETIF, 0) && -+ !ifa_in_nx_info(ifa, current->nx_info)) -+ continue; - if (!buf) { - done += sizeof(ifr); - continue; -@@ -1091,6 +1124,7 @@ static int inet_dump_ifaddr(struct sk_bu - struct net_device *dev; - struct in_device *in_dev; - struct in_ifaddr *ifa; -+ struct sock *sk = skb->sk; - int s_ip_idx, s_idx = cb->args[0]; - - s_ip_idx = ip_idx = cb->args[1]; -@@ -1108,6 +1142,9 @@ static int inet_dump_ifaddr(struct sk_bu - - for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; - ifa = ifa->ifa_next, ip_idx++) { -+ if (sk && vx_info_flags(sk->sk_vx_info, VXF_HIDE_NETIF, 0) && -+ !ifa_in_nx_info(ifa, sk->sk_nx_info)) -+ continue; - if (ip_idx < s_ip_idx) - continue; - if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, -diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c -index e2890ec..c9b54bb 100644 ---- a/net/ipv4/fib_hash.c -+++ b/net/ipv4/fib_hash.c -@@ -989,6 +989,8 @@ static unsigned fib_flag_trans(int type, - return flags; - } - -+extern int dev_in_nx_info(struct net_device *, struct nx_info *); -+ - /* - * This outputs /proc/net/route. - * -@@ -1019,7 +1021,8 @@ static int fib_seq_show(struct seq_file - prefix = f->fn_key; - mask = FZ_MASK(iter->zone); - flags = fib_flag_trans(fa->fa_type, mask, fi); -- if (fi) -+ if (fi && (!vx_flags(VXF_HIDE_NETIF, 0) || -+ dev_in_nx_info(fi->fib_dev, current->nx_info))) - snprintf(bf, sizeof(bf), - "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u", - fi->fib_dev ? fi->fib_dev->name : "*", prefix, -diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c -index ae20281..a7c37bd 100644 ---- a/net/ipv4/inet_connection_sock.c -+++ b/net/ipv4/inet_connection_sock.c -@@ -40,7 +40,6 @@ int sysctl_local_port_range[2] = { 1024, - int inet_csk_bind_conflict(const struct sock *sk, - const struct inet_bind_bucket *tb) - { -- const u32 sk_rcv_saddr = inet_rcv_saddr(sk); - struct sock *sk2; - struct hlist_node *node; - int reuse = sk->sk_reuse; -@@ -53,9 +52,8 @@ int inet_csk_bind_conflict(const struct - sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { - if (!reuse || !sk2->sk_reuse || - sk2->sk_state == TCP_LISTEN) { -- const u32 sk2_rcv_saddr = inet_rcv_saddr(sk2); -- if (!sk2_rcv_saddr || !sk_rcv_saddr || -- sk2_rcv_saddr == sk_rcv_saddr) -+ if (nx_addr_conflict(sk->sk_nx_info, -+ inet_rcv_saddr(sk), sk2)) - break; - } - } -diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c -index 457db99..03cfe8f 100644 ---- a/net/ipv4/inet_diag.c -+++ b/net/ipv4/inet_diag.c -@@ -694,6 +694,8 @@ static int inet_diag_dump(struct sk_buff - sk_for_each(sk, node, &hashinfo->listening_hash[i]) { - struct inet_sock *inet = inet_sk(sk); - -+ if (!vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) -+ continue; - if (num < s_num) { - num++; - continue; -@@ -754,6 +756,8 @@ skip_listen_ht: - sk_for_each(sk, node, &head->chain) { - struct inet_sock *inet = inet_sk(sk); - -+ if (!vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) -+ continue; - if (num < s_num) - goto next_normal; - if (!(r->idiag_states & (1 << sk->sk_state))) -@@ -778,6 +782,8 @@ next_normal: - inet_twsk_for_each(tw, node, - &hashinfo->ehash[i + hashinfo->ehash_size].chain) { - -+ if (!vx_check(tw->tw_xid, VX_IDENT|VX_WATCH)) -+ continue; - if (num < s_num) - goto next_dying; - if (r->id.idiag_sport != tw->tw_sport && -diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c -index 3322811..d3ec834 100644 ---- a/net/ipv4/inet_hashtables.c -+++ b/net/ipv4/inet_hashtables.c -@@ -143,11 +143,10 @@ struct sock *__inet_lookup_listener(cons - const __u32 rcv_saddr = inet->rcv_saddr; - int score = sk->sk_family == PF_INET ? 1 : 0; - -- if (rcv_saddr) { -- if (rcv_saddr != daddr) -- continue; -+ if (inet_addr_match(sk->sk_nx_info, daddr, rcv_saddr)) - score += 2; -- } -+ else -+ continue; - if (sk->sk_bound_dev_if) { - if (sk->sk_bound_dev_if != dif) - continue; -diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c -index f29a12d..84faac0 100644 ---- a/net/ipv4/raw.c -+++ b/net/ipv4/raw.c -@@ -102,6 +102,27 @@ static void raw_v4_unhash(struct sock *s - write_unlock_bh(&raw_v4_lock); - } - -+ -+/* -+ * Check if a given address matches for a socket -+ * -+ * nxi: the socket's nx_info if any -+ * addr: to be verified address -+ * saddr/baddr: socket addresses -+ */ -+static inline int raw_addr_match ( -+ struct nx_info *nxi, -+ uint32_t addr, -+ uint32_t saddr, -+ uint32_t baddr) -+{ -+ if (addr && (saddr == addr || baddr == addr)) -+ return 1; -+ if (!saddr) -+ return addr_in_nx_info(nxi, addr); -+ return 0; -+} -+ - struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num, - unsigned long raddr, unsigned long laddr, - int dif) -@@ -113,7 +134,8 @@ struct sock *__raw_v4_lookup(struct sock - - if (inet->num == num && - !(inet->daddr && inet->daddr != raddr) && -- !(inet->rcv_saddr && inet->rcv_saddr != laddr) && -+ raw_addr_match(sk->sk_nx_info, laddr, -+ inet->rcv_saddr, inet->rcv_saddr2) && - !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) - goto found; /* gotcha */ - } -@@ -313,6 +335,11 @@ static int raw_send_hdrinc(struct sock * - iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); - } - -+ err = -EPERM; -+ if (!vx_check(0, VX_ADMIN) && !capable(CAP_NET_RAW) -+ && (!addr_in_nx_info(sk->sk_nx_info, iph->saddr))) -+ goto error_free; -+ - err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, - dst_output); - if (err > 0) -@@ -324,6 +351,7 @@ out: - - error_fault: - err = -EFAULT; -+error_free: - kfree_skb(skb); - error: - IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS); -@@ -484,6 +512,12 @@ static int raw_sendmsg(struct kiocb *ioc - if (!inet->hdrincl) - raw_probe_proto_opt(&fl, msg); - -+ if (sk->sk_nx_info) { -+ err = ip_find_src(sk->sk_nx_info, &rt, &fl); -+ -+ if (err) -+ goto done; -+ } - err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); - } - if (err) -@@ -753,7 +787,8 @@ static struct sock *raw_get_first(struct - struct hlist_node *node; - - sk_for_each(sk, node, &raw_v4_htable[state->bucket]) -- if (sk->sk_family == PF_INET) -+ if (sk->sk_family == PF_INET && -+ vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) - goto found; - } - sk = NULL; -@@ -769,7 +804,8 @@ static struct sock *raw_get_next(struct - sk = sk_next(sk); - try_again: - ; -- } while (sk && sk->sk_family != PF_INET); -+ } while (sk && (sk->sk_family != PF_INET || -+ !vx_check(sk->sk_xid, VX_IDENT|VX_WATCH))); - - if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) { - sk = sk_head(&raw_v4_htable[state->bucket]); -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 00aa80e..2d52d50 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -257,6 +257,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index 233bdf2..dd0dbd8 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -77,6 +77,7 @@ - #include - #include - #include -+#include - - int sysctl_tcp_tw_reuse; - int sysctl_tcp_low_latency; -@@ -1350,6 +1351,12 @@ static void *listening_get_next(struct s - req = req->dl_next; - while (1) { - while (req) { -+ vxdprintk(VXD_CBIT(net, 6), -+ "sk,req: %p [#%d] (from %d)", req->sk, -+ (req->sk)?req->sk->sk_xid:0, vx_current_xid()); -+ if (req->sk && -+ !vx_check(req->sk->sk_xid, VX_IDENT|VX_WATCH)) -+ continue; - if (req->rsk_ops->family == st->family) { - cur = req; - goto out; -@@ -1374,6 +1381,10 @@ get_req: - } - get_sk: - sk_for_each_from(sk, node) { -+ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)", -+ sk, sk->sk_xid, vx_current_xid()); -+ if (!vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) -+ continue; - if (sk->sk_family == st->family) { - cur = sk; - goto out; -@@ -1425,18 +1436,26 @@ static void *established_get_first(struc - - read_lock(&tcp_hashinfo.ehash[st->bucket].lock); - sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { -- if (sk->sk_family != st->family) { -+ vxdprintk(VXD_CBIT(net, 6), -+ "sk,egf: %p [#%d] (from %d)", -+ sk, sk->sk_xid, vx_current_xid()); -+ if (!vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) -+ continue; -+ if (sk->sk_family != st->family) - continue; -- } - rc = sk; - goto out; - } - st->state = TCP_SEQ_STATE_TIME_WAIT; - inet_twsk_for_each(tw, node, - &tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain) { -- if (tw->tw_family != st->family) { -+ vxdprintk(VXD_CBIT(net, 6), -+ "tw: %p [#%d] (from %d)", -+ tw, tw->tw_xid, vx_current_xid()); -+ if (!vx_check(tw->tw_xid, VX_IDENT|VX_WATCH)) -+ continue; -+ if (tw->tw_family != st->family) - continue; -- } - rc = tw; - goto out; - } -@@ -1460,7 +1479,8 @@ static void *established_get_next(struct - tw = cur; - tw = tw_next(tw); - get_tw: -- while (tw && tw->tw_family != st->family) { -+ while (tw && (tw->tw_family != st->family || -+ !vx_check(tw->tw_xid, VX_IDENT|VX_WATCH))) { - tw = tw_next(tw); - } - if (tw) { -@@ -1484,6 +1504,11 @@ get_tw: - sk = sk_next(sk); - - sk_for_each_from(sk, node) { -+ vxdprintk(VXD_CBIT(net, 6), -+ "sk,egn: %p [#%d] (from %d)", -+ sk, sk->sk_xid, vx_current_xid()); -+ if (!vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) -+ continue; - if (sk->sk_family == st->family) - goto found; - } -diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c -index 2b9b7f6..0582ec2 100644 ---- a/net/ipv4/tcp_minisocks.c -+++ b/net/ipv4/tcp_minisocks.c -@@ -29,6 +29,10 @@ - #include - #include - -+#include -+#include -+#include -+ - #ifdef CONFIG_SYSCTL - #define SYNC_INIT 0 /* let the user enable it */ - #else -@@ -295,6 +299,11 @@ void tcp_time_wait(struct sock *sk, int - tcptw->tw_ts_recent = tp->rx_opt.ts_recent; - tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp; - -+ tw->tw_xid = sk->sk_xid; -+ tw->tw_vx_info = NULL; -+ tw->tw_nid = sk->sk_nid; -+ tw->tw_nx_info = NULL; -+ - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - if (tw->tw_family == PF_INET6) { - struct ipv6_pinfo *np = inet6_sk(sk); -diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index 0084047..9b2757c 100644 ---- a/net/ipv4/udp.c -+++ b/net/ipv4/udp.c -@@ -176,14 +176,12 @@ gotit: - struct inet_sock *inet2 = inet_sk(sk2); - - if (inet2->num == snum && -- sk2 != sk && -- !ipv6_only_sock(sk2) && -+ sk2 != sk && !ipv6_only_sock(sk2) && - (!sk2->sk_bound_dev_if || - !sk->sk_bound_dev_if || - sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && -- (!inet2->rcv_saddr || -- !inet->rcv_saddr || -- inet2->rcv_saddr == inet->rcv_saddr) && -+ nx_addr_conflict(sk->sk_nx_info, -+ inet_rcv_saddr(sk), sk2) && - (!sk2->sk_reuse || !sk->sk_reuse)) - goto fail; - } -@@ -218,6 +216,17 @@ static void udp_v4_unhash(struct sock *s - write_unlock_bh(&udp_hash_lock); - } - -+static inline int udp_in_list(struct nx_info *nx_info, u32 addr) -+{ -+ int n = nx_info->nbipv4; -+ int i; -+ -+ for (i=0; iipv4[i] == addr) -+ return 1; -+ return 0; -+} -+ - /* UDP is nearly always wildcards out the wazoo, it makes no sense to try - * harder than this. -DaveM - */ -@@ -238,6 +247,11 @@ static struct sock *udp_v4_lookup_longwa - if (inet->rcv_saddr != daddr) - continue; - score+=2; -+ } else if (sk->sk_nx_info) { -+ if (udp_in_list(sk->sk_nx_info, daddr)) -+ score+=2; -+ else -+ continue; - } - if (inet->daddr) { - if (inet->daddr != saddr) -@@ -294,7 +308,8 @@ static inline struct sock *udp_v4_mcast_ - if (inet->num != hnum || - (inet->daddr && inet->daddr != rmt_addr) || - (inet->dport != rmt_port && inet->dport) || -- (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || -+ (inet->rcv_saddr && inet->rcv_saddr != loc_addr && -+ inet->rcv_saddr2 && inet->rcv_saddr2 != loc_addr) || - ipv6_only_sock(s) || - (s->sk_bound_dev_if && s->sk_bound_dev_if != dif)) - continue; -@@ -604,6 +619,15 @@ int udp_sendmsg(struct kiocb *iocb, stru - .uli_u = { .ports = - { .sport = inet->sport, - .dport = dport } } }; -+ struct nx_info *nxi = sk->sk_nx_info; -+ -+ if (nxi) { -+ err = ip_find_src(nxi, &rt, &fl); -+ if (err) -+ goto out; -+ if (daddr == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) -+ daddr = fl.fl4_dst = nxi->ipv4[0]; -+ } - err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); - if (err) - goto out; -@@ -1370,8 +1394,10 @@ static struct sock *udp_get_first(struct - - for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) { - struct hlist_node *node; -+ - sk_for_each(sk, node, &udp_hash[state->bucket]) { -- if (sk->sk_family == state->family) -+ if (sk->sk_family == state->family && -+ vx_check(sk->sk_xid, VX_IDENT|VX_WATCH)) - goto found; - } - } -@@ -1388,7 +1414,8 @@ static struct sock *udp_get_next(struct - sk = sk_next(sk); - try_again: - ; -- } while (sk && sk->sk_family != state->family); -+ } while (sk && (sk->sk_family != state->family || -+ !vx_check(sk->sk_xid, VX_IDENT|VX_WATCH))); - - if (!sk && ++state->bucket < UDP_HTABLE_SIZE) { - sk = sk_head(&udp_hash[state->bucket]); -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index b7d8822..d4ef097 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -2646,7 +2646,10 @@ static void if6_seq_stop(struct seq_file - static int if6_seq_show(struct seq_file *seq, void *v) - { - struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v; -- seq_printf(seq, -+ -+ /* no ipv6 inside a vserver for now */ -+ if (vx_check(0, VX_ADMIN|VX_WATCH)) -+ seq_printf(seq, - NIP6_SEQFMT " %02x %02x %02x %02x %8s\n", - NIP6(ifp->addr), - ifp->idev->dev->ifindex, -@@ -3002,6 +3005,10 @@ static int inet6_dump_addr(struct sk_buf - struct ifmcaddr6 *ifmca; - struct ifacaddr6 *ifaca; - -+ /* no ipv6 inside a vserver for now */ -+ if (skb->sk && skb->sk->sk_vx_info) -+ return skb->len; -+ - s_idx = cb->args[0]; - s_ip_idx = ip_idx = cb->args[1]; - read_lock(&dev_base_lock); -@@ -3207,6 +3214,10 @@ static int inet6_dump_ifinfo(struct sk_b - struct net_device *dev; - struct inet6_dev *idev; - -+ /* no ipv6 inside a vserver for now */ -+ if (skb->sk && skb->sk->sk_vx_info) -+ return skb->len; -+ - read_lock(&dev_base_lock); - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { - if (idx < s_idx) -diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c -index 6b9772d..2f8b8f2 100644 ---- a/net/netlink/af_netlink.c -+++ b/net/netlink/af_netlink.c -@@ -56,6 +56,9 @@ - #include - #include - #include -+#include -+#include -+#include - - #include - #include -diff --git a/net/socket.c b/net/socket.c -index a00851f..a942fe6 100644 ---- a/net/socket.c -+++ b/net/socket.c -@@ -96,6 +96,7 @@ - - #include - #include -+#include - - static int sock_no_open(struct inode *irrelevant, struct file *dontcare); - static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf, -@@ -536,7 +537,7 @@ static inline int __sock_sendmsg(struct - struct msghdr *msg, size_t size) - { - struct sock_iocb *si = kiocb_to_siocb(iocb); -- int err; -+ int err, len; - - si->sock = sock; - si->scm = NULL; -@@ -547,7 +548,21 @@ static inline int __sock_sendmsg(struct - if (err) - return err; - -- return sock->ops->sendmsg(iocb, sock, msg, size); -+ len = sock->ops->sendmsg(iocb, sock, msg, size); -+ if (sock->sk) { -+ if (len == size) -+ vx_sock_send(sock->sk, size); -+ else -+ vx_sock_fail(sock->sk, size); -+ } -+ vxdprintk(VXD_CBIT(net, 7), -+ "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d", -+ sock, sock->sk, -+ (sock->sk)?sock->sk->sk_nx_info:0, -+ (sock->sk)?sock->sk->sk_vx_info:0, -+ (sock->sk)?sock->sk->sk_xid:0, -+ (unsigned int)size, len); -+ return len; - } - - int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) -@@ -585,7 +600,7 @@ int kernel_sendmsg(struct socket *sock, - static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t size, int flags) - { -- int err; -+ int err, len; - struct sock_iocb *si = kiocb_to_siocb(iocb); - - si->sock = sock; -@@ -598,7 +613,17 @@ static inline int __sock_recvmsg(struct - if (err) - return err; - -- return sock->ops->recvmsg(iocb, sock, msg, size, flags); -+ len = sock->ops->recvmsg(iocb, sock, msg, size, flags); -+ if ((len >= 0) && sock->sk) -+ vx_sock_recv(sock->sk, len); -+ vxdprintk(VXD_CBIT(net, 7), -+ "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d", -+ sock, sock->sk, -+ (sock->sk)?sock->sk->sk_nx_info:0, -+ (sock->sk)?sock->sk->sk_vx_info:0, -+ (sock->sk)?sock->sk->sk_xid:0, -+ (unsigned int)size, len); -+ return len; - } - - int sock_recvmsg(struct socket *sock, struct msghdr *msg, -@@ -1088,6 +1113,10 @@ static int __sock_create(int family, int - if (type < 0 || type >= SOCK_MAX) - return -EINVAL; - -+ /* disable IPv6 inside vservers for now */ -+ if (family == PF_INET6 && !vx_check(0, VX_ADMIN)) -+ return -EAFNOSUPPORT; -+ - /* Compatibility. - - This uglymoron is moved from INET layer to here to avoid -@@ -1198,6 +1227,7 @@ asmlinkage long sys_socket(int family, i - if (retval < 0) - goto out; - -+ set_bit(SOCK_USER_SOCKET, &sock->flags); - retval = sock_map_fd(sock); - if (retval < 0) - goto out_release; -@@ -1228,10 +1258,12 @@ asmlinkage long sys_socketpair(int famil - err = sock_create(family, type, protocol, &sock1); - if (err < 0) - goto out; -+ set_bit(SOCK_USER_SOCKET, &sock1->flags); - - err = sock_create(family, type, protocol, &sock2); - if (err < 0) - goto out_release_1; -+ set_bit(SOCK_USER_SOCKET, &sock2->flags); - - err = sock1->ops->socketpair(sock1, sock2); - if (err < 0) -diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c -index 8d6f1a1..9c893ef 100644 ---- a/net/sunrpc/auth.c -+++ b/net/sunrpc/auth.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - #ifdef RPC_DEBUG - # define RPCDBG_FACILITY RPCDBG_AUTH -@@ -251,6 +252,7 @@ rpcauth_lookupcred(struct rpc_auth *auth - struct auth_cred acred = { - .uid = current->fsuid, - .gid = current->fsgid, -+ .xid = vx_current_xid(), - .group_info = current->group_info, - }; - struct rpc_cred *ret; -@@ -270,6 +272,7 @@ rpcauth_bindcred(struct rpc_task *task) - struct auth_cred acred = { - .uid = current->fsuid, - .gid = current->fsgid, -+ .xid = vx_current_xid(), - .group_info = current->group_info, - }; - struct rpc_cred *ret; -diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c -index df14b6b..4f2ad4f 100644 ---- a/net/sunrpc/auth_unix.c -+++ b/net/sunrpc/auth_unix.c -@@ -11,12 +11,14 @@ - #include - #include - #include -+#include - - #define NFS_NGROUPS 16 - - struct unx_cred { - struct rpc_cred uc_base; - gid_t uc_gid; -+ xid_t uc_xid; - gid_t uc_gids[NFS_NGROUPS]; - }; - #define uc_uid uc_base.cr_uid -@@ -78,6 +80,7 @@ unx_create_cred(struct rpc_auth *auth, s - if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { - cred->uc_uid = 0; - cred->uc_gid = 0; -+ cred->uc_xid = vx_current_xid(); - cred->uc_gids[0] = NOGROUP; - } else { - int groups = acred->group_info->ngroups; -@@ -86,6 +89,7 @@ unx_create_cred(struct rpc_auth *auth, s - - cred->uc_uid = acred->uid; - cred->uc_gid = acred->gid; -+ cred->uc_xid = acred->xid; - for (i = 0; i < groups; i++) - cred->uc_gids[i] = GROUP_AT(acred->group_info, i); - if (i < NFS_NGROUPS) -@@ -117,7 +121,8 @@ unx_match(struct auth_cred *acred, struc - int groups; - - if (cred->uc_uid != acred->uid -- || cred->uc_gid != acred->gid) -+ || cred->uc_gid != acred->gid -+ || cred->uc_xid != acred->xid) - return 0; - - groups = acred->group_info->ngroups; -@@ -143,7 +148,7 @@ unx_marshal(struct rpc_task *task, u32 * - struct rpc_clnt *clnt = task->tk_client; - struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred; - u32 *base, *hold; -- int i; -+ int i, tagxid; - - *p++ = htonl(RPC_AUTH_UNIX); - base = p++; -@@ -153,9 +158,12 @@ unx_marshal(struct rpc_task *task, u32 * - * Copy the UTS nodename captured when the client was created. - */ - p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); -+ tagxid = task->tk_client->cl_tagxid; - -- *p++ = htonl((u32) cred->uc_uid); -- *p++ = htonl((u32) cred->uc_gid); -+ *p++ = htonl((u32) XIDINO_UID(tagxid, -+ cred->uc_uid, cred->uc_xid)); -+ *p++ = htonl((u32) XIDINO_GID(tagxid, -+ cred->uc_gid, cred->uc_xid)); - hold = p++; - for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++) - *p++ = htonl((u32) cred->uc_gids[i]); -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index c323cc6..7020c57 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -117,6 +117,9 @@ - #include - #include - #include -+#include -+#include -+#include - - int sysctl_unix_max_dgram_qlen = 10; - -@@ -235,6 +238,8 @@ static struct sock *__unix_find_socket_b - sk_for_each(s, node, &unix_socket_table[hash ^ type]) { - struct unix_sock *u = unix_sk(s); - -+ if (!vx_check(s->sk_xid, VX_IDENT|VX_WATCH)) -+ continue; - if (u->addr->len == len && - !memcmp(u->addr->name, sunname, len)) - goto found; -@@ -781,7 +786,7 @@ static int unix_bind(struct socket *sock - */ - mode = S_IFSOCK | - (SOCK_INODE(sock)->i_mode & ~current->fs->umask); -- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); -+ err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL); - if (err) - goto out_mknod_dput; - mutex_unlock(&nd.dentry->d_inode->i_mutex); -diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c -index 72b6ff3..3da1bd9 100644 ---- a/net/x25/af_x25.c -+++ b/net/x25/af_x25.c -@@ -491,7 +491,10 @@ static int x25_create(struct socket *soc - - x25 = x25_sk(sk); - -- sock_init_data(sock, sk); -+ sk->sk_socket = sock; -+ sk->sk_type = sock->type; -+ sk->sk_sleep = &sock->wait; -+ sock->sk = sk; - - x25_init_timers(sk); - -diff --git a/security/commoncap.c b/security/commoncap.c -index 8a6e097..403e104 100644 ---- a/security/commoncap.c -+++ b/security/commoncap.c -@@ -143,7 +143,7 @@ void cap_bprm_apply_creds (struct linux_ - /* Derived from fs/exec.c:compute_creds. */ - kernel_cap_t new_permitted, working; - -- new_permitted = cap_intersect (bprm->cap_permitted, cap_bset); -+ new_permitted = cap_intersect (bprm->cap_permitted, vx_current_bcaps()); - working = cap_intersect (bprm->cap_inheritable, - current->cap_inheritable); - new_permitted = cap_combine (new_permitted, working); -@@ -312,7 +312,8 @@ void cap_task_reparent_to_init (struct t - - int cap_syslog (int type) - { -- if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN)) -+ if ((type != 3 && type != 10) && -+ !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SYSLOG)) - return -EPERM; - return 0; - } -diff --git a/security/security.c b/security/security.c -index f693e1f..8bbe110 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -186,6 +186,8 @@ int mod_unreg_security(const char *name, - */ - int capable(int cap) - { -+ if (vx_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap)) -+ return 0; - if (security_ops->capable(current, cap)) { - /* capability denied */ - return 0; -@@ -196,9 +198,24 @@ int capable(int cap) - return 1; - } - -+int vx_capable(int cap, int ccap) -+{ -+ if (security_ops->capable(current, cap)) { -+ /* capability denied */ -+ return 0; -+ } -+ if (!vx_ccaps(ccap)) -+ return 0; -+ -+ /* capability granted */ -+ current->flags |= PF_SUPERPRIV; -+ return 1; -+} -+ - EXPORT_SYMBOL_GPL(register_security); - EXPORT_SYMBOL_GPL(unregister_security); - EXPORT_SYMBOL_GPL(mod_reg_security); - EXPORT_SYMBOL_GPL(mod_unreg_security); - EXPORT_SYMBOL(capable); -+EXPORT_SYMBOL(vx_capable); - EXPORT_SYMBOL(security_ops); diff --git a/debian/patches/vserver-vs2.0.2-rc14-update.patch b/debian/patches/vserver-vs2.0.2-rc14-update.patch deleted file mode 100644 index 67996859b..000000000 --- a/debian/patches/vserver-vs2.0.2-rc14-update.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- linux-2.6.16-vs2.0.2-rc13/fs/ioprio.c 2006-03-20 17:34:49 +0100 -+++ linux-2.6.16-vs2.0.2-rc14/fs/ioprio.c 2006-03-23 19:35:17 +0100 -@@ -96,7 +96,7 @@ - if (!who) - user = current->user; - else -- user = find_user(who, vx_current_xid()); -+ user = find_user(vx_current_xid(), who); - - if (!user) - break; -@@ -150,7 +150,7 @@ - if (!who) - user = current->user; - else -- user = find_user(who, vx_current_xid()); -+ user = find_user(vx_current_xid(), who); - - if (!user) - break; ---- linux-2.6.16-vs2.0.2-rc13/fs/read_write.c 2006-03-20 17:34:49 +0100 -+++ linux-2.6.16/fs/read_write.c 2006-03-20 17:33:14 +0100 -@@ -667,8 +667,9 @@ - if (!(in_file->f_mode & FMODE_PREAD)) - goto fput_in; - retval = rw_verify_area(READ, in_file, ppos, count); -+ if (retval < 0) -- if (retval) - goto fput_in; -+ count = retval; - - retval = security_file_permission (in_file, MAY_READ); - if (retval) -@@ -688,8 +689,9 @@ - goto fput_out; - out_inode = out_file->f_dentry->d_inode; - retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); -+ if (retval < 0) -- if (retval) - goto fput_out; -+ count = retval; - - retval = security_file_permission (out_file, MAY_WRITE); - if (retval) diff --git a/debian/patches/vserver-vs2.0.2-rc15-update.patch b/debian/patches/vserver-vs2.0.2-rc15-update.patch deleted file mode 100644 index 8765c3746..000000000 --- a/debian/patches/vserver-vs2.0.2-rc15-update.patch +++ /dev/null @@ -1,679 +0,0 @@ -diff -u linux-2.6.16-vs2.0.2-rc14/drivers/block/vroot.c linux-2.6.16-vs2.0.2-rc15/drivers/block/vroot.c ---- linux-2.6.16-vs2.0.2-rc14/drivers/block/vroot.c 2006-03-20 17:34:49 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/drivers/block/vroot.c 2006-03-24 16:50:44 +0100 -@@ -12,7 +12,6 @@ - * - */ - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vs_context.h linux-2.6.16-vs2.0.2-rc15/include/linux/vs_context.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vs_context.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vs_context.h 2006-04-03 05:31:18 +0200 -@@ -170,7 +170,7 @@ - wake_up_interruptible(&vxi->vx_wait); - } - --extern void exit_vx_info(struct task_struct *); -+extern void exit_vx_info(struct task_struct *, int); - - static inline - struct task_struct *vx_child_reaper(struct task_struct *p) -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vs_memory.h linux-2.6.16-vs2.0.2-rc15/include/linux/vs_memory.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vs_memory.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vs_memory.h 2006-03-24 16:50:44 +0100 -@@ -1,7 +1,6 @@ - #ifndef _VX_VS_MEMORY_H - #define _VX_VS_MEMORY_H - --#include - #include "vserver/limit.h" - #include "vserver/debug.h" - #include "vserver/limit_int.h" -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vs_sched.h linux-2.6.16-vs2.0.2-rc15/include/linux/vs_sched.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vs_sched.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vs_sched.h 2006-03-24 16:50:44 +0100 -@@ -1,7 +1,6 @@ - #ifndef _VX_VS_SCHED_H - #define _VX_VS_SCHED_H - --#include - #include "vserver/sched.h" - - -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/context.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/context.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/context.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/context.h 2006-04-03 05:31:18 +0200 -@@ -1,7 +1,6 @@ - #ifndef _VX_CONTEXT_H - #define _VX_CONTEXT_H - --#include - #include - - -@@ -111,13 +110,15 @@ - struct task_struct *vx_reaper; /* guest reaper process */ - pid_t vx_initpid; /* PID of guest init */ - -- wait_queue_head_t vx_wait; /* context exit waitqueue */ -- - struct _vx_limit limit; /* vserver limits */ - struct _vx_sched sched; /* vserver scheduler */ - struct _vx_cvirt cvirt; /* virtual/bias stuff */ - struct _vx_cacct cacct; /* context accounting */ - -+ wait_queue_head_t vx_wait; /* context exit waitqueue */ -+ int reboot_cmd; /* last sys_reboot() cmd */ -+ int exit_code; /* last process exit code */ -+ - char vx_name[65]; /* vserver name */ - }; - -@@ -128,6 +129,7 @@ - #define VXS_PAUSED 0x0010 - #define VXS_ONHOLD 0x0020 - #define VXS_SHUTDOWN 0x0100 -+#define VXS_HELPER 0x1000 - #define VXS_RELEASED 0x8000 - - /* check conditions */ -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/cvirt_def.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/cvirt_def.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/cvirt_def.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/cvirt_def.h 2006-03-24 16:50:44 +0100 -@@ -1,7 +1,6 @@ - #ifndef _VX_CVIRT_DEF_H - #define _VX_CVIRT_DEF_H - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/debug.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/debug.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/debug.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/debug.h 2006-03-24 16:50:44 +0100 -@@ -1,8 +1,6 @@ - #ifndef _VX_DEBUG_H - #define _VX_DEBUG_H - --#include -- - - #define VXD_CBIT(n,m) (vx_debug_ ## n & (1 << (m))) - #define VXD_CMIN(n,m) (vx_debug_ ## n > (m)) -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/dlimit_cmd.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/dlimit_cmd.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/dlimit_cmd.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/dlimit_cmd.h 2006-03-24 16:50:44 +0100 -@@ -1,8 +1,6 @@ - #ifndef _VX_DLIMIT_CMD_H - #define _VX_DLIMIT_CMD_H - --#include -- - - /* dlimit vserver commands */ - -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/inode.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/inode.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/inode.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/inode.h 2006-03-24 16:50:44 +0100 -@@ -15,8 +15,6 @@ - - #ifdef __KERNEL__ - --#include -- - - #ifdef CONFIG_VSERVER_PROC_SECURE - #define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE ) -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/inode_cmd.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/inode_cmd.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/inode_cmd.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/inode_cmd.h 2006-03-24 16:50:44 +0100 -@@ -28,8 +28,6 @@ - - #ifdef __KERNEL__ - --#include -- - - #ifdef CONFIG_COMPAT - -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/limit_cmd.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/limit_cmd.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/limit_cmd.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/limit_cmd.h 2006-04-03 02:37:59 +0200 -@@ -28,10 +28,28 @@ - #ifdef __KERNEL__ - -+#ifdef CONFIG_IA32_EMULATION -+ -+struct vcmd_ctx_rlimit_v0_x32 { -+ uint32_t id; -+ uint64_t minimum; -+ uint64_t softlimit; -+ uint64_t maximum; -+} __attribute__ ((aligned (4))); -+ -+#endif /* CONFIG_IA32_EMULATION */ -+ - #include - - extern int vc_get_rlimit(uint32_t, void __user *); - extern int vc_set_rlimit(uint32_t, void __user *); - extern int vc_get_rlimit_mask(uint32_t, void __user *); - -+#ifdef CONFIG_IA32_EMULATION -+ -+extern int vc_get_rlimit_x32(uint32_t, void __user *); -+extern int vc_set_rlimit_x32(uint32_t, void __user *); -+ -+#endif /* CONFIG_IA32_EMULATION */ -+ - #endif /* __KERNEL__ */ - #endif /* _VX_LIMIT_CMD_H */ -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/limit_def.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/limit_def.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/limit_def.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/limit_def.h 2006-03-24 16:50:44 +0100 -@@ -1,7 +1,6 @@ - #ifndef _VX_LIMIT_DEF_H - #define _VX_LIMIT_DEF_H - --#include - #include - #include - -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/sched_def.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/sched_def.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/sched_def.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/sched_def.h 2006-03-24 16:50:44 +0100 -@@ -1,7 +1,6 @@ - #ifndef _VX_SCHED_DEF_H - #define _VX_SCHED_DEF_H - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/signal_cmd.h linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/signal_cmd.h ---- linux-2.6.16-vs2.0.2-rc14/include/linux/vserver/signal_cmd.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/include/linux/vserver/signal_cmd.h 2006-04-03 05:31:18 +0200 -@@ -13,8 +13,8 @@ - }; - - struct vcmd_wait_exit_v0 { -- int32_t a; -- int32_t b; -+ int32_t reboot_cmd; -+ int32_t exit_code; - }; - - #ifdef __KERNEL__ -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/exit.c linux-2.6.16-vs2.0.2-rc15/kernel/exit.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/exit.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/exit.c 2006-04-03 05:31:18 +0200 -@@ -869,7 +869,7 @@ - __exit_files(tsk); - __exit_fs(tsk); - exit_namespace(tsk); -- exit_vx_info(tsk); -+ exit_vx_info(tsk, code); - exit_nx_info(tsk); - exit_thread(); - cpuset_exit(tsk); -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/Kconfig linux-2.6.16-vs2.0.2-rc15/kernel/vserver/Kconfig ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/Kconfig 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/Kconfig 2006-03-24 16:50:44 +0100 -@@ -2,21 +2,6 @@ - # Linux VServer configuration - # - --config VSERVER -- bool -- default y -- --config VSERVER_SECURITY -- bool -- depends on SECURITY -- default y -- select SECURITY_CAPABILITIES -- --config VSERVER_LEGACYNET -- bool -- depends on !VSERVER_NGNET -- default y -- - menu "Linux VServer" - - config VSERVER_LEGACY -@@ -179,0 +165,16 @@ -+ -+config VSERVER -+ bool -+ default y -+ -+config VSERVER_SECURITY -+ bool -+ depends on SECURITY -+ default y -+ select SECURITY_CAPABILITIES -+ -+config VSERVER_LEGACYNET -+ bool -+ depends on !VSERVER_NGNET -+ default y -+ -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/context.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/context.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/context.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/context.c 2006-04-03 05:31:18 +0200 -@@ -19,7 +19,6 @@ - * - */ - --#include - #include - #include - #include -@@ -82,6 +81,9 @@ - new->vx_bcaps = CAP_INIT_EFF_SET; - new->vx_ccaps = 0; - -+ new->reboot_cmd = 0; -+ new->exit_code = 0; -+ - vxdprintk(VXD_CBIT(xid, 0), - "alloc_vx_info(%d) = %p", xid, new); - vxh_alloc_vx_info(new); -@@ -617,12 +619,13 @@ - return 0; - } - --void vx_exit_init(struct vx_info *vxi, struct task_struct *p) -+void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code) - { - vxdprintk(VXD_CBIT(xid, 6), - "vx_exit_init(%p[#%d],%p[#%d,%d,%d])", - vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid); - -+ vxi->exit_code = code; - vxi->vx_initpid = 0; - } - -@@ -643,7 +646,7 @@ - - /* task must be current or locked */ - --void exit_vx_info(struct task_struct *p) -+void exit_vx_info(struct task_struct *p, int code) - { - struct vx_info *vxi = p->vx_info; - -@@ -651,8 +654,9 @@ - atomic_dec(&vxi->cvirt.nr_threads); - vx_nproc_dec(p); - -+ vxi->exit_code = code; - if (vxi->vx_initpid == p->tgid) -- vx_exit_init(vxi, p); -+ vx_exit_init(vxi, p, code); - if (vxi->vx_reaper == p) - vx_set_reaper(vxi, child_reaper); - release_vx_info(vxi, p); -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/cvirt_init.h linux-2.6.16-vs2.0.2-rc15/kernel/vserver/cvirt_init.h ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/cvirt_init.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/cvirt_init.h 2006-03-24 16:50:48 +0100 -@@ -1,6 +1,4 @@ - --#include -- - - #include - -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/dlimit.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/dlimit.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/dlimit.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/dlimit.c 2006-03-24 16:50:48 +0100 -@@ -10,7 +10,6 @@ - * - */ - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/helper.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/helper.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/helper.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/helper.c 2006-04-03 05:30:52 +0200 -@@ -9,7 +9,6 @@ - * - */ - --#include - #include - #include - #include -@@ -64,6 +63,10 @@ - "PATH=/sbin:/usr/sbin:/bin:/usr/bin", - uid_buf, pid_buf, cmd_buf, 0}; - -+ if (vx_info_state(vxi, VXS_HELPER)) -+ return -EAGAIN; -+ vxi->vx_state |= VXS_HELPER; -+ - snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id); - - snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd); -@@ -88,6 +91,7 @@ - break; - - default: -+ vxi->vx_state &= ~VXS_HELPER; - return 0; - } - -@@ -96,6 +100,8 @@ - #else - ret = do_vshelper(vshelper_path, argv, envp, 0); - #endif -+ vxi->vx_state &= ~VXS_HELPER; -+ __wakeup_vx_info(vxi); - return (ret) ? -EPERM : 0; - } - -@@ -108,6 +114,12 @@ - vxdprintk(VXD_CBIT(misc, 5), - "vs_reboot(%p[#%d],%d)", - vxi, vxi?vxi->vx_id:0, cmd); -+ -+ ret = vs_reboot_helper(vxi, cmd, arg); -+ if (ret) -+ return ret; -+ -+ vxi->reboot_cmd = cmd; - if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) { - switch (cmd) { - case LINUX_REBOOT_CMD_RESTART: -@@ -118,10 +130,8 @@ - default: - break; - } -- } else { -- ret = vs_reboot_helper(vxi, cmd, arg); - } -- return ret; -+ return 0; - } - - -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/history.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/history.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/history.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/history.c 2006-03-24 16:50:48 +0100 -@@ -11,7 +11,6 @@ - * - */ - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/init.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/init.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/init.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/init.c 2006-03-24 16:50:44 +0100 -@@ -9,7 +9,6 @@ - * - */ - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/inode.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/inode.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/inode.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/inode.c 2006-03-24 16:50:48 +0100 -@@ -9,7 +9,6 @@ - * - */ - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/limit.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/limit.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/limit.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/limit.c 2006-04-03 01:43:40 +0200 -@@ -71,53 +71,114 @@ - return limit; - } - --int vc_get_rlimit(uint32_t id, void __user *data) -+int do_get_rlimit(xid_t xid, uint32_t id, -+ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum) - { - struct vx_info *vxi; -- struct vcmd_ctx_rlimit_v0 vc_data; - -- if (copy_from_user (&vc_data, data, sizeof(vc_data))) -- return -EFAULT; -- if (!is_valid_rlimit(vc_data.id)) -+ if (!is_valid_rlimit(id)) - return -EINVAL; - -- vxi = lookup_vx_info(id); -+ vxi = lookup_vx_info(xid); - if (!vxi) - return -ESRCH; - -- vc_data.maximum = vc_get_rlim(vxi, vc_data.id); -- vc_data.minimum = CRLIM_UNSET; -- vc_data.softlimit = CRLIM_UNSET; -+ if (minimum) -+ *minimum = CRLIM_UNSET; -+ if (softlimit) -+ *softlimit = CRLIM_UNSET; -+ if (maximum) -+ *maximum = vc_get_rlim(vxi, id); - put_vx_info(vxi); -+ return 0; -+} -+ -+int vc_get_rlimit(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_rlimit_v0 vc_data; -+ int ret; -+ -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ ret = do_get_rlimit(id, vc_data.id, -+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); -+ if (ret) -+ return ret; - - if (copy_to_user (data, &vc_data, sizeof(vc_data))) - return -EFAULT; - return 0; - } - --int vc_set_rlimit(uint32_t id, void __user *data) -+int do_set_rlimit(xid_t xid, uint32_t id, -+ uint64_t minimum, uint64_t softlimit, uint64_t maximum) - { - struct vx_info *vxi; -+ -+ if (!is_valid_rlimit(id)) -+ return -EINVAL; -+ -+ vxi = lookup_vx_info(xid); -+ if (!vxi) -+ return -ESRCH; -+ -+ if (maximum != CRLIM_KEEP) -+ vxi->limit.rlim[id] = maximum; -+ -+ put_vx_info(vxi); -+ return 0; -+} -+ -+int vc_set_rlimit(uint32_t id, void __user *data) -+{ - struct vcmd_ctx_rlimit_v0 vc_data; - - if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) - return -EPERM; - if (copy_from_user (&vc_data, data, sizeof(vc_data))) - return -EFAULT; -- if (!is_valid_rlimit(vc_data.id)) -- return -EINVAL; - -- vxi = lookup_vx_info(id); -- if (!vxi) -- return -ESRCH; -+ return do_set_rlimit(id, vc_data.id, -+ vc_data.minimum, vc_data.softlimit, vc_data.maximum); -+} - -- if (vc_data.maximum != CRLIM_KEEP) -- vxi->limit.rlim[vc_data.id] = vc_data.maximum; -- put_vx_info(vxi); -+#ifdef CONFIG_IA32_EMULATION -+ -+int vc_set_rlimit_x32(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_rlimit_v0_x32 vc_data; -+ -+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) -+ return -EPERM; -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ return do_set_rlimit(id, vc_data.id, -+ vc_data.minimum, vc_data.softlimit, vc_data.maximum); -+} - -+int vc_get_rlimit_x32(uint32_t id, void __user *data) -+{ -+ struct vcmd_ctx_rlimit_v0_x32 vc_data; -+ int ret; -+ -+ if (copy_from_user (&vc_data, data, sizeof(vc_data))) -+ return -EFAULT; -+ -+ ret = do_get_rlimit(id, vc_data.id, -+ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); -+ if (ret) -+ return ret; -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ return -EFAULT; - return 0; - } - -+#endif /* CONFIG_IA32_EMULATION */ -+ -+ - int vc_get_rlimit_mask(uint32_t id, void __user *data) - { - static struct vcmd_ctx_rlimit_mask_v0 mask = { -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/limit_init.h linux-2.6.16-vs2.0.2-rc15/kernel/vserver/limit_init.h ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/limit_init.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/limit_init.h 2006-03-24 16:50:48 +0100 -@@ -1,6 +1,4 @@ - --#include -- - - #include - -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/network.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/network.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/network.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/network.c 2006-03-24 16:50:48 +0100 -@@ -13,7 +13,6 @@ - * - */ - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/sched.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/sched.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/sched.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/sched.c 2006-03-24 16:50:48 +0100 -@@ -10,7 +10,6 @@ - * - */ - --#include - #include - #include - #include -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/signal.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/signal.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/signal.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/signal.c 2006-04-03 05:31:18 +0200 -@@ -99,7 +99,8 @@ - set_current_state(TASK_INTERRUPTIBLE); - - wait: -- if (vx_info_state(vxi, VXS_SHUTDOWN|VXS_HASHED) == VXS_SHUTDOWN) -+ if (vx_info_state(vxi, -+ VXS_SHUTDOWN|VXS_HASHED|VXS_HELPER) == VXS_SHUTDOWN) - goto out; - if (signal_pending(current)) { - ret = -ERESTARTSYS; -@@ -119,6 +120,7 @@ - int vc_wait_exit(uint32_t id, void __user *data) - { - struct vx_info *vxi; -+ struct vcmd_wait_exit_v0 vc_data; - int ret; - - vxi = lookup_vx_info(id); -@@ -126,7 +128,12 @@ - return -ESRCH; - - ret = __wait_exit(vxi); -+ vc_data.reboot_cmd = vxi->reboot_cmd; -+ vc_data.exit_code = vxi->exit_code; - put_vx_info(vxi); -+ -+ if (copy_to_user (data, &vc_data, sizeof(vc_data))) -+ ret = -EFAULT; - return ret; - } - -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/switch.c linux-2.6.16-vs2.0.2-rc15/kernel/vserver/switch.c ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/switch.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/switch.c 2006-04-03 02:38:01 +0200 -@@ -14,7 +14,6 @@ - * - */ - --#include - #include - #include - #include -@@ -131,10 +130,17 @@ - #endif - - switch (cmd) { -+#ifdef CONFIG_IA32_EMULATION -+ case VCMD_get_rlimit: -+ return __COMPAT(vc_get_rlimit, id, data, compat); -+ case VCMD_set_rlimit: -+ return __COMPAT(vc_set_rlimit, id, data, compat); -+#else - case VCMD_get_rlimit: - return vc_get_rlimit(id, data); - case VCMD_set_rlimit: - return vc_set_rlimit(id, data); -+#endif - case VCMD_get_rlimit_mask: - return vc_get_rlimit_mask(id, data); - -diff -u linux-2.6.16-vs2.0.2-rc14/kernel/vserver/vci_config.h linux-2.6.16-vs2.0.2-rc15/kernel/vserver/vci_config.h ---- linux-2.6.16-vs2.0.2-rc14/kernel/vserver/vci_config.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16-vs2.0.2-rc15/kernel/vserver/vci_config.h 2006-03-24 16:50:44 +0100 -@@ -1,7 +1,4 @@ - --#include -- -- - enum { - VCI_KCBIT_LEGACY = 1, - VCI_KCBIT_LEGACYNET, diff --git a/debian/patches/vserver-vs2.0.2-rc17-update.patch b/debian/patches/vserver-vs2.0.2-rc17-update.patch deleted file mode 100644 index 798e10e3a..000000000 --- a/debian/patches/vserver-vs2.0.2-rc17-update.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff -urN linux-2.6-2.6.16-vs2.0.2-rc16/fs/namei.c linux-2.6-2.6.16-vs2.0.2-rc17/fs/namei.c ---- linux-2.6-2.6.16-vs2.0.2-rc16/fs/namei.c 2006-04-19 14:47:38.000000000 +0200 -+++ linux-2.6-2.6.16-vs2.0.2-rc17/fs/namei.c 2006-04-19 14:48:36.000000000 +0200 -@@ -242,7 +242,7 @@ - - vxwprintk(1, "xid=%d denied access to %p[#%d,%lu] »%s«.", - vx_current_xid(), inode, inode->i_xid, inode->i_ino, -- vxd_path(nd->dentry, nd->mnt)); -+ vxd_cond_path(nd)); - return -EACCES; - } - -diff -urN linux-2.6-2.6.16-vs2.0.2-rc16/include/linux/vserver/debug.h linux-2.6-2.6.16-vs2.0.2-rc17/include/linux/vserver/debug.h ---- linux-2.6-2.6.16-vs2.0.2-rc16/include/linux/vserver/debug.h 2006-04-19 14:47:39.000000000 +0200 -+++ linux-2.6-2.6.16-vs2.0.2-rc17/include/linux/vserver/debug.h 2006-04-19 14:48:36.000000000 +0200 -@@ -60,11 +60,13 @@ - printk(VX_WARNLEVEL f "\n" , ##x); \ - } while (0) - -- - #define vxd_path(d,m) \ - ({ static char _buffer[PATH_MAX]; \ - d_path((d), (m), _buffer, sizeof(_buffer)); }) - -+#define vxd_cond_path(n) \ -+ ((n) ? vxd_path((n)->dentry, (n)->mnt) : "" ) -+ - #else /* CONFIG_VSERVER_DEBUG */ - - #define vx_debug_switch 0 -@@ -82,6 +84,7 @@ - #define vxwprintk(x...) do { } while (0) - - #define vxd_path "" -+#define vxd_cond_path vxd_path - - #endif /* CONFIG_VSERVER_DEBUG */ - -diff -urN linux-2.6-2.6.16-vs2.0.2-rc16/net/ipv4/devinet.c linux-2.6-2.6.16-vs2.0.2-rc17/net/ipv4/devinet.c ---- linux-2.6-2.6.16-vs2.0.2-rc16/net/ipv4/devinet.c 2006-04-19 14:47:39.000000000 +0200 -+++ linux-2.6-2.6.16-vs2.0.2-rc17/net/ipv4/devinet.c 2006-04-19 14:48:37.000000000 +0200 -@@ -529,33 +529,6 @@ - return rc; - } - --/* -- Check that a device is not member of the ipv4root assigned to the process -- Return true if this is the case -- -- If the process is not bound to specific IP, then it returns 0 (all -- interface are fine). --*/ --static inline int devinet_notiproot (struct in_ifaddr *ifa) --{ -- int ret = 0; -- struct nx_info *nxi; -- -- if ((nxi = current->nx_info)) { -- int i; -- int nbip = nxi->nbipv4; -- __u32 addr = ifa->ifa_local; -- ret = 1; -- for (i=0; iipv4[i] == addr) { -- ret = 0; -- break; -- } -- } -- } -- return ret; --} -- - - int devinet_ioctl(unsigned int cmd, void __user *arg) - { diff --git a/debian/patches/vserver-vs2.0.2-rc18-update.patch b/debian/patches/vserver-vs2.0.2-rc18-update.patch deleted file mode 100644 index cdd9420eb..000000000 --- a/debian/patches/vserver-vs2.0.2-rc18-update.patch +++ /dev/null @@ -1,349 +0,0 @@ -diff -u linux-2.6.16.8-vs2.0.2-rc17/fs/namespace.c linux-2.6.16.11-vs2.0.2-rc18/fs/namespace.c ---- linux-2.6.16.8-vs2.0.2-rc17/fs/namespace.c 2006-03-20 17:34:49 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/fs/namespace.c 2006-04-28 01:59:36 +0200 -@@ -676,7 +676,7 @@ - goto dput_and_out; - - retval = -EPERM; -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) - goto dput_and_out; - - retval = do_umount(nd.mnt, flags); -@@ -700,9 +700,7 @@ - - static int mount_is_safe(struct nameidata *nd) - { -- if (capable(CAP_SYS_ADMIN)) -- return 0; -- if (vx_ccaps(VXC_SECURE_MOUNT)) -+ if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) - return 0; - return -EPERM; - #ifdef notyet -@@ -996,7 +994,7 @@ - int err; - struct super_block *sb = nd->mnt->mnt_sb; - -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_REMOUNT)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_REMOUNT)) - return -EPERM; - - if (!check_mnt(nd->mnt)) -@@ -1030,7 +1028,7 @@ - struct nameidata old_nd, parent_nd; - struct vfsmount *p; - int err = 0; -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) - return -EPERM; - if (!old_name || !*old_name) - return -EINVAL; -@@ -1110,7 +1108,7 @@ - return -EINVAL; - - /* we need capabilities... */ -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) - return -EPERM; - - mnt = do_kern_mount(type, flags, name, data); -@@ -1502,7 +1500,7 @@ - if (!(flags & CLONE_NEWNS)) - return 0; - -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SECURE_MOUNT)) { -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) { - err = -EPERM; - goto out; - } -diff -u linux-2.6.16.8-vs2.0.2-rc17/fs/quota.c linux-2.6.16.11-vs2.0.2-rc18/fs/quota.c ---- linux-2.6.16.8-vs2.0.2-rc17/fs/quota.c 2006-03-20 17:34:49 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/fs/quota.c 2006-04-28 01:59:36 +0200 -@@ -84,11 +84,11 @@ - if (cmd == Q_GETQUOTA) { - if (((type == USRQUOTA && current->euid != id) || - (type == GRPQUOTA && !in_egroup_p(id))) && -- !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) -+ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) - return -EPERM; - } - else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO) -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) - return -EPERM; - - return 0; -@@ -135,10 +135,10 @@ - if (cmd == Q_XGETQUOTA) { - if (((type == XQM_USRQUOTA && current->euid != id) || - (type == XQM_GRPQUOTA && !in_egroup_p(id))) && -- !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) -+ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) - return -EPERM; - } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) { -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) - return -EPERM; - } - -diff -u linux-2.6.16.8-vs2.0.2-rc17/fs/super.c linux-2.6.16.11-vs2.0.2-rc18/fs/super.c ---- linux-2.6.16.8-vs2.0.2-rc17/fs/super.c 2006-03-20 17:34:49 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/fs/super.c 2006-04-28 01:59:36 +0200 -@@ -815,7 +815,7 @@ - - sb = ERR_PTR(-EPERM); - if ((type->fs_flags & FS_BINARY_MOUNTDATA) && -- !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_BINARY_MOUNT)) -+ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT)) - goto out; - - sb = ERR_PTR(-ENOMEM); -diff -u linux-2.6.16.8-vs2.0.2-rc17/fs/xfs/quota/xfs_qm_syscalls.c linux-2.6.16.11-vs2.0.2-rc18/fs/xfs/quota/xfs_qm_syscalls.c ---- linux-2.6.16.8-vs2.0.2-rc17/fs/xfs/quota/xfs_qm_syscalls.c 2006-03-20 17:34:49 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/fs/xfs/quota/xfs_qm_syscalls.c 2006-04-28 01:59:36 +0200 -@@ -215,7 +215,7 @@ - xfs_qoff_logitem_t *qoffstart; - int nculprits; - -- if (!force && !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) -+ if (!force && !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) - return XFS_ERROR(EPERM); - /* - * No file system can have quotas enabled on disk but not in core. -@@ -384,7 +384,7 @@ - int error; - xfs_inode_t *qip; - -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) - return XFS_ERROR(EPERM); - error = 0; - if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) { -@@ -429,7 +429,7 @@ - uint accflags; - __int64_t sbflags; - -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) - return XFS_ERROR(EPERM); - - flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); -@@ -600,7 +600,7 @@ - int error; - xfs_qcnt_t hard, soft; - -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_QUOTA_CTL)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) - return XFS_ERROR(EPERM); - - if ((newlim->d_fieldmask & -diff -u linux-2.6.16.8-vs2.0.2-rc17/include/linux/vs_base.h linux-2.6.16.11-vs2.0.2-rc18/include/linux/vs_base.h ---- linux-2.6.16.8-vs2.0.2-rc17/include/linux/vs_base.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/include/linux/vs_base.h 2006-04-28 02:00:37 +0200 -@@ -97,6 +97,9 @@ - (current->vx_info && \ - (current->vx_info->vx_initpid == (n))) - -+#define vx_capable(b,c) (capable(b) || \ -+ ((current->euid == 0) && vx_ccaps(c))) -+ - - #else - #warning duplicate inclusion -diff -u linux-2.6.16.8-vs2.0.2-rc17/include/net/route.h linux-2.6.16.11-vs2.0.2-rc18/include/net/route.h ---- linux-2.6.16.8-vs2.0.2-rc17/include/net/route.h 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/include/net/route.h 2006-04-26 19:12:32 +0200 -@@ -229,6 +229,8 @@ - return err; - if (fl.fl4_dst == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) - fl.fl4_dst = nx_info->ipv4[0]; -+ if (fl.fl4_src == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) -+ fl.fl4_src = nx_info->ipv4[0]; - } - if (!fl.fl4_dst || !fl.fl4_src) { - err = __ip_route_output_key(rp, &fl); -diff -u linux-2.6.16.8-vs2.0.2-rc17/kernel/sys.c linux-2.6.16.11-vs2.0.2-rc18/kernel/sys.c ---- linux-2.6.16.8-vs2.0.2-rc17/kernel/sys.c 2006-04-18 02:12:08 +0200 -+++ linux-2.6.16.11-vs2.0.2-rc18/kernel/sys.c 2006-04-28 01:59:36 +0200 -@@ -1547,7 +1547,7 @@ - int errno; - char tmp[__NEW_UTS_LEN]; - -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME)) - return -EPERM; - if (len < 0 || len > __NEW_UTS_LEN) - return -EINVAL; -@@ -1596,7 +1596,7 @@ - int errno; - char tmp[__NEW_UTS_LEN]; - -- if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME)) -+ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME)) - return -EPERM; - if (len < 0 || len > __NEW_UTS_LEN) - return -EINVAL; -@@ -1664,7 +1664,7 @@ - return -EINVAL; - old_rlim = current->signal->rlim + resource; - if ((new_rlim.rlim_max > old_rlim->rlim_max) && -- !capable(CAP_SYS_RESOURCE) && !vx_ccaps(VXC_SET_RLIMIT)) -+ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT)) - return -EPERM; - if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN) - return -EPERM; -diff -u linux-2.6.16.8-vs2.0.2-rc17/kernel/vserver/legacy.c linux-2.6.16.11-vs2.0.2-rc18/kernel/vserver/legacy.c ---- linux-2.6.16.8-vs2.0.2-rc17/kernel/vserver/legacy.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/kernel/vserver/legacy.c 2006-04-28 03:18:07 +0200 -@@ -31,6 +31,7 @@ - if (!init) - return -ESRCH; - -+ vxi->vx_flags &= ~VXF_STATE_INIT; - return vx_set_init(vxi, init); - } - -@@ -88,7 +89,7 @@ - vx_info_flags(new_vxi, VX_INFO_PRIVATE, 0)) - goto out_put; - -- new_vxi->vx_flags &= ~(VXF_STATE_SETUP|VXF_STATE_INIT); -+ new_vxi->vx_flags &= ~VXF_STATE_SETUP; - - ret = vx_migrate_task(current, new_vxi); - if (ret == 0) { -@@ -102,6 +103,9 @@ - if (vc_data.flags & VX_INFO_NPROC) - new_vxi->limit.rlim[RLIMIT_NPROC] = - current->signal->rlim[RLIMIT_NPROC].rlim_max; -+ -+ /* tweak some defaults for legacy */ -+ new_vxi->vx_flags |= (VXF_HIDE_NETIF|VXF_INFO_INIT); - ret = new_vxi->vx_id; - } - out_put: -diff -u linux-2.6.16.8-vs2.0.2-rc17/kernel/vserver/sched.c linux-2.6.16.11-vs2.0.2-rc18/kernel/vserver/sched.c ---- linux-2.6.16.8-vs2.0.2-rc17/kernel/vserver/sched.c 2006-03-24 16:50:48 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/kernel/vserver/sched.c 2006-04-28 01:39:59 +0200 -@@ -117,7 +117,7 @@ - vavavoom = 0; - - vxi->sched.vavavoom = vavavoom; -- return vavavoom; -+ return vavavoom + vxi->sched.priority_bias; - } - - -diff -u linux-2.6.16.8-vs2.0.2-rc17/net/ipv4/devinet.c linux-2.6.16.11-vs2.0.2-rc18/net/ipv4/devinet.c ---- linux-2.6.16.8-vs2.0.2-rc17/net/ipv4/devinet.c 2006-04-17 20:56:32 +0200 -+++ linux-2.6.16.11-vs2.0.2-rc18/net/ipv4/devinet.c 2006-04-26 19:09:22 +0200 -@@ -607,6 +607,9 @@ - *colon = ':'; - - if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { -+ struct nx_info *nxi = current->nx_info; -+ int hide_netif = vx_flags(VXF_HIDE_NETIF, 0); -+ - if (tryaddrmatch) { - /* Matthias Andree */ - /* compare label and address (4.4BSD style) */ -@@ -615,6 +618,8 @@ - This is checked above. */ - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; - ifap = &ifa->ifa_next) { -+ if (hide_netif && !ifa_in_nx_info(ifa, nxi)) -+ continue; - if (!strcmp(ifr.ifr_name, ifa->ifa_label) && - sin_orig.sin_addr.s_addr == - ifa->ifa_address) { -@@ -627,18 +632,18 @@ - comparing just the label */ - if (!ifa) { - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; -- ifap = &ifa->ifa_next) -+ ifap = &ifa->ifa_next) { -+ if (hide_netif && !ifa_in_nx_info(ifa, nxi)) -+ continue; - if (!strcmp(ifr.ifr_name, ifa->ifa_label)) - break; -+ } - } - } - - ret = -EADDRNOTAVAIL; - if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS) - goto done; -- if (vx_flags(VXF_HIDE_NETIF, 0) && -- !ifa_in_nx_info(ifa, current->nx_info)) -- goto done; - - switch(cmd) { - case SIOCGIFADDR: /* Get interface address */ -diff -u linux-2.6.16.8-vs2.0.2-rc17/net/ipv4/udp.c linux-2.6.16.11-vs2.0.2-rc18/net/ipv4/udp.c ---- linux-2.6.16.8-vs2.0.2-rc17/net/ipv4/udp.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/net/ipv4/udp.c 2006-04-26 19:08:56 +0200 -@@ -216,16 +216,6 @@ - write_unlock_bh(&udp_hash_lock); - } - --static inline int udp_in_list(struct nx_info *nx_info, u32 addr) --{ -- int n = nx_info->nbipv4; -- int i; -- -- for (i=0; iipv4[i] == addr) -- return 1; -- return 0; --} - - /* UDP is nearly always wildcards out the wazoo, it makes no sense to try - * harder than this. -DaveM -@@ -248,7 +238,7 @@ - continue; - score+=2; - } else if (sk->sk_nx_info) { -- if (udp_in_list(sk->sk_nx_info, daddr)) -+ if (addr_in_nx_info(sk->sk_nx_info, daddr)) - score+=2; - else - continue; -diff -u linux-2.6.16.8-vs2.0.2-rc17/security/commoncap.c linux-2.6.16.11-vs2.0.2-rc18/security/commoncap.c ---- linux-2.6.16.8-vs2.0.2-rc17/security/commoncap.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/security/commoncap.c 2006-04-28 01:59:36 +0200 -@@ -313,7 +313,7 @@ - int cap_syslog (int type) - { - if ((type != 3 && type != 10) && -- !capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SYSLOG)) -+ !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG)) - return -EPERM; - return 0; - } -diff -u linux-2.6.16.8-vs2.0.2-rc17/security/security.c linux-2.6.16.11-vs2.0.2-rc18/security/security.c ---- linux-2.6.16.8-vs2.0.2-rc17/security/security.c 2006-03-20 17:34:50 +0100 -+++ linux-2.6.16.11-vs2.0.2-rc18/security/security.c 2006-04-28 01:59:36 +0200 -@@ -200,22 +200,8 @@ - --int vx_capable(int cap, int ccap) --{ -- if (security_ops->capable(current, cap)) { -- /* capability denied */ -- return 0; -- } -- if (!vx_ccaps(ccap)) -- return 0; -- -- /* capability granted */ -- current->flags |= PF_SUPERPRIV; -- return 1; --} - - EXPORT_SYMBOL_GPL(register_security); - EXPORT_SYMBOL_GPL(unregister_security); - EXPORT_SYMBOL_GPL(mod_reg_security); - EXPORT_SYMBOL_GPL(mod_unreg_security); - EXPORT_SYMBOL(capable); --EXPORT_SYMBOL(vx_capable); - EXPORT_SYMBOL(security_ops); diff --git a/debian/patches/xen-tree-merge-22448.patch b/debian/patches/xen-tree-merge-22448.patch deleted file mode 100644 index d52f410b6..000000000 --- a/debian/patches/xen-tree-merge-22448.patch +++ /dev/null @@ -1,79333 +0,0 @@ -diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig -index 5b1a7d4..6a4988c 100644 ---- a/arch/i386/Kconfig -+++ b/arch/i386/Kconfig -@@ -58,6 +58,15 @@ config X86_PC - help - Choose this option if your computer is a standard PC or compatible. - -+config X86_XEN -+ bool "Xen-compatible" -+ select X86_UP_APIC if !SMP && XEN_PRIVILEGED_GUEST -+ select X86_UP_IOAPIC if !SMP && XEN_PRIVILEGED_GUEST -+ select SWIOTLB -+ help -+ Choose this option if you plan to run this kernel on top of the -+ Xen Hypervisor. -+ - config X86_ELAN - bool "AMD Elan" - help -@@ -159,6 +168,7 @@ source "arch/i386/Kconfig.cpu" - - config HPET_TIMER - bool "HPET Timer Support" -+ depends on !X86_XEN - help - This enables the use of the HPET for the kernel's internal timer. - HPET is the next generation timer replacing legacy 8254s. -@@ -202,6 +212,19 @@ config SMP - - If you don't know what to do here, say N. - -+config SMP_ALTERNATIVES -+ bool "SMP alternatives support (EXPERIMENTAL)" -+ depends on SMP && EXPERIMENTAL -+ help -+ Try to reduce the overhead of running an SMP kernel on a uniprocessor -+ host slightly by replacing certain key instruction sequences -+ according to whether we currently have more than one CPU available. -+ This should provide a noticeable boost to performance when -+ running SMP kernels on UP machines, and have negligible impact -+ when running on an true SMP host. -+ -+ If unsure, say N. -+ - config NR_CPUS - int "Maximum number of CPUs (2-255)" - range 2 255 -@@ -218,7 +241,7 @@ config NR_CPUS - - config SCHED_SMT - bool "SMT (Hyperthreading) scheduler support" -- depends on SMP -+ depends on SMP && !X86_XEN - default off - help - SMT scheduler support improves the CPU scheduler's decision making -@@ -230,7 +253,7 @@ source "kernel/Kconfig.preempt" - - config X86_UP_APIC - bool "Local APIC support on uniprocessors" -- depends on !SMP && !(X86_VISWS || X86_VOYAGER) -+ depends on !SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST) - help - A local APIC (Advanced Programmable Interrupt Controller) is an - integrated interrupt controller in the CPU. If you have a single-CPU -@@ -255,12 +278,12 @@ config X86_UP_IOAPIC - - config X86_LOCAL_APIC - bool -- depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) -+ depends on X86_UP_APIC || ((X86_VISWS || SMP) && !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)) - default y - - config X86_IO_APIC - bool -- depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) -+ depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER || XEN_UNPRIVILEGED_GUEST)) - default y - - config X86_VISWS_APIC -@@ -268,9 +291,14 @@ config X86_VISWS_APIC - depends on X86_VISWS - default y - -+config X86_TSC -+ bool -+ depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ && !X86_XEN -+ default y -+ - config X86_MCE - bool "Machine Check Exception" -- depends on !X86_VOYAGER -+ depends on !(X86_VOYAGER || X86_XEN) - ---help--- - Machine Check Exception support allows the processor to notify the - kernel if it detects a problem (e.g. overheating, component failure). -@@ -360,6 +388,7 @@ config X86_REBOOTFIXUPS - - config MICROCODE - tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" -+ depends on !XEN_UNPRIVILEGED_GUEST - ---help--- - If you say Y here and also to "/dev file system support" in the - 'File systems' section, you will be able to update the microcode on -@@ -377,6 +406,7 @@ config MICROCODE - - config X86_MSR - tristate "/dev/cpu/*/msr - Model-specific register support" -+ depends on !X86_XEN - help - This device gives privileged processes access to the x86 - Model-Specific Registers (MSRs). It is a character device with -@@ -392,6 +422,10 @@ config X86_CPUID - with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to - /dev/cpu/31/cpuid. - -+config SWIOTLB -+ bool -+ default n -+ - source "drivers/firmware/Kconfig" - - choice -@@ -560,7 +594,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID - - config HIGHPTE - bool "Allocate 3rd-level pagetables from highmem" -- depends on HIGHMEM4G || HIGHMEM64G -+ depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN - help - The VM uses one page table entry for each page of physical memory. - For systems with a lot of RAM, this can be wasteful of precious -@@ -569,6 +603,7 @@ config HIGHPTE - - config MATH_EMULATION - bool "Math emulation" -+ depends on !X86_XEN - ---help--- - Linux can emulate a math coprocessor (used for floating point - operations) if you don't have one. 486DX and Pentium processors have -@@ -594,6 +629,8 @@ config MATH_EMULATION - - config MTRR - bool "MTRR (Memory Type Range Register) support" -+ depends on !XEN_UNPRIVILEGED_GUEST -+ default y if X86_XEN - ---help--- - On Intel P6 family processors (Pentium Pro, Pentium II and later) - the Memory Type Range Registers (MTRRs) may be used to control -@@ -628,7 +665,7 @@ config MTRR - - config EFI - bool "Boot from EFI support (EXPERIMENTAL)" -- depends on ACPI -+ depends on ACPI && !X86_XEN - default n - ---help--- - This enables the the kernel to boot on EFI platforms using -@@ -646,7 +683,7 @@ config EFI - - config IRQBALANCE - bool "Enable kernel irq balancing" -- depends on SMP && X86_IO_APIC -+ depends on SMP && X86_IO_APIC && !X86_XEN - default y - help - The default yes will allow the kernel to do irq load balancing. -@@ -689,7 +726,7 @@ source kernel/Kconfig.hz - - config KEXEC - bool "kexec system call (EXPERIMENTAL)" -- depends on EXPERIMENTAL -+ depends on EXPERIMENTAL && !X86_XEN - help - kexec is a system call that implements the ability to shutdown your - current kernel, and to start another kernel. It is like a reboot -@@ -743,6 +780,7 @@ config HOTPLUG_CPU - config DOUBLEFAULT - default y - bool "Enable doublefault exception handler" if EMBEDDED -+ depends on !X86_NO_TSS - help - This option allows trapping of rare doublefault exceptions that - would otherwise cause a system to silently reboot. Disabling this -@@ -753,18 +791,20 @@ endmenu - - - menu "Power management options (ACPI, APM)" -- depends on !X86_VOYAGER -+ depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST) - -+if !X86_XEN - source kernel/power/Kconfig -+endif - - source "drivers/acpi/Kconfig" - - menu "APM (Advanced Power Management) BIOS Support" --depends on PM && !X86_VISWS -+depends on PM && !(X86_VISWS || X86_XEN) - - config APM - tristate "APM (Advanced Power Management) BIOS support" -- depends on PM -+ depends on PM && PM_LEGACY - ---help--- - APM is a BIOS specification for saving power using several different - techniques. This is mostly useful for battery powered laptops with -@@ -949,6 +989,7 @@ choice - - config PCI_GOBIOS - bool "BIOS" -+ depends on !X86_XEN - - config PCI_GOMMCONFIG - bool "MMConfig" -@@ -956,6 +997,13 @@ config PCI_GOMMCONFIG - config PCI_GODIRECT - bool "Direct" - -+config PCI_GOXEN_FE -+ bool "Xen PCI Frontend" -+ depends on X86_XEN -+ help -+ The PCI device frontend driver allows the kernel to import arbitrary -+ PCI devices from a PCI backend to support PCI driver domains. -+ - config PCI_GOANY - bool "Any" - -@@ -963,7 +1011,7 @@ endchoice - - config PCI_BIOS - bool -- depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) -+ depends on !(X86_VISWS || X86_XEN) && PCI && (PCI_GOBIOS || PCI_GOANY) - default y - - config PCI_DIRECT -@@ -976,6 +1024,18 @@ config PCI_MMCONFIG - depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) - default y - -+config XEN_PCIDEV_FRONTEND -+ bool -+ depends on PCI && X86_XEN && (PCI_GOXEN_FE || PCI_GOANY) -+ default y -+ -+config XEN_PCIDEV_FE_DEBUG -+ bool "Xen PCI Frontend Debugging" -+ depends on XEN_PCIDEV_FRONTEND -+ default n -+ help -+ Enables some debug statements within the PCI Frontend. -+ - source "drivers/pci/pcie/Kconfig" - - source "drivers/pci/Kconfig" -@@ -986,7 +1046,7 @@ config ISA_DMA_API - - config ISA - bool "ISA support" -- depends on !(X86_VOYAGER || X86_VISWS) -+ depends on !(X86_VOYAGER || X86_VISWS || X86_XEN) - help - Find out whether you have ISA slots on your motherboard. ISA is the - name of a bus system, i.e. the way the CPU talks to the other stuff -@@ -1013,7 +1073,7 @@ config EISA - source "drivers/eisa/Kconfig" - - config MCA -- bool "MCA support" if !(X86_VISWS || X86_VOYAGER) -+ bool "MCA support" if !(X86_VISWS || X86_VOYAGER || X86_XEN) - default y if X86_VOYAGER - help - MicroChannel Architecture is found in some IBM PS/2 machines and -@@ -1056,7 +1116,9 @@ source "fs/Kconfig" - menu "Instrumentation Support" - depends on EXPERIMENTAL - -+if !X86_XEN - source "arch/i386/oprofile/Kconfig" -+endif - - config KPROBES - bool "Kprobes (EXPERIMENTAL)" -@@ -1075,6 +1137,8 @@ source "security/Kconfig" - - source "crypto/Kconfig" - -+source "drivers/xen/Kconfig" -+ - source "lib/Kconfig" - - # -@@ -1100,7 +1164,7 @@ config X86_SMP - - config X86_HT - bool -- depends on SMP && !(X86_VISWS || X86_VOYAGER) -+ depends on SMP && !(X86_VISWS || X86_VOYAGER || X86_XEN) - default y - - config X86_BIOS_REBOOT -@@ -1113,6 +1177,21 @@ config X86_TRAMPOLINE - depends on X86_SMP || (X86_VOYAGER && SMP) - default y - -+config X86_NO_TSS -+ bool -+ depends on X86_XEN -+ default y -+ -+config X86_SYSENTER -+ bool -+ depends on !X86_NO_TSS -+ default y -+ -+config X86_NO_IDT -+ bool -+ depends on X86_XEN -+ default y -+ - config KTIME_SCALAR - bool - default y -diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu -index 79603b3..a52d7d4 100644 ---- a/arch/i386/Kconfig.cpu -+++ b/arch/i386/Kconfig.cpu -@@ -251,7 +251,7 @@ config X86_PPRO_FENCE - - config X86_F00F_BUG - bool -- depends on M586MMX || M586TSC || M586 || M486 || M386 -+ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !X86_NO_IDT - default y - - config X86_WP_WORKS_OK -diff --git a/arch/i386/Makefile b/arch/i386/Makefile -index 36bef65..757acb8 100644 ---- a/arch/i386/Makefile -+++ b/arch/i386/Makefile -@@ -68,6 +68,10 @@ mcore-$(CONFIG_X86_BIGSMP) := mach-defau - mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit - mcore-$(CONFIG_X86_SUMMIT) := mach-default - -+# Xen subarch support -+mflags-$(CONFIG_X86_XEN) := -Iinclude/asm-i386/mach-xen -+mcore-$(CONFIG_X86_XEN) := mach-xen -+ - # generic subarchitecture - mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-i386/mach-generic - mcore-$(CONFIG_X86_GENERICARCH) := mach-default -@@ -96,12 +100,25 @@ drivers-$(CONFIG_PM) += arch/i386/powe - - CFLAGS += $(mflags-y) - AFLAGS += $(mflags-y) -+CPPFLAGS += $(mflags-y) - - boot := arch/i386/boot - - .PHONY: zImage bzImage compressed zlilo bzlilo \ - zdisk bzdisk fdimage fdimage144 fdimage288 install - -+ifdef CONFIG_XEN -+head-y := arch/i386/kernel/head-xen.o arch/i386/kernel/init_task-xen.o -+boot := arch/i386/boot-xen -+.PHONY: vmlinuz -+all: vmlinuz -+ -+vmlinuz: vmlinux -+ $(Q)$(MAKE) $(build)=$(boot) $@ -+ -+install: -+ $(Q)$(MAKE) $(build)=$(boot) XENGUEST=$(XENGUEST) $@ -+else - all: bzImage - - # KBUILD_IMAGE specify target image being built -@@ -124,6 +141,7 @@ fdimage fdimage144 fdimage288: vmlinux - - install: - $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install -+endif - - archclean: - $(Q)$(MAKE) $(clean)=arch/i386/boot -diff --git a/arch/i386/boot-xen/Makefile b/arch/i386/boot-xen/Makefile -new file mode 100644 -index 0000000..bf15a77 ---- /dev/null -+++ b/arch/i386/boot-xen/Makefile -@@ -0,0 +1,21 @@ -+ -+OBJCOPYFLAGS := -g --strip-unneeded -+ -+vmlinuz: vmlinux-stripped FORCE -+ $(call if_changed,gzip) -+ -+vmlinux-stripped: vmlinux FORCE -+ $(call if_changed,objcopy) -+ -+INSTALL_ROOT := $(patsubst %/boot,%,$(INSTALL_PATH)) -+ -+XINSTALL_NAME ?= $(KERNELRELEASE) -+install: -+ mkdir -p $(INSTALL_ROOT)/boot -+ ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_ROOT)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(XENGUEST)$(INSTALL_SUFFIX) -+ rm -f $(INSTALL_ROOT)/boot/vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) -+ install -m0644 vmlinuz $(INSTALL_ROOT)/boot/vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) -+ install -m0644 vmlinux $(INSTALL_ROOT)/boot/vmlinux-syms-$(XINSTALL_NAME)$(INSTALL_SUFFIX) -+ install -m0664 .config $(INSTALL_ROOT)/boot/config-$(XINSTALL_NAME)$(INSTALL_SUFFIX) -+ install -m0664 System.map $(INSTALL_ROOT)/boot/System.map-$(XINSTALL_NAME)$(INSTALL_SUFFIX) -+ ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_ROOT)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX) -diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile -index 65656c0..5661a9b 100644 ---- a/arch/i386/kernel/Makefile -+++ b/arch/i386/kernel/Makefile -@@ -37,17 +37,26 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o - obj-$(CONFIG_DOUBLEFAULT) += doublefault.o - obj-$(CONFIG_VM86) += vm86.o - obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -+obj-$(CONFIG_SMP_ALTERNATIVES) += smpalts.o - - EXTRA_AFLAGS := -traditional - - obj-$(CONFIG_SCx200) += scx200.o - -+ifdef CONFIG_XEN -+vsyscall_note := vsyscall-note-xen.o -+else -+vsyscall_note := vsyscall-note.o -+endif -+ -+VSYSCALL_TYPES-y := int80 -+VSYSCALL_TYPES-$(CONFIG_X86_SYSENTER) += sysenter - # vsyscall.o contains the vsyscall DSO images as __initdata. - # We must build both images before we can assemble it. - # Note: kbuild does not track this dependency due to usage of .incbin --$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so --targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) --targets += vsyscall-note.o vsyscall.lds -+$(obj)/vsyscall.o: $(foreach F,$(VSYSCALL_TYPES-y),$(obj)/vsyscall-$F.so) -+targets += $(foreach F,$(VSYSCALL_TYPES-y),vsyscall-$F.o vsyscall-$F.so) -+targets += $(vsyscall_note) vsyscall.lds - - # The DSO images are built using a special linker script. - quiet_cmd_syscall = SYSCALL $@ -@@ -62,7 +71,7 @@ SYSCFLAGS_vsyscall-int80.so = $(vsyscall - - $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \ - $(obj)/vsyscall-%.so: $(src)/vsyscall.lds \ -- $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE -+ $(obj)/vsyscall-%.o $(obj)/$(vsyscall_note) FORCE - $(call if_changed,syscall) - - # We also create a special relocatable object that should mirror the symbol -@@ -74,5 +83,18 @@ $(obj)/built-in.o: ld_flags += -R $(obj) - - SYSCFLAGS_vsyscall-syms.o = -r - $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \ -- $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE -+ $(foreach F,$(VSYSCALL_TYPES-y),$(obj)/vsyscall-$F.o) \ -+ $(obj)/$(vsyscall_note) FORCE - $(call if_changed,syscall) -+ -+ifdef CONFIG_XEN -+include $(srctree)/scripts/Makefile.xen -+ -+obj-y += fixup.o -+microcode-$(subst m,y,$(CONFIG_MICROCODE)) := microcode-xen.o -+n-obj-xen := i8259.o timers/ reboot.o smpboot.o trampoline.o -+ -+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen)) -+obj-y := $(call cherrypickxen, $(obj-y)) -+extra-y := $(call cherrypickxen, $(extra-y)) -+endif -diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile -index 7e9ac99..fa783e6 100644 ---- a/arch/i386/kernel/acpi/Makefile -+++ b/arch/i386/kernel/acpi/Makefile -@@ -6,3 +6,7 @@ ifneq ($(CONFIG_ACPI_PROCESSOR),) - obj-y += cstate.o processor.o - endif - -+ifdef CONFIG_XEN -+include $(srctree)/scripts/Makefile.xen -+obj-y := $(call cherrypickxen, $(obj-y), $(src)) -+endif -diff --git a/arch/i386/kernel/acpi/boot-xen.c b/arch/i386/kernel/acpi/boot-xen.c -new file mode 100644 -index 0000000..96e4525 ---- /dev/null -+++ b/arch/i386/kernel/acpi/boot-xen.c -@@ -0,0 +1,1161 @@ -+/* -+ * boot.c - Architecture-Specific Low-Level ACPI Boot Support -+ * -+ * Copyright (C) 2001, 2002 Paul Diefenbaugh -+ * Copyright (C) 2001 Jun Nakajima -+ * -+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_X86_64 -+ -+extern void __init clustered_apic_check(void); -+ -+extern int gsi_irq_sharing(int gsi); -+#include -+ -+static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } -+ -+ -+#else /* X86 */ -+ -+#ifdef CONFIG_X86_LOCAL_APIC -+#include -+#include -+#endif /* CONFIG_X86_LOCAL_APIC */ -+ -+static inline int gsi_irq_sharing(int gsi) { return gsi; } -+ -+#endif /* X86 */ -+ -+#define BAD_MADT_ENTRY(entry, end) ( \ -+ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ -+ ((acpi_table_entry_header *)entry)->length != sizeof(*entry)) -+ -+#define PREFIX "ACPI: " -+ -+int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ -+int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ -+int acpi_ht __initdata = 1; /* enable HT */ -+ -+int acpi_lapic; -+int acpi_ioapic; -+int acpi_strict; -+EXPORT_SYMBOL(acpi_strict); -+ -+acpi_interrupt_flags acpi_sci_flags __initdata; -+int acpi_sci_override_gsi __initdata; -+int acpi_skip_timer_override __initdata; -+ -+#ifdef CONFIG_X86_LOCAL_APIC -+static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; -+#endif -+ -+#ifndef __HAVE_ARCH_CMPXCHG -+#warning ACPI uses CMPXCHG, i486 and later hardware -+#endif -+ -+#define MAX_MADT_ENTRIES 256 -+u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = -+ {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; -+EXPORT_SYMBOL(x86_acpiid_to_apicid); -+ -+/* -------------------------------------------------------------------------- -+ Boot-time Configuration -+ -------------------------------------------------------------------------- */ -+ -+/* -+ * The default interrupt routing model is PIC (8259). This gets -+ * overriden if IOAPICs are enumerated (below). -+ */ -+enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; -+ -+#if defined(CONFIG_X86_64) && !defined(CONFIG_XEN) -+ -+/* rely on all ACPI tables being in the direct mapping */ -+char *__acpi_map_table(unsigned long phys_addr, unsigned long size) -+{ -+ if (!phys_addr || !size) -+ return NULL; -+ -+ if (phys_addr+size <= (end_pfn_map << PAGE_SHIFT) + PAGE_SIZE) -+ return __va(phys_addr); -+ -+ return NULL; -+} -+ -+#else -+ -+/* -+ * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, -+ * to map the target physical address. The problem is that set_fixmap() -+ * provides a single page, and it is possible that the page is not -+ * sufficient. -+ * By using this area, we can map up to MAX_IO_APICS pages temporarily, -+ * i.e. until the next __va_range() call. -+ * -+ * Important Safety Note: The fixed I/O APIC page numbers are *subtracted* -+ * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and -+ * count idx down while incrementing the phys address. -+ */ -+char *__acpi_map_table(unsigned long phys, unsigned long size) -+{ -+ unsigned long base, offset, mapped_size; -+ int idx; -+ -+#ifndef CONFIG_XEN -+ if (phys + size < 8 * 1024 * 1024) -+ return __va(phys); -+#endif -+ -+ offset = phys & (PAGE_SIZE - 1); -+ mapped_size = PAGE_SIZE - offset; -+ set_fixmap(FIX_ACPI_END, phys); -+ base = fix_to_virt(FIX_ACPI_END); -+ -+ /* -+ * Most cases can be covered by the below. -+ */ -+ idx = FIX_ACPI_END; -+ while (mapped_size < size) { -+ if (--idx < FIX_ACPI_BEGIN) -+ return NULL; /* cannot handle this */ -+ phys += PAGE_SIZE; -+ set_fixmap(idx, phys); -+ mapped_size += PAGE_SIZE; -+ } -+ -+ return ((unsigned char *)base + offset); -+} -+#endif -+ -+#ifdef CONFIG_PCI_MMCONFIG -+/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -+struct acpi_table_mcfg_config *pci_mmcfg_config; -+int pci_mmcfg_config_num; -+ -+int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) -+{ -+ struct acpi_table_mcfg *mcfg; -+ unsigned long i; -+ int config_size; -+ -+ if (!phys_addr || !size) -+ return -EINVAL; -+ -+ mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); -+ if (!mcfg) { -+ printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); -+ return -ENODEV; -+ } -+ -+ /* how many config structures do we have */ -+ pci_mmcfg_config_num = 0; -+ i = size - sizeof(struct acpi_table_mcfg); -+ while (i >= sizeof(struct acpi_table_mcfg_config)) { -+ ++pci_mmcfg_config_num; -+ i -= sizeof(struct acpi_table_mcfg_config); -+ }; -+ if (pci_mmcfg_config_num == 0) { -+ printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); -+ return -ENODEV; -+ } -+ -+ config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); -+ pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); -+ if (!pci_mmcfg_config) { -+ printk(KERN_WARNING PREFIX -+ "No memory for MCFG config tables\n"); -+ return -ENOMEM; -+ } -+ -+ memcpy(pci_mmcfg_config, &mcfg->config, config_size); -+ for (i = 0; i < pci_mmcfg_config_num; ++i) { -+ if (mcfg->config[i].base_reserved) { -+ printk(KERN_ERR PREFIX -+ "MMCONFIG not in low 4GB of memory\n"); -+ return -ENODEV; -+ } -+ } -+ -+ return 0; -+} -+#endif /* CONFIG_PCI_MMCONFIG */ -+ -+#ifdef CONFIG_X86_LOCAL_APIC -+static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) -+{ -+ struct acpi_table_madt *madt = NULL; -+ -+ if (!phys_addr || !size) -+ return -EINVAL; -+ -+ madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); -+ if (!madt) { -+ printk(KERN_WARNING PREFIX "Unable to map MADT\n"); -+ return -ENODEV; -+ } -+ -+ if (madt->lapic_address) { -+ acpi_lapic_addr = (u64) madt->lapic_address; -+ -+ printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", -+ madt->lapic_address); -+ } -+ -+ acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); -+ -+ return 0; -+} -+ -+static int __init -+acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) -+{ -+ struct acpi_table_lapic *processor = NULL; -+ -+ processor = (struct acpi_table_lapic *)header; -+ -+ if (BAD_MADT_ENTRY(processor, end)) -+ return -EINVAL; -+ -+ acpi_table_print_madt_entry(header); -+ -+ /* Record local apic id only when enabled */ -+ if (processor->flags.enabled) -+ x86_acpiid_to_apicid[processor->acpi_id] = processor->id; -+ -+ /* -+ * We need to register disabled CPU as well to permit -+ * counting disabled CPUs. This allows us to size -+ * cpus_possible_map more accurately, to permit -+ * to not preallocating memory for all NR_CPUS -+ * when we use CPU hotplug. -+ */ -+ mp_register_lapic(processor->id, /* APIC ID */ -+ processor->flags.enabled); /* Enabled? */ -+ -+ return 0; -+} -+ -+static int __init -+acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, -+ const unsigned long end) -+{ -+ struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; -+ -+ lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header; -+ -+ if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) -+ return -EINVAL; -+ -+ acpi_lapic_addr = lapic_addr_ovr->address; -+ -+ return 0; -+} -+ -+static int __init -+acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) -+{ -+ struct acpi_table_lapic_nmi *lapic_nmi = NULL; -+ -+ lapic_nmi = (struct acpi_table_lapic_nmi *)header; -+ -+ if (BAD_MADT_ENTRY(lapic_nmi, end)) -+ return -EINVAL; -+ -+ acpi_table_print_madt_entry(header); -+ -+ if (lapic_nmi->lint != 1) -+ printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n"); -+ -+ return 0; -+} -+ -+#endif /*CONFIG_X86_LOCAL_APIC */ -+ -+#ifdef CONFIG_X86_IO_APIC -+ -+static int __init -+acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) -+{ -+ struct acpi_table_ioapic *ioapic = NULL; -+ -+ ioapic = (struct acpi_table_ioapic *)header; -+ -+ if (BAD_MADT_ENTRY(ioapic, end)) -+ return -EINVAL; -+ -+ acpi_table_print_madt_entry(header); -+ -+ mp_register_ioapic(ioapic->id, -+ ioapic->address, ioapic->global_irq_base); -+ -+ return 0; -+} -+ -+/* -+ * Parse Interrupt Source Override for the ACPI SCI -+ */ -+static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) -+{ -+ if (trigger == 0) /* compatible SCI trigger is level */ -+ trigger = 3; -+ -+ if (polarity == 0) /* compatible SCI polarity is low */ -+ polarity = 3; -+ -+ /* Command-line over-ride via acpi_sci= */ -+ if (acpi_sci_flags.trigger) -+ trigger = acpi_sci_flags.trigger; -+ -+ if (acpi_sci_flags.polarity) -+ polarity = acpi_sci_flags.polarity; -+ -+ /* -+ * mp_config_acpi_legacy_irqs() already setup IRQs < 16 -+ * If GSI is < 16, this will update its flags, -+ * else it will create a new mp_irqs[] entry. -+ */ -+ mp_override_legacy_irq(gsi, polarity, trigger, gsi); -+ -+ /* -+ * stash over-ride to indicate we've been here -+ * and for later update of acpi_fadt -+ */ -+ acpi_sci_override_gsi = gsi; -+ return; -+} -+ -+static int __init -+acpi_parse_int_src_ovr(acpi_table_entry_header * header, -+ const unsigned long end) -+{ -+ struct acpi_table_int_src_ovr *intsrc = NULL; -+ -+ intsrc = (struct acpi_table_int_src_ovr *)header; -+ -+ if (BAD_MADT_ENTRY(intsrc, end)) -+ return -EINVAL; -+ -+ acpi_table_print_madt_entry(header); -+ -+ if (intsrc->bus_irq == acpi_fadt.sci_int) { -+ acpi_sci_ioapic_setup(intsrc->global_irq, -+ intsrc->flags.polarity, -+ intsrc->flags.trigger); -+ return 0; -+ } -+ -+ if (acpi_skip_timer_override && -+ intsrc->bus_irq == 0 && intsrc->global_irq == 2) { -+ printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); -+ return 0; -+ } -+ -+ mp_override_legacy_irq(intsrc->bus_irq, -+ intsrc->flags.polarity, -+ intsrc->flags.trigger, intsrc->global_irq); -+ -+ return 0; -+} -+ -+static int __init -+acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) -+{ -+ struct acpi_table_nmi_src *nmi_src = NULL; -+ -+ nmi_src = (struct acpi_table_nmi_src *)header; -+ -+ if (BAD_MADT_ENTRY(nmi_src, end)) -+ return -EINVAL; -+ -+ acpi_table_print_madt_entry(header); -+ -+ /* TBD: Support nimsrc entries? */ -+ -+ return 0; -+} -+ -+#endif /* CONFIG_X86_IO_APIC */ -+ -+/* -+ * acpi_pic_sci_set_trigger() -+ * -+ * use ELCR to set PIC-mode trigger type for SCI -+ * -+ * If a PIC-mode SCI is not recognized or gives spurious IRQ7's -+ * it may require Edge Trigger -- use "acpi_sci=edge" -+ * -+ * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers -+ * for the 8259 PIC. bit[n] = 1 means irq[n] is Level, otherwise Edge. -+ * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0) -+ * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0) -+ */ -+ -+void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) -+{ -+ unsigned int mask = 1 << irq; -+ unsigned int old, new; -+ -+ /* Real old ELCR mask */ -+ old = inb(0x4d0) | (inb(0x4d1) << 8); -+ -+ /* -+ * If we use ACPI to set PCI irq's, then we should clear ELCR -+ * since we will set it correctly as we enable the PCI irq -+ * routing. -+ */ -+ new = acpi_noirq ? old : 0; -+ -+ /* -+ * Update SCI information in the ELCR, it isn't in the PCI -+ * routing tables.. -+ */ -+ switch (trigger) { -+ case 1: /* Edge - clear */ -+ new &= ~mask; -+ break; -+ case 3: /* Level - set */ -+ new |= mask; -+ break; -+ } -+ -+ if (old == new) -+ return; -+ -+ printk(PREFIX "setting ELCR to %04x (from %04x)\n", new, old); -+ outb(new, 0x4d0); -+ outb(new >> 8, 0x4d1); -+} -+ -+int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) -+{ -+#ifdef CONFIG_X86_IO_APIC -+ if (use_pci_vector() && !platform_legacy_irq(gsi)) -+ *irq = IO_APIC_VECTOR(gsi); -+ else -+#endif -+ *irq = gsi_irq_sharing(gsi); -+ return 0; -+} -+ -+/* -+ * success: return IRQ number (>=0) -+ * failure: return < 0 -+ */ -+int acpi_register_gsi(u32 gsi, int triggering, int polarity) -+{ -+ unsigned int irq; -+ unsigned int plat_gsi = gsi; -+ -+#ifdef CONFIG_PCI -+ /* -+ * Make sure all (legacy) PCI IRQs are set as level-triggered. -+ */ -+ if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { -+ extern void eisa_set_level_irq(unsigned int irq); -+ -+ if (triggering == ACPI_LEVEL_SENSITIVE) -+ eisa_set_level_irq(gsi); -+ } -+#endif -+ -+#ifdef CONFIG_X86_IO_APIC -+ if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { -+ plat_gsi = mp_register_gsi(gsi, triggering, polarity); -+ } -+#endif -+ acpi_gsi_to_irq(plat_gsi, &irq); -+ return irq; -+} -+ -+EXPORT_SYMBOL(acpi_register_gsi); -+ -+/* -+ * ACPI based hotplug support for CPU -+ */ -+#ifdef CONFIG_ACPI_HOTPLUG_CPU -+int acpi_map_lsapic(acpi_handle handle, int *pcpu) -+{ -+ /* TBD */ -+ return -EINVAL; -+} -+ -+EXPORT_SYMBOL(acpi_map_lsapic); -+ -+int acpi_unmap_lsapic(int cpu) -+{ -+ /* TBD */ -+ return -EINVAL; -+} -+ -+EXPORT_SYMBOL(acpi_unmap_lsapic); -+#endif /* CONFIG_ACPI_HOTPLUG_CPU */ -+ -+int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) -+{ -+ /* TBD */ -+ return -EINVAL; -+} -+ -+EXPORT_SYMBOL(acpi_register_ioapic); -+ -+int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) -+{ -+ /* TBD */ -+ return -EINVAL; -+} -+ -+EXPORT_SYMBOL(acpi_unregister_ioapic); -+ -+static unsigned long __init -+acpi_scan_rsdp(unsigned long start, unsigned long length) -+{ -+ unsigned long offset = 0; -+ unsigned long sig_len = sizeof("RSD PTR ") - 1; -+ unsigned long vstart = (unsigned long)isa_bus_to_virt(start); -+ -+ /* -+ * Scan all 16-byte boundaries of the physical memory region for the -+ * RSDP signature. -+ */ -+ for (offset = 0; offset < length; offset += 16) { -+ if (strncmp((char *)(vstart + offset), "RSD PTR ", sig_len)) -+ continue; -+ return (start + offset); -+ } -+ -+ return 0; -+} -+ -+static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) -+{ -+ struct acpi_table_sbf *sb; -+ -+ if (!phys_addr || !size) -+ return -EINVAL; -+ -+ sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); -+ if (!sb) { -+ printk(KERN_WARNING PREFIX "Unable to map SBF\n"); -+ return -ENODEV; -+ } -+ -+ sbf_port = sb->sbf_cmos; /* Save CMOS port */ -+ -+ return 0; -+} -+ -+#ifdef CONFIG_HPET_TIMER -+ -+static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) -+{ -+ struct acpi_table_hpet *hpet_tbl; -+ -+ if (!phys || !size) -+ return -EINVAL; -+ -+ hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size); -+ if (!hpet_tbl) { -+ printk(KERN_WARNING PREFIX "Unable to map HPET\n"); -+ return -ENODEV; -+ } -+ -+ if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) { -+ printk(KERN_WARNING PREFIX "HPET timers must be located in " -+ "memory.\n"); -+ return -1; -+ } -+#ifdef CONFIG_X86_64 -+ vxtime.hpet_address = hpet_tbl->addr.addrl | -+ ((long)hpet_tbl->addr.addrh << 32); -+ -+ printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", -+ hpet_tbl->id, vxtime.hpet_address); -+#else /* X86 */ -+ { -+ extern unsigned long hpet_address; -+ -+ hpet_address = hpet_tbl->addr.addrl; -+ printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", -+ hpet_tbl->id, hpet_address); -+ } -+#endif /* X86 */ -+ -+ return 0; -+} -+#else -+#define acpi_parse_hpet NULL -+#endif -+ -+#ifdef CONFIG_X86_PM_TIMER -+extern u32 pmtmr_ioport; -+#endif -+ -+static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) -+{ -+ struct fadt_descriptor_rev2 *fadt = NULL; -+ -+ fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size); -+ if (!fadt) { -+ printk(KERN_WARNING PREFIX "Unable to map FADT\n"); -+ return 0; -+ } -+ /* initialize sci_int early for INT_SRC_OVR MADT parsing */ -+ acpi_fadt.sci_int = fadt->sci_int; -+ -+ /* initialize rev and apic_phys_dest_mode for x86_64 genapic */ -+ acpi_fadt.revision = fadt->revision; -+ acpi_fadt.force_apic_physical_destination_mode = -+ fadt->force_apic_physical_destination_mode; -+ -+#if defined(CONFIG_X86_PM_TIMER) && !defined(CONFIG_XEN) -+ /* detect the location of the ACPI PM Timer */ -+ if (fadt->revision >= FADT2_REVISION_ID) { -+ /* FADT rev. 2 */ -+ if (fadt->xpm_tmr_blk.address_space_id != -+ ACPI_ADR_SPACE_SYSTEM_IO) -+ return 0; -+ -+ pmtmr_ioport = fadt->xpm_tmr_blk.address; -+ /* -+ * "X" fields are optional extensions to the original V1.0 -+ * fields, so we must selectively expand V1.0 fields if the -+ * corresponding X field is zero. -+ */ -+ if (!pmtmr_ioport) -+ pmtmr_ioport = fadt->V1_pm_tmr_blk; -+ } else { -+ /* FADT rev. 1 */ -+ pmtmr_ioport = fadt->V1_pm_tmr_blk; -+ } -+ if (pmtmr_ioport) -+ printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", -+ pmtmr_ioport); -+#endif -+ return 0; -+} -+ -+unsigned long __init acpi_find_rsdp(void) -+{ -+ unsigned long rsdp_phys = 0; -+ -+ if (efi_enabled) { -+ if (efi.acpi20) -+ return __pa(efi.acpi20); -+ else if (efi.acpi) -+ return __pa(efi.acpi); -+ } -+ /* -+ * Scan memory looking for the RSDP signature. First search EBDA (low -+ * memory) paragraphs and then search upper memory (E0000-FFFFF). -+ */ -+ rsdp_phys = acpi_scan_rsdp(0, 0x400); -+ if (!rsdp_phys) -+ rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000); -+ -+ return rsdp_phys; -+} -+ -+#ifdef CONFIG_X86_LOCAL_APIC -+/* -+ * Parse LAPIC entries in MADT -+ * returns 0 on success, < 0 on error -+ */ -+static int __init acpi_parse_madt_lapic_entries(void) -+{ -+ int count; -+ -+ /* -+ * Note that the LAPIC address is obtained from the MADT (32-bit value) -+ * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). -+ */ -+ -+ count = -+ acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, -+ acpi_parse_lapic_addr_ovr, 0); -+ if (count < 0) { -+ printk(KERN_ERR PREFIX -+ "Error parsing LAPIC address override entry\n"); -+ return count; -+ } -+ -+ mp_register_lapic_address(acpi_lapic_addr); -+ -+ count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, -+ MAX_APICS); -+ if (!count) { -+ printk(KERN_ERR PREFIX "No LAPIC entries present\n"); -+ /* TBD: Cleanup to allow fallback to MPS */ -+ return -ENODEV; -+ } else if (count < 0) { -+ printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); -+ /* TBD: Cleanup to allow fallback to MPS */ -+ return count; -+ } -+ -+ count = -+ acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); -+ if (count < 0) { -+ printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); -+ /* TBD: Cleanup to allow fallback to MPS */ -+ return count; -+ } -+ return 0; -+} -+#endif /* CONFIG_X86_LOCAL_APIC */ -+ -+#ifdef CONFIG_X86_IO_APIC -+/* -+ * Parse IOAPIC related entries in MADT -+ * returns 0 on success, < 0 on error -+ */ -+static int __init acpi_parse_madt_ioapic_entries(void) -+{ -+ int count; -+ -+ /* -+ * ACPI interpreter is required to complete interrupt setup, -+ * so if it is off, don't enumerate the io-apics with ACPI. -+ * If MPS is present, it will handle them, -+ * otherwise the system will stay in PIC mode -+ */ -+ if (acpi_disabled || acpi_noirq) { -+ return -ENODEV; -+ } -+ -+ /* -+ * if "noapic" boot option, don't look for IO-APICs -+ */ -+ if (skip_ioapic_setup) { -+ printk(KERN_INFO PREFIX "Skipping IOAPIC probe " -+ "due to 'noapic' option.\n"); -+ return -ENODEV; -+ } -+ -+ count = -+ acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, -+ MAX_IO_APICS); -+ if (!count) { -+ printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); -+ return -ENODEV; -+ } else if (count < 0) { -+ printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); -+ return count; -+ } -+ -+ count = -+ acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, -+ NR_IRQ_VECTORS); -+ if (count < 0) { -+ printk(KERN_ERR PREFIX -+ "Error parsing interrupt source overrides entry\n"); -+ /* TBD: Cleanup to allow fallback to MPS */ -+ return count; -+ } -+ -+ /* -+ * If BIOS did not supply an INT_SRC_OVR for the SCI -+ * pretend we got one so we can set the SCI flags. -+ */ -+ if (!acpi_sci_override_gsi) -+ acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); -+ -+ /* Fill in identity legacy mapings where no override */ -+ mp_config_acpi_legacy_irqs(); -+ -+ count = -+ acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, -+ NR_IRQ_VECTORS); -+ if (count < 0) { -+ printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); -+ /* TBD: Cleanup to allow fallback to MPS */ -+ return count; -+ } -+ -+ return 0; -+} -+#else -+static inline int acpi_parse_madt_ioapic_entries(void) -+{ -+ return -1; -+} -+#endif /* !CONFIG_X86_IO_APIC */ -+ -+static void __init acpi_process_madt(void) -+{ -+#ifdef CONFIG_X86_LOCAL_APIC -+ int count, error; -+ -+ count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); -+ if (count >= 1) { -+ -+ /* -+ * Parse MADT LAPIC entries -+ */ -+ error = acpi_parse_madt_lapic_entries(); -+ if (!error) { -+ acpi_lapic = 1; -+ -+#ifdef CONFIG_X86_GENERICARCH -+ generic_bigsmp_probe(); -+#endif -+ /* -+ * Parse MADT IO-APIC entries -+ */ -+ error = acpi_parse_madt_ioapic_entries(); -+ if (!error) { -+ acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; -+ acpi_irq_balance_set(NULL); -+ acpi_ioapic = 1; -+ -+ smp_found_config = 1; -+ clustered_apic_check(); -+ } -+ } -+ if (error == -EINVAL) { -+ /* -+ * Dell Precision Workstation 410, 610 come here. -+ */ -+ printk(KERN_ERR PREFIX -+ "Invalid BIOS MADT, disabling ACPI\n"); -+ disable_acpi(); -+ } -+ } -+#endif -+ return; -+} -+ -+extern int acpi_force; -+ -+#ifdef __i386__ -+ -+static int __init disable_acpi_irq(struct dmi_system_id *d) -+{ -+ if (!acpi_force) { -+ printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", -+ d->ident); -+ acpi_noirq_set(); -+ } -+ return 0; -+} -+ -+static int __init disable_acpi_pci(struct dmi_system_id *d) -+{ -+ if (!acpi_force) { -+ printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", -+ d->ident); -+ acpi_disable_pci(); -+ } -+ return 0; -+} -+ -+static int __init dmi_disable_acpi(struct dmi_system_id *d) -+{ -+ if (!acpi_force) { -+ printk(KERN_NOTICE "%s detected: acpi off\n", d->ident); -+ disable_acpi(); -+ } else { -+ printk(KERN_NOTICE -+ "Warning: DMI blacklist says broken, but acpi forced\n"); -+ } -+ return 0; -+} -+ -+/* -+ * Limit ACPI to CPU enumeration for HT -+ */ -+static int __init force_acpi_ht(struct dmi_system_id *d) -+{ -+ if (!acpi_force) { -+ printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", -+ d->ident); -+ disable_acpi(); -+ acpi_ht = 1; -+ } else { -+ printk(KERN_NOTICE -+ "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); -+ } -+ return 0; -+} -+ -+/* -+ * If your system is blacklisted here, but you find that acpi=force -+ * works for you, please contact acpi-devel@sourceforge.net -+ */ -+static struct dmi_system_id __initdata acpi_dmi_table[] = { -+ /* -+ * Boxes that need ACPI disabled -+ */ -+ { -+ .callback = dmi_disable_acpi, -+ .ident = "IBM Thinkpad", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), -+ DMI_MATCH(DMI_BOARD_NAME, "2629H1G"), -+ }, -+ }, -+ -+ /* -+ * Boxes that need acpi=ht -+ */ -+ { -+ .callback = force_acpi_ht, -+ .ident = "FSC Primergy T850", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "DELL GX240", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), -+ DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "HP VISUALIZE NT Workstation", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "Compaq Workstation W8000", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "ASUS P4B266", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "P4B266"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "ASUS P2B-DS", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "ASUS CUR-DLS", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "ABIT i440BX-W83977", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ABIT "), -+ DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "IBM Bladecenter", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), -+ DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "IBM eServer xSeries 360", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), -+ DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "IBM eserver xSeries 330", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), -+ DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), -+ }, -+ }, -+ { -+ .callback = force_acpi_ht, -+ .ident = "IBM eserver xSeries 440", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), -+ }, -+ }, -+ -+ /* -+ * Boxes that need ACPI PCI IRQ routing disabled -+ */ -+ { -+ .callback = disable_acpi_irq, -+ .ident = "ASUS A7V", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), -+ DMI_MATCH(DMI_BOARD_NAME, ""), -+ /* newer BIOS, Revision 1011, does work */ -+ DMI_MATCH(DMI_BIOS_VERSION, -+ "ASUS A7V ACPI BIOS Revision 1007"), -+ }, -+ }, -+ -+ /* -+ * Boxes that need ACPI PCI IRQ routing and PCI scan disabled -+ */ -+ { /* _BBN 0 bug */ -+ .callback = disable_acpi_pci, -+ .ident = "ASUS PR-DLS", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), -+ DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"), -+ DMI_MATCH(DMI_BIOS_VERSION, -+ "ASUS PR-DLS ACPI BIOS Revision 1010"), -+ DMI_MATCH(DMI_BIOS_DATE, "03/21/2003") -+ }, -+ }, -+ { -+ .callback = disable_acpi_pci, -+ .ident = "Acer TravelMate 36x Laptop", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), -+ }, -+ }, -+ {} -+}; -+ -+#endif /* __i386__ */ -+ -+/* -+ * acpi_boot_table_init() and acpi_boot_init() -+ * called from setup_arch(), always. -+ * 1. checksums all tables -+ * 2. enumerates lapics -+ * 3. enumerates io-apics -+ * -+ * acpi_table_init() is separate to allow reading SRAT without -+ * other side effects. -+ * -+ * side effects of acpi_boot_init: -+ * acpi_lapic = 1 if LAPIC found -+ * acpi_ioapic = 1 if IOAPIC found -+ * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; -+ * if acpi_blacklisted() acpi_disabled = 1; -+ * acpi_irq_model=... -+ * ... -+ * -+ * return value: (currently ignored) -+ * 0: success -+ * !0: failure -+ */ -+ -+int __init acpi_boot_table_init(void) -+{ -+ int error; -+ -+#ifdef __i386__ -+ dmi_check_system(acpi_dmi_table); -+#endif -+ -+ /* -+ * If acpi_disabled, bail out -+ * One exception: acpi=ht continues far enough to enumerate LAPICs -+ */ -+ if (acpi_disabled && !acpi_ht) -+ return 1; -+ -+ /* -+ * Initialize the ACPI boot-time table parser. -+ */ -+ error = acpi_table_init(); -+ if (error) { -+ disable_acpi(); -+ return error; -+ } -+ -+ acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); -+ -+ /* -+ * blacklist may disable ACPI entirely -+ */ -+ error = acpi_blacklisted(); -+ if (error) { -+ if (acpi_force) { -+ printk(KERN_WARNING PREFIX "acpi=force override\n"); -+ } else { -+ printk(KERN_WARNING PREFIX "Disabling ACPI support\n"); -+ disable_acpi(); -+ return error; -+ } -+ } -+ -+ return 0; -+} -+ -+int __init acpi_boot_init(void) -+{ -+ /* -+ * If acpi_disabled, bail out -+ * One exception: acpi=ht continues far enough to enumerate LAPICs -+ */ -+ if (acpi_disabled && !acpi_ht) -+ return 1; -+ -+ acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); -+ -+ /* -+ * set sci_int and PM timer address -+ */ -+ acpi_table_parse(ACPI_FADT, acpi_parse_fadt); -+ -+ /* -+ * Process the Multiple APIC Description Table (MADT), if present -+ */ -+ acpi_process_madt(); -+ -+ acpi_table_parse(ACPI_HPET, acpi_parse_hpet); -+ -+ return 0; -+} -diff --git a/arch/i386/kernel/apic-xen.c b/arch/i386/kernel/apic-xen.c -new file mode 100644 -index 0000000..07a0994 ---- /dev/null -+++ b/arch/i386/kernel/apic-xen.c -@@ -0,0 +1,140 @@ -+/* -+ * Local APIC handling, local APIC timers -+ * -+ * (c) 1999, 2000 Ingo Molnar -+ * -+ * Fixes -+ * Maciej W. Rozycki : Bits for genuine 82489DX APICs; -+ * thanks to Eric Gilmore -+ * and Rolf G. Tews -+ * for testing these extensively. -+ * Maciej W. Rozycki : Various updates and fixes. -+ * Mikael Pettersson : Power Management for UP-APIC. -+ * Pavel Machek and -+ * Mikael Pettersson : PM converted to driver model. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "io_ports.h" -+ -+#ifndef CONFIG_XEN -+/* -+ * cpu_mask that denotes the CPUs that needs timer interrupt coming in as -+ * IPIs in place of local APIC timers -+ */ -+static cpumask_t timer_bcast_ipi; -+#endif -+ -+/* -+ * Knob to control our willingness to enable the local APIC. -+ */ -+int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ -+ -+/* -+ * Debug level -+ */ -+int apic_verbosity; -+ -+/* -+ * 'what should we do if we get a hw irq event on an illegal vector'. -+ * each architecture has to answer this themselves. -+ */ -+void ack_bad_irq(unsigned int irq) -+{ -+ printk("unexpected IRQ trap at vector %02x\n", irq); -+ /* -+ * Currently unexpected vectors happen only on SMP and APIC. -+ * We _must_ ack these because every local APIC has only N -+ * irq slots per priority level, and a 'hanging, unacked' IRQ -+ * holds up an irq slot - in excessive cases (when multiple -+ * unexpected vectors occur) that might lock up the APIC -+ * completely. -+ * But only ack when the APIC is enabled -AK -+ */ -+ if (cpu_has_apic) -+ ack_APIC_irq(); -+} -+ -+int get_physical_broadcast(void) -+{ -+ return 0xff; -+} -+ -+#ifndef CONFIG_XEN -+#ifndef CONFIG_SMP -+static void up_apic_timer_interrupt_call(struct pt_regs *regs) -+{ -+ int cpu = smp_processor_id(); -+ -+ /* -+ * the NMI deadlock-detector uses this. -+ */ -+ per_cpu(irq_stat, cpu).apic_timer_irqs++; -+ -+ smp_local_timer_interrupt(regs); -+} -+#endif -+ -+void smp_send_timer_broadcast_ipi(struct pt_regs *regs) -+{ -+ cpumask_t mask; -+ -+ cpus_and(mask, cpu_online_map, timer_bcast_ipi); -+ if (!cpus_empty(mask)) { -+#ifdef CONFIG_SMP -+ send_IPI_mask(mask, LOCAL_TIMER_VECTOR); -+#else -+ /* -+ * We can directly call the apic timer interrupt handler -+ * in UP case. Minus all irq related functions -+ */ -+ up_apic_timer_interrupt_call(regs); -+#endif -+ } -+} -+#endif -+ -+int setup_profiling_timer(unsigned int multiplier) -+{ -+ return -EINVAL; -+} -+ -+/* -+ * This initializes the IO-APIC and APIC hardware if this is -+ * a UP kernel. -+ */ -+int __init APIC_init_uniprocessor (void) -+{ -+#ifdef CONFIG_X86_IO_APIC -+ if (smp_found_config) -+ if (!skip_ioapic_setup && nr_ioapics) -+ setup_IO_APIC(); -+#endif -+ -+ return 0; -+} -diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c -index 36d66e2..3c4a0f4 100644 ---- a/arch/i386/kernel/asm-offsets.c -+++ b/arch/i386/kernel/asm-offsets.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - #define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) -@@ -63,10 +64,12 @@ void foo(void) - OFFSET(pbe_orig_address, pbe, orig_address); - OFFSET(pbe_next, pbe, next); - -+#ifdef CONFIG_X86_SYSENTER - /* Offset from the sysenter stack to tss.esp0 */ - DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) - - sizeof(struct tss_struct)); -+#endif - - DEFINE(PAGE_SIZE_asm, PAGE_SIZE); -- DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL)); -+ DEFINE(VSYSCALL_BASE, VSYSCALL_BASE); - } -diff --git a/arch/i386/kernel/cpu/Makefile b/arch/i386/kernel/cpu/Makefile -index 010aecf..753f1d7 100644 ---- a/arch/i386/kernel/cpu/Makefile -+++ b/arch/i386/kernel/cpu/Makefile -@@ -17,3 +17,8 @@ obj-$(CONFIG_X86_MCE) += mcheck/ - - obj-$(CONFIG_MTRR) += mtrr/ - obj-$(CONFIG_CPU_FREQ) += cpufreq/ -+ -+ifdef CONFIG_XEN -+include $(srctree)/scripts/Makefile.xen -+obj-y := $(call cherrypickxen, $(obj-y), $(src)) -+endif -diff --git a/arch/i386/kernel/cpu/common-xen.c b/arch/i386/kernel/cpu/common-xen.c -new file mode 100644 -index 0000000..db05bd0 ---- /dev/null -+++ b/arch/i386/kernel/cpu/common-xen.c -@@ -0,0 +1,719 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_X86_LOCAL_APIC -+#include -+#include -+#include -+#endif -+#include -+ -+#include "cpu.h" -+ -+DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); -+EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); -+ -+#ifndef CONFIG_XEN -+DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); -+EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); -+#endif -+ -+static int cachesize_override __devinitdata = -1; -+static int disable_x86_fxsr __devinitdata = 0; -+static int disable_x86_serial_nr __devinitdata = 1; -+ -+struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; -+ -+extern int disable_pse; -+ -+static void default_init(struct cpuinfo_x86 * c) -+{ -+ /* Not much we can do here... */ -+ /* Check if at least it has cpuid */ -+ if (c->cpuid_level == -1) { -+ /* No cpuid. It must be an ancient CPU */ -+ if (c->x86 == 4) -+ strcpy(c->x86_model_id, "486"); -+ else if (c->x86 == 3) -+ strcpy(c->x86_model_id, "386"); -+ } -+} -+ -+static struct cpu_dev default_cpu = { -+ .c_init = default_init, -+ .c_vendor = "Unknown", -+}; -+static struct cpu_dev * this_cpu = &default_cpu; -+ -+static int __init cachesize_setup(char *str) -+{ -+ get_option (&str, &cachesize_override); -+ return 1; -+} -+__setup("cachesize=", cachesize_setup); -+ -+int __devinit get_model_name(struct cpuinfo_x86 *c) -+{ -+ unsigned int *v; -+ char *p, *q; -+ -+ if (cpuid_eax(0x80000000) < 0x80000004) -+ return 0; -+ -+ v = (unsigned int *) c->x86_model_id; -+ cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); -+ cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); -+ cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); -+ c->x86_model_id[48] = 0; -+ -+ /* Intel chips right-justify this string for some dumb reason; -+ undo that brain damage */ -+ p = q = &c->x86_model_id[0]; -+ while ( *p == ' ' ) -+ p++; -+ if ( p != q ) { -+ while ( *p ) -+ *q++ = *p++; -+ while ( q <= &c->x86_model_id[48] ) -+ *q++ = '\0'; /* Zero-pad the rest */ -+ } -+ -+ return 1; -+} -+ -+ -+void __devinit display_cacheinfo(struct cpuinfo_x86 *c) -+{ -+ unsigned int n, dummy, ecx, edx, l2size; -+ -+ n = cpuid_eax(0x80000000); -+ -+ if (n >= 0x80000005) { -+ cpuid(0x80000005, &dummy, &dummy, &ecx, &edx); -+ printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n", -+ edx>>24, edx&0xFF, ecx>>24, ecx&0xFF); -+ c->x86_cache_size=(ecx>>24)+(edx>>24); -+ } -+ -+ if (n < 0x80000006) /* Some chips just has a large L1. */ -+ return; -+ -+ ecx = cpuid_ecx(0x80000006); -+ l2size = ecx >> 16; -+ -+ /* do processor-specific cache resizing */ -+ if (this_cpu->c_size_cache) -+ l2size = this_cpu->c_size_cache(c,l2size); -+ -+ /* Allow user to override all this if necessary. */ -+ if (cachesize_override != -1) -+ l2size = cachesize_override; -+ -+ if ( l2size == 0 ) -+ return; /* Again, no L2 cache is possible */ -+ -+ c->x86_cache_size = l2size; -+ -+ printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n", -+ l2size, ecx & 0xFF); -+} -+ -+/* Naming convention should be: [()] */ -+/* This table only is used unless init_() below doesn't set it; */ -+/* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ -+ -+/* Look up CPU names by table lookup. */ -+static char __devinit *table_lookup_model(struct cpuinfo_x86 *c) -+{ -+ struct cpu_model_info *info; -+ -+ if ( c->x86_model >= 16 ) -+ return NULL; /* Range check */ -+ -+ if (!this_cpu) -+ return NULL; -+ -+ info = this_cpu->c_models; -+ -+ while (info && info->family) { -+ if (info->family == c->x86) -+ return info->model_names[c->x86_model]; -+ info++; -+ } -+ return NULL; /* Not found */ -+} -+ -+ -+static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) -+{ -+ char *v = c->x86_vendor_id; -+ int i; -+ static int printed; -+ -+ for (i = 0; i < X86_VENDOR_NUM; i++) { -+ if (cpu_devs[i]) { -+ if (!strcmp(v,cpu_devs[i]->c_ident[0]) || -+ (cpu_devs[i]->c_ident[1] && -+ !strcmp(v,cpu_devs[i]->c_ident[1]))) { -+ c->x86_vendor = i; -+ if (!early) -+ this_cpu = cpu_devs[i]; -+ return; -+ } -+ } -+ } -+ if (!printed) { -+ printed++; -+ printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n"); -+ printk(KERN_ERR "CPU: Your system may be unstable.\n"); -+ } -+ c->x86_vendor = X86_VENDOR_UNKNOWN; -+ this_cpu = &default_cpu; -+} -+ -+ -+static int __init x86_fxsr_setup(char * s) -+{ -+ disable_x86_fxsr = 1; -+ return 1; -+} -+__setup("nofxsr", x86_fxsr_setup); -+ -+ -+/* Standard macro to see if a specific flag is changeable */ -+static inline int flag_is_changeable_p(u32 flag) -+{ -+ u32 f1, f2; -+ -+ asm("pushfl\n\t" -+ "pushfl\n\t" -+ "popl %0\n\t" -+ "movl %0,%1\n\t" -+ "xorl %2,%0\n\t" -+ "pushl %0\n\t" -+ "popfl\n\t" -+ "pushfl\n\t" -+ "popl %0\n\t" -+ "popfl\n\t" -+ : "=&r" (f1), "=&r" (f2) -+ : "ir" (flag)); -+ -+ return ((f1^f2) & flag) != 0; -+} -+ -+ -+/* Probe for the CPUID instruction */ -+static int __devinit have_cpuid_p(void) -+{ -+ return flag_is_changeable_p(X86_EFLAGS_ID); -+} -+ -+/* Do minimum CPU detection early. -+ Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. -+ The others are not touched to avoid unwanted side effects. -+ -+ WARNING: this function is only called on the BP. Don't add code here -+ that is supposed to run on all CPUs. */ -+static void __init early_cpu_detect(void) -+{ -+ struct cpuinfo_x86 *c = &boot_cpu_data; -+ -+ c->x86_cache_alignment = 32; -+ -+ if (!have_cpuid_p()) -+ return; -+ -+ /* Get vendor name */ -+ cpuid(0x00000000, &c->cpuid_level, -+ (int *)&c->x86_vendor_id[0], -+ (int *)&c->x86_vendor_id[8], -+ (int *)&c->x86_vendor_id[4]); -+ -+ get_cpu_vendor(c, 1); -+ -+ c->x86 = 4; -+ if (c->cpuid_level >= 0x00000001) { -+ u32 junk, tfms, cap0, misc; -+ cpuid(0x00000001, &tfms, &misc, &junk, &cap0); -+ c->x86 = (tfms >> 8) & 15; -+ c->x86_model = (tfms >> 4) & 15; -+ if (c->x86 == 0xf) -+ c->x86 += (tfms >> 20) & 0xff; -+ if (c->x86 >= 0x6) -+ c->x86_model += ((tfms >> 16) & 0xF) << 4; -+ c->x86_mask = tfms & 15; -+ if (cap0 & (1<<19)) -+ c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8; -+ } -+} -+ -+void __devinit generic_identify(struct cpuinfo_x86 * c) -+{ -+ u32 tfms, xlvl; -+ int junk; -+ -+ if (have_cpuid_p()) { -+ /* Get vendor name */ -+ cpuid(0x00000000, &c->cpuid_level, -+ (int *)&c->x86_vendor_id[0], -+ (int *)&c->x86_vendor_id[8], -+ (int *)&c->x86_vendor_id[4]); -+ -+ get_cpu_vendor(c, 0); -+ /* Initialize the standard set of capabilities */ -+ /* Note that the vendor-specific code below might override */ -+ -+ /* Intel-defined flags: level 0x00000001 */ -+ if ( c->cpuid_level >= 0x00000001 ) { -+ u32 capability, excap; -+ cpuid(0x00000001, &tfms, &junk, &excap, &capability); -+ c->x86_capability[0] = capability; -+ c->x86_capability[4] = excap; -+ c->x86 = (tfms >> 8) & 15; -+ c->x86_model = (tfms >> 4) & 15; -+ if (c->x86 == 0xf) -+ c->x86 += (tfms >> 20) & 0xff; -+ if (c->x86 >= 0x6) -+ c->x86_model += ((tfms >> 16) & 0xF) << 4; -+ c->x86_mask = tfms & 15; -+ } else { -+ /* Have CPUID level 0 only - unheard of */ -+ c->x86 = 4; -+ } -+ -+ /* AMD-defined flags: level 0x80000001 */ -+ xlvl = cpuid_eax(0x80000000); -+ if ( (xlvl & 0xffff0000) == 0x80000000 ) { -+ if ( xlvl >= 0x80000001 ) { -+ c->x86_capability[1] = cpuid_edx(0x80000001); -+ c->x86_capability[6] = cpuid_ecx(0x80000001); -+ } -+ if ( xlvl >= 0x80000004 ) -+ get_model_name(c); /* Default name */ -+ } -+ } -+ -+ early_intel_workaround(c); -+ -+#ifdef CONFIG_X86_HT -+ phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; -+#endif -+} -+ -+static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) -+{ -+ if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { -+ /* Disable processor serial number */ -+ unsigned long lo,hi; -+ rdmsr(MSR_IA32_BBL_CR_CTL,lo,hi); -+ lo |= 0x200000; -+ wrmsr(MSR_IA32_BBL_CR_CTL,lo,hi); -+ printk(KERN_NOTICE "CPU serial number disabled.\n"); -+ clear_bit(X86_FEATURE_PN, c->x86_capability); -+ -+ /* Disabling the serial number may affect the cpuid level */ -+ c->cpuid_level = cpuid_eax(0); -+ } -+} -+ -+static int __init x86_serial_nr_setup(char *s) -+{ -+ disable_x86_serial_nr = 0; -+ return 1; -+} -+__setup("serialnumber", x86_serial_nr_setup); -+ -+ -+ -+/* -+ * This does the hard work of actually picking apart the CPU stuff... -+ */ -+void __devinit identify_cpu(struct cpuinfo_x86 *c) -+{ -+ int i; -+ -+ c->loops_per_jiffy = loops_per_jiffy; -+ c->x86_cache_size = -1; -+ c->x86_vendor = X86_VENDOR_UNKNOWN; -+ c->cpuid_level = -1; /* CPUID not detected */ -+ c->x86_model = c->x86_mask = 0; /* So far unknown... */ -+ c->x86_vendor_id[0] = '\0'; /* Unset */ -+ c->x86_model_id[0] = '\0'; /* Unset */ -+ c->x86_max_cores = 1; -+ memset(&c->x86_capability, 0, sizeof c->x86_capability); -+ -+ if (!have_cpuid_p()) { -+ /* First of all, decide if this is a 486 or higher */ -+ /* It's a 486 if we can modify the AC flag */ -+ if ( flag_is_changeable_p(X86_EFLAGS_AC) ) -+ c->x86 = 4; -+ else -+ c->x86 = 3; -+ } -+ -+ generic_identify(c); -+ -+ printk(KERN_DEBUG "CPU: After generic identify, caps:"); -+ for (i = 0; i < NCAPINTS; i++) -+ printk(" %08lx", c->x86_capability[i]); -+ printk("\n"); -+ -+ if (this_cpu->c_identify) { -+ this_cpu->c_identify(c); -+ -+ printk(KERN_DEBUG "CPU: After vendor identify, caps:"); -+ for (i = 0; i < NCAPINTS; i++) -+ printk(" %08lx", c->x86_capability[i]); -+ printk("\n"); -+ } -+ -+ /* -+ * Vendor-specific initialization. In this section we -+ * canonicalize the feature flags, meaning if there are -+ * features a certain CPU supports which CPUID doesn't -+ * tell us, CPUID claiming incorrect flags, or other bugs, -+ * we handle them here. -+ * -+ * At the end of this section, c->x86_capability better -+ * indicate the features this CPU genuinely supports! -+ */ -+ if (this_cpu->c_init) -+ this_cpu->c_init(c); -+ -+ /* Disable the PN if appropriate */ -+ squash_the_stupid_serial_number(c); -+ -+ /* -+ * The vendor-specific functions might have changed features. Now -+ * we do "generic changes." -+ */ -+ -+#ifndef CONFIG_XEN -+ /* TSC disabled? */ -+ if ( tsc_disable ) -+ clear_bit(X86_FEATURE_TSC, c->x86_capability); -+#endif -+ -+ /* FXSR disabled? */ -+ if (disable_x86_fxsr) { -+ clear_bit(X86_FEATURE_FXSR, c->x86_capability); -+ clear_bit(X86_FEATURE_XMM, c->x86_capability); -+ } -+ -+ if (disable_pse) -+ clear_bit(X86_FEATURE_PSE, c->x86_capability); -+ -+ /* If the model name is still unset, do table lookup. */ -+ if ( !c->x86_model_id[0] ) { -+ char *p; -+ p = table_lookup_model(c); -+ if ( p ) -+ strcpy(c->x86_model_id, p); -+ else -+ /* Last resort... */ -+ sprintf(c->x86_model_id, "%02x/%02x", -+ c->x86_vendor, c->x86_model); -+ } -+ -+ /* Now the feature flags better reflect actual CPU features! */ -+ -+ printk(KERN_DEBUG "CPU: After all inits, caps:"); -+ for (i = 0; i < NCAPINTS; i++) -+ printk(" %08lx", c->x86_capability[i]); -+ printk("\n"); -+ -+ /* -+ * On SMP, boot_cpu_data holds the common feature set between -+ * all CPUs; so make sure that we indicate which features are -+ * common between the CPUs. The first time this routine gets -+ * executed, c == &boot_cpu_data. -+ */ -+ if ( c != &boot_cpu_data ) { -+ /* AND the already accumulated flags with these */ -+ for ( i = 0 ; i < NCAPINTS ; i++ ) -+ boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; -+ } -+ -+ /* Init Machine Check Exception if available. */ -+ mcheck_init(c); -+ -+ if (c == &boot_cpu_data) -+ sysenter_setup(); -+ enable_sep_cpu(); -+ -+ if (c == &boot_cpu_data) -+ mtrr_bp_init(); -+ else -+ mtrr_ap_init(); -+} -+ -+#ifdef CONFIG_X86_HT -+void __devinit detect_ht(struct cpuinfo_x86 *c) -+{ -+ u32 eax, ebx, ecx, edx; -+ int index_msb, core_bits; -+ int cpu = smp_processor_id(); -+ -+ cpuid(1, &eax, &ebx, &ecx, &edx); -+ -+ c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); -+ -+ if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) -+ return; -+ -+ smp_num_siblings = (ebx & 0xff0000) >> 16; -+ -+ if (smp_num_siblings == 1) { -+ printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); -+ } else if (smp_num_siblings > 1 ) { -+ -+ if (smp_num_siblings > NR_CPUS) { -+ printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); -+ smp_num_siblings = 1; -+ return; -+ } -+ -+ index_msb = get_count_order(smp_num_siblings); -+ phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); -+ -+ printk(KERN_INFO "CPU: Physical Processor ID: %d\n", -+ phys_proc_id[cpu]); -+ -+ smp_num_siblings = smp_num_siblings / c->x86_max_cores; -+ -+ index_msb = get_count_order(smp_num_siblings) ; -+ -+ core_bits = get_count_order(c->x86_max_cores); -+ -+ cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) & -+ ((1 << core_bits) - 1); -+ -+ if (c->x86_max_cores > 1) -+ printk(KERN_INFO "CPU: Processor Core ID: %d\n", -+ cpu_core_id[cpu]); -+ } -+} -+#endif -+ -+void __devinit print_cpu_info(struct cpuinfo_x86 *c) -+{ -+ char *vendor = NULL; -+ -+ if (c->x86_vendor < X86_VENDOR_NUM) -+ vendor = this_cpu->c_vendor; -+ else if (c->cpuid_level >= 0) -+ vendor = c->x86_vendor_id; -+ -+ if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor))) -+ printk("%s ", vendor); -+ -+ if (!c->x86_model_id[0]) -+ printk("%d86", c->x86); -+ else -+ printk("%s", c->x86_model_id); -+ -+ if (c->x86_mask || c->cpuid_level >= 0) -+ printk(" stepping %02x\n", c->x86_mask); -+ else -+ printk("\n"); -+} -+ -+cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; -+ -+/* This is hacky. :) -+ * We're emulating future behavior. -+ * In the future, the cpu-specific init functions will be called implicitly -+ * via the magic of initcalls. -+ * They will insert themselves into the cpu_devs structure. -+ * Then, when cpu_init() is called, we can just iterate over that array. -+ */ -+ -+extern int intel_cpu_init(void); -+extern int cyrix_init_cpu(void); -+extern int nsc_init_cpu(void); -+extern int amd_init_cpu(void); -+extern int centaur_init_cpu(void); -+extern int transmeta_init_cpu(void); -+extern int rise_init_cpu(void); -+extern int nexgen_init_cpu(void); -+extern int umc_init_cpu(void); -+ -+void __init early_cpu_init(void) -+{ -+ intel_cpu_init(); -+ cyrix_init_cpu(); -+ nsc_init_cpu(); -+ amd_init_cpu(); -+ centaur_init_cpu(); -+ transmeta_init_cpu(); -+ rise_init_cpu(); -+ nexgen_init_cpu(); -+ umc_init_cpu(); -+ early_cpu_detect(); -+ -+#ifdef CONFIG_DEBUG_PAGEALLOC -+ /* pse is not compatible with on-the-fly unmapping, -+ * disable it even if the cpus claim to support it. -+ */ -+ clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); -+ disable_pse = 1; -+#endif -+} -+ -+void __cpuinit cpu_gdt_init(struct Xgt_desc_struct *gdt_descr) -+{ -+ unsigned long frames[16]; -+ unsigned long va; -+ int f; -+ -+ for (va = gdt_descr->address, f = 0; -+ va < gdt_descr->address + gdt_descr->size; -+ va += PAGE_SIZE, f++) { -+ frames[f] = virt_to_mfn(va); -+ make_lowmem_page_readonly( -+ (void *)va, XENFEAT_writable_descriptor_tables); -+ } -+ if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8)) -+ BUG(); -+} -+ -+/* -+ * cpu_init() initializes state that is per-CPU. Some data is already -+ * initialized (naturally) in the bootstrap process, such as the GDT -+ * and IDT. We reload them nevertheless, this function acts as a -+ * 'CPU state barrier', nothing should get across. -+ */ -+void __cpuinit cpu_init(void) -+{ -+ int cpu = smp_processor_id(); -+#ifndef CONFIG_X86_NO_TSS -+ struct tss_struct * t = &per_cpu(init_tss, cpu); -+#endif -+ struct thread_struct *thread = ¤t->thread; -+ struct desc_struct *gdt; -+ struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); -+ -+ if (cpu_test_and_set(cpu, cpu_initialized)) { -+ printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); -+ for (;;) local_irq_enable(); -+ } -+ printk(KERN_INFO "Initializing CPU#%d\n", cpu); -+ -+ if (cpu_has_vme || cpu_has_de) -+ clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); -+#ifndef CONFIG_XEN -+ if (tsc_disable && cpu_has_tsc) { -+ printk(KERN_NOTICE "Disabling TSC...\n"); -+ /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ -+ clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); -+ set_in_cr4(X86_CR4_TSD); -+ } -+#endif -+ -+#ifndef CONFIG_XEN -+ /* -+ * This is a horrible hack to allocate the GDT. The problem -+ * is that cpu_init() is called really early for the boot CPU -+ * (and hence needs bootmem) but much later for the secondary -+ * CPUs, when bootmem will have gone away -+ */ -+ if (NODE_DATA(0)->bdata->node_bootmem_map) { -+ gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); -+ /* alloc_bootmem_pages panics on failure, so no check */ -+ memset(gdt, 0, PAGE_SIZE); -+ } else { -+ gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); -+ if (unlikely(!gdt)) { -+ printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); -+ for (;;) -+ local_irq_enable(); -+ } -+ } -+ -+ /* -+ * Initialize the per-CPU GDT with the boot GDT, -+ * and set up the GDT descriptor: -+ */ -+ memcpy(gdt, cpu_gdt_table, GDT_SIZE); -+ -+ /* Set up GDT entry for 16bit stack */ -+ *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |= -+ ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) | -+ ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) | -+ (CPU_16BIT_STACK_SIZE - 1); -+ -+ cpu_gdt_descr->size = GDT_SIZE - 1; -+ cpu_gdt_descr->address = (unsigned long)gdt; -+#else -+ if (cpu == 0 && cpu_gdt_descr->address == 0) { -+ gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); -+ /* alloc_bootmem_pages panics on failure, so no check */ -+ memset(gdt, 0, PAGE_SIZE); -+ -+ memcpy(gdt, cpu_gdt_table, GDT_SIZE); -+ -+ cpu_gdt_descr->size = GDT_SIZE; -+ cpu_gdt_descr->address = (unsigned long)gdt; -+ } -+#endif -+ -+ cpu_gdt_init(cpu_gdt_descr); -+ -+ /* -+ * Set up and load the per-CPU TSS and LDT -+ */ -+ atomic_inc(&init_mm.mm_count); -+ current->active_mm = &init_mm; -+ if (current->mm) -+ BUG(); -+ enter_lazy_tlb(&init_mm, current); -+ -+ load_esp0(t, thread); -+ -+ load_LDT(&init_mm.context); -+ -+#ifdef CONFIG_DOUBLEFAULT -+ /* Set up doublefault TSS pointer in the GDT */ -+ __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); -+#endif -+ -+ /* Clear %fs and %gs. */ -+ asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); -+ -+ /* Clear all 6 debug registers: */ -+ set_debugreg(0, 0); -+ set_debugreg(0, 1); -+ set_debugreg(0, 2); -+ set_debugreg(0, 3); -+ set_debugreg(0, 6); -+ set_debugreg(0, 7); -+ -+ /* -+ * Force FPU initialization: -+ */ -+ current_thread_info()->status = 0; -+ clear_used_math(); -+ mxcsr_feature_mask_init(); -+} -+ -+#ifdef CONFIG_HOTPLUG_CPU -+void __devinit cpu_uninit(void) -+{ -+ int cpu = raw_smp_processor_id(); -+ cpu_clear(cpu, cpu_initialized); -+ -+ /* lazy TLB state */ -+ per_cpu(cpu_tlbstate, cpu).state = 0; -+ per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm; -+} -+#endif -diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig -index 26892d2..be1850c 100644 ---- a/arch/i386/kernel/cpu/cpufreq/Kconfig -+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig -@@ -158,7 +158,7 @@ config X86_SPEEDSTEP_ICH - config X86_SPEEDSTEP_SMI - tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)" - select CPU_FREQ_TABLE -- depends on EXPERIMENTAL -+ depends on EXPERIMENTAL && !X86_XEN - help - This adds the CPUFreq driver for certain mobile Intel Pentium III - (Coppermine), all mobile Intel Pentium III-M (Tualatin) -diff --git a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/i386/kernel/cpu/mtrr/Makefile -index a25b701..06df4fe 100644 ---- a/arch/i386/kernel/cpu/mtrr/Makefile -+++ b/arch/i386/kernel/cpu/mtrr/Makefile -@@ -3,3 +3,10 @@ obj-y += amd.o - obj-y += cyrix.o - obj-y += centaur.o - -+ifdef CONFIG_XEN -+include $(srctree)/scripts/Makefile.xen -+n-obj-xen := generic.o state.o amd.o cyrix.o centaur.o -+ -+obj-y := $(call filterxen, $(obj-y), $(n-obj-xen)) -+obj-y := $(call cherrypickxen, $(obj-y)) -+endif -diff --git a/arch/i386/kernel/cpu/mtrr/main-xen.c b/arch/i386/kernel/cpu/mtrr/main-xen.c -new file mode 100644 -index 0000000..8f09bd7 ---- /dev/null -+++ b/arch/i386/kernel/cpu/mtrr/main-xen.c -@@ -0,0 +1,196 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "mtrr.h" -+ -+static DECLARE_MUTEX(mtrr_sem); -+ -+void generic_get_mtrr(unsigned int reg, unsigned long *base, -+ unsigned int *size, mtrr_type * type) -+{ -+ dom0_op_t op; -+ -+ op.cmd = DOM0_READ_MEMTYPE; -+ op.u.read_memtype.reg = reg; -+ (void)HYPERVISOR_dom0_op(&op); -+ -+ *size = op.u.read_memtype.nr_mfns; -+ *base = op.u.read_memtype.mfn; -+ *type = op.u.read_memtype.type; -+} -+ -+struct mtrr_ops generic_mtrr_ops = { -+ .use_intel_if = 1, -+ .get = generic_get_mtrr, -+}; -+ -+struct mtrr_ops *mtrr_if = &generic_mtrr_ops; -+unsigned int num_var_ranges; -+unsigned int *usage_table; -+ -+static void __init set_num_var_ranges(void) -+{ -+ dom0_op_t op; -+ -+ for (num_var_ranges = 0; ; num_var_ranges++) { -+ op.cmd = DOM0_READ_MEMTYPE; -+ op.u.read_memtype.reg = num_var_ranges; -+ if (HYPERVISOR_dom0_op(&op) != 0) -+ break; -+ } -+} -+ -+static void __init init_table(void) -+{ -+ int i, max; -+ -+ max = num_var_ranges; -+ if ((usage_table = kmalloc(max * sizeof *usage_table, GFP_KERNEL)) -+ == NULL) { -+ printk(KERN_ERR "mtrr: could not allocate\n"); -+ return; -+ } -+ for (i = 0; i < max; i++) -+ usage_table[i] = 0; -+} -+ -+int mtrr_add_page(unsigned long base, unsigned long size, -+ unsigned int type, char increment) -+{ -+ int error; -+ dom0_op_t op; -+ -+ down(&mtrr_sem); -+ -+ op.cmd = DOM0_ADD_MEMTYPE; -+ op.u.add_memtype.mfn = base; -+ op.u.add_memtype.nr_mfns = size; -+ op.u.add_memtype.type = type; -+ error = HYPERVISOR_dom0_op(&op); -+ if (error) { -+ up(&mtrr_sem); -+ BUG_ON(error > 0); -+ return error; -+ } -+ -+ if (increment) -+ ++usage_table[op.u.add_memtype.reg]; -+ -+ up(&mtrr_sem); -+ -+ return op.u.add_memtype.reg; -+} -+ -+static int mtrr_check(unsigned long base, unsigned long size) -+{ -+ if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { -+ printk(KERN_WARNING -+ "mtrr: size and base must be multiples of 4 kiB\n"); -+ printk(KERN_DEBUG -+ "mtrr: size: 0x%lx base: 0x%lx\n", size, base); -+ dump_stack(); -+ return -1; -+ } -+ return 0; -+} -+ -+int -+mtrr_add(unsigned long base, unsigned long size, unsigned int type, -+ char increment) -+{ -+ if (mtrr_check(base, size)) -+ return -EINVAL; -+ return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, -+ increment); -+} -+ -+int mtrr_del_page(int reg, unsigned long base, unsigned long size) -+{ -+ unsigned i; -+ mtrr_type ltype; -+ unsigned long lbase; -+ unsigned int lsize; -+ int error = -EINVAL; -+ dom0_op_t op; -+ -+ down(&mtrr_sem); -+ -+ if (reg < 0) { -+ /* Search for existing MTRR */ -+ for (i = 0; i < num_var_ranges; ++i) { -+ mtrr_if->get(i, &lbase, &lsize, <ype); -+ if (lbase == base && lsize == size) { -+ reg = i; -+ break; -+ } -+ } -+ if (reg < 0) { -+ printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base, -+ size); -+ goto out; -+ } -+ } -+ if (usage_table[reg] < 1) { -+ printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg); -+ goto out; -+ } -+ if (--usage_table[reg] < 1) { -+ op.cmd = DOM0_DEL_MEMTYPE; -+ op.u.del_memtype.handle = 0; -+ op.u.del_memtype.reg = reg; -+ error = HYPERVISOR_dom0_op(&op); -+ if (error) { -+ BUG_ON(error > 0); -+ goto out; -+ } -+ } -+ error = reg; -+ out: -+ up(&mtrr_sem); -+ return error; -+} -+ -+int -+mtrr_del(int reg, unsigned long base, unsigned long size) -+{ -+ if (mtrr_check(base, size)) -+ return -EINVAL; -+ return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); -+} -+ -+EXPORT_SYMBOL(mtrr_add); -+EXPORT_SYMBOL(mtrr_del); -+ -+void __init mtrr_bp_init(void) -+{ -+} -+ -+void mtrr_ap_init(void) -+{ -+} -+ -+static int __init mtrr_init(void) -+{ -+ struct cpuinfo_x86 *c = &boot_cpu_data; -+ -+ if (!(xen_start_info->flags & SIF_PRIVILEGED)) -+ return -ENODEV; -+ -+ if ((!cpu_has(c, X86_FEATURE_MTRR)) && -+ (!cpu_has(c, X86_FEATURE_K6_MTRR)) && -+ (!cpu_has(c, X86_FEATURE_CYRIX_ARR)) && -+ (!cpu_has(c, X86_FEATURE_CENTAUR_MCR))) -+ return -ENODEV; -+ -+ set_num_var_ranges(); -+ init_table(); -+ -+ return 0; -+} -+ -+subsys_initcall(mtrr_init); -diff --git a/arch/i386/kernel/early_printk-xen.c b/arch/i386/kernel/early_printk-xen.c -new file mode 100644 -index 0000000..7a5d206 ---- /dev/null -+++ b/arch/i386/kernel/early_printk-xen.c -@@ -0,0 +1,2 @@ -+ -+#include "../../x86_64/kernel/early_printk-xen.c" -diff --git a/arch/i386/kernel/entry-xen.S b/arch/i386/kernel/entry-xen.S -new file mode 100644 -index 0000000..ec17d1c ---- /dev/null -+++ b/arch/i386/kernel/entry-xen.S -@@ -0,0 +1,861 @@ -+/* -+ * linux/arch/i386/entry.S -+ * -+ * Copyright (C) 1991, 1992 Linus Torvalds -+ */ -+ -+/* -+ * entry.S contains the system-call and fault low-level handling routines. -+ * This also contains the timer-interrupt handler, as well as all interrupts -+ * and faults that can result in a task-switch. -+ * -+ * NOTE: This code handles signal-recognition, which happens every time -+ * after a timer-interrupt and after each system call. -+ * -+ * I changed all the .align's to 4 (16 byte alignment), as that's faster -+ * on a 486. -+ * -+ * Stack layout in 'ret_from_system_call': -+ * ptrace needs to have all regs on the stack. -+ * if the order here is changed, it needs to be -+ * updated in fork.c:copy_process, signal.c:do_signal, -+ * ptrace.c and ptrace.h -+ * -+ * 0(%esp) - %ebx -+ * 4(%esp) - %ecx -+ * 8(%esp) - %edx -+ * C(%esp) - %esi -+ * 10(%esp) - %edi -+ * 14(%esp) - %ebp -+ * 18(%esp) - %eax -+ * 1C(%esp) - %ds -+ * 20(%esp) - %es -+ * 24(%esp) - orig_eax -+ * 28(%esp) - %eip -+ * 2C(%esp) - %cs -+ * 30(%esp) - %eflags -+ * 34(%esp) - %oldesp -+ * 38(%esp) - %oldss -+ * -+ * "current" is in register %ebx during any slow entries. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "irq_vectors.h" -+#include -+ -+#define nr_syscalls ((syscall_table_size)/4) -+ -+EBX = 0x00 -+ECX = 0x04 -+EDX = 0x08 -+ESI = 0x0C -+EDI = 0x10 -+EBP = 0x14 -+EAX = 0x18 -+DS = 0x1C -+ES = 0x20 -+ORIG_EAX = 0x24 -+EIP = 0x28 -+CS = 0x2C -+EVENT_MASK = 0x2E -+EFLAGS = 0x30 -+OLDESP = 0x34 -+OLDSS = 0x38 -+ -+CF_MASK = 0x00000001 -+TF_MASK = 0x00000100 -+IF_MASK = 0x00000200 -+DF_MASK = 0x00000400 -+NT_MASK = 0x00004000 -+VM_MASK = 0x00020000 -+/* Pseudo-eflags. */ -+NMI_MASK = 0x80000000 -+ -+#ifndef CONFIG_XEN -+#define DISABLE_INTERRUPTS cli -+#define ENABLE_INTERRUPTS sti -+#else -+/* Offsets into shared_info_t. */ -+#define evtchn_upcall_pending /* 0 */ -+#define evtchn_upcall_mask 1 -+ -+#define sizeof_vcpu_shift 6 -+ -+#ifdef CONFIG_SMP -+#define GET_VCPU_INFO movl TI_cpu(%ebp),%esi ; \ -+ shl $sizeof_vcpu_shift,%esi ; \ -+ addl HYPERVISOR_shared_info,%esi -+#else -+#define GET_VCPU_INFO movl HYPERVISOR_shared_info,%esi -+#endif -+ -+#define __DISABLE_INTERRUPTS movb $1,evtchn_upcall_mask(%esi) -+#define __ENABLE_INTERRUPTS movb $0,evtchn_upcall_mask(%esi) -+#define DISABLE_INTERRUPTS GET_VCPU_INFO ; \ -+ __DISABLE_INTERRUPTS -+#define ENABLE_INTERRUPTS GET_VCPU_INFO ; \ -+ __ENABLE_INTERRUPTS -+#define __TEST_PENDING testb $0xFF,evtchn_upcall_pending(%esi) -+#endif -+ -+#ifdef CONFIG_PREEMPT -+#define preempt_stop cli -+#else -+#define preempt_stop -+#define resume_kernel restore_nocheck -+#endif -+ -+#define SAVE_ALL \ -+ cld; \ -+ pushl %es; \ -+ pushl %ds; \ -+ pushl %eax; \ -+ pushl %ebp; \ -+ pushl %edi; \ -+ pushl %esi; \ -+ pushl %edx; \ -+ pushl %ecx; \ -+ pushl %ebx; \ -+ movl $(__USER_DS), %edx; \ -+ movl %edx, %ds; \ -+ movl %edx, %es; -+ -+#define RESTORE_INT_REGS \ -+ popl %ebx; \ -+ popl %ecx; \ -+ popl %edx; \ -+ popl %esi; \ -+ popl %edi; \ -+ popl %ebp; \ -+ popl %eax -+ -+#define RESTORE_REGS \ -+ RESTORE_INT_REGS; \ -+1: popl %ds; \ -+2: popl %es; \ -+.section .fixup,"ax"; \ -+3: movl $0,(%esp); \ -+ jmp 1b; \ -+4: movl $0,(%esp); \ -+ jmp 2b; \ -+.previous; \ -+.section __ex_table,"a";\ -+ .align 4; \ -+ .long 1b,3b; \ -+ .long 2b,4b; \ -+.previous -+ -+ -+ENTRY(ret_from_fork) -+ pushl %eax -+ call schedule_tail -+ GET_THREAD_INFO(%ebp) -+ popl %eax -+ jmp syscall_exit -+ -+/* -+ * Return to user mode is not as complex as all this looks, -+ * but we want the default path for a system call return to -+ * go as quickly as possible which is why some of this is -+ * less clear than it otherwise should be. -+ */ -+ -+ # userspace resumption stub bypassing syscall exit tracing -+ ALIGN -+ret_from_exception: -+ preempt_stop -+ret_from_intr: -+ GET_THREAD_INFO(%ebp) -+ movl EFLAGS(%esp), %eax # mix EFLAGS and CS -+ movb CS(%esp), %al -+ testl $(VM_MASK | 2), %eax -+ jz resume_kernel -+ENTRY(resume_userspace) -+ DISABLE_INTERRUPTS # make sure we don't miss an interrupt -+ # setting need_resched or sigpending -+ # between sampling and the iret -+ movl TI_flags(%ebp), %ecx -+ andl $_TIF_WORK_MASK, %ecx # is there any work to be done on -+ # int/exception return? -+ jne work_pending -+ jmp restore_all -+ -+#ifdef CONFIG_PREEMPT -+ENTRY(resume_kernel) -+ cli -+ cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? -+ jnz restore_nocheck -+need_resched: -+ movl TI_flags(%ebp), %ecx # need_resched set ? -+ testb $_TIF_NEED_RESCHED, %cl -+ jz restore_all -+ testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ? -+ jz restore_all -+ call preempt_schedule_irq -+ jmp need_resched -+#endif -+ -+#ifdef CONFIG_X86_SYSENTER -+/* SYSENTER_RETURN points to after the "sysenter" instruction in -+ the vsyscall page. See vsyscall-sysentry.S, which defines the symbol. */ -+ -+ # sysenter call handler stub -+ENTRY(sysenter_entry) -+ movl TSS_sysenter_esp0(%esp),%esp -+sysenter_past_esp: -+ sti -+ pushl $(__USER_DS) -+ pushl %ebp -+ pushfl -+ pushl $(__USER_CS) -+ pushl $SYSENTER_RETURN -+ -+/* -+ * Load the potential sixth argument from user stack. -+ * Careful about security. -+ */ -+ cmpl $__PAGE_OFFSET-3,%ebp -+ jae syscall_fault -+1: movl (%ebp),%ebp -+.section __ex_table,"a" -+ .align 4 -+ .long 1b,syscall_fault -+.previous -+ -+ pushl %eax -+ SAVE_ALL -+ GET_THREAD_INFO(%ebp) -+ -+ /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ -+ testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) -+ jnz syscall_trace_entry -+ cmpl $(nr_syscalls), %eax -+ jae syscall_badsys -+ call *sys_call_table(,%eax,4) -+ movl %eax,EAX(%esp) -+ cli -+ movl TI_flags(%ebp), %ecx -+ testw $_TIF_ALLWORK_MASK, %cx -+ jne syscall_exit_work -+/* if something modifies registers it must also disable sysexit */ -+ movl EIP(%esp), %edx -+ movl OLDESP(%esp), %ecx -+ xorl %ebp,%ebp -+ sti -+ sysexit -+#endif /* CONFIG_X86_SYSENTER */ -+ -+ -+ # system call handler stub -+ENTRY(system_call) -+ pushl %eax # save orig_eax -+ SAVE_ALL -+ GET_THREAD_INFO(%ebp) -+ # system call tracing in operation / emulation -+ /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ -+ testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) -+ jnz syscall_trace_entry -+ cmpl $(nr_syscalls), %eax -+ jae syscall_badsys -+syscall_call: -+ call *sys_call_table(,%eax,4) -+ movl %eax,EAX(%esp) # store the return value -+syscall_exit: -+ DISABLE_INTERRUPTS # make sure we don't miss an interrupt -+ # setting need_resched or sigpending -+ # between sampling and the iret -+ movl TI_flags(%ebp), %ecx -+ testw $_TIF_ALLWORK_MASK, %cx # current->work -+ jne syscall_exit_work -+ -+restore_all: -+#ifndef CONFIG_XEN -+ movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS -+ # Warning: OLDSS(%esp) contains the wrong/random values if we -+ # are returning to the kernel. -+ # See comments in process.c:copy_thread() for details. -+ movb OLDSS(%esp), %ah -+ movb CS(%esp), %al -+ andl $(VM_MASK | (4 << 8) | 3), %eax -+ cmpl $((4 << 8) | 3), %eax -+ je ldt_ss # returning to user-space with LDT SS -+restore_nocheck: -+#else -+restore_nocheck: -+ testl $(VM_MASK|NMI_MASK), EFLAGS(%esp) -+ jnz hypervisor_iret -+ movb EVENT_MASK(%esp), %al -+ notb %al # %al == ~saved_mask -+ GET_VCPU_INFO -+ andb evtchn_upcall_mask(%esi),%al -+ andb $1,%al # %al == mask & ~saved_mask -+ jnz restore_all_enable_events # != 0 => reenable event delivery -+#endif -+ RESTORE_REGS -+ addl $4, %esp -+1: iret -+.section .fixup,"ax" -+iret_exc: -+#ifndef CONFIG_XEN -+ sti -+#endif -+ pushl $0 # no error code -+ pushl $do_iret_error -+ jmp error_code -+.previous -+.section __ex_table,"a" -+ .align 4 -+ .long 1b,iret_exc -+.previous -+ -+#ifndef CONFIG_XEN -+ldt_ss: -+ larl OLDSS(%esp), %eax -+ jnz restore_nocheck -+ testl $0x00400000, %eax # returning to 32bit stack? -+ jnz restore_nocheck # allright, normal return -+ /* If returning to userspace with 16bit stack, -+ * try to fix the higher word of ESP, as the CPU -+ * won't restore it. -+ * This is an "official" bug of all the x86-compatible -+ * CPUs, which we can try to work around to make -+ * dosemu and wine happy. */ -+ subl $8, %esp # reserve space for switch16 pointer -+ cli -+ movl %esp, %eax -+ /* Set up the 16bit stack frame with switch32 pointer on top, -+ * and a switch16 pointer on top of the current frame. */ -+ call setup_x86_bogus_stack -+ RESTORE_REGS -+ lss 20+4(%esp), %esp # switch to 16bit stack -+1: iret -+.section __ex_table,"a" -+ .align 4 -+ .long 1b,iret_exc -+.previous -+#else -+hypervisor_iret: -+ andl $~NMI_MASK, EFLAGS(%esp) -+ RESTORE_REGS -+ addl $4, %esp -+ jmp hypercall_page + (__HYPERVISOR_iret * 32) -+#endif -+ -+ # perform work that needs to be done immediately before resumption -+ ALIGN -+work_pending: -+ testb $_TIF_NEED_RESCHED, %cl -+ jz work_notifysig -+work_resched: -+ call schedule -+ DISABLE_INTERRUPTS # make sure we don't miss an interrupt -+ # setting need_resched or sigpending -+ # between sampling and the iret -+ movl TI_flags(%ebp), %ecx -+ andl $_TIF_WORK_MASK, %ecx # is there any work to be done other -+ # than syscall tracing? -+ jz restore_all -+ testb $_TIF_NEED_RESCHED, %cl -+ jnz work_resched -+ -+work_notifysig: # deal with pending signals and -+ # notify-resume requests -+ testl $VM_MASK, EFLAGS(%esp) -+ movl %esp, %eax -+ jne work_notifysig_v86 # returning to kernel-space or -+ # vm86-space -+ xorl %edx, %edx -+ call do_notify_resume -+ jmp resume_userspace -+ -+ ALIGN -+work_notifysig_v86: -+#ifdef CONFIG_VM86 -+ pushl %ecx # save ti_flags for do_notify_resume -+ call save_v86_state # %eax contains pt_regs pointer -+ popl %ecx -+ movl %eax, %esp -+ xorl %edx, %edx -+ call do_notify_resume -+ jmp resume_userspace -+#endif -+ -+ # perform syscall exit tracing -+ ALIGN -+syscall_trace_entry: -+ movl $-ENOSYS,EAX(%esp) -+ movl %esp, %eax -+ xorl %edx,%edx -+ call do_syscall_trace -+ cmpl $0, %eax -+ jne resume_userspace # ret != 0 -> running under PTRACE_SYSEMU, -+ # so must skip actual syscall -+ movl ORIG_EAX(%esp), %eax -+ cmpl $(nr_syscalls), %eax -+ jnae syscall_call -+ jmp syscall_exit -+ -+ # perform syscall exit tracing -+ ALIGN -+syscall_exit_work: -+ testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl -+ jz work_pending -+ ENABLE_INTERRUPTS # could let do_syscall_trace() call -+ # schedule() instead -+ movl %esp, %eax -+ movl $1, %edx -+ call do_syscall_trace -+ jmp resume_userspace -+ -+ ALIGN -+syscall_fault: -+ pushl %eax # save orig_eax -+ SAVE_ALL -+ GET_THREAD_INFO(%ebp) -+ movl $-EFAULT,EAX(%esp) -+ jmp resume_userspace -+ -+ ALIGN -+syscall_badsys: -+ movl $-ENOSYS,EAX(%esp) -+ jmp resume_userspace -+ -+#ifndef CONFIG_XEN -+#define FIXUP_ESPFIX_STACK \ -+ movl %esp, %eax; \ -+ /* switch to 32bit stack using the pointer on top of 16bit stack */ \ -+ lss %ss:CPU_16BIT_STACK_SIZE-8, %esp; \ -+ /* copy data from 16bit stack to 32bit stack */ \ -+ call fixup_x86_bogus_stack; \ -+ /* put ESP to the proper location */ \ -+ movl %eax, %esp; -+#define UNWIND_ESPFIX_STACK \ -+ pushl %eax; \ -+ movl %ss, %eax; \ -+ /* see if on 16bit stack */ \ -+ cmpw $__ESPFIX_SS, %ax; \ -+ jne 28f; \ -+ movl $__KERNEL_DS, %edx; \ -+ movl %edx, %ds; \ -+ movl %edx, %es; \ -+ /* switch to 32bit stack */ \ -+ FIXUP_ESPFIX_STACK \ -+28: popl %eax; -+ -+/* -+ * Build the entry stubs and pointer table with -+ * some assembler magic. -+ */ -+.data -+ENTRY(interrupt) -+.text -+ -+vector=0 -+ENTRY(irq_entries_start) -+.rept NR_IRQS -+ ALIGN -+1: pushl $vector-256 -+ jmp common_interrupt -+.data -+ .long 1b -+.text -+vector=vector+1 -+.endr -+ -+ ALIGN -+common_interrupt: -+ SAVE_ALL -+ movl %esp,%eax -+ call do_IRQ -+ jmp ret_from_intr -+ -+#define BUILD_INTERRUPT(name, nr) \ -+ENTRY(name) \ -+ pushl $nr-256; \ -+ SAVE_ALL \ -+ movl %esp,%eax; \ -+ call smp_/**/name; \ -+ jmp ret_from_intr; -+ -+/* The include is where all of the SMP etc. interrupts come from */ -+#include "entry_arch.h" -+#else -+#define UNWIND_ESPFIX_STACK -+#endif -+ -+ENTRY(divide_error) -+ pushl $0 # no error code -+ pushl $do_divide_error -+ ALIGN -+error_code: -+ pushl %ds -+ pushl %eax -+ xorl %eax, %eax -+ pushl %ebp -+ pushl %edi -+ pushl %esi -+ pushl %edx -+ decl %eax # eax = -1 -+ pushl %ecx -+ pushl %ebx -+ cld -+ pushl %es -+ UNWIND_ESPFIX_STACK -+ popl %ecx -+ movl ES(%esp), %edi # get the function address -+ movl ORIG_EAX(%esp), %edx # get the error code -+ movl %eax, ORIG_EAX(%esp) -+ movl %ecx, ES(%esp) -+ movl $(__USER_DS), %ecx -+ movl %ecx, %ds -+ movl %ecx, %es -+ movl %esp,%eax # pt_regs pointer -+ call *%edi -+ jmp ret_from_exception -+ -+#ifdef CONFIG_XEN -+# A note on the "critical region" in our callback handler. -+# We want to avoid stacking callback handlers due to events occurring -+# during handling of the last event. To do this, we keep events disabled -+# until we've done all processing. HOWEVER, we must enable events before -+# popping the stack frame (can't be done atomically) and so it would still -+# be possible to get enough handler activations to overflow the stack. -+# Although unlikely, bugs of that kind are hard to track down, so we'd -+# like to avoid the possibility. -+# So, on entry to the handler we detect whether we interrupted an -+# existing activation in its critical region -- if so, we pop the current -+# activation and restart the handler using the previous one. -+ENTRY(hypervisor_callback) -+ pushl %eax -+ SAVE_ALL -+ movl EIP(%esp),%eax -+ cmpl $scrit,%eax -+ jb 11f -+ cmpl $ecrit,%eax -+ jb critical_region_fixup -+11: push %esp -+ call evtchn_do_upcall -+ add $4,%esp -+ jmp ret_from_intr -+ -+ ALIGN -+restore_all_enable_events: -+ __ENABLE_INTERRUPTS -+scrit: /**** START OF CRITICAL REGION ****/ -+ __TEST_PENDING -+ jnz 14f # process more events if necessary... -+ RESTORE_REGS -+ addl $4, %esp -+1: iret -+.section .fixup,"ax" -+2: pushl $0 -+ pushl $do_iret_error -+ jmp error_code -+.previous -+.section __ex_table,"a" -+ .align 4 -+ .long 1b,2b -+.previous -+14: __DISABLE_INTERRUPTS -+ jmp 11b -+ecrit: /**** END OF CRITICAL REGION ****/ -+# [How we do the fixup]. We want to merge the current stack frame with the -+# just-interrupted frame. How we do this depends on where in the critical -+# region the interrupted handler was executing, and so how many saved -+# registers are in each frame. We do this quickly using the lookup table -+# 'critical_fixup_table'. For each byte offset in the critical region, it -+# provides the number of bytes which have already been popped from the -+# interrupted stack frame. -+critical_region_fixup: -+ addl $critical_fixup_table-scrit,%eax -+ movzbl (%eax),%eax # %eax contains num bytes popped -+ cmpb $0xff,%al # 0xff => vcpu_info critical region -+ jne 15f -+ GET_THREAD_INFO(%ebp) -+ xorl %eax,%eax -+15: mov %esp,%esi -+ add %eax,%esi # %esi points at end of src region -+ mov %esp,%edi -+ add $0x34,%edi # %edi points at end of dst region -+ mov %eax,%ecx -+ shr $2,%ecx # convert words to bytes -+ je 17f # skip loop if nothing to copy -+16: subl $4,%esi # pre-decrementing copy loop -+ subl $4,%edi -+ movl (%esi),%eax -+ movl %eax,(%edi) -+ loop 16b -+17: movl %edi,%esp # final %edi is top of merged stack -+ jmp 11b -+ -+critical_fixup_table: -+ .byte 0xff,0xff,0xff # testb $0xff,(%esi) = __TEST_PENDING -+ .byte 0xff,0xff # jnz 14f -+ .byte 0x00 # pop %ebx -+ .byte 0x04 # pop %ecx -+ .byte 0x08 # pop %edx -+ .byte 0x0c # pop %esi -+ .byte 0x10 # pop %edi -+ .byte 0x14 # pop %ebp -+ .byte 0x18 # pop %eax -+ .byte 0x1c # pop %ds -+ .byte 0x20 # pop %es -+ .byte 0x24,0x24,0x24 # add $4,%esp -+ .byte 0x28 # iret -+ .byte 0xff,0xff,0xff,0xff # movb $1,1(%esi) -+ .byte 0x00,0x00 # jmp 11b -+ -+# Hypervisor uses this for application faults while it executes. -+ENTRY(failsafe_callback) -+1: popl %ds -+2: popl %es -+3: popl %fs -+4: popl %gs -+ subl $4,%esp -+ SAVE_ALL -+ jmp ret_from_exception -+.section .fixup,"ax"; \ -+6: movl $0,(%esp); \ -+ jmp 1b; \ -+7: movl $0,(%esp); \ -+ jmp 2b; \ -+8: movl $0,(%esp); \ -+ jmp 3b; \ -+9: movl $0,(%esp); \ -+ jmp 4b; \ -+.previous; \ -+.section __ex_table,"a";\ -+ .align 4; \ -+ .long 1b,6b; \ -+ .long 2b,7b; \ -+ .long 3b,8b; \ -+ .long 4b,9b; \ -+.previous -+#endif -+ -+ENTRY(coprocessor_error) -+ pushl $0 -+ pushl $do_coprocessor_error -+ jmp error_code -+ -+ENTRY(simd_coprocessor_error) -+ pushl $0 -+ pushl $do_simd_coprocessor_error -+ jmp error_code -+ -+ENTRY(device_not_available) -+ pushl $-1 # mark this as an int -+ SAVE_ALL -+#ifndef CONFIG_XEN -+ movl %cr0, %eax -+ testl $0x4, %eax # EM (math emulation bit) -+ je device_available_emulate -+ pushl $0 # temporary storage for ORIG_EIP -+ call math_emulate -+ addl $4, %esp -+ jmp ret_from_exception -+device_available_emulate: -+#endif -+ preempt_stop -+ call math_state_restore -+ jmp ret_from_exception -+ -+#ifdef CONFIG_X86_SYSENTER -+/* -+ * Debug traps and NMI can happen at the one SYSENTER instruction -+ * that sets up the real kernel stack. Check here, since we can't -+ * allow the wrong stack to be used. -+ * -+ * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have -+ * already pushed 3 words if it hits on the sysenter instruction: -+ * eflags, cs and eip. -+ * -+ * We just load the right stack, and push the three (known) values -+ * by hand onto the new stack - while updating the return eip past -+ * the instruction that would have done it for sysenter. -+ */ -+#define FIX_STACK(offset, ok, label) \ -+ cmpw $__KERNEL_CS,4(%esp); \ -+ jne ok; \ -+label: \ -+ movl TSS_sysenter_esp0+offset(%esp),%esp; \ -+ pushfl; \ -+ pushl $__KERNEL_CS; \ -+ pushl $sysenter_past_esp -+#endif /* CONFIG_X86_SYSENTER */ -+ -+KPROBE_ENTRY(debug) -+#ifdef CONFIG_X86_SYSENTER -+ cmpl $sysenter_entry,(%esp) -+ jne debug_stack_correct -+ FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) -+debug_stack_correct: -+#endif /* !CONFIG_X86_SYSENTER */ -+ pushl $-1 # mark this as an int -+ SAVE_ALL -+ xorl %edx,%edx # error code 0 -+ movl %esp,%eax # pt_regs pointer -+ call do_debug -+ jmp ret_from_exception -+ .previous .text -+ -+#ifndef CONFIG_XEN -+/* -+ * NMI is doubly nasty. It can happen _while_ we're handling -+ * a debug fault, and the debug fault hasn't yet been able to -+ * clear up the stack. So we first check whether we got an -+ * NMI on the sysenter entry path, but after that we need to -+ * check whether we got an NMI on the debug path where the debug -+ * fault happened on the sysenter path. -+ */ -+ENTRY(nmi) -+ pushl %eax -+ movl %ss, %eax -+ cmpw $__ESPFIX_SS, %ax -+ popl %eax -+ je nmi_16bit_stack -+ cmpl $sysenter_entry,(%esp) -+ je nmi_stack_fixup -+ pushl %eax -+ movl %esp,%eax -+ /* Do not access memory above the end of our stack page, -+ * it might not exist. -+ */ -+ andl $(THREAD_SIZE-1),%eax -+ cmpl $(THREAD_SIZE-20),%eax -+ popl %eax -+ jae nmi_stack_correct -+ cmpl $sysenter_entry,12(%esp) -+ je nmi_debug_stack_check -+nmi_stack_correct: -+ pushl %eax -+ SAVE_ALL -+ xorl %edx,%edx # zero error code -+ movl %esp,%eax # pt_regs pointer -+ call do_nmi -+ jmp restore_all -+ -+nmi_stack_fixup: -+ FIX_STACK(12,nmi_stack_correct, 1) -+ jmp nmi_stack_correct -+nmi_debug_stack_check: -+ cmpw $__KERNEL_CS,16(%esp) -+ jne nmi_stack_correct -+ cmpl $debug,(%esp) -+ jb nmi_stack_correct -+ cmpl $debug_esp_fix_insn,(%esp) -+ ja nmi_stack_correct -+ FIX_STACK(24,nmi_stack_correct, 1) -+ jmp nmi_stack_correct -+ -+nmi_16bit_stack: -+ /* create the pointer to lss back */ -+ pushl %ss -+ pushl %esp -+ movzwl %sp, %esp -+ addw $4, (%esp) -+ /* copy the iret frame of 12 bytes */ -+ .rept 3 -+ pushl 16(%esp) -+ .endr -+ pushl %eax -+ SAVE_ALL -+ FIXUP_ESPFIX_STACK # %eax == %esp -+ xorl %edx,%edx # zero error code -+ call do_nmi -+ RESTORE_REGS -+ lss 12+4(%esp), %esp # back to 16bit stack -+1: iret -+.section __ex_table,"a" -+ .align 4 -+ .long 1b,iret_exc -+.previous -+#else -+ENTRY(nmi) -+ pushl %eax -+ SAVE_ALL -+ xorl %edx,%edx # zero error code -+ movl %esp,%eax # pt_regs pointer -+ call do_nmi -+ orl $NMI_MASK, EFLAGS(%esp) -+ jmp restore_all -+#endif -+ -+KPROBE_ENTRY(int3) -+ pushl $-1 # mark this as an int -+ SAVE_ALL -+ xorl %edx,%edx # zero error code -+ movl %esp,%eax # pt_regs pointer -+ call do_int3 -+ jmp ret_from_exception -+ .previous .text -+ -+ENTRY(overflow) -+ pushl $0 -+ pushl $do_overflow -+ jmp error_code -+ -+ENTRY(bounds) -+ pushl $0 -+ pushl $do_bounds -+ jmp error_code -+ -+ENTRY(invalid_op) -+ pushl $0 -+ pushl $do_invalid_op -+ jmp error_code -+ -+ENTRY(coprocessor_segment_overrun) -+ pushl $0 -+ pushl $do_coprocessor_segment_overrun -+ jmp error_code -+ -+ENTRY(invalid_TSS) -+ pushl $do_invalid_TSS -+ jmp error_code -+ -+ENTRY(segment_not_present) -+ pushl $do_segment_not_present -+ jmp error_code -+ -+ENTRY(stack_segment) -+ pushl $do_stack_segment -+ jmp error_code -+ -+KPROBE_ENTRY(general_protection) -+ pushl $do_general_protection -+ jmp error_code -+ .previous .text -+ -+ENTRY(alignment_check) -+ pushl $do_alignment_check -+ jmp error_code -+ -+KPROBE_ENTRY(page_fault) -+ pushl $do_page_fault -+ jmp error_code -+ .previous .text -+ -+#ifdef CONFIG_X86_MCE -+ENTRY(machine_check) -+ pushl $0 -+ pushl machine_check_vector -+ jmp error_code -+#endif -+ -+ENTRY(fixup_4gb_segment) -+ pushl $do_fixup_4gb_segment -+ jmp error_code -+ -+.section .rodata,"a" -+#include "syscall_table.S" -+ -+syscall_table_size=(.-sys_call_table) -diff --git a/arch/i386/kernel/fixup.c b/arch/i386/kernel/fixup.c -new file mode 100644 -index 0000000..5188b23 ---- /dev/null -+++ b/arch/i386/kernel/fixup.c -@@ -0,0 +1,95 @@ -+/****************************************************************************** -+ * fixup.c -+ * -+ * Binary-rewriting of certain IA32 instructions, on notification by Xen. -+ * Used to avoid repeated slow emulation of common instructions used by the -+ * user-space TLS (Thread-Local Storage) libraries. -+ * -+ * **** NOTE **** -+ * Issues with the binary rewriting have caused it to be removed. Instead -+ * we rely on Xen's emulator to boot the kernel, and then print a banner -+ * message recommending that the user disables /lib/tls. -+ * -+ * Copyright (c) 2004, K A Fraser -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DP(_f, _args...) printk(KERN_ALERT " " _f "\n" , ## _args ) -+ -+fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code) -+{ -+ static unsigned long printed = 0; -+ char info[100]; -+ int i; -+ -+ if (test_and_set_bit(0, &printed)) -+ return; -+ -+ HYPERVISOR_vm_assist( -+ VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify); -+ -+ sprintf(info, "%s (pid=%d)", current->comm, current->tgid); -+ -+ -+ DP(""); -+ DP("***************************************************************"); -+ DP("***************************************************************"); -+ DP("** WARNING: Currently emulating unsupported memory accesses **"); -+ DP("** in /lib/tls glibc libraries. The emulation is **"); -+ DP("** slow. To ensure full performance you should **"); -+ DP("** install a 'xen-friendly' (nosegneg) version of **"); -+ DP("** the library, or disable tls support by executing **"); -+ DP("** the following as root: **"); -+ DP("** mv /lib/tls /lib/tls.disabled **"); -+ DP("** Offending process: %-38.38s **", info); -+ DP("***************************************************************"); -+ DP("***************************************************************"); -+ DP(""); -+ -+ for (i = 5; i > 0; i--) { -+ printk("Pausing... %d", i); -+ mdelay(1000); -+ printk("\b\b\b\b\b\b\b\b\b\b\b\b"); -+ } -+ -+ printk("Continuing...\n\n"); -+} -+ -+static int __init fixup_init(void) -+{ -+ HYPERVISOR_vm_assist( -+ VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify); -+ return 0; -+} -+__initcall(fixup_init); -+ -+/* -+ * Local variables: -+ * c-file-style: "linux" -+ * indent-tabs-mode: t -+ * c-indent-level: 8 -+ * c-basic-offset: 8 -+ * tab-width: 8 -+ * End: -+ */ -diff --git a/arch/i386/kernel/head-xen.S b/arch/i386/kernel/head-xen.S -new file mode 100644 -index 0000000..23e62c0 ---- /dev/null -+++ b/arch/i386/kernel/head-xen.S -@@ -0,0 +1,171 @@ -+ -+ -+.text -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * References to members of the new_cpu_data structure. -+ */ -+ -+#define X86 new_cpu_data+CPUINFO_x86 -+#define X86_VENDOR new_cpu_data+CPUINFO_x86_vendor -+#define X86_MODEL new_cpu_data+CPUINFO_x86_model -+#define X86_MASK new_cpu_data+CPUINFO_x86_mask -+#define X86_HARD_MATH new_cpu_data+CPUINFO_hard_math -+#define X86_CPUID new_cpu_data+CPUINFO_cpuid_level -+#define X86_CAPABILITY new_cpu_data+CPUINFO_x86_capability -+#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id -+ -+ENTRY(startup_32) -+ movl %esi,xen_start_info -+ cld -+ -+ /* Set up the stack pointer */ -+ movl $(init_thread_union+THREAD_SIZE),%esp -+ -+ /* get vendor info */ -+ xorl %eax,%eax # call CPUID with 0 -> return vendor ID -+ XEN_CPUID -+ movl %eax,X86_CPUID # save CPUID level -+ movl %ebx,X86_VENDOR_ID # lo 4 chars -+ movl %edx,X86_VENDOR_ID+4 # next 4 chars -+ movl %ecx,X86_VENDOR_ID+8 # last 4 chars -+ -+ movl $1,%eax # Use the CPUID instruction to get CPU type -+ XEN_CPUID -+ movb %al,%cl # save reg for future use -+ andb $0x0f,%ah # mask processor family -+ movb %ah,X86 -+ andb $0xf0,%al # mask model -+ shrb $4,%al -+ movb %al,X86_MODEL -+ andb $0x0f,%cl # mask mask revision -+ movb %cl,X86_MASK -+ movl %edx,X86_CAPABILITY -+ -+ movb $1,X86_HARD_MATH -+ -+ xorl %eax,%eax # Clear FS/GS and LDT -+ movl %eax,%fs -+ movl %eax,%gs -+ cld # gcc2 wants the direction flag cleared at all times -+ -+ call start_kernel -+L6: -+ jmp L6 # main should never return here, but -+ # just in case, we know what happens. -+ -+#define HYPERCALL_PAGE_OFFSET 0x1000 -+.org HYPERCALL_PAGE_OFFSET -+ENTRY(hypercall_page) -+.skip 0x1000 -+ -+/* -+ * Real beginning of normal "text" segment -+ */ -+ENTRY(stext) -+ENTRY(_stext) -+ -+/* -+ * BSS section -+ */ -+.section ".bss.page_aligned","w" -+ENTRY(empty_zero_page) -+ .fill 4096,1,0 -+ -+/* -+ * This starts the data section. -+ */ -+.data -+ -+/* -+ * The Global Descriptor Table contains 28 quadwords, per-CPU. -+ */ -+ENTRY(cpu_gdt_table) -+ .quad 0x0000000000000000 /* NULL descriptor */ -+ .quad 0x0000000000000000 /* 0x0b reserved */ -+ .quad 0x0000000000000000 /* 0x13 reserved */ -+ .quad 0x0000000000000000 /* 0x1b reserved */ -+ .quad 0x0000000000000000 /* 0x20 unused */ -+ .quad 0x0000000000000000 /* 0x28 unused */ -+ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ -+ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ -+ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ -+ .quad 0x0000000000000000 /* 0x4b reserved */ -+ .quad 0x0000000000000000 /* 0x53 reserved */ -+ .quad 0x0000000000000000 /* 0x5b reserved */ -+ -+ .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ -+ .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ -+ .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */ -+ .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */ -+ -+ .quad 0x0000000000000000 /* 0x80 TSS descriptor */ -+ .quad 0x0000000000000000 /* 0x88 LDT descriptor */ -+ -+ /* -+ * Segments used for calling PnP BIOS have byte granularity. -+ * They code segments and data segments have fixed 64k limits, -+ * the transfer segment sizes are set at run time. -+ */ -+ .quad 0x0000000000000000 /* 0x90 32-bit code */ -+ .quad 0x0000000000000000 /* 0x98 16-bit code */ -+ .quad 0x0000000000000000 /* 0xa0 16-bit data */ -+ .quad 0x0000000000000000 /* 0xa8 16-bit data */ -+ .quad 0x0000000000000000 /* 0xb0 16-bit data */ -+ -+ /* -+ * The APM segments have byte granularity and their bases -+ * are set at run time. All have 64k limits. -+ */ -+ .quad 0x0000000000000000 /* 0xb8 APM CS code */ -+ .quad 0x0000000000000000 /* 0xc0 APM CS 16 code (16 bit) */ -+ .quad 0x0000000000000000 /* 0xc8 APM DS data */ -+ -+ .quad 0x0000000000000000 /* 0xd0 - ESPFIX 16-bit SS */ -+ .quad 0x0000000000000000 /* 0xd8 - unused */ -+ .quad 0x0000000000000000 /* 0xe0 - unused */ -+ .quad 0x0000000000000000 /* 0xe8 - unused */ -+ .quad 0x0000000000000000 /* 0xf0 - unused */ -+ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ -+ -+/* -+ * __xen_guest information -+ */ -+.macro utoa value -+ .if (\value) < 0 || (\value) >= 0x10 -+ utoa (((\value)>>4)&0x0fffffff) -+ .endif -+ .if ((\value) & 0xf) < 10 -+ .byte '0' + ((\value) & 0xf) -+ .else -+ .byte 'A' + ((\value) & 0xf) - 10 -+ .endif -+.endm -+ -+.section __xen_guest -+ .ascii "GUEST_OS=linux,GUEST_VER=2.6" -+ .ascii ",XEN_VER=xen-3.0" -+ .ascii ",VIRT_BASE=0x" -+ utoa __PAGE_OFFSET -+ .ascii ",HYPERCALL_PAGE=0x" -+ utoa ((__PHYSICAL_START+HYPERCALL_PAGE_OFFSET)>>PAGE_SHIFT) -+ .ascii ",FEATURES=writable_page_tables" -+ .ascii "|writable_descriptor_tables" -+ .ascii "|auto_translated_physmap" -+ .ascii "|pae_pgdir_above_4gb" -+ .ascii "|supervisor_mode_kernel" -+#ifdef CONFIG_X86_PAE -+ .ascii ",PAE=yes" -+#else -+ .ascii ",PAE=no" -+#endif -+ .ascii ",LOADER=generic" -+ .byte 0 -diff --git a/arch/i386/kernel/init_task-xen.c b/arch/i386/kernel/init_task-xen.c -new file mode 100644 -index 0000000..c4da1cc ---- /dev/null -+++ b/arch/i386/kernel/init_task-xen.c -@@ -0,0 +1,51 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static struct fs_struct init_fs = INIT_FS; -+static struct files_struct init_files = INIT_FILES; -+static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -+ -+#define swapper_pg_dir ((pgd_t *)NULL) -+struct mm_struct init_mm = INIT_MM(init_mm); -+#undef swapper_pg_dir -+ -+EXPORT_SYMBOL(init_mm); -+ -+/* -+ * Initial thread structure. -+ * -+ * We need to make sure that this is THREAD_SIZE aligned due to the -+ * way process stacks are handled. This is done by having a special -+ * "init_task" linker map entry.. -+ */ -+union thread_union init_thread_union -+ __attribute__((__section__(".data.init_task"))) = -+ { INIT_THREAD_INFO(init_task) }; -+ -+/* -+ * Initial task structure. -+ * -+ * All other task structs will be allocated on slabs in fork.c -+ */ -+struct task_struct init_task = INIT_TASK(init_task); -+ -+EXPORT_SYMBOL(init_task); -+ -+#ifndef CONFIG_X86_NO_TSS -+/* -+ * per-CPU TSS segments. Threads are completely 'soft' on Linux, -+ * no more per-task TSS's. -+ */ -+DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; -+#endif -+ -diff --git a/arch/i386/kernel/io_apic-xen.c b/arch/i386/kernel/io_apic-xen.c -new file mode 100644 -index 0000000..47edb05 ---- /dev/null -+++ b/arch/i386/kernel/io_apic-xen.c -@@ -0,0 +1,2747 @@ -+/* -+ * Intel IO-APIC support for multi-Pentium hosts. -+ * -+ * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo -+ * -+ * Many thanks to Stig Venaas for trying out countless experimental -+ * patches and reporting/debugging problems patiently! -+ * -+ * (c) 1999, Multiple IO-APIC support, developed by -+ * Ken-ichi Yaku and -+ * Hidemi Kishimoto , -+ * further tested and cleaned up by Zach Brown -+ * and Ingo Molnar -+ * -+ * Fixes -+ * Maciej W. Rozycki : Bits for genuine 82489DX APICs; -+ * thanks to Eric Gilmore -+ * and Rolf G. Tews -+ * for testing these extensively -+ * Paul Diefenbaugh : Added full ACPI support -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "io_ports.h" -+ -+#ifdef CONFIG_XEN -+ -+#include -+#include -+ -+/* Fake i8259 */ -+#define make_8259A_irq(_irq) (io_apic_irqs &= ~(1UL<<(_irq))) -+#define disable_8259A_irq(_irq) ((void)0) -+#define i8259A_irq_pending(_irq) (0) -+ -+unsigned long io_apic_irqs; -+ -+static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg) -+{ -+ physdev_op_t op; -+ int ret; -+ -+ op.cmd = PHYSDEVOP_APIC_READ; -+ op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr; -+ op.u.apic_op.reg = reg; -+ ret = HYPERVISOR_physdev_op(&op); -+ if (ret) -+ return ret; -+ return op.u.apic_op.value; -+} -+ -+static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) -+{ -+ physdev_op_t op; -+ -+ op.cmd = PHYSDEVOP_APIC_WRITE; -+ op.u.apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr; -+ op.u.apic_op.reg = reg; -+ op.u.apic_op.value = value; -+ HYPERVISOR_physdev_op(&op); -+} -+ -+#define io_apic_read(a,r) xen_io_apic_read(a,r) -+#define io_apic_write(a,r,v) xen_io_apic_write(a,r,v) -+ -+#endif /* CONFIG_XEN */ -+ -+int (*ioapic_renumber_irq)(int ioapic, int irq); -+atomic_t irq_mis_count; -+ -+/* Where if anywhere is the i8259 connect in external int mode */ -+static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; -+ -+static DEFINE_SPINLOCK(ioapic_lock); -+ -+int timer_over_8254 __initdata = 1; -+ -+/* -+ * Is the SiS APIC rmw bug present ? -+ * -1 = don't know, 0 = no, 1 = yes -+ */ -+int sis_apic_bug = -1; -+ -+/* -+ * # of IRQ routing registers -+ */ -+int nr_ioapic_registers[MAX_IO_APICS]; -+ -+int disable_timer_pin_1 __initdata; -+ -+/* -+ * Rough estimation of how many shared IRQs there are, can -+ * be changed anytime. -+ */ -+#define MAX_PLUS_SHARED_IRQS NR_IRQS -+#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS) -+ -+/* -+ * This is performance-critical, we want to do it O(1) -+ * -+ * the indexing order of this array favors 1:1 mappings -+ * between pins and IRQs. -+ */ -+ -+static struct irq_pin_list { -+ int apic, pin, next; -+} irq_2_pin[PIN_MAP_SIZE]; -+ -+int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; -+#ifdef CONFIG_PCI_MSI -+#define vector_to_irq(vector) \ -+ (platform_legacy_irq(vector) ? vector : vector_irq[vector]) -+#else -+#define vector_to_irq(vector) (vector) -+#endif -+ -+/* -+ * The common case is 1:1 IRQ<->pin mappings. Sometimes there are -+ * shared ISA-space IRQs, so we have to support them. We are super -+ * fast in the common case, and fast for shared ISA-space IRQs. -+ */ -+static void add_pin_to_irq(unsigned int irq, int apic, int pin) -+{ -+ static int first_free_entry = NR_IRQS; -+ struct irq_pin_list *entry = irq_2_pin + irq; -+ -+ while (entry->next) -+ entry = irq_2_pin + entry->next; -+ -+ if (entry->pin != -1) { -+ entry->next = first_free_entry; -+ entry = irq_2_pin + entry->next; -+ if (++first_free_entry >= PIN_MAP_SIZE) -+ panic("io_apic.c: whoops"); -+ } -+ entry->apic = apic; -+ entry->pin = pin; -+} -+ -+#ifdef CONFIG_XEN -+#define clear_IO_APIC() ((void)0) -+#else -+/* -+ * Reroute an IRQ to a different pin. -+ */ -+static void __init replace_pin_at_irq(unsigned int irq, -+ int oldapic, int oldpin, -+ int newapic, int newpin) -+{ -+ struct irq_pin_list *entry = irq_2_pin + irq; -+ -+ while (1) { -+ if (entry->apic == oldapic && entry->pin == oldpin) { -+ entry->apic = newapic; -+ entry->pin = newpin; -+ } -+ if (!entry->next) -+ break; -+ entry = irq_2_pin + entry->next; -+ } -+} -+ -+static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable) -+{ -+ struct irq_pin_list *entry = irq_2_pin + irq; -+ unsigned int pin, reg; -+ -+ for (;;) { -+ pin = entry->pin; -+ if (pin == -1) -+ break; -+ reg = io_apic_read(entry->apic, 0x10 + pin*2); -+ reg &= ~disable; -+ reg |= enable; -+ io_apic_modify(entry->apic, 0x10 + pin*2, reg); -+ if (!entry->next) -+ break; -+ entry = irq_2_pin + entry->next; -+ } -+} -+ -+/* mask = 1 */ -+static void __mask_IO_APIC_irq (unsigned int irq) -+{ -+ __modify_IO_APIC_irq(irq, 0x00010000, 0); -+} -+ -+/* mask = 0 */ -+static void __unmask_IO_APIC_irq (unsigned int irq) -+{ -+ __modify_IO_APIC_irq(irq, 0, 0x00010000); -+} -+ -+/* mask = 1, trigger = 0 */ -+static void __mask_and_edge_IO_APIC_irq (unsigned int irq) -+{ -+ __modify_IO_APIC_irq(irq, 0x00010000, 0x00008000); -+} -+ -+/* mask = 0, trigger = 1 */ -+static void __unmask_and_level_IO_APIC_irq (unsigned int irq) -+{ -+ __modify_IO_APIC_irq(irq, 0x00008000, 0x00010000); -+} -+ -+static void mask_IO_APIC_irq (unsigned int irq) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ __mask_IO_APIC_irq(irq); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+} -+ -+static void unmask_IO_APIC_irq (unsigned int irq) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ __unmask_IO_APIC_irq(irq); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+} -+ -+static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) -+{ -+ struct IO_APIC_route_entry entry; -+ unsigned long flags; -+ -+ /* Check delivery_mode to be sure we're not clearing an SMI pin */ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); -+ *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ if (entry.delivery_mode == dest_SMI) -+ return; -+ -+ /* -+ * Disable it in the IO-APIC irq-routing table: -+ */ -+ memset(&entry, 0, sizeof(entry)); -+ entry.mask = 1; -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0)); -+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1)); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+} -+ -+static void clear_IO_APIC (void) -+{ -+ int apic, pin; -+ -+ for (apic = 0; apic < nr_ioapics; apic++) -+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) -+ clear_IO_APIC_pin(apic, pin); -+} -+ -+#ifdef CONFIG_SMP -+static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) -+{ -+ unsigned long flags; -+ int pin; -+ struct irq_pin_list *entry = irq_2_pin + irq; -+ unsigned int apicid_value; -+ cpumask_t tmp; -+ -+ cpus_and(tmp, cpumask, cpu_online_map); -+ if (cpus_empty(tmp)) -+ tmp = TARGET_CPUS; -+ -+ cpus_and(cpumask, tmp, CPU_MASK_ALL); -+ -+ apicid_value = cpu_mask_to_apicid(cpumask); -+ /* Prepare to do the io_apic_write */ -+ apicid_value = apicid_value << 24; -+ spin_lock_irqsave(&ioapic_lock, flags); -+ for (;;) { -+ pin = entry->pin; -+ if (pin == -1) -+ break; -+ io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value); -+ if (!entry->next) -+ break; -+ entry = irq_2_pin + entry->next; -+ } -+ set_irq_info(irq, cpumask); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+} -+ -+#if defined(CONFIG_IRQBALANCE) -+# include /* kernel_thread() */ -+# include /* kstat */ -+# include /* kmalloc() */ -+# include /* time_after() */ -+ -+# ifdef CONFIG_BALANCED_IRQ_DEBUG -+# define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) -+# define Dprintk(x...) do { TDprintk(x); } while (0) -+# else -+# define TDprintk(x...) -+# define Dprintk(x...) -+# endif -+ -+ -+#define IRQBALANCE_CHECK_ARCH -999 -+static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; -+static int physical_balance = 0; -+ -+static struct irq_cpu_info { -+ unsigned long * last_irq; -+ unsigned long * irq_delta; -+ unsigned long irq; -+} irq_cpu_data[NR_CPUS]; -+ -+#define CPU_IRQ(cpu) (irq_cpu_data[cpu].irq) -+#define LAST_CPU_IRQ(cpu,irq) (irq_cpu_data[cpu].last_irq[irq]) -+#define IRQ_DELTA(cpu,irq) (irq_cpu_data[cpu].irq_delta[irq]) -+ -+#define IDLE_ENOUGH(cpu,now) \ -+ (idle_cpu(cpu) && ((now) - per_cpu(irq_stat, (cpu)).idle_timestamp > 1)) -+ -+#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask) -+ -+#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) -+ -+#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) -+#define MIN_BALANCED_IRQ_INTERVAL (HZ/2) -+#define BALANCED_IRQ_MORE_DELTA (HZ/10) -+#define BALANCED_IRQ_LESS_DELTA (HZ) -+ -+static long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; -+ -+static unsigned long move(int curr_cpu, cpumask_t allowed_mask, -+ unsigned long now, int direction) -+{ -+ int search_idle = 1; -+ int cpu = curr_cpu; -+ -+ goto inside; -+ -+ do { -+ if (unlikely(cpu == curr_cpu)) -+ search_idle = 0; -+inside: -+ if (direction == 1) { -+ cpu++; -+ if (cpu >= NR_CPUS) -+ cpu = 0; -+ } else { -+ cpu--; -+ if (cpu == -1) -+ cpu = NR_CPUS-1; -+ } -+ } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu,allowed_mask) || -+ (search_idle && !IDLE_ENOUGH(cpu,now))); -+ -+ return cpu; -+} -+ -+static inline void balance_irq(int cpu, int irq) -+{ -+ unsigned long now = jiffies; -+ cpumask_t allowed_mask; -+ unsigned int new_cpu; -+ -+ if (irqbalance_disabled) -+ return; -+ -+ cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); -+ new_cpu = move(cpu, allowed_mask, now, 1); -+ if (cpu != new_cpu) { -+ set_pending_irq(irq, cpumask_of_cpu(new_cpu)); -+ } -+} -+ -+static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) -+{ -+ int i, j; -+ Dprintk("Rotating IRQs among CPUs.\n"); -+ for (i = 0; i < NR_CPUS; i++) { -+ for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) { -+ if (!irq_desc[j].action) -+ continue; -+ /* Is it a significant load ? */ -+ if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i),j) < -+ useful_load_threshold) -+ continue; -+ balance_irq(i, j); -+ } -+ } -+ balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, -+ balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); -+ return; -+} -+ -+static void do_irq_balance(void) -+{ -+ int i, j; -+ unsigned long max_cpu_irq = 0, min_cpu_irq = (~0); -+ unsigned long move_this_load = 0; -+ int max_loaded = 0, min_loaded = 0; -+ int load; -+ unsigned long useful_load_threshold = balanced_irq_interval + 10; -+ int selected_irq; -+ int tmp_loaded, first_attempt = 1; -+ unsigned long tmp_cpu_irq; -+ unsigned long imbalance = 0; -+ cpumask_t allowed_mask, target_cpu_mask, tmp; -+ -+ for (i = 0; i < NR_CPUS; i++) { -+ int package_index; -+ CPU_IRQ(i) = 0; -+ if (!cpu_online(i)) -+ continue; -+ package_index = CPU_TO_PACKAGEINDEX(i); -+ for (j = 0; j < NR_IRQS; j++) { -+ unsigned long value_now, delta; -+ /* Is this an active IRQ? */ -+ if (!irq_desc[j].action) -+ continue; -+ if ( package_index == i ) -+ IRQ_DELTA(package_index,j) = 0; -+ /* Determine the total count per processor per IRQ */ -+ value_now = (unsigned long) kstat_cpu(i).irqs[j]; -+ -+ /* Determine the activity per processor per IRQ */ -+ delta = value_now - LAST_CPU_IRQ(i,j); -+ -+ /* Update last_cpu_irq[][] for the next time */ -+ LAST_CPU_IRQ(i,j) = value_now; -+ -+ /* Ignore IRQs whose rate is less than the clock */ -+ if (delta < useful_load_threshold) -+ continue; -+ /* update the load for the processor or package total */ -+ IRQ_DELTA(package_index,j) += delta; -+ -+ /* Keep track of the higher numbered sibling as well */ -+ if (i != package_index) -+ CPU_IRQ(i) += delta; -+ /* -+ * We have sibling A and sibling B in the package -+ * -+ * cpu_irq[A] = load for cpu A + load for cpu B -+ * cpu_irq[B] = load for cpu B -+ */ -+ CPU_IRQ(package_index) += delta; -+ } -+ } -+ /* Find the least loaded processor package */ -+ for (i = 0; i < NR_CPUS; i++) { -+ if (!cpu_online(i)) -+ continue; -+ if (i != CPU_TO_PACKAGEINDEX(i)) -+ continue; -+ if (min_cpu_irq > CPU_IRQ(i)) { -+ min_cpu_irq = CPU_IRQ(i); -+ min_loaded = i; -+ } -+ } -+ max_cpu_irq = ULONG_MAX; -+ -+tryanothercpu: -+ /* Look for heaviest loaded processor. -+ * We may come back to get the next heaviest loaded processor. -+ * Skip processors with trivial loads. -+ */ -+ tmp_cpu_irq = 0; -+ tmp_loaded = -1; -+ for (i = 0; i < NR_CPUS; i++) { -+ if (!cpu_online(i)) -+ continue; -+ if (i != CPU_TO_PACKAGEINDEX(i)) -+ continue; -+ if (max_cpu_irq <= CPU_IRQ(i)) -+ continue; -+ if (tmp_cpu_irq < CPU_IRQ(i)) { -+ tmp_cpu_irq = CPU_IRQ(i); -+ tmp_loaded = i; -+ } -+ } -+ -+ if (tmp_loaded == -1) { -+ /* In the case of small number of heavy interrupt sources, -+ * loading some of the cpus too much. We use Ingo's original -+ * approach to rotate them around. -+ */ -+ if (!first_attempt && imbalance >= useful_load_threshold) { -+ rotate_irqs_among_cpus(useful_load_threshold); -+ return; -+ } -+ goto not_worth_the_effort; -+ } -+ -+ first_attempt = 0; /* heaviest search */ -+ max_cpu_irq = tmp_cpu_irq; /* load */ -+ max_loaded = tmp_loaded; /* processor */ -+ imbalance = (max_cpu_irq - min_cpu_irq) / 2; -+ -+ Dprintk("max_loaded cpu = %d\n", max_loaded); -+ Dprintk("min_loaded cpu = %d\n", min_loaded); -+ Dprintk("max_cpu_irq load = %ld\n", max_cpu_irq); -+ Dprintk("min_cpu_irq load = %ld\n", min_cpu_irq); -+ Dprintk("load imbalance = %lu\n", imbalance); -+ -+ /* if imbalance is less than approx 10% of max load, then -+ * observe diminishing returns action. - quit -+ */ -+ if (imbalance < (max_cpu_irq >> 3)) { -+ Dprintk("Imbalance too trivial\n"); -+ goto not_worth_the_effort; -+ } -+ -+tryanotherirq: -+ /* if we select an IRQ to move that can't go where we want, then -+ * see if there is another one to try. -+ */ -+ move_this_load = 0; -+ selected_irq = -1; -+ for (j = 0; j < NR_IRQS; j++) { -+ /* Is this an active IRQ? */ -+ if (!irq_desc[j].action) -+ continue; -+ if (imbalance <= IRQ_DELTA(max_loaded,j)) -+ continue; -+ /* Try to find the IRQ that is closest to the imbalance -+ * without going over. -+ */ -+ if (move_this_load < IRQ_DELTA(max_loaded,j)) { -+ move_this_load = IRQ_DELTA(max_loaded,j); -+ selected_irq = j; -+ } -+ } -+ if (selected_irq == -1) { -+ goto tryanothercpu; -+ } -+ -+ imbalance = move_this_load; -+ -+ /* For physical_balance case, we accumlated both load -+ * values in the one of the siblings cpu_irq[], -+ * to use the same code for physical and logical processors -+ * as much as possible. -+ * -+ * NOTE: the cpu_irq[] array holds the sum of the load for -+ * sibling A and sibling B in the slot for the lowest numbered -+ * sibling (A), _AND_ the load for sibling B in the slot for -+ * the higher numbered sibling. -+ * -+ * We seek the least loaded sibling by making the comparison -+ * (A+B)/2 vs B -+ */ -+ load = CPU_IRQ(min_loaded) >> 1; -+ for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) { -+ if (load > CPU_IRQ(j)) { -+ /* This won't change cpu_sibling_map[min_loaded] */ -+ load = CPU_IRQ(j); -+ min_loaded = j; -+ } -+ } -+ -+ cpus_and(allowed_mask, cpu_online_map, irq_affinity[selected_irq]); -+ target_cpu_mask = cpumask_of_cpu(min_loaded); -+ cpus_and(tmp, target_cpu_mask, allowed_mask); -+ -+ if (!cpus_empty(tmp)) { -+ -+ Dprintk("irq = %d moved to cpu = %d\n", -+ selected_irq, min_loaded); -+ /* mark for change destination */ -+ set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded)); -+ -+ /* Since we made a change, come back sooner to -+ * check for more variation. -+ */ -+ balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, -+ balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); -+ return; -+ } -+ goto tryanotherirq; -+ -+not_worth_the_effort: -+ /* -+ * if we did not find an IRQ to move, then adjust the time interval -+ * upward -+ */ -+ balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL, -+ balanced_irq_interval + BALANCED_IRQ_MORE_DELTA); -+ Dprintk("IRQ worth rotating not found\n"); -+ return; -+} -+ -+static int balanced_irq(void *unused) -+{ -+ int i; -+ unsigned long prev_balance_time = jiffies; -+ long time_remaining = balanced_irq_interval; -+ -+ daemonize("kirqd"); -+ -+ /* push everything to CPU 0 to give us a starting point. */ -+ for (i = 0 ; i < NR_IRQS ; i++) { -+ pending_irq_cpumask[i] = cpumask_of_cpu(0); -+ set_pending_irq(i, cpumask_of_cpu(0)); -+ } -+ -+ for ( ; ; ) { -+ time_remaining = schedule_timeout_interruptible(time_remaining); -+ try_to_freeze(); -+ if (time_after(jiffies, -+ prev_balance_time+balanced_irq_interval)) { -+ preempt_disable(); -+ do_irq_balance(); -+ prev_balance_time = jiffies; -+ time_remaining = balanced_irq_interval; -+ preempt_enable(); -+ } -+ } -+ return 0; -+} -+ -+static int __init balanced_irq_init(void) -+{ -+ int i; -+ struct cpuinfo_x86 *c; -+ cpumask_t tmp; -+ -+ cpus_shift_right(tmp, cpu_online_map, 2); -+ c = &boot_cpu_data; -+ /* When not overwritten by the command line ask subarchitecture. */ -+ if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH) -+ irqbalance_disabled = NO_BALANCE_IRQ; -+ if (irqbalance_disabled) -+ return 0; -+ -+ /* disable irqbalance completely if there is only one processor online */ -+ if (num_online_cpus() < 2) { -+ irqbalance_disabled = 1; -+ return 0; -+ } -+ /* -+ * Enable physical balance only if more than 1 physical processor -+ * is present -+ */ -+ if (smp_num_siblings > 1 && !cpus_empty(tmp)) -+ physical_balance = 1; -+ -+ for (i = 0; i < NR_CPUS; i++) { -+ if (!cpu_online(i)) -+ continue; -+ irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); -+ irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); -+ if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { -+ printk(KERN_ERR "balanced_irq_init: out of memory"); -+ goto failed; -+ } -+ memset(irq_cpu_data[i].irq_delta,0,sizeof(unsigned long) * NR_IRQS); -+ memset(irq_cpu_data[i].last_irq,0,sizeof(unsigned long) * NR_IRQS); -+ } -+ -+ printk(KERN_INFO "Starting balanced_irq\n"); -+ if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) -+ return 0; -+ else -+ printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); -+failed: -+ for (i = 0; i < NR_CPUS; i++) { -+ kfree(irq_cpu_data[i].irq_delta); -+ kfree(irq_cpu_data[i].last_irq); -+ } -+ return 0; -+} -+ -+int __init irqbalance_disable(char *str) -+{ -+ irqbalance_disabled = 1; -+ return 0; -+} -+ -+__setup("noirqbalance", irqbalance_disable); -+ -+late_initcall(balanced_irq_init); -+#endif /* CONFIG_IRQBALANCE */ -+#endif /* CONFIG_SMP */ -+#endif -+ -+#ifndef CONFIG_SMP -+void fastcall send_IPI_self(int vector) -+{ -+#ifndef CONFIG_XEN -+ unsigned int cfg; -+ -+ /* -+ * Wait for idle. -+ */ -+ apic_wait_icr_idle(); -+ cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL; -+ /* -+ * Send the IPI. The write to APIC_ICR fires this off. -+ */ -+ apic_write_around(APIC_ICR, cfg); -+#endif -+} -+#endif /* !CONFIG_SMP */ -+ -+ -+/* -+ * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to -+ * specific CPU-side IRQs. -+ */ -+ -+#define MAX_PIRQS 8 -+static int pirq_entries [MAX_PIRQS]; -+static int pirqs_enabled; -+int skip_ioapic_setup; -+ -+static int __init ioapic_setup(char *str) -+{ -+ skip_ioapic_setup = 1; -+ return 1; -+} -+ -+__setup("noapic", ioapic_setup); -+ -+static int __init ioapic_pirq_setup(char *str) -+{ -+ int i, max; -+ int ints[MAX_PIRQS+1]; -+ -+ get_options(str, ARRAY_SIZE(ints), ints); -+ -+ for (i = 0; i < MAX_PIRQS; i++) -+ pirq_entries[i] = -1; -+ -+ pirqs_enabled = 1; -+ apic_printk(APIC_VERBOSE, KERN_INFO -+ "PIRQ redirection, working around broken MP-BIOS.\n"); -+ max = MAX_PIRQS; -+ if (ints[0] < MAX_PIRQS) -+ max = ints[0]; -+ -+ for (i = 0; i < max; i++) { -+ apic_printk(APIC_VERBOSE, KERN_DEBUG -+ "... PIRQ%d -> IRQ %d\n", i, ints[i+1]); -+ /* -+ * PIRQs are mapped upside down, usually. -+ */ -+ pirq_entries[MAX_PIRQS-i-1] = ints[i+1]; -+ } -+ return 1; -+} -+ -+__setup("pirq=", ioapic_pirq_setup); -+ -+/* -+ * Find the IRQ entry number of a certain pin. -+ */ -+static int find_irq_entry(int apic, int pin, int type) -+{ -+ int i; -+ -+ for (i = 0; i < mp_irq_entries; i++) -+ if (mp_irqs[i].mpc_irqtype == type && -+ (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid || -+ mp_irqs[i].mpc_dstapic == MP_APIC_ALL) && -+ mp_irqs[i].mpc_dstirq == pin) -+ return i; -+ -+ return -1; -+} -+ -+/* -+ * Find the pin to which IRQ[irq] (ISA) is connected -+ */ -+static int __init find_isa_irq_pin(int irq, int type) -+{ -+ int i; -+ -+ for (i = 0; i < mp_irq_entries; i++) { -+ int lbus = mp_irqs[i].mpc_srcbus; -+ -+ if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || -+ mp_bus_id_to_type[lbus] == MP_BUS_EISA || -+ mp_bus_id_to_type[lbus] == MP_BUS_MCA || -+ mp_bus_id_to_type[lbus] == MP_BUS_NEC98 -+ ) && -+ (mp_irqs[i].mpc_irqtype == type) && -+ (mp_irqs[i].mpc_srcbusirq == irq)) -+ -+ return mp_irqs[i].mpc_dstirq; -+ } -+ return -1; -+} -+ -+static int __init find_isa_irq_apic(int irq, int type) -+{ -+ int i; -+ -+ for (i = 0; i < mp_irq_entries; i++) { -+ int lbus = mp_irqs[i].mpc_srcbus; -+ -+ if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || -+ mp_bus_id_to_type[lbus] == MP_BUS_EISA || -+ mp_bus_id_to_type[lbus] == MP_BUS_MCA || -+ mp_bus_id_to_type[lbus] == MP_BUS_NEC98 -+ ) && -+ (mp_irqs[i].mpc_irqtype == type) && -+ (mp_irqs[i].mpc_srcbusirq == irq)) -+ break; -+ } -+ if (i < mp_irq_entries) { -+ int apic; -+ for(apic = 0; apic < nr_ioapics; apic++) { -+ if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic) -+ return apic; -+ } -+ } -+ -+ return -1; -+} -+ -+/* -+ * Find a specific PCI IRQ entry. -+ * Not an __init, possibly needed by modules -+ */ -+static int pin_2_irq(int idx, int apic, int pin); -+ -+int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) -+{ -+ int apic, i, best_guess = -1; -+ -+ apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, " -+ "slot:%d, pin:%d.\n", bus, slot, pin); -+ if (mp_bus_id_to_pci_bus[bus] == -1) { -+ printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus); -+ return -1; -+ } -+ for (i = 0; i < mp_irq_entries; i++) { -+ int lbus = mp_irqs[i].mpc_srcbus; -+ -+ for (apic = 0; apic < nr_ioapics; apic++) -+ if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic || -+ mp_irqs[i].mpc_dstapic == MP_APIC_ALL) -+ break; -+ -+ if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) && -+ !mp_irqs[i].mpc_irqtype && -+ (bus == lbus) && -+ (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) { -+ int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq); -+ -+ if (!(apic || IO_APIC_IRQ(irq))) -+ continue; -+ -+ if (pin == (mp_irqs[i].mpc_srcbusirq & 3)) -+ return irq; -+ /* -+ * Use the first all-but-pin matching entry as a -+ * best-guess fuzzy result for broken mptables. -+ */ -+ if (best_guess < 0) -+ best_guess = irq; -+ } -+ } -+ return best_guess; -+} -+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); -+ -+/* -+ * This function currently is only a helper for the i386 smp boot process where -+ * we need to reprogram the ioredtbls to cater for the cpus which have come online -+ * so mask in all cases should simply be TARGET_CPUS -+ */ -+#ifdef CONFIG_SMP -+#ifndef CONFIG_XEN -+void __init setup_ioapic_dest(void) -+{ -+ int pin, ioapic, irq, irq_entry; -+ -+ if (skip_ioapic_setup == 1) -+ return; -+ -+ for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { -+ for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { -+ irq_entry = find_irq_entry(ioapic, pin, mp_INT); -+ if (irq_entry == -1) -+ continue; -+ irq = pin_2_irq(irq_entry, ioapic, pin); -+ set_ioapic_affinity_irq(irq, TARGET_CPUS); -+ } -+ -+ } -+} -+#endif /* !CONFIG_XEN */ -+#endif -+ -+/* -+ * EISA Edge/Level control register, ELCR -+ */ -+static int EISA_ELCR(unsigned int irq) -+{ -+ if (irq < 16) { -+ unsigned int port = 0x4d0 + (irq >> 3); -+ return (inb(port) >> (irq & 7)) & 1; -+ } -+ apic_printk(APIC_VERBOSE, KERN_INFO -+ "Broken MPtable reports ISA irq %d\n", irq); -+ return 0; -+} -+ -+/* EISA interrupts are always polarity zero and can be edge or level -+ * trigger depending on the ELCR value. If an interrupt is listed as -+ * EISA conforming in the MP table, that means its trigger type must -+ * be read in from the ELCR */ -+ -+#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq)) -+#define default_EISA_polarity(idx) (0) -+ -+/* ISA interrupts are always polarity zero edge triggered, -+ * when listed as conforming in the MP table. */ -+ -+#define default_ISA_trigger(idx) (0) -+#define default_ISA_polarity(idx) (0) -+ -+/* PCI interrupts are always polarity one level triggered, -+ * when listed as conforming in the MP table. */ -+ -+#define default_PCI_trigger(idx) (1) -+#define default_PCI_polarity(idx) (1) -+ -+/* MCA interrupts are always polarity zero level triggered, -+ * when listed as conforming in the MP table. */ -+ -+#define default_MCA_trigger(idx) (1) -+#define default_MCA_polarity(idx) (0) -+ -+/* NEC98 interrupts are always polarity zero edge triggered, -+ * when listed as conforming in the MP table. */ -+ -+#define default_NEC98_trigger(idx) (0) -+#define default_NEC98_polarity(idx) (0) -+ -+static int __init MPBIOS_polarity(int idx) -+{ -+ int bus = mp_irqs[idx].mpc_srcbus; -+ int polarity; -+ -+ /* -+ * Determine IRQ line polarity (high active or low active): -+ */ -+ switch (mp_irqs[idx].mpc_irqflag & 3) -+ { -+ case 0: /* conforms, ie. bus-type dependent polarity */ -+ { -+ switch (mp_bus_id_to_type[bus]) -+ { -+ case MP_BUS_ISA: /* ISA pin */ -+ { -+ polarity = default_ISA_polarity(idx); -+ break; -+ } -+ case MP_BUS_EISA: /* EISA pin */ -+ { -+ polarity = default_EISA_polarity(idx); -+ break; -+ } -+ case MP_BUS_PCI: /* PCI pin */ -+ { -+ polarity = default_PCI_polarity(idx); -+ break; -+ } -+ case MP_BUS_MCA: /* MCA pin */ -+ { -+ polarity = default_MCA_polarity(idx); -+ break; -+ } -+ case MP_BUS_NEC98: /* NEC 98 pin */ -+ { -+ polarity = default_NEC98_polarity(idx); -+ break; -+ } -+ default: -+ { -+ printk(KERN_WARNING "broken BIOS!!\n"); -+ polarity = 1; -+ break; -+ } -+ } -+ break; -+ } -+ case 1: /* high active */ -+ { -+ polarity = 0; -+ break; -+ } -+ case 2: /* reserved */ -+ { -+ printk(KERN_WARNING "broken BIOS!!\n"); -+ polarity = 1; -+ break; -+ } -+ case 3: /* low active */ -+ { -+ polarity = 1; -+ break; -+ } -+ default: /* invalid */ -+ { -+ printk(KERN_WARNING "broken BIOS!!\n"); -+ polarity = 1; -+ break; -+ } -+ } -+ return polarity; -+} -+ -+static int MPBIOS_trigger(int idx) -+{ -+ int bus = mp_irqs[idx].mpc_srcbus; -+ int trigger; -+ -+ /* -+ * Determine IRQ trigger mode (edge or level sensitive): -+ */ -+ switch ((mp_irqs[idx].mpc_irqflag>>2) & 3) -+ { -+ case 0: /* conforms, ie. bus-type dependent */ -+ { -+ switch (mp_bus_id_to_type[bus]) -+ { -+ case MP_BUS_ISA: /* ISA pin */ -+ { -+ trigger = default_ISA_trigger(idx); -+ break; -+ } -+ case MP_BUS_EISA: /* EISA pin */ -+ { -+ trigger = default_EISA_trigger(idx); -+ break; -+ } -+ case MP_BUS_PCI: /* PCI pin */ -+ { -+ trigger = default_PCI_trigger(idx); -+ break; -+ } -+ case MP_BUS_MCA: /* MCA pin */ -+ { -+ trigger = default_MCA_trigger(idx); -+ break; -+ } -+ case MP_BUS_NEC98: /* NEC 98 pin */ -+ { -+ trigger = default_NEC98_trigger(idx); -+ break; -+ } -+ default: -+ { -+ printk(KERN_WARNING "broken BIOS!!\n"); -+ trigger = 1; -+ break; -+ } -+ } -+ break; -+ } -+ case 1: /* edge */ -+ { -+ trigger = 0; -+ break; -+ } -+ case 2: /* reserved */ -+ { -+ printk(KERN_WARNING "broken BIOS!!\n"); -+ trigger = 1; -+ break; -+ } -+ case 3: /* level */ -+ { -+ trigger = 1; -+ break; -+ } -+ default: /* invalid */ -+ { -+ printk(KERN_WARNING "broken BIOS!!\n"); -+ trigger = 0; -+ break; -+ } -+ } -+ return trigger; -+} -+ -+static inline int irq_polarity(int idx) -+{ -+ return MPBIOS_polarity(idx); -+} -+ -+static inline int irq_trigger(int idx) -+{ -+ return MPBIOS_trigger(idx); -+} -+ -+static int pin_2_irq(int idx, int apic, int pin) -+{ -+ int irq, i; -+ int bus = mp_irqs[idx].mpc_srcbus; -+ -+ /* -+ * Debugging check, we are in big trouble if this message pops up! -+ */ -+ if (mp_irqs[idx].mpc_dstirq != pin) -+ printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); -+ -+ switch (mp_bus_id_to_type[bus]) -+ { -+ case MP_BUS_ISA: /* ISA pin */ -+ case MP_BUS_EISA: -+ case MP_BUS_MCA: -+ case MP_BUS_NEC98: -+ { -+ irq = mp_irqs[idx].mpc_srcbusirq; -+ break; -+ } -+ case MP_BUS_PCI: /* PCI pin */ -+ { -+ /* -+ * PCI IRQs are mapped in order -+ */ -+ i = irq = 0; -+ while (i < apic) -+ irq += nr_ioapic_registers[i++]; -+ irq += pin; -+ -+ /* -+ * For MPS mode, so far only needed by ES7000 platform -+ */ -+ if (ioapic_renumber_irq) -+ irq = ioapic_renumber_irq(apic, irq); -+ -+ break; -+ } -+ default: -+ { -+ printk(KERN_ERR "unknown bus type %d.\n",bus); -+ irq = 0; -+ break; -+ } -+ } -+ -+ /* -+ * PCI IRQ command line redirection. Yes, limits are hardcoded. -+ */ -+ if ((pin >= 16) && (pin <= 23)) { -+ if (pirq_entries[pin-16] != -1) { -+ if (!pirq_entries[pin-16]) { -+ apic_printk(APIC_VERBOSE, KERN_DEBUG -+ "disabling PIRQ%d\n", pin-16); -+ } else { -+ irq = pirq_entries[pin-16]; -+ apic_printk(APIC_VERBOSE, KERN_DEBUG -+ "using PIRQ%d -> IRQ %d\n", -+ pin-16, irq); -+ } -+ } -+ } -+ return irq; -+} -+ -+static inline int IO_APIC_irq_trigger(int irq) -+{ -+ int apic, idx, pin; -+ -+ for (apic = 0; apic < nr_ioapics; apic++) { -+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { -+ idx = find_irq_entry(apic,pin,mp_INT); -+ if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin))) -+ return irq_trigger(idx); -+ } -+ } -+ /* -+ * nonexistent IRQs are edge default -+ */ -+ return 0; -+} -+ -+/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ -+u8 irq_vector[NR_IRQ_VECTORS] __read_mostly; /* = { FIRST_DEVICE_VECTOR , 0 }; */ -+ -+int assign_irq_vector(int irq) -+{ -+ static int current_vector = FIRST_DEVICE_VECTOR; -+ physdev_op_t op; -+ -+ BUG_ON(irq >= NR_IRQ_VECTORS); -+ if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) -+ return IO_APIC_VECTOR(irq); -+ -+ op.cmd = PHYSDEVOP_ASSIGN_VECTOR; -+ op.u.irq_op.irq = irq; -+ if (HYPERVISOR_physdev_op(&op)) -+ return -ENOSPC; -+ current_vector = op.u.irq_op.vector; -+ -+ vector_irq[current_vector] = irq; -+ if (irq != AUTO_ASSIGN) -+ IO_APIC_VECTOR(irq) = current_vector; -+ -+ return current_vector; -+} -+ -+#ifndef CONFIG_XEN -+static struct hw_interrupt_type ioapic_level_type; -+static struct hw_interrupt_type ioapic_edge_type; -+ -+#define IOAPIC_AUTO -1 -+#define IOAPIC_EDGE 0 -+#define IOAPIC_LEVEL 1 -+ -+static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) -+{ -+ if (use_pci_vector() && !platform_legacy_irq(irq)) { -+ if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || -+ trigger == IOAPIC_LEVEL) -+ irq_desc[vector].handler = &ioapic_level_type; -+ else -+ irq_desc[vector].handler = &ioapic_edge_type; -+ set_intr_gate(vector, interrupt[vector]); -+ } else { -+ if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || -+ trigger == IOAPIC_LEVEL) -+ irq_desc[irq].handler = &ioapic_level_type; -+ else -+ irq_desc[irq].handler = &ioapic_edge_type; -+ set_intr_gate(vector, interrupt[irq]); -+ } -+} -+#else -+#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0) -+#endif -+ -+static void __init setup_IO_APIC_irqs(void) -+{ -+ struct IO_APIC_route_entry entry; -+ int apic, pin, idx, irq, first_notcon = 1, vector; -+ unsigned long flags; -+ -+ apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); -+ -+ for (apic = 0; apic < nr_ioapics; apic++) { -+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { -+ -+ /* -+ * add it to the IO-APIC irq-routing table: -+ */ -+ memset(&entry,0,sizeof(entry)); -+ -+ entry.delivery_mode = INT_DELIVERY_MODE; -+ entry.dest_mode = INT_DEST_MODE; -+ entry.mask = 0; /* enable IRQ */ -+ entry.dest.logical.logical_dest = -+ cpu_mask_to_apicid(TARGET_CPUS); -+ -+ idx = find_irq_entry(apic,pin,mp_INT); -+ if (idx == -1) { -+ if (first_notcon) { -+ apic_printk(APIC_VERBOSE, KERN_DEBUG -+ " IO-APIC (apicid-pin) %d-%d", -+ mp_ioapics[apic].mpc_apicid, -+ pin); -+ first_notcon = 0; -+ } else -+ apic_printk(APIC_VERBOSE, ", %d-%d", -+ mp_ioapics[apic].mpc_apicid, pin); -+ continue; -+ } -+ -+ entry.trigger = irq_trigger(idx); -+ entry.polarity = irq_polarity(idx); -+ -+ if (irq_trigger(idx)) { -+ entry.trigger = 1; -+ entry.mask = 1; -+ } -+ -+ irq = pin_2_irq(idx, apic, pin); -+ /* -+ * skip adding the timer int on secondary nodes, which causes -+ * a small but painful rift in the time-space continuum -+ */ -+ if (multi_timer_check(apic, irq)) -+ continue; -+ else -+ add_pin_to_irq(irq, apic, pin); -+ -+ if (/*!apic &&*/ !IO_APIC_IRQ(irq)) -+ continue; -+ -+ if (IO_APIC_IRQ(irq)) { -+ vector = assign_irq_vector(irq); -+ entry.vector = vector; -+ ioapic_register_intr(irq, vector, IOAPIC_AUTO); -+ -+ if (!apic && (irq < 16)) -+ disable_8259A_irq(irq); -+ } -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); -+ io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); -+ set_native_irq_info(irq, TARGET_CPUS); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ } -+ } -+ -+ if (!first_notcon) -+ apic_printk(APIC_VERBOSE, " not connected.\n"); -+} -+ -+/* -+ * Set up the 8259A-master output pin: -+ */ -+#ifndef CONFIG_XEN -+static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector) -+{ -+ struct IO_APIC_route_entry entry; -+ unsigned long flags; -+ -+ memset(&entry,0,sizeof(entry)); -+ -+ disable_8259A_irq(0); -+ -+ /* mask LVT0 */ -+ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); -+ -+ /* -+ * We use logical delivery to get the timer IRQ -+ * to the first CPU. -+ */ -+ entry.dest_mode = INT_DEST_MODE; -+ entry.mask = 0; /* unmask IRQ now */ -+ entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); -+ entry.delivery_mode = INT_DELIVERY_MODE; -+ entry.polarity = 0; -+ entry.trigger = 0; -+ entry.vector = vector; -+ -+ /* -+ * The timer IRQ doesn't have to know that behind the -+ * scene we have a 8259A-master in AEOI mode ... -+ */ -+ irq_desc[0].handler = &ioapic_edge_type; -+ -+ /* -+ * Add it to the IO-APIC irq-routing table: -+ */ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); -+ io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ enable_8259A_irq(0); -+} -+ -+static inline void UNEXPECTED_IO_APIC(void) -+{ -+} -+ -+void __init print_IO_APIC(void) -+{ -+ int apic, i; -+ union IO_APIC_reg_00 reg_00; -+ union IO_APIC_reg_01 reg_01; -+ union IO_APIC_reg_02 reg_02; -+ union IO_APIC_reg_03 reg_03; -+ unsigned long flags; -+ -+ if (apic_verbosity == APIC_QUIET) -+ return; -+ -+ printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); -+ for (i = 0; i < nr_ioapics; i++) -+ printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", -+ mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]); -+ -+ /* -+ * We are a bit conservative about what we expect. We have to -+ * know about every hardware change ASAP. -+ */ -+ printk(KERN_INFO "testing the IO APIC.......................\n"); -+ -+ for (apic = 0; apic < nr_ioapics; apic++) { -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ reg_00.raw = io_apic_read(apic, 0); -+ reg_01.raw = io_apic_read(apic, 1); -+ if (reg_01.bits.version >= 0x10) -+ reg_02.raw = io_apic_read(apic, 2); -+ if (reg_01.bits.version >= 0x20) -+ reg_03.raw = io_apic_read(apic, 3); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid); -+ printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); -+ printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); -+ printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); -+ printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); -+ if (reg_00.bits.ID >= get_physical_broadcast()) -+ UNEXPECTED_IO_APIC(); -+ if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) -+ UNEXPECTED_IO_APIC(); -+ -+ printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw); -+ printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); -+ if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */ -+ (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */ -+ (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */ -+ (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */ -+ (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */ -+ (reg_01.bits.entries != 0x2E) && -+ (reg_01.bits.entries != 0x3F) -+ ) -+ UNEXPECTED_IO_APIC(); -+ -+ printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); -+ printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); -+ if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */ -+ (reg_01.bits.version != 0x10) && /* oldest IO-APICs */ -+ (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */ -+ (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */ -+ (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */ -+ ) -+ UNEXPECTED_IO_APIC(); -+ if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2) -+ UNEXPECTED_IO_APIC(); -+ -+ /* -+ * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, -+ * but the value of reg_02 is read as the previous read register -+ * value, so ignore it if reg_02 == reg_01. -+ */ -+ if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { -+ printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); -+ printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); -+ if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2) -+ UNEXPECTED_IO_APIC(); -+ } -+ -+ /* -+ * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02 -+ * or reg_03, but the value of reg_0[23] is read as the previous read -+ * register value, so ignore it if reg_03 == reg_0[12]. -+ */ -+ if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw && -+ reg_03.raw != reg_01.raw) { -+ printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); -+ printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); -+ if (reg_03.bits.__reserved_1) -+ UNEXPECTED_IO_APIC(); -+ } -+ -+ printk(KERN_DEBUG ".... IRQ redirection table:\n"); -+ -+ printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol" -+ " Stat Dest Deli Vect: \n"); -+ -+ for (i = 0; i <= reg_01.bits.entries; i++) { -+ struct IO_APIC_route_entry entry; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); -+ *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ printk(KERN_DEBUG " %02x %03X %02X ", -+ i, -+ entry.dest.logical.logical_dest, -+ entry.dest.physical.physical_dest -+ ); -+ -+ printk("%1d %1d %1d %1d %1d %1d %1d %02X\n", -+ entry.mask, -+ entry.trigger, -+ entry.irr, -+ entry.polarity, -+ entry.delivery_status, -+ entry.dest_mode, -+ entry.delivery_mode, -+ entry.vector -+ ); -+ } -+ } -+ if (use_pci_vector()) -+ printk(KERN_INFO "Using vector-based indexing\n"); -+ printk(KERN_DEBUG "IRQ to pin mappings:\n"); -+ for (i = 0; i < NR_IRQS; i++) { -+ struct irq_pin_list *entry = irq_2_pin + i; -+ if (entry->pin < 0) -+ continue; -+ if (use_pci_vector() && !platform_legacy_irq(i)) -+ printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); -+ else -+ printk(KERN_DEBUG "IRQ%d ", i); -+ for (;;) { -+ printk("-> %d:%d", entry->apic, entry->pin); -+ if (!entry->next) -+ break; -+ entry = irq_2_pin + entry->next; -+ } -+ printk("\n"); -+ } -+ -+ printk(KERN_INFO ".................................... done.\n"); -+ -+ return; -+} -+ -+#if 0 -+ -+static void print_APIC_bitfield (int base) -+{ -+ unsigned int v; -+ int i, j; -+ -+ if (apic_verbosity == APIC_QUIET) -+ return; -+ -+ printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG); -+ for (i = 0; i < 8; i++) { -+ v = apic_read(base + i*0x10); -+ for (j = 0; j < 32; j++) { -+ if (v & (1< 3) /* Due to the Pentium erratum 3AP. */ -+ apic_write(APIC_ESR, 0); -+ v = apic_read(APIC_ESR); -+ printk(KERN_DEBUG "... APIC ESR: %08x\n", v); -+ } -+ -+ v = apic_read(APIC_ICR); -+ printk(KERN_DEBUG "... APIC ICR: %08x\n", v); -+ v = apic_read(APIC_ICR2); -+ printk(KERN_DEBUG "... APIC ICR2: %08x\n", v); -+ -+ v = apic_read(APIC_LVTT); -+ printk(KERN_DEBUG "... APIC LVTT: %08x\n", v); -+ -+ if (maxlvt > 3) { /* PC is LVT#4. */ -+ v = apic_read(APIC_LVTPC); -+ printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v); -+ } -+ v = apic_read(APIC_LVT0); -+ printk(KERN_DEBUG "... APIC LVT0: %08x\n", v); -+ v = apic_read(APIC_LVT1); -+ printk(KERN_DEBUG "... APIC LVT1: %08x\n", v); -+ -+ if (maxlvt > 2) { /* ERR is LVT#3. */ -+ v = apic_read(APIC_LVTERR); -+ printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v); -+ } -+ -+ v = apic_read(APIC_TMICT); -+ printk(KERN_DEBUG "... APIC TMICT: %08x\n", v); -+ v = apic_read(APIC_TMCCT); -+ printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v); -+ v = apic_read(APIC_TDCR); -+ printk(KERN_DEBUG "... APIC TDCR: %08x\n", v); -+ printk("\n"); -+} -+ -+void print_all_local_APICs (void) -+{ -+ on_each_cpu(print_local_APIC, NULL, 1, 1); -+} -+ -+void /*__init*/ print_PIC(void) -+{ -+ unsigned int v; -+ unsigned long flags; -+ -+ if (apic_verbosity == APIC_QUIET) -+ return; -+ -+ printk(KERN_DEBUG "\nprinting PIC contents\n"); -+ -+ spin_lock_irqsave(&i8259A_lock, flags); -+ -+ v = inb(0xa1) << 8 | inb(0x21); -+ printk(KERN_DEBUG "... PIC IMR: %04x\n", v); -+ -+ v = inb(0xa0) << 8 | inb(0x20); -+ printk(KERN_DEBUG "... PIC IRR: %04x\n", v); -+ -+ outb(0x0b,0xa0); -+ outb(0x0b,0x20); -+ v = inb(0xa0) << 8 | inb(0x20); -+ outb(0x0a,0xa0); -+ outb(0x0a,0x20); -+ -+ spin_unlock_irqrestore(&i8259A_lock, flags); -+ -+ printk(KERN_DEBUG "... PIC ISR: %04x\n", v); -+ -+ v = inb(0x4d1) << 8 | inb(0x4d0); -+ printk(KERN_DEBUG "... PIC ELCR: %04x\n", v); -+} -+ -+#endif /* 0 */ -+ -+#else -+void __init print_IO_APIC(void) { } -+#endif /* !CONFIG_XEN */ -+ -+static void __init enable_IO_APIC(void) -+{ -+ union IO_APIC_reg_01 reg_01; -+ int i8259_apic, i8259_pin; -+ int i, apic; -+ unsigned long flags; -+ -+ for (i = 0; i < PIN_MAP_SIZE; i++) { -+ irq_2_pin[i].pin = -1; -+ irq_2_pin[i].next = 0; -+ } -+ if (!pirqs_enabled) -+ for (i = 0; i < MAX_PIRQS; i++) -+ pirq_entries[i] = -1; -+ -+ /* -+ * The number of IO-APIC IRQ registers (== #pins): -+ */ -+ for (apic = 0; apic < nr_ioapics; apic++) { -+ spin_lock_irqsave(&ioapic_lock, flags); -+ reg_01.raw = io_apic_read(apic, 1); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ nr_ioapic_registers[apic] = reg_01.bits.entries+1; -+ } -+ for(apic = 0; apic < nr_ioapics; apic++) { -+ int pin; -+ /* See if any of the pins is in ExtINT mode */ -+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { -+ struct IO_APIC_route_entry entry; -+ spin_lock_irqsave(&ioapic_lock, flags); -+ *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); -+ *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ -+ /* If the interrupt line is enabled and in ExtInt mode -+ * I have found the pin where the i8259 is connected. -+ */ -+ if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) { -+ ioapic_i8259.apic = apic; -+ ioapic_i8259.pin = pin; -+ goto found_i8259; -+ } -+ } -+ } -+ found_i8259: -+ /* Look to see what if the MP table has reported the ExtINT */ -+ /* If we could not find the appropriate pin by looking at the ioapic -+ * the i8259 probably is not connected the ioapic but give the -+ * mptable a chance anyway. -+ */ -+ i8259_pin = find_isa_irq_pin(0, mp_ExtINT); -+ i8259_apic = find_isa_irq_apic(0, mp_ExtINT); -+ /* Trust the MP table if nothing is setup in the hardware */ -+ if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) { -+ printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n"); -+ ioapic_i8259.pin = i8259_pin; -+ ioapic_i8259.apic = i8259_apic; -+ } -+ /* Complain if the MP table and the hardware disagree */ -+ if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) && -+ (i8259_pin >= 0) && (ioapic_i8259.pin >= 0)) -+ { -+ printk(KERN_WARNING "ExtINT in hardware and MP table differ\n"); -+ } -+ -+ /* -+ * Do not trust the IO-APIC being empty at bootup -+ */ -+ clear_IO_APIC(); -+} -+ -+/* -+ * Not an __init, needed by the reboot code -+ */ -+void disable_IO_APIC(void) -+{ -+ /* -+ * Clear the IO-APIC before rebooting: -+ */ -+ clear_IO_APIC(); -+ -+#ifndef CONFIG_XEN -+ /* -+ * If the i8259 is routed through an IOAPIC -+ * Put that IOAPIC in virtual wire mode -+ * so legacy interrupts can be delivered. -+ */ -+ if (ioapic_i8259.pin != -1) { -+ struct IO_APIC_route_entry entry; -+ unsigned long flags; -+ -+ memset(&entry, 0, sizeof(entry)); -+ entry.mask = 0; /* Enabled */ -+ entry.trigger = 0; /* Edge */ -+ entry.irr = 0; -+ entry.polarity = 0; /* High */ -+ entry.delivery_status = 0; -+ entry.dest_mode = 0; /* Physical */ -+ entry.delivery_mode = dest_ExtINT; /* ExtInt */ -+ entry.vector = 0; -+ entry.dest.physical.physical_dest = -+ GET_APIC_ID(apic_read(APIC_ID)); -+ -+ /* -+ * Add it to the IO-APIC irq-routing table: -+ */ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin, -+ *(((int *)&entry)+1)); -+ io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin, -+ *(((int *)&entry)+0)); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ } -+ disconnect_bsp_APIC(ioapic_i8259.pin != -1); -+#endif -+} -+ -+/* -+ * function to set the IO-APIC physical IDs based on the -+ * values stored in the MPC table. -+ * -+ * by Matt Domsch Tue Dec 21 12:25:05 CST 1999 -+ */ -+ -+#if !defined(CONFIG_XEN) && !defined(CONFIG_X86_NUMAQ) -+static void __init setup_ioapic_ids_from_mpc(void) -+{ -+ union IO_APIC_reg_00 reg_00; -+ physid_mask_t phys_id_present_map; -+ int apic; -+ int i; -+ unsigned char old_id; -+ unsigned long flags; -+ -+ /* -+ * Don't check I/O APIC IDs for xAPIC systems. They have -+ * no meaning without the serial APIC bus. -+ */ -+ if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15)) -+ return; -+ /* -+ * This is broken; anything with a real cpu count has to -+ * circumvent this idiocy regardless. -+ */ -+ phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map); -+ -+ /* -+ * Set the IOAPIC ID to the value stored in the MPC table. -+ */ -+ for (apic = 0; apic < nr_ioapics; apic++) { -+ -+ /* Read the register 0 value */ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ reg_00.raw = io_apic_read(apic, 0); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ old_id = mp_ioapics[apic].mpc_apicid; -+ -+ if (mp_ioapics[apic].mpc_apicid >= get_physical_broadcast()) { -+ printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", -+ apic, mp_ioapics[apic].mpc_apicid); -+ printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", -+ reg_00.bits.ID); -+ mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; -+ } -+ -+ /* -+ * Sanity check, is the ID really free? Every APIC in a -+ * system must have a unique ID or we get lots of nice -+ * 'stuck on smp_invalidate_needed IPI wait' messages. -+ */ -+ if (check_apicid_used(phys_id_present_map, -+ mp_ioapics[apic].mpc_apicid)) { -+ printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", -+ apic, mp_ioapics[apic].mpc_apicid); -+ for (i = 0; i < get_physical_broadcast(); i++) -+ if (!physid_isset(i, phys_id_present_map)) -+ break; -+ if (i >= get_physical_broadcast()) -+ panic("Max APIC ID exceeded!\n"); -+ printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", -+ i); -+ physid_set(i, phys_id_present_map); -+ mp_ioapics[apic].mpc_apicid = i; -+ } else { -+ physid_mask_t tmp; -+ tmp = apicid_to_cpu_present(mp_ioapics[apic].mpc_apicid); -+ apic_printk(APIC_VERBOSE, "Setting %d in the " -+ "phys_id_present_map\n", -+ mp_ioapics[apic].mpc_apicid); -+ physids_or(phys_id_present_map, phys_id_present_map, tmp); -+ } -+ -+ -+ /* -+ * We need to adjust the IRQ routing table -+ * if the ID changed. -+ */ -+ if (old_id != mp_ioapics[apic].mpc_apicid) -+ for (i = 0; i < mp_irq_entries; i++) -+ if (mp_irqs[i].mpc_dstapic == old_id) -+ mp_irqs[i].mpc_dstapic -+ = mp_ioapics[apic].mpc_apicid; -+ -+ /* -+ * Read the right value from the MPC table and -+ * write it into the ID register. -+ */ -+ apic_printk(APIC_VERBOSE, KERN_INFO -+ "...changing IO-APIC physical APIC ID to %d ...", -+ mp_ioapics[apic].mpc_apicid); -+ -+ reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(apic, 0, reg_00.raw); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ /* -+ * Sanity check -+ */ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ reg_00.raw = io_apic_read(apic, 0); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) -+ printk("could not set ID!\n"); -+ else -+ apic_printk(APIC_VERBOSE, " ok.\n"); -+ } -+} -+#else -+static void __init setup_ioapic_ids_from_mpc(void) { } -+#endif -+ -+#ifndef CONFIG_XEN -+/* -+ * There is a nasty bug in some older SMP boards, their mptable lies -+ * about the timer IRQ. We do the following to work around the situation: -+ * -+ * - timer IRQ defaults to IO-APIC IRQ -+ * - if this function detects that timer IRQs are defunct, then we fall -+ * back to ISA timer IRQs -+ */ -+static int __init timer_irq_works(void) -+{ -+ unsigned long t1 = jiffies; -+ -+ local_irq_enable(); -+ /* Let ten ticks pass... */ -+ mdelay((10 * 1000) / HZ); -+ -+ /* -+ * Expect a few ticks at least, to be sure some possible -+ * glue logic does not lock up after one or two first -+ * ticks in a non-ExtINT mode. Also the local APIC -+ * might have cached one ExtINT interrupt. Finally, at -+ * least one tick may be lost due to delays. -+ */ -+ if (jiffies - t1 > 4) -+ return 1; -+ -+ return 0; -+} -+ -+/* -+ * In the SMP+IOAPIC case it might happen that there are an unspecified -+ * number of pending IRQ events unhandled. These cases are very rare, -+ * so we 'resend' these IRQs via IPIs, to the same CPU. It's much -+ * better to do it this way as thus we do not have to be aware of -+ * 'pending' interrupts in the IRQ path, except at this point. -+ */ -+/* -+ * Edge triggered needs to resend any interrupt -+ * that was delayed but this is now handled in the device -+ * independent code. -+ */ -+ -+/* -+ * Starting up a edge-triggered IO-APIC interrupt is -+ * nasty - we need to make sure that we get the edge. -+ * If it is already asserted for some reason, we need -+ * return 1 to indicate that is was pending. -+ * -+ * This is not complete - we should be able to fake -+ * an edge even if it isn't on the 8259A... -+ */ -+static unsigned int startup_edge_ioapic_irq(unsigned int irq) -+{ -+ int was_pending = 0; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ if (irq < 16) { -+ disable_8259A_irq(irq); -+ if (i8259A_irq_pending(irq)) -+ was_pending = 1; -+ } -+ __unmask_IO_APIC_irq(irq); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ return was_pending; -+} -+ -+/* -+ * Once we have recorded IRQ_PENDING already, we can mask the -+ * interrupt for real. This prevents IRQ storms from unhandled -+ * devices. -+ */ -+static void ack_edge_ioapic_irq(unsigned int irq) -+{ -+ move_irq(irq); -+ if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) -+ == (IRQ_PENDING | IRQ_DISABLED)) -+ mask_IO_APIC_irq(irq); -+ ack_APIC_irq(); -+} -+ -+/* -+ * Level triggered interrupts can just be masked, -+ * and shutting down and starting up the interrupt -+ * is the same as enabling and disabling them -- except -+ * with a startup need to return a "was pending" value. -+ * -+ * Level triggered interrupts are special because we -+ * do not touch any IO-APIC register while handling -+ * them. We ack the APIC in the end-IRQ handler, not -+ * in the start-IRQ-handler. Protection against reentrance -+ * from the same interrupt is still provided, both by the -+ * generic IRQ layer and by the fact that an unacked local -+ * APIC does not accept IRQs. -+ */ -+static unsigned int startup_level_ioapic_irq (unsigned int irq) -+{ -+ unmask_IO_APIC_irq(irq); -+ -+ return 0; /* don't check for pending */ -+} -+ -+static void end_level_ioapic_irq (unsigned int irq) -+{ -+ unsigned long v; -+ int i; -+ -+ move_irq(irq); -+/* -+ * It appears there is an erratum which affects at least version 0x11 -+ * of I/O APIC (that's the 82093AA and cores integrated into various -+ * chipsets). Under certain conditions a level-triggered interrupt is -+ * erroneously delivered as edge-triggered one but the respective IRR -+ * bit gets set nevertheless. As a result the I/O unit expects an EOI -+ * message but it will never arrive and further interrupts are blocked -+ * from the source. The exact reason is so far unknown, but the -+ * phenomenon was observed when two consecutive interrupt requests -+ * from a given source get delivered to the same CPU and the source is -+ * temporarily disabled in between. -+ * -+ * A workaround is to simulate an EOI message manually. We achieve it -+ * by setting the trigger mode to edge and then to level when the edge -+ * trigger mode gets detected in the TMR of a local APIC for a -+ * level-triggered interrupt. We mask the source for the time of the -+ * operation to prevent an edge-triggered interrupt escaping meanwhile. -+ * The idea is from Manfred Spraul. --macro -+ */ -+ i = IO_APIC_VECTOR(irq); -+ -+ v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); -+ -+ ack_APIC_irq(); -+ -+ if (!(v & (1 << (i & 0x1f)))) { -+ atomic_inc(&irq_mis_count); -+ spin_lock(&ioapic_lock); -+ __mask_and_edge_IO_APIC_irq(irq); -+ __unmask_and_level_IO_APIC_irq(irq); -+ spin_unlock(&ioapic_lock); -+ } -+} -+ -+#ifdef CONFIG_PCI_MSI -+static unsigned int startup_edge_ioapic_vector(unsigned int vector) -+{ -+ int irq = vector_to_irq(vector); -+ -+ return startup_edge_ioapic_irq(irq); -+} -+ -+static void ack_edge_ioapic_vector(unsigned int vector) -+{ -+ int irq = vector_to_irq(vector); -+ -+ move_native_irq(vector); -+ ack_edge_ioapic_irq(irq); -+} -+ -+static unsigned int startup_level_ioapic_vector (unsigned int vector) -+{ -+ int irq = vector_to_irq(vector); -+ -+ return startup_level_ioapic_irq (irq); -+} -+ -+static void end_level_ioapic_vector (unsigned int vector) -+{ -+ int irq = vector_to_irq(vector); -+ -+ move_native_irq(vector); -+ end_level_ioapic_irq(irq); -+} -+ -+static void mask_IO_APIC_vector (unsigned int vector) -+{ -+ int irq = vector_to_irq(vector); -+ -+ mask_IO_APIC_irq(irq); -+} -+ -+static void unmask_IO_APIC_vector (unsigned int vector) -+{ -+ int irq = vector_to_irq(vector); -+ -+ unmask_IO_APIC_irq(irq); -+} -+ -+#ifdef CONFIG_SMP -+static void set_ioapic_affinity_vector (unsigned int vector, -+ cpumask_t cpu_mask) -+{ -+ int irq = vector_to_irq(vector); -+ -+ set_native_irq_info(vector, cpu_mask); -+ set_ioapic_affinity_irq(irq, cpu_mask); -+} -+#endif -+#endif -+ -+/* -+ * Level and edge triggered IO-APIC interrupts need different handling, -+ * so we use two separate IRQ descriptors. Edge triggered IRQs can be -+ * handled with the level-triggered descriptor, but that one has slightly -+ * more overhead. Level-triggered interrupts cannot be handled with the -+ * edge-triggered handler, without risking IRQ storms and other ugly -+ * races. -+ */ -+static struct hw_interrupt_type ioapic_edge_type __read_mostly = { -+ .typename = "IO-APIC-edge", -+ .startup = startup_edge_ioapic, -+ .shutdown = shutdown_edge_ioapic, -+ .enable = enable_edge_ioapic, -+ .disable = disable_edge_ioapic, -+ .ack = ack_edge_ioapic, -+ .end = end_edge_ioapic, -+#ifdef CONFIG_SMP -+ .set_affinity = set_ioapic_affinity, -+#endif -+}; -+ -+static struct hw_interrupt_type ioapic_level_type __read_mostly = { -+ .typename = "IO-APIC-level", -+ .startup = startup_level_ioapic, -+ .shutdown = shutdown_level_ioapic, -+ .enable = enable_level_ioapic, -+ .disable = disable_level_ioapic, -+ .ack = mask_and_ack_level_ioapic, -+ .end = end_level_ioapic, -+#ifdef CONFIG_SMP -+ .set_affinity = set_ioapic_affinity, -+#endif -+}; -+#endif /* !CONFIG_XEN */ -+ -+static inline void init_IO_APIC_traps(void) -+{ -+ int irq; -+ -+ /* -+ * NOTE! The local APIC isn't very good at handling -+ * multiple interrupts at the same interrupt level. -+ * As the interrupt level is determined by taking the -+ * vector number and shifting that right by 4, we -+ * want to spread these out a bit so that they don't -+ * all fall in the same interrupt level. -+ * -+ * Also, we've got to be careful not to trash gate -+ * 0x80, because int 0x80 is hm, kind of importantish. ;) -+ */ -+ for (irq = 0; irq < NR_IRQS ; irq++) { -+ int tmp = irq; -+ if (use_pci_vector()) { -+ if (!platform_legacy_irq(tmp)) -+ if ((tmp = vector_to_irq(tmp)) == -1) -+ continue; -+ } -+ if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { -+ /* -+ * Hmm.. We don't have an entry for this, -+ * so default to an old-fashioned 8259 -+ * interrupt if we can.. -+ */ -+ if (irq < 16) -+ make_8259A_irq(irq); -+#ifndef CONFIG_XEN -+ else -+ /* Strange. Oh, well.. */ -+ irq_desc[irq].handler = &no_irq_type; -+#endif -+ } -+ } -+} -+ -+#ifndef CONFIG_XEN -+static void enable_lapic_irq (unsigned int irq) -+{ -+ unsigned long v; -+ -+ v = apic_read(APIC_LVT0); -+ apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); -+} -+ -+static void disable_lapic_irq (unsigned int irq) -+{ -+ unsigned long v; -+ -+ v = apic_read(APIC_LVT0); -+ apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); -+} -+ -+static void ack_lapic_irq (unsigned int irq) -+{ -+ ack_APIC_irq(); -+} -+ -+static void end_lapic_irq (unsigned int i) { /* nothing */ } -+ -+static struct hw_interrupt_type lapic_irq_type __read_mostly = { -+ .typename = "local-APIC-edge", -+ .startup = NULL, /* startup_irq() not used for IRQ0 */ -+ .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */ -+ .enable = enable_lapic_irq, -+ .disable = disable_lapic_irq, -+ .ack = ack_lapic_irq, -+ .end = end_lapic_irq -+}; -+ -+static void setup_nmi (void) -+{ -+ /* -+ * Dirty trick to enable the NMI watchdog ... -+ * We put the 8259A master into AEOI mode and -+ * unmask on all local APICs LVT0 as NMI. -+ * -+ * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') -+ * is from Maciej W. Rozycki - so we do not have to EOI from -+ * the NMI handler or the timer interrupt. -+ */ -+ apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); -+ -+ on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1); -+ -+ apic_printk(APIC_VERBOSE, " done.\n"); -+} -+ -+/* -+ * This looks a bit hackish but it's about the only one way of sending -+ * a few INTA cycles to 8259As and any associated glue logic. ICR does -+ * not support the ExtINT mode, unfortunately. We need to send these -+ * cycles as some i82489DX-based boards have glue logic that keeps the -+ * 8259A interrupt line asserted until INTA. --macro -+ */ -+static inline void unlock_ExtINT_logic(void) -+{ -+ int apic, pin, i; -+ struct IO_APIC_route_entry entry0, entry1; -+ unsigned char save_control, save_freq_select; -+ unsigned long flags; -+ -+ pin = find_isa_irq_pin(8, mp_INT); -+ apic = find_isa_irq_apic(8, mp_INT); -+ if (pin == -1) -+ return; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin); -+ *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ clear_IO_APIC_pin(apic, pin); -+ -+ memset(&entry1, 0, sizeof(entry1)); -+ -+ entry1.dest_mode = 0; /* physical delivery */ -+ entry1.mask = 0; /* unmask IRQ now */ -+ entry1.dest.physical.physical_dest = hard_smp_processor_id(); -+ entry1.delivery_mode = dest_ExtINT; -+ entry1.polarity = entry0.polarity; -+ entry1.trigger = 0; -+ entry1.vector = 0; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1)); -+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0)); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ save_control = CMOS_READ(RTC_CONTROL); -+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT); -+ CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6, -+ RTC_FREQ_SELECT); -+ CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL); -+ -+ i = 100; -+ while (i-- > 0) { -+ mdelay(10); -+ if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF) -+ i -= 10; -+ } -+ -+ CMOS_WRITE(save_control, RTC_CONTROL); -+ CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); -+ clear_IO_APIC_pin(apic, pin); -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1)); -+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0)); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+} -+ -+/* -+ * This code may look a bit paranoid, but it's supposed to cooperate with -+ * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ -+ * is so screwy. Thanks to Brian Perkins for testing/hacking this beast -+ * fanatically on his truly buggy board. -+ */ -+static inline void check_timer(void) -+{ -+ int apic1, pin1, apic2, pin2; -+ int vector; -+ -+ /* -+ * get/set the timer IRQ vector: -+ */ -+ disable_8259A_irq(0); -+ vector = assign_irq_vector(0); -+ set_intr_gate(vector, interrupt[0]); -+ -+ /* -+ * Subtle, code in do_timer_interrupt() expects an AEOI -+ * mode for the 8259A whenever interrupts are routed -+ * through I/O APICs. Also IRQ0 has to be enabled in -+ * the 8259A which implies the virtual wire has to be -+ * disabled in the local APIC. -+ */ -+ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); -+ init_8259A(1); -+ timer_ack = 1; -+ if (timer_over_8254 > 0) -+ enable_8259A_irq(0); -+ -+ pin1 = find_isa_irq_pin(0, mp_INT); -+ apic1 = find_isa_irq_apic(0, mp_INT); -+ pin2 = ioapic_i8259.pin; -+ apic2 = ioapic_i8259.apic; -+ -+ printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", -+ vector, apic1, pin1, apic2, pin2); -+ -+ if (pin1 != -1) { -+ /* -+ * Ok, does IRQ0 through the IOAPIC work? -+ */ -+ unmask_IO_APIC_irq(0); -+ if (timer_irq_works()) { -+ if (nmi_watchdog == NMI_IO_APIC) { -+ disable_8259A_irq(0); -+ setup_nmi(); -+ enable_8259A_irq(0); -+ } -+ if (disable_timer_pin_1 > 0) -+ clear_IO_APIC_pin(0, pin1); -+ return; -+ } -+ clear_IO_APIC_pin(apic1, pin1); -+ printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to " -+ "IO-APIC\n"); -+ } -+ -+ printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... "); -+ if (pin2 != -1) { -+ printk("\n..... (found pin %d) ...", pin2); -+ /* -+ * legacy devices should be connected to IO APIC #0 -+ */ -+ setup_ExtINT_IRQ0_pin(apic2, pin2, vector); -+ if (timer_irq_works()) { -+ printk("works.\n"); -+ if (pin1 != -1) -+ replace_pin_at_irq(0, apic1, pin1, apic2, pin2); -+ else -+ add_pin_to_irq(0, apic2, pin2); -+ if (nmi_watchdog == NMI_IO_APIC) { -+ setup_nmi(); -+ } -+ return; -+ } -+ /* -+ * Cleanup, just in case ... -+ */ -+ clear_IO_APIC_pin(apic2, pin2); -+ } -+ printk(" failed.\n"); -+ -+ if (nmi_watchdog == NMI_IO_APIC) { -+ printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); -+ nmi_watchdog = 0; -+ } -+ -+ printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); -+ -+ disable_8259A_irq(0); -+ irq_desc[0].handler = &lapic_irq_type; -+ apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ -+ enable_8259A_irq(0); -+ -+ if (timer_irq_works()) { -+ printk(" works.\n"); -+ return; -+ } -+ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); -+ printk(" failed.\n"); -+ -+ printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); -+ -+ timer_ack = 0; -+ init_8259A(0); -+ make_8259A_irq(0); -+ apic_write_around(APIC_LVT0, APIC_DM_EXTINT); -+ -+ unlock_ExtINT_logic(); -+ -+ if (timer_irq_works()) { -+ printk(" works.\n"); -+ return; -+ } -+ printk(" failed :(.\n"); -+ panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " -+ "report. Then try booting with the 'noapic' option"); -+} -+#else -+#define check_timer() ((void)0) -+#endif -+ -+/* -+ * -+ * IRQ's that are handled by the PIC in the MPS IOAPIC case. -+ * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ. -+ * Linux doesn't really care, as it's not actually used -+ * for any interrupt handling anyway. -+ */ -+#define PIC_IRQS (1 << PIC_CASCADE_IR) -+ -+void __init setup_IO_APIC(void) -+{ -+ enable_IO_APIC(); -+ -+ if (acpi_ioapic) -+ io_apic_irqs = ~0; /* all IRQs go through IOAPIC */ -+ else -+ io_apic_irqs = ~PIC_IRQS; -+ -+ printk("ENABLING IO-APIC IRQs\n"); -+ -+ /* -+ * Set up IO-APIC IRQ routing. -+ */ -+ if (!acpi_ioapic) -+ setup_ioapic_ids_from_mpc(); -+#ifndef CONFIG_XEN -+ sync_Arb_IDs(); -+#endif -+ setup_IO_APIC_irqs(); -+ init_IO_APIC_traps(); -+ check_timer(); -+ if (!acpi_ioapic) -+ print_IO_APIC(); -+} -+ -+static int __init setup_disable_8254_timer(char *s) -+{ -+ timer_over_8254 = -1; -+ return 1; -+} -+static int __init setup_enable_8254_timer(char *s) -+{ -+ timer_over_8254 = 2; -+ return 1; -+} -+ -+__setup("disable_8254_timer", setup_disable_8254_timer); -+__setup("enable_8254_timer", setup_enable_8254_timer); -+ -+/* -+ * Called after all the initialization is done. If we didnt find any -+ * APIC bugs then we can allow the modify fast path -+ */ -+ -+static int __init io_apic_bug_finalize(void) -+{ -+ if(sis_apic_bug == -1) -+ sis_apic_bug = 0; -+ return 0; -+} -+ -+late_initcall(io_apic_bug_finalize); -+ -+struct sysfs_ioapic_data { -+ struct sys_device dev; -+ struct IO_APIC_route_entry entry[0]; -+}; -+static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS]; -+ -+static int ioapic_suspend(struct sys_device *dev, pm_message_t state) -+{ -+ struct IO_APIC_route_entry *entry; -+ struct sysfs_ioapic_data *data; -+ unsigned long flags; -+ int i; -+ -+ data = container_of(dev, struct sysfs_ioapic_data, dev); -+ entry = data->entry; -+ spin_lock_irqsave(&ioapic_lock, flags); -+ for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { -+ *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); -+ *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); -+ } -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ return 0; -+} -+ -+static int ioapic_resume(struct sys_device *dev) -+{ -+ struct IO_APIC_route_entry *entry; -+ struct sysfs_ioapic_data *data; -+ unsigned long flags; -+ union IO_APIC_reg_00 reg_00; -+ int i; -+ -+ data = container_of(dev, struct sysfs_ioapic_data, dev); -+ entry = data->entry; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ reg_00.raw = io_apic_read(dev->id, 0); -+ if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) { -+ reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; -+ io_apic_write(dev->id, 0, reg_00.raw); -+ } -+ for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { -+ io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); -+ io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); -+ } -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ return 0; -+} -+ -+static struct sysdev_class ioapic_sysdev_class = { -+ set_kset_name("ioapic"), -+ .suspend = ioapic_suspend, -+ .resume = ioapic_resume, -+}; -+ -+static int __init ioapic_init_sysfs(void) -+{ -+ struct sys_device * dev; -+ int i, size, error = 0; -+ -+ error = sysdev_class_register(&ioapic_sysdev_class); -+ if (error) -+ return error; -+ -+ for (i = 0; i < nr_ioapics; i++ ) { -+ size = sizeof(struct sys_device) + nr_ioapic_registers[i] -+ * sizeof(struct IO_APIC_route_entry); -+ mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL); -+ if (!mp_ioapic_data[i]) { -+ printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); -+ continue; -+ } -+ memset(mp_ioapic_data[i], 0, size); -+ dev = &mp_ioapic_data[i]->dev; -+ dev->id = i; -+ dev->cls = &ioapic_sysdev_class; -+ error = sysdev_register(dev); -+ if (error) { -+ kfree(mp_ioapic_data[i]); -+ mp_ioapic_data[i] = NULL; -+ printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i); -+ continue; -+ } -+ } -+ -+ return 0; -+} -+ -+device_initcall(ioapic_init_sysfs); -+ -+/* -------------------------------------------------------------------------- -+ ACPI-based IOAPIC Configuration -+ -------------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_ACPI -+ -+int __init io_apic_get_unique_id (int ioapic, int apic_id) -+{ -+#ifndef CONFIG_XEN -+ union IO_APIC_reg_00 reg_00; -+ static physid_mask_t apic_id_map = PHYSID_MASK_NONE; -+ physid_mask_t tmp; -+ unsigned long flags; -+ int i = 0; -+ -+ /* -+ * The P4 platform supports up to 256 APIC IDs on two separate APIC -+ * buses (one for LAPICs, one for IOAPICs), where predecessors only -+ * supports up to 16 on one shared APIC bus. -+ * -+ * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full -+ * advantage of new APIC bus architecture. -+ */ -+ -+ if (physids_empty(apic_id_map)) -+ apic_id_map = ioapic_phys_id_map(phys_cpu_present_map); -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ reg_00.raw = io_apic_read(ioapic, 0); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ if (apic_id >= get_physical_broadcast()) { -+ printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " -+ "%d\n", ioapic, apic_id, reg_00.bits.ID); -+ apic_id = reg_00.bits.ID; -+ } -+ -+ /* -+ * Every APIC in a system must have a unique ID or we get lots of nice -+ * 'stuck on smp_invalidate_needed IPI wait' messages. -+ */ -+ if (check_apicid_used(apic_id_map, apic_id)) { -+ -+ for (i = 0; i < get_physical_broadcast(); i++) { -+ if (!check_apicid_used(apic_id_map, i)) -+ break; -+ } -+ -+ if (i == get_physical_broadcast()) -+ panic("Max apic_id exceeded!\n"); -+ -+ printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " -+ "trying %d\n", ioapic, apic_id, i); -+ -+ apic_id = i; -+ } -+ -+ tmp = apicid_to_cpu_present(apic_id); -+ physids_or(apic_id_map, apic_id_map, tmp); -+ -+ if (reg_00.bits.ID != apic_id) { -+ reg_00.bits.ID = apic_id; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(ioapic, 0, reg_00.raw); -+ reg_00.raw = io_apic_read(ioapic, 0); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ /* Sanity check */ -+ if (reg_00.bits.ID != apic_id) { -+ printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); -+ return -1; -+ } -+ } -+ -+ apic_printk(APIC_VERBOSE, KERN_INFO -+ "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); -+#endif /* !CONFIG_XEN */ -+ -+ return apic_id; -+} -+ -+ -+int __init io_apic_get_version (int ioapic) -+{ -+ union IO_APIC_reg_01 reg_01; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ reg_01.raw = io_apic_read(ioapic, 1); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ return reg_01.bits.version; -+} -+ -+ -+int __init io_apic_get_redir_entries (int ioapic) -+{ -+ union IO_APIC_reg_01 reg_01; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ reg_01.raw = io_apic_read(ioapic, 1); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ return reg_01.bits.entries; -+} -+ -+ -+int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low) -+{ -+ struct IO_APIC_route_entry entry; -+ unsigned long flags; -+ -+ if (!IO_APIC_IRQ(irq)) { -+ printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n", -+ ioapic); -+ return -EINVAL; -+ } -+ -+ /* -+ * Generate a PCI IRQ routing entry and program the IOAPIC accordingly. -+ * Note that we mask (disable) IRQs now -- these get enabled when the -+ * corresponding device driver registers for this IRQ. -+ */ -+ -+ memset(&entry,0,sizeof(entry)); -+ -+ entry.delivery_mode = INT_DELIVERY_MODE; -+ entry.dest_mode = INT_DEST_MODE; -+ entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); -+ entry.trigger = edge_level; -+ entry.polarity = active_high_low; -+ entry.mask = 1; -+ -+ /* -+ * IRQs < 16 are already in the irq_2_pin[] map -+ */ -+ if (irq >= 16) -+ add_pin_to_irq(irq, ioapic, pin); -+ -+ entry.vector = assign_irq_vector(irq); -+ -+ apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry " -+ "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic, -+ mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, -+ edge_level, active_high_low); -+ -+ ioapic_register_intr(irq, entry.vector, edge_level); -+ -+ if (!ioapic && (irq < 16)) -+ disable_8259A_irq(irq); -+ -+ spin_lock_irqsave(&ioapic_lock, flags); -+ io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); -+ io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); -+ set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); -+ spin_unlock_irqrestore(&ioapic_lock, flags); -+ -+ return 0; -+} -+ -+#endif /* CONFIG_ACPI */ -diff --git a/arch/i386/kernel/ioport-xen.c b/arch/i386/kernel/ioport-xen.c -new file mode 100644 -index 0000000..fe395b1 ---- /dev/null -+++ b/arch/i386/kernel/ioport-xen.c -@@ -0,0 +1,122 @@ -+/* -+ * linux/arch/i386/kernel/ioport.c -+ * -+ * This contains the io-permission bitmap code - written by obz, with changes -+ * by Linus. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ -+static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) -+{ -+ unsigned long mask; -+ unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG); -+ unsigned int low_index = base & (BITS_PER_LONG-1); -+ int length = low_index + extent; -+ -+ if (low_index != 0) { -+ mask = (~0UL << low_index); -+ if (length < BITS_PER_LONG) -+ mask &= ~(~0UL << length); -+ if (new_value) -+ *bitmap_base++ |= mask; -+ else -+ *bitmap_base++ &= ~mask; -+ length -= BITS_PER_LONG; -+ } -+ -+ mask = (new_value ? ~0UL : 0UL); -+ while (length >= BITS_PER_LONG) { -+ *bitmap_base++ = mask; -+ length -= BITS_PER_LONG; -+ } -+ -+ if (length > 0) { -+ mask = ~(~0UL << length); -+ if (new_value) -+ *bitmap_base++ |= mask; -+ else -+ *bitmap_base++ &= ~mask; -+ } -+} -+ -+ -+/* -+ * this changes the io permissions bitmap in the current task. -+ */ -+asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) -+{ -+ struct thread_struct * t = ¤t->thread; -+ unsigned long *bitmap; -+ physdev_op_t op; -+ -+ if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) -+ 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->io_bitmap_ptr) { -+ bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); -+ if (!bitmap) -+ return -ENOMEM; -+ -+ memset(bitmap, 0xff, IO_BITMAP_BYTES); -+ t->io_bitmap_ptr = bitmap; -+ -+ op.cmd = PHYSDEVOP_SET_IOBITMAP; -+ op.u.set_iobitmap.bitmap = (char *)bitmap; -+ op.u.set_iobitmap.nr_ports = IO_BITMAP_BITS; -+ HYPERVISOR_physdev_op(&op); -+ } -+ -+ set_bitmap(t->io_bitmap_ptr, from, num, !turn_on); -+ -+ return 0; -+} -+ -+/* -+ * sys_iopl has to be used when you want to access the IO ports -+ * beyond the 0x3ff range: to get the full 65536 ports bitmapped -+ * you'd need 8kB of bitmaps/process, which is a bit excessive. -+ * -+ * Here we just change the eflags value on the stack: we allow -+ * only the super-user to do it. This depends on the stack-layout -+ * on system-call entry - see also fork() and the signal handling -+ * code. -+ */ -+ -+asmlinkage long sys_iopl(unsigned long unused) -+{ -+ volatile struct pt_regs * regs = (struct pt_regs *) &unused; -+ unsigned int level = regs->ebx; -+ struct thread_struct *t = ¤t->thread; -+ unsigned int old = (t->iopl >> 12) & 3; -+ -+ if (level > 3) -+ return -EINVAL; -+ /* Trying to gain more privileges? */ -+ if (level > old) { -+ if (!capable(CAP_SYS_RAWIO)) -+ return -EPERM; -+ } -+ t->iopl = level << 12; -+ set_iopl_mask(t->iopl); -+ return 0; -+} -diff --git a/arch/i386/kernel/irq-xen.c b/arch/i386/kernel/irq-xen.c -new file mode 100644 -index 0000000..d4b9753 ---- /dev/null -+++ b/arch/i386/kernel/irq-xen.c -@@ -0,0 +1,306 @@ -+/* -+ * linux/arch/i386/kernel/irq.c -+ * -+ * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar -+ * -+ * This file contains the lowest level x86-specific interrupt -+ * entry, irq-stacks and irq statistics code. All the remaining -+ * irq logic is done by the generic kernel/irq/ code and -+ * by the x86-specific irq controller code. (e.g. i8259.c and -+ * io_apic.c.) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp; -+EXPORT_PER_CPU_SYMBOL(irq_stat); -+ -+#ifndef CONFIG_X86_LOCAL_APIC -+/* -+ * 'what should we do if we get a hw irq event on an illegal vector'. -+ * each architecture has to answer this themselves. -+ */ -+void ack_bad_irq(unsigned int irq) -+{ -+ printk("unexpected IRQ trap at vector %02x\n", irq); -+} -+#endif -+ -+#ifdef CONFIG_4KSTACKS -+/* -+ * per-CPU IRQ handling contexts (thread information and stack) -+ */ -+union irq_ctx { -+ struct thread_info tinfo; -+ u32 stack[THREAD_SIZE/sizeof(u32)]; -+}; -+ -+static union irq_ctx *hardirq_ctx[NR_CPUS]; -+static union irq_ctx *softirq_ctx[NR_CPUS]; -+#endif -+ -+/* -+ * do_IRQ handles all normal device IRQ's (the special -+ * SMP cross-CPU interrupts have their own specific -+ * handlers). -+ */ -+fastcall unsigned int do_IRQ(struct pt_regs *regs) -+{ -+ /* high bits used in ret_from_ code */ -+ int irq = regs->orig_eax & __IRQ_MASK(HARDIRQ_BITS); -+#ifdef CONFIG_4KSTACKS -+ union irq_ctx *curctx, *irqctx; -+ u32 *isp; -+#endif -+ -+ irq_enter(); -+#ifdef CONFIG_DEBUG_STACKOVERFLOW -+ /* Debugging check for stack overflow: is there less than 1KB free? */ -+ { -+ long esp; -+ -+ __asm__ __volatile__("andl %%esp,%0" : -+ "=r" (esp) : "0" (THREAD_SIZE - 1)); -+ if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) { -+ printk("do_IRQ: stack overflow: %ld\n", -+ esp - sizeof(struct thread_info)); -+ dump_stack(); -+ } -+ } -+#endif -+ -+#ifdef CONFIG_4KSTACKS -+ -+ curctx = (union irq_ctx *) current_thread_info(); -+ irqctx = hardirq_ctx[smp_processor_id()]; -+ -+ /* -+ * this is where we switch to the IRQ stack. However, if we are -+ * already using the IRQ stack (because we interrupted a hardirq -+ * handler) we can't do that and just have to keep using the -+ * current stack (which is the irq stack already after all) -+ */ -+ if (curctx != irqctx) { -+ int arg1, arg2, ebx; -+ -+ /* build the stack frame on the IRQ stack */ -+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); -+ irqctx->tinfo.task = curctx->tinfo.task; -+ irqctx->tinfo.previous_esp = current_stack_pointer; -+ -+ asm volatile( -+ " xchgl %%ebx,%%esp \n" -+ " call __do_IRQ \n" -+ " movl %%ebx,%%esp \n" -+ : "=a" (arg1), "=d" (arg2), "=b" (ebx) -+ : "0" (irq), "1" (regs), "2" (isp) -+ : "memory", "cc", "ecx" -+ ); -+ } else -+#endif -+ __do_IRQ(irq, regs); -+ -+ irq_exit(); -+ -+ return 1; -+} -+ -+#ifdef CONFIG_4KSTACKS -+ -+/* -+ * These should really be __section__(".bss.page_aligned") as well, but -+ * gcc's 3.0 and earlier don't handle that correctly. -+ */ -+static char softirq_stack[NR_CPUS * THREAD_SIZE] -+ __attribute__((__aligned__(THREAD_SIZE))); -+ -+static char hardirq_stack[NR_CPUS * THREAD_SIZE] -+ __attribute__((__aligned__(THREAD_SIZE))); -+ -+/* -+ * allocate per-cpu stacks for hardirq and for softirq processing -+ */ -+void irq_ctx_init(int cpu) -+{ -+ union irq_ctx *irqctx; -+ -+ if (hardirq_ctx[cpu]) -+ return; -+ -+ irqctx = (union irq_ctx*) &hardirq_stack[cpu*THREAD_SIZE]; -+ irqctx->tinfo.task = NULL; -+ irqctx->tinfo.exec_domain = NULL; -+ irqctx->tinfo.cpu = cpu; -+ irqctx->tinfo.preempt_count = HARDIRQ_OFFSET; -+ irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); -+ -+ hardirq_ctx[cpu] = irqctx; -+ -+ irqctx = (union irq_ctx*) &softirq_stack[cpu*THREAD_SIZE]; -+ irqctx->tinfo.task = NULL; -+ irqctx->tinfo.exec_domain = NULL; -+ irqctx->tinfo.cpu = cpu; -+ irqctx->tinfo.preempt_count = SOFTIRQ_OFFSET; -+ irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); -+ -+ softirq_ctx[cpu] = irqctx; -+ -+ printk("CPU %u irqstacks, hard=%p soft=%p\n", -+ cpu,hardirq_ctx[cpu],softirq_ctx[cpu]); -+} -+ -+void irq_ctx_exit(int cpu) -+{ -+ hardirq_ctx[cpu] = NULL; -+} -+ -+extern asmlinkage void __do_softirq(void); -+ -+asmlinkage void do_softirq(void) -+{ -+ unsigned long flags; -+ struct thread_info *curctx; -+ union irq_ctx *irqctx; -+ u32 *isp; -+ -+ if (in_interrupt()) -+ return; -+ -+ local_irq_save(flags); -+ -+ if (local_softirq_pending()) { -+ curctx = current_thread_info(); -+ irqctx = softirq_ctx[smp_processor_id()]; -+ irqctx->tinfo.task = curctx->task; -+ irqctx->tinfo.previous_esp = current_stack_pointer; -+ -+ /* build the stack frame on the softirq stack */ -+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); -+ -+ asm volatile( -+ " xchgl %%ebx,%%esp \n" -+ " call __do_softirq \n" -+ " movl %%ebx,%%esp \n" -+ : "=b"(isp) -+ : "0"(isp) -+ : "memory", "cc", "edx", "ecx", "eax" -+ ); -+ } -+ -+ local_irq_restore(flags); -+} -+ -+EXPORT_SYMBOL(do_softirq); -+#endif -+ -+/* -+ * Interrupt statistics: -+ */ -+ -+atomic_t irq_err_count; -+ -+/* -+ * /proc/interrupts printing: -+ */ -+ -+int show_interrupts(struct seq_file *p, void *v) -+{ -+ int i = *(loff_t *) v, j; -+ struct irqaction * action; -+ unsigned long flags; -+ -+ if (i == 0) { -+ seq_printf(p, " "); -+ for_each_online_cpu(j) -+ seq_printf(p, "CPU%d ",j); -+ seq_putc(p, '\n'); -+ } -+ -+ if (i < NR_IRQS) { -+ spin_lock_irqsave(&irq_desc[i].lock, flags); -+ action = irq_desc[i].action; -+ if (!action) -+ goto skip; -+ seq_printf(p, "%3d: ",i); -+#ifndef CONFIG_SMP -+ seq_printf(p, "%10u ", kstat_irqs(i)); -+#else -+ for_each_online_cpu(j) -+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); -+#endif -+ seq_printf(p, " %14s", irq_desc[i].handler->typename); -+ seq_printf(p, " %s", action->name); -+ -+ for (action=action->next; action; action = action->next) -+ seq_printf(p, ", %s", action->name); -+ -+ seq_putc(p, '\n'); -+skip: -+ spin_unlock_irqrestore(&irq_desc[i].lock, flags); -+ } else if (i == NR_IRQS) { -+ seq_printf(p, "NMI: "); -+ for_each_online_cpu(j) -+ seq_printf(p, "%10u ", nmi_count(j)); -+ seq_putc(p, '\n'); -+#ifdef CONFIG_X86_LOCAL_APIC -+ seq_printf(p, "LOC: "); -+ for_each_online_cpu(j) -+ seq_printf(p, "%10u ", -+ per_cpu(irq_stat,j).apic_timer_irqs); -+ seq_putc(p, '\n'); -+#endif -+ seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); -+#if defined(CONFIG_X86_IO_APIC) -+ seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); -+#endif -+ } -+ return 0; -+} -+ -+#ifdef CONFIG_HOTPLUG_CPU -+ -+void fixup_irqs(cpumask_t map) -+{ -+ unsigned int irq; -+ static int warned; -+ -+ for (irq = 0; irq < NR_IRQS; irq++) { -+ cpumask_t mask; -+ if (irq == 2) -+ continue; -+ -+ cpus_and(mask, irq_affinity[irq], map); -+ if (any_online_cpu(mask) == NR_CPUS) { -+ /*printk("Breaking affinity for irq %i\n", irq);*/ -+ mask = map; -+ } -+ if (irq_desc[irq].handler->set_affinity) -+ irq_desc[irq].handler->set_affinity(irq, mask); -+ else if (irq_desc[irq].action && !(warned++)) -+ printk("Cannot set affinity for irq %i\n", irq); -+ } -+ -+#if 0 -+ barrier(); -+ /* Ingo Molnar says: "after the IO-APIC masks have been redirected -+ [note the nop - the interrupt-enable boundary on x86 is two -+ instructions from sti] - to flush out pending hardirqs and -+ IPIs. After this point nothing is supposed to reach this CPU." */ -+ __asm__ __volatile__("sti; nop; cli"); -+ barrier(); -+#else -+ /* That doesn't seem sufficient. Give it 1ms. */ -+ local_irq_enable(); -+ mdelay(1); -+ local_irq_disable(); -+#endif -+} -+#endif -+ -diff --git a/arch/i386/kernel/ldt-xen.c b/arch/i386/kernel/ldt-xen.c -new file mode 100644 -index 0000000..06970d9 ---- /dev/null -+++ b/arch/i386/kernel/ldt-xen.c -@@ -0,0 +1,269 @@ -+/* -+ * linux/kernel/ldt.c -+ * -+ * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds -+ * Copyright (C) 1999 Ingo Molnar -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_SMP /* avoids "defined but not used" warnig */ -+static void flush_ldt(void *null) -+{ -+ if (current->active_mm) -+ load_LDT(¤t->active_mm->context); -+} -+#endif -+ -+static int alloc_ldt(mm_context_t *pc, int mincount, int reload) -+{ -+ void *oldldt; -+ void *newldt; -+ int oldsize; -+ -+ if (mincount <= pc->size) -+ return 0; -+ oldsize = pc->size; -+ mincount = (mincount+511)&(~511); -+ if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE) -+ newldt = vmalloc(mincount*LDT_ENTRY_SIZE); -+ else -+ newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL); -+ -+ if (!newldt) -+ return -ENOMEM; -+ -+ if (oldsize) -+ memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE); -+ oldldt = pc->ldt; -+ memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE); -+ pc->ldt = newldt; -+ wmb(); -+ pc->size = mincount; -+ wmb(); -+ -+ if (reload) { -+#ifdef CONFIG_SMP -+ cpumask_t mask; -+ preempt_disable(); -+#endif -+ make_pages_readonly( -+ pc->ldt, -+ (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE, -+ XENFEAT_writable_descriptor_tables); -+ load_LDT(pc); -+#ifdef CONFIG_SMP -+ mask = cpumask_of_cpu(smp_processor_id()); -+ if (!cpus_equal(current->mm->cpu_vm_mask, mask)) -+ smp_call_function(flush_ldt, NULL, 1, 1); -+ preempt_enable(); -+#endif -+ } -+ if (oldsize) { -+ make_pages_writable( -+ oldldt, -+ (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE, -+ XENFEAT_writable_descriptor_tables); -+ if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE) -+ vfree(oldldt); -+ else -+ kfree(oldldt); -+ } -+ return 0; -+} -+ -+static inline int copy_ldt(mm_context_t *new, mm_context_t *old) -+{ -+ int err = alloc_ldt(new, old->size, 0); -+ if (err < 0) -+ return err; -+ memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE); -+ make_pages_readonly( -+ new->ldt, -+ (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE, -+ XENFEAT_writable_descriptor_tables); -+ return 0; -+} -+ -+/* -+ * we do not have to muck with descriptors here, that is -+ * done in switch_mm() as needed. -+ */ -+int init_new_context(struct task_struct *tsk, struct mm_struct *mm) -+{ -+ struct mm_struct * old_mm; -+ int retval = 0; -+ -+ init_MUTEX(&mm->context.sem); -+ mm->context.size = 0; -+ old_mm = current->mm; -+ if (old_mm && old_mm->context.size > 0) { -+ down(&old_mm->context.sem); -+ retval = copy_ldt(&mm->context, &old_mm->context); -+ up(&old_mm->context.sem); -+ } -+ return retval; -+} -+ -+/* -+ * No need to lock the MM as we are the last user -+ */ -+void destroy_context(struct mm_struct *mm) -+{ -+ if (mm->context.size) { -+ if (mm == current->active_mm) -+ clear_LDT(); -+ make_pages_writable( -+ mm->context.ldt, -+ (mm->context.size * LDT_ENTRY_SIZE) / PAGE_SIZE, -+ XENFEAT_writable_descriptor_tables); -+ if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE) -+ vfree(mm->context.ldt); -+ else -+ kfree(mm->context.ldt); -+ mm->context.size = 0; -+ } -+} -+ -+static int read_ldt(void __user * ptr, unsigned long bytecount) -+{ -+ int err; -+ unsigned long size; -+ struct mm_struct * mm = current->mm; -+ -+ if (!mm->context.size) -+ return 0; -+ if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) -+ bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; -+ -+ down(&mm->context.sem); -+ size = mm->context.size*LDT_ENTRY_SIZE; -+ if (size > bytecount) -+ size = bytecount; -+ -+ err = 0; -+ if (copy_to_user(ptr, mm->context.ldt, size)) -+ err = -EFAULT; -+ up(&mm->context.sem); -+ if (err < 0) -+ goto error_return; -+ if (size != bytecount) { -+ /* zero-fill the rest */ -+ if (clear_user(ptr+size, bytecount-size) != 0) { -+ err = -EFAULT; -+ goto error_return; -+ } -+ } -+ return bytecount; -+error_return: -+ return err; -+} -+ -+static int read_default_ldt(void __user * ptr, unsigned long bytecount) -+{ -+ int err; -+ unsigned long size; -+ void *address; -+ -+ err = 0; -+ address = &default_ldt[0]; -+ size = 5*sizeof(struct desc_struct); -+ if (size > bytecount) -+ size = bytecount; -+ -+ err = size; -+ if (copy_to_user(ptr, address, size)) -+ err = -EFAULT; -+ -+ return err; -+} -+ -+static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode) -+{ -+ struct mm_struct * mm = current->mm; -+ __u32 entry_1, entry_2; -+ int error; -+ struct user_desc ldt_info; -+ -+ error = -EINVAL; -+ if (bytecount != sizeof(ldt_info)) -+ goto out; -+ error = -EFAULT; -+ if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) -+ goto out; -+ -+ error = -EINVAL; -+ if (ldt_info.entry_number >= LDT_ENTRIES) -+ goto out; -+ if (ldt_info.contents == 3) { -+ if (oldmode) -+ goto out; -+ if (ldt_info.seg_not_present == 0) -+ goto out; -+ } -+ -+ down(&mm->context.sem); -+ if (ldt_info.entry_number >= mm->context.size) { -+ error = alloc_ldt(¤t->mm->context, ldt_info.entry_number+1, 1); -+ if (error < 0) -+ goto out_unlock; -+ } -+ -+ /* Allow LDTs to be cleared by the user. */ -+ if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { -+ if (oldmode || LDT_empty(&ldt_info)) { -+ entry_1 = 0; -+ entry_2 = 0; -+ goto install; -+ } -+ } -+ -+ entry_1 = LDT_entry_a(&ldt_info); -+ entry_2 = LDT_entry_b(&ldt_info); -+ if (oldmode) -+ entry_2 &= ~(1 << 20); -+ -+ /* Install the new entry ... */ -+install: -+ error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number, -+ entry_1, entry_2); -+ -+out_unlock: -+ up(&mm->context.sem); -+out: -+ return error; -+} -+ -+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) -+{ -+ int ret = -ENOSYS; -+ -+ switch (func) { -+ case 0: -+ ret = read_ldt(ptr, bytecount); -+ break; -+ case 1: -+ ret = write_ldt(ptr, bytecount, 1); -+ break; -+ case 2: -+ ret = read_default_ldt(ptr, bytecount); -+ break; -+ case 0x11: -+ ret = write_ldt(ptr, bytecount, 0); -+ break; -+ } -+ return ret; -+} -diff --git a/arch/i386/kernel/microcode-xen.c b/arch/i386/kernel/microcode-xen.c -new file mode 100644 -index 0000000..07db5cc ---- /dev/null -+++ b/arch/i386/kernel/microcode-xen.c -@@ -0,0 +1,165 @@ -+/* -+ * Intel CPU Microcode Update Driver for Linux -+ * -+ * Copyright (C) 2000-2004 Tigran Aivazian -+ * -+ * This driver allows to upgrade microcode on Intel processors -+ * belonging to IA-32 family - PentiumPro, Pentium II, -+ * Pentium III, Xeon, Pentium 4, etc. -+ * -+ * Reference: Section 8.10 of Volume III, Intel Pentium 4 Manual, -+ * Order Number 245472 or free download from: -+ * -+ * http://developer.intel.com/design/pentium4/manuals/245472.htm -+ * -+ * For more information, go to http://www.urbanmyth.org/microcode -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+//#define DEBUG /* pr_debug */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver"); -+MODULE_AUTHOR("Tigran Aivazian "); -+MODULE_LICENSE("GPL"); -+ -+#define MICROCODE_VERSION "1.14-xen" -+ -+#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ -+#define MC_HEADER_SIZE (sizeof (microcode_header_t)) /* 48 bytes */ -+#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */ -+ -+/* no concurrent ->write()s are allowed on /dev/cpu/microcode */ -+static DECLARE_MUTEX(microcode_sem); -+ -+static void __user *user_buffer; /* user area microcode data buffer */ -+static unsigned int user_buffer_size; /* it's size */ -+ -+static int microcode_open (struct inode *unused1, struct file *unused2) -+{ -+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; -+} -+ -+ -+static int do_microcode_update (void) -+{ -+ int err; -+ dom0_op_t op; -+ -+ err = sys_mlock((unsigned long)user_buffer, user_buffer_size); -+ if (err != 0) -+ return err; -+ -+ op.cmd = DOM0_MICROCODE; -+ op.u.microcode.data = user_buffer; -+ op.u.microcode.length = user_buffer_size; -+ err = HYPERVISOR_dom0_op(&op); -+ -+ (void)sys_munlock((unsigned long)user_buffer, user_buffer_size); -+ -+ return err; -+} -+ -+static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos) -+{ -+ ssize_t ret; -+ -+ if (len < DEFAULT_UCODE_TOTALSIZE) { -+ printk(KERN_ERR "microcode: not enough data\n"); -+ return -EINVAL; -+ } -+ -+ if ((len >> PAGE_SHIFT) > num_physpages) { -+ printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages); -+ return -EINVAL; -+ } -+ -+ down(µcode_sem); -+ -+ user_buffer = (void __user *) buf; -+ user_buffer_size = (int) len; -+ -+ ret = do_microcode_update(); -+ if (!ret) -+ ret = (ssize_t)len; -+ -+ up(µcode_sem); -+ -+ return ret; -+} -+ -+static int microcode_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ switch (cmd) { -+ /* -+ * XXX: will be removed after microcode_ctl -+ * is updated to ignore failure of this ioctl() -+ */ -+ case MICROCODE_IOCFREE: -+ return 0; -+ default: -+ return -EINVAL; -+ } -+ return -EINVAL; -+} -+ -+static struct file_operations microcode_fops = { -+ .owner = THIS_MODULE, -+ .write = microcode_write, -+ .ioctl = microcode_ioctl, -+ .open = microcode_open, -+}; -+ -+static struct miscdevice microcode_dev = { -+ .minor = MICROCODE_MINOR, -+ .name = "microcode", -+ .devfs_name = "cpu/microcode", -+ .fops = µcode_fops, -+}; -+ -+static int __init microcode_init (void) -+{ -+ int error; -+ -+ error = misc_register(µcode_dev); -+ if (error) { -+ printk(KERN_ERR -+ "microcode: can't misc_register on minor=%d\n", -+ MICROCODE_MINOR); -+ return error; -+ } -+ -+ printk(KERN_INFO -+ "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " \n"); -+ return 0; -+} -+ -+static void __exit microcode_exit (void) -+{ -+ misc_deregister(µcode_dev); -+ printk(KERN_INFO "IA-32 Microcode Update Driver v" MICROCODE_VERSION " unregistered\n"); -+} -+ -+module_init(microcode_init) -+module_exit(microcode_exit) -+MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); -diff --git a/arch/i386/kernel/mpparse-xen.c b/arch/i386/kernel/mpparse-xen.c -new file mode 100644 -index 0000000..f5daedb ---- /dev/null -+++ b/arch/i386/kernel/mpparse-xen.c -@@ -0,0 +1,1188 @@ -+/* -+ * Intel Multiprocessor Specification 1.1 and 1.4 -+ * compliant MP-table parsing routines. -+ * -+ * (c) 1995 Alan Cox, Building #3 -+ * (c) 1998, 1999, 2000 Ingo Molnar -+ * -+ * Fixes -+ * Erich Boleyn : MP v1.4 and additional changes. -+ * Alan Cox : Added EBDA scanning -+ * Ingo Molnar : various cleanups and rewrites -+ * Maciej W. Rozycki: Bits for default MP configurations -+ * Paul Diefenbaugh: Added full ACPI support -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+/* Have we found an MP table */ -+int smp_found_config; -+unsigned int __initdata maxcpus = NR_CPUS; -+ -+#ifdef CONFIG_HOTPLUG_CPU -+#define CPU_HOTPLUG_ENABLED (1) -+#else -+#define CPU_HOTPLUG_ENABLED (0) -+#endif -+ -+/* -+ * Various Linux-internal data structures created from the -+ * MP-table. -+ */ -+int apic_version [MAX_APICS]; -+int mp_bus_id_to_type [MAX_MP_BUSSES]; -+int mp_bus_id_to_node [MAX_MP_BUSSES]; -+int mp_bus_id_to_local [MAX_MP_BUSSES]; -+int quad_local_to_mp_bus_id [NR_CPUS/4][4]; -+int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; -+static int mp_current_pci_id; -+ -+/* I/O APIC entries */ -+struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; -+ -+/* # of MP IRQ source entries */ -+struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; -+ -+/* MP IRQ source entries */ -+int mp_irq_entries; -+ -+int nr_ioapics; -+ -+int pic_mode; -+unsigned long mp_lapic_addr; -+ -+unsigned int def_to_bigsmp = 0; -+ -+/* Processor that is doing the boot up */ -+unsigned int boot_cpu_physical_apicid = -1U; -+/* Internal processor count */ -+static unsigned int __devinitdata num_processors; -+ -+/* Bitmask of physically existing CPUs */ -+physid_mask_t phys_cpu_present_map; -+ -+u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; -+ -+/* -+ * Intel MP BIOS table parsing routines: -+ */ -+ -+ -+/* -+ * Checksum an MP configuration block. -+ */ -+ -+static int __init mpf_checksum(unsigned char *mp, int len) -+{ -+ int sum = 0; -+ -+ while (len--) -+ sum += *mp++; -+ -+ return sum & 0xFF; -+} -+ -+/* -+ * Have to match translation table entries to main table entries by counter -+ * hence the mpc_record variable .... can't see a less disgusting way of -+ * doing this .... -+ */ -+ -+static int mpc_record; -+static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; -+ -+#ifdef CONFIG_X86_NUMAQ -+static int MP_valid_apicid(int apicid, int version) -+{ -+ return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf; -+} -+#elif !defined(CONFIG_XEN) -+static int MP_valid_apicid(int apicid, int version) -+{ -+ if (version >= 0x14) -+ return apicid < 0xff; -+ else -+ return apicid < 0xf; -+} -+#endif -+ -+#ifndef CONFIG_XEN -+static void __devinit MP_processor_info (struct mpc_config_processor *m) -+{ -+ int ver, apicid; -+ physid_mask_t phys_cpu; -+ -+ if (!(m->mpc_cpuflag & CPU_ENABLED)) -+ return; -+ -+ apicid = mpc_apic_id(m, translation_table[mpc_record]); -+ -+ if (m->mpc_featureflag&(1<<0)) -+ Dprintk(" Floating point unit present.\n"); -+ if (m->mpc_featureflag&(1<<7)) -+ Dprintk(" Machine Exception supported.\n"); -+ if (m->mpc_featureflag&(1<<8)) -+ Dprintk(" 64 bit compare & exchange supported.\n"); -+ if (m->mpc_featureflag&(1<<9)) -+ Dprintk(" Internal APIC present.\n"); -+ if (m->mpc_featureflag&(1<<11)) -+ Dprintk(" SEP present.\n"); -+ if (m->mpc_featureflag&(1<<12)) -+ Dprintk(" MTRR present.\n"); -+ if (m->mpc_featureflag&(1<<13)) -+ Dprintk(" PGE present.\n"); -+ if (m->mpc_featureflag&(1<<14)) -+ Dprintk(" MCA present.\n"); -+ if (m->mpc_featureflag&(1<<15)) -+ Dprintk(" CMOV present.\n"); -+ if (m->mpc_featureflag&(1<<16)) -+ Dprintk(" PAT present.\n"); -+ if (m->mpc_featureflag&(1<<17)) -+ Dprintk(" PSE present.\n"); -+ if (m->mpc_featureflag&(1<<18)) -+ Dprintk(" PSN present.\n"); -+ if (m->mpc_featureflag&(1<<19)) -+ Dprintk(" Cache Line Flush Instruction present.\n"); -+ /* 20 Reserved */ -+ if (m->mpc_featureflag&(1<<21)) -+ Dprintk(" Debug Trace and EMON Store present.\n"); -+ if (m->mpc_featureflag&(1<<22)) -+ Dprintk(" ACPI Thermal Throttle Registers present.\n"); -+ if (m->mpc_featureflag&(1<<23)) -+ Dprintk(" MMX present.\n"); -+ if (m->mpc_featureflag&(1<<24)) -+ Dprintk(" FXSR present.\n"); -+ if (m->mpc_featureflag&(1<<25)) -+ Dprintk(" XMM present.\n"); -+ if (m->mpc_featureflag&(1<<26)) -+ Dprintk(" Willamette New Instructions present.\n"); -+ if (m->mpc_featureflag&(1<<27)) -+ Dprintk(" Self Snoop present.\n"); -+ if (m->mpc_featureflag&(1<<28)) -+ Dprintk(" HT present.\n"); -+ if (m->mpc_featureflag&(1<<29)) -+ Dprintk(" Thermal Monitor present.\n"); -+ /* 30, 31 Reserved */ -+ -+ -+ if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { -+ Dprintk(" Bootup CPU\n"); -+ boot_cpu_physical_apicid = m->mpc_apicid; -+ } -+ -+ ver = m->mpc_apicver; -+ -+ if (!MP_valid_apicid(apicid, ver)) { -+ printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", -+ m->mpc_apicid, MAX_APICS); -+ return; -+ } -+ -+ /* -+ * Validate version -+ */ -+ if (ver == 0x0) { -+ printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! " -+ "fixing up to 0x10. (tell your hw vendor)\n", -+ m->mpc_apicid); -+ ver = 0x10; -+ } -+ apic_version[m->mpc_apicid] = ver; -+ -+ phys_cpu = apicid_to_cpu_present(apicid); -+ physids_or(phys_cpu_present_map, phys_cpu_present_map, phys_cpu); -+ -+ if (num_processors >= NR_CPUS) { -+ printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." -+ " Processor ignored.\n", NR_CPUS); -+ return; -+ } -+ -+ if (num_processors >= maxcpus) { -+ printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." -+ " Processor ignored.\n", maxcpus); -+ return; -+ } -+ -+ cpu_set(num_processors, cpu_possible_map); -+ num_processors++; -+ -+ if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) { -+ switch (boot_cpu_data.x86_vendor) { -+ case X86_VENDOR_INTEL: -+ if (!APIC_XAPIC(ver)) { -+ def_to_bigsmp = 0; -+ break; -+ } -+ /* If P4 and above fall through */ -+ case X86_VENDOR_AMD: -+ def_to_bigsmp = 1; -+ } -+ } -+ bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; -+} -+#else -+void __init MP_processor_info (struct mpc_config_processor *m) -+{ -+ num_processors++; -+} -+#endif /* CONFIG_XEN */ -+ -+static void __init MP_bus_info (struct mpc_config_bus *m) -+{ -+ char str[7]; -+ -+ memcpy(str, m->mpc_bustype, 6); -+ str[6] = 0; -+ -+ mpc_oem_bus_info(m, str, translation_table[mpc_record]); -+ -+ if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { -+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; -+ } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { -+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; -+ } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) { -+ mpc_oem_pci_bus(m, translation_table[mpc_record]); -+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; -+ mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; -+ mp_current_pci_id++; -+ } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) { -+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; -+ } else if (strncmp(str, BUSTYPE_NEC98, sizeof(BUSTYPE_NEC98)-1) == 0) { -+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_NEC98; -+ } else { -+ printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); -+ } -+} -+ -+static void __init MP_ioapic_info (struct mpc_config_ioapic *m) -+{ -+ if (!(m->mpc_flags & MPC_APIC_USABLE)) -+ return; -+ -+ printk(KERN_INFO "I/O APIC #%d Version %d at 0x%lX.\n", -+ m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); -+ if (nr_ioapics >= MAX_IO_APICS) { -+ printk(KERN_CRIT "Max # of I/O APICs (%d) exceeded (found %d).\n", -+ MAX_IO_APICS, nr_ioapics); -+ panic("Recompile kernel with bigger MAX_IO_APICS!.\n"); -+ } -+ if (!m->mpc_apicaddr) { -+ printk(KERN_ERR "WARNING: bogus zero I/O APIC address" -+ " found in MP table, skipping!\n"); -+ return; -+ } -+ mp_ioapics[nr_ioapics] = *m; -+ nr_ioapics++; -+} -+ -+static void __init MP_intsrc_info (struct mpc_config_intsrc *m) -+{ -+ mp_irqs [mp_irq_entries] = *m; -+ Dprintk("Int: type %d, pol %d, trig %d, bus %d," -+ " IRQ %02x, APIC ID %x, APIC INT %02x\n", -+ m->mpc_irqtype, m->mpc_irqflag & 3, -+ (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus, -+ m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq); -+ if (++mp_irq_entries == MAX_IRQ_SOURCES) -+ panic("Max # of irq sources exceeded!!\n"); -+} -+ -+static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) -+{ -+ Dprintk("Lint: type %d, pol %d, trig %d, bus %d," -+ " IRQ %02x, APIC ID %x, APIC LINT %02x\n", -+ m->mpc_irqtype, m->mpc_irqflag & 3, -+ (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, -+ m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); -+ /* -+ * Well it seems all SMP boards in existence -+ * use ExtINT/LVT1 == LINT0 and -+ * NMI/LVT2 == LINT1 - the following check -+ * will show us if this assumptions is false. -+ * Until then we do not have to add baggage. -+ */ -+ if ((m->mpc_irqtype == mp_ExtINT) && -+ (m->mpc_destapiclint != 0)) -+ BUG(); -+ if ((m->mpc_irqtype == mp_NMI) && -+ (m->mpc_destapiclint != 1)) -+ BUG(); -+} -+ -+#ifdef CONFIG_X86_NUMAQ -+static void __init MP_translation_info (struct mpc_config_translation *m) -+{ -+ printk(KERN_INFO "Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local); -+ -+ if (mpc_record >= MAX_MPC_ENTRY) -+ printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n"); -+ else -+ translation_table[mpc_record] = m; /* stash this for later */ -+ if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad)) -+ node_set_online(m->trans_quad); -+} -+ -+/* -+ * Read/parse the MPC oem tables -+ */ -+ -+static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \ -+ unsigned short oemsize) -+{ -+ int count = sizeof (*oemtable); /* the header size */ -+ unsigned char *oemptr = ((unsigned char *)oemtable)+count; -+ -+ mpc_record = 0; -+ printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n", oemtable); -+ if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4)) -+ { -+ printk(KERN_WARNING "SMP mpc oemtable: bad signature [%c%c%c%c]!\n", -+ oemtable->oem_signature[0], -+ oemtable->oem_signature[1], -+ oemtable->oem_signature[2], -+ oemtable->oem_signature[3]); -+ return; -+ } -+ if (mpf_checksum((unsigned char *)oemtable,oemtable->oem_length)) -+ { -+ printk(KERN_WARNING "SMP oem mptable: checksum error!\n"); -+ return; -+ } -+ while (count < oemtable->oem_length) { -+ switch (*oemptr) { -+ case MP_TRANSLATION: -+ { -+ struct mpc_config_translation *m= -+ (struct mpc_config_translation *)oemptr; -+ MP_translation_info(m); -+ oemptr += sizeof(*m); -+ count += sizeof(*m); -+ ++mpc_record; -+ break; -+ } -+ default: -+ { -+ printk(KERN_WARNING "Unrecognised OEM table entry type! - %d\n", (int) *oemptr); -+ return; -+ } -+ } -+ } -+} -+ -+static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, -+ char *productid) -+{ -+ if (strncmp(oem, "IBM NUMA", 8)) -+ printk("Warning! May not be a NUMA-Q system!\n"); -+ if (mpc->mpc_oemptr) -+ smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, -+ mpc->mpc_oemsize); -+} -+#endif /* CONFIG_X86_NUMAQ */ -+ -+/* -+ * Read/parse the MPC -+ */ -+ -+static int __init smp_read_mpc(struct mp_config_table *mpc) -+{ -+ char str[16]; -+ char oem[10]; -+ int count=sizeof(*mpc); -+ unsigned char *mpt=((unsigned char *)mpc)+count; -+ -+ if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { -+ printk(KERN_ERR "SMP mptable: bad signature [0x%x]!\n", -+ *(u32 *)mpc->mpc_signature); -+ return 0; -+ } -+ if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { -+ printk(KERN_ERR "SMP mptable: checksum error!\n"); -+ return 0; -+ } -+ if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { -+ printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n", -+ mpc->mpc_spec); -+ return 0; -+ } -+ if (!mpc->mpc_lapic) { -+ printk(KERN_ERR "SMP mptable: null local APIC address!\n"); -+ return 0; -+ } -+ memcpy(oem,mpc->mpc_oem,8); -+ oem[8]=0; -+ printk(KERN_INFO "OEM ID: %s ",oem); -+ -+ memcpy(str,mpc->mpc_productid,12); -+ str[12]=0; -+ printk("Product ID: %s ",str); -+ -+ mps_oem_check(mpc, oem, str); -+ -+ printk("APIC at: 0x%lX\n",mpc->mpc_lapic); -+ -+ /* -+ * Save the local APIC address (it might be non-default) -- but only -+ * if we're not using ACPI. -+ */ -+ if (!acpi_lapic) -+ mp_lapic_addr = mpc->mpc_lapic; -+ -+ /* -+ * Now process the configuration blocks. -+ */ -+ mpc_record = 0; -+ while (count < mpc->mpc_length) { -+ switch(*mpt) { -+ case MP_PROCESSOR: -+ { -+ struct mpc_config_processor *m= -+ (struct mpc_config_processor *)mpt; -+ /* ACPI may have already provided this data */ -+ if (!acpi_lapic) -+ MP_processor_info(m); -+ mpt += sizeof(*m); -+ count += sizeof(*m); -+ break; -+ } -+ case MP_BUS: -+ { -+ struct mpc_config_bus *m= -+ (struct mpc_config_bus *)mpt; -+ MP_bus_info(m); -+ mpt += sizeof(*m); -+ count += sizeof(*m); -+ break; -+ } -+ case MP_IOAPIC: -+ { -+ struct mpc_config_ioapic *m= -+ (struct mpc_config_ioapic *)mpt; -+ MP_ioapic_info(m); -+ mpt+=sizeof(*m); -+ count+=sizeof(*m); -+ break; -+ } -+ case MP_INTSRC: -+ { -+ struct mpc_config_intsrc *m= -+ (struct mpc_config_intsrc *)mpt; -+ -+ MP_intsrc_info(m); -+ mpt+=sizeof(*m); -+ count+=sizeof(*m); -+ break; -+ } -+ case MP_LINTSRC: -+ { -+ struct mpc_config_lintsrc *m= -+ (struct mpc_config_lintsrc *)mpt; -+ MP_lintsrc_info(m); -+ mpt+=sizeof(*m); -+ count+=sizeof(*m); -+ break; -+ } -+ default: -+ { -+ count = mpc->mpc_length; -+ break; -+ } -+ } -+ ++mpc_record; -+ } -+ clustered_apic_check(); -+ if (!num_processors) -+ printk(KERN_ERR "SMP mptable: no processors registered!\n"); -+ return num_processors; -+} -+ -+static int __init ELCR_trigger(unsigned int irq) -+{ -+ unsigned int port; -+ -+ port = 0x4d0 + (irq >> 3); -+ return (inb(port) >> (irq & 7)) & 1; -+} -+ -+static void __init construct_default_ioirq_mptable(int mpc_default_type) -+{ -+ struct mpc_config_intsrc intsrc; -+ int i; -+ int ELCR_fallback = 0; -+ -+ intsrc.mpc_type = MP_INTSRC; -+ intsrc.mpc_irqflag = 0; /* conforming */ -+ intsrc.mpc_srcbus = 0; -+ intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid; -+ -+ intsrc.mpc_irqtype = mp_INT; -+ -+ /* -+ * If true, we have an ISA/PCI system with no IRQ entries -+ * in the MP table. To prevent the PCI interrupts from being set up -+ * incorrectly, we try to use the ELCR. The sanity check to see if -+ * there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can -+ * never be level sensitive, so we simply see if the ELCR agrees. -+ * If it does, we assume it's valid. -+ */ -+ if (mpc_default_type == 5) { -+ printk(KERN_INFO "ISA/PCI bus type with no IRQ information... falling back to ELCR\n"); -+ -+ if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13)) -+ printk(KERN_WARNING "ELCR contains invalid data... not using ELCR\n"); -+ else { -+ printk(KERN_INFO "Using ELCR to identify PCI interrupts\n"); -+ ELCR_fallback = 1; -+ } -+ } -+ -+ for (i = 0; i < 16; i++) { -+ switch (mpc_default_type) { -+ case 2: -+ if (i == 0 || i == 13) -+ continue; /* IRQ0 & IRQ13 not connected */ -+ /* fall through */ -+ default: -+ if (i == 2) -+ continue; /* IRQ2 is never connected */ -+ } -+ -+ if (ELCR_fallback) { -+ /* -+ * If the ELCR indicates a level-sensitive interrupt, we -+ * copy that information over to the MP table in the -+ * irqflag field (level sensitive, active high polarity). -+ */ -+ if (ELCR_trigger(i)) -+ intsrc.mpc_irqflag = 13; -+ else -+ intsrc.mpc_irqflag = 0; -+ } -+ -+ intsrc.mpc_srcbusirq = i; -+ intsrc.mpc_dstirq = i ? i : 2; /* IRQ0 to INTIN2 */ -+ MP_intsrc_info(&intsrc); -+ } -+ -+ intsrc.mpc_irqtype = mp_ExtINT; -+ intsrc.mpc_srcbusirq = 0; -+ intsrc.mpc_dstirq = 0; /* 8259A to INTIN0 */ -+ MP_intsrc_info(&intsrc); -+} -+ -+static inline void __init construct_default_ISA_mptable(int mpc_default_type) -+{ -+ struct mpc_config_processor processor; -+ struct mpc_config_bus bus; -+ struct mpc_config_ioapic ioapic; -+ struct mpc_config_lintsrc lintsrc; -+ int linttypes[2] = { mp_ExtINT, mp_NMI }; -+ int i; -+ -+ /* -+ * local APIC has default address -+ */ -+ mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; -+ -+ /* -+ * 2 CPUs, numbered 0 & 1. -+ */ -+ processor.mpc_type = MP_PROCESSOR; -+ /* Either an integrated APIC or a discrete 82489DX. */ -+ processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; -+ processor.mpc_cpuflag = CPU_ENABLED; -+ processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | -+ (boot_cpu_data.x86_model << 4) | -+ boot_cpu_data.x86_mask; -+ processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; -+ processor.mpc_reserved[0] = 0; -+ processor.mpc_reserved[1] = 0; -+ for (i = 0; i < 2; i++) { -+ processor.mpc_apicid = i; -+ MP_processor_info(&processor); -+ } -+ -+ bus.mpc_type = MP_BUS; -+ bus.mpc_busid = 0; -+ switch (mpc_default_type) { -+ default: -+ printk("???\n"); -+ printk(KERN_ERR "Unknown standard configuration %d\n", -+ mpc_default_type); -+ /* fall through */ -+ case 1: -+ case 5: -+ memcpy(bus.mpc_bustype, "ISA ", 6); -+ break; -+ case 2: -+ case 6: -+ case 3: -+ memcpy(bus.mpc_bustype, "EISA ", 6); -+ break; -+ case 4: -+ case 7: -+ memcpy(bus.mpc_bustype, "MCA ", 6); -+ } -+ MP_bus_info(&bus); -+ if (mpc_default_type > 4) { -+ bus.mpc_busid = 1; -+ memcpy(bus.mpc_bustype, "PCI ", 6); -+ MP_bus_info(&bus); -+ } -+ -+ ioapic.mpc_type = MP_IOAPIC; -+ ioapic.mpc_apicid = 2; -+ ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; -+ ioapic.mpc_flags = MPC_APIC_USABLE; -+ ioapic.mpc_apicaddr = 0xFEC00000; -+ MP_ioapic_info(&ioapic); -+ -+ /* -+ * We set up most of the low 16 IO-APIC pins according to MPS rules. -+ */ -+ construct_default_ioirq_mptable(mpc_default_type); -+ -+ lintsrc.mpc_type = MP_LINTSRC; -+ lintsrc.mpc_irqflag = 0; /* conforming */ -+ lintsrc.mpc_srcbusid = 0; -+ lintsrc.mpc_srcbusirq = 0; -+ lintsrc.mpc_destapic = MP_APIC_ALL; -+ for (i = 0; i < 2; i++) { -+ lintsrc.mpc_irqtype = linttypes[i]; -+ lintsrc.mpc_destapiclint = i; -+ MP_lintsrc_info(&lintsrc); -+ } -+} -+ -+static struct intel_mp_floating *mpf_found; -+ -+/* -+ * Scan the memory blocks for an SMP configuration block. -+ */ -+void __init get_smp_config (void) -+{ -+ struct intel_mp_floating *mpf = mpf_found; -+ -+ /* -+ * ACPI supports both logical (e.g. Hyper-Threading) and physical -+ * processors, where MPS only supports physical. -+ */ -+ if (acpi_lapic && acpi_ioapic) { -+ printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n"); -+ return; -+ } -+ else if (acpi_lapic) -+ printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); -+ -+ printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); -+ if (mpf->mpf_feature2 & (1<<7)) { -+ printk(KERN_INFO " IMCR and PIC compatibility mode.\n"); -+ pic_mode = 1; -+ } else { -+ printk(KERN_INFO " Virtual Wire compatibility mode.\n"); -+ pic_mode = 0; -+ } -+ -+ /* -+ * Now see if we need to read further. -+ */ -+ if (mpf->mpf_feature1 != 0) { -+ -+ printk(KERN_INFO "Default MP configuration #%d\n", mpf->mpf_feature1); -+ construct_default_ISA_mptable(mpf->mpf_feature1); -+ -+ } else if (mpf->mpf_physptr) { -+ -+ /* -+ * Read the physical hardware table. Anything here will -+ * override the defaults. -+ */ -+ if (!smp_read_mpc(isa_bus_to_virt(mpf->mpf_physptr))) { -+ smp_found_config = 0; -+ printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"); -+ printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n"); -+ return; -+ } -+ /* -+ * If there are no explicit MP IRQ entries, then we are -+ * broken. We set up most of the low 16 IO-APIC pins to -+ * ISA defaults and hope it will work. -+ */ -+ if (!mp_irq_entries) { -+ struct mpc_config_bus bus; -+ -+ printk(KERN_ERR "BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n"); -+ -+ bus.mpc_type = MP_BUS; -+ bus.mpc_busid = 0; -+ memcpy(bus.mpc_bustype, "ISA ", 6); -+ MP_bus_info(&bus); -+ -+ construct_default_ioirq_mptable(0); -+ } -+ -+ } else -+ BUG(); -+ -+ printk(KERN_INFO "Processors: %d\n", num_processors); -+ /* -+ * Only use the first configuration found. -+ */ -+} -+ -+static int __init smp_scan_config (unsigned long base, unsigned long length) -+{ -+ unsigned long *bp = isa_bus_to_virt(base); -+ struct intel_mp_floating *mpf; -+ -+ Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length); -+ if (sizeof(*mpf) != 16) -+ printk("Error: MPF size\n"); -+ -+ while (length > 0) { -+ mpf = (struct intel_mp_floating *)bp; -+ if ((*bp == SMP_MAGIC_IDENT) && -+ (mpf->mpf_length == 1) && -+ !mpf_checksum((unsigned char *)bp, 16) && -+ ((mpf->mpf_specification == 1) -+ || (mpf->mpf_specification == 4)) ) { -+ -+ smp_found_config = 1; -+#ifndef CONFIG_XEN -+ printk(KERN_INFO "found SMP MP-table at %08lx\n", -+ virt_to_phys(mpf)); -+ reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE); -+ if (mpf->mpf_physptr) { -+ /* -+ * We cannot access to MPC table to compute -+ * table size yet, as only few megabytes from -+ * the bottom is mapped now. -+ * PC-9800's MPC table places on the very last -+ * of physical memory; so that simply reserving -+ * PAGE_SIZE from mpg->mpf_physptr yields BUG() -+ * in reserve_bootmem. -+ */ -+ unsigned long size = PAGE_SIZE; -+ unsigned long end = max_low_pfn * PAGE_SIZE; -+ if (mpf->mpf_physptr + size > end) -+ size = end - mpf->mpf_physptr; -+ reserve_bootmem(mpf->mpf_physptr, size); -+ } -+#else -+ printk(KERN_INFO "found SMP MP-table at %08lx\n", -+ ((unsigned long)bp - (unsigned long)isa_bus_to_virt(base)) + base); -+#endif -+ -+ mpf_found = mpf; -+ return 1; -+ } -+ bp += 4; -+ length -= 16; -+ } -+ return 0; -+} -+ -+void __init find_smp_config (void) -+{ -+#ifndef CONFIG_XEN -+ unsigned int address; -+#endif -+ -+ /* -+ * FIXME: Linux assumes you have 640K of base ram.. -+ * this continues the error... -+ * -+ * 1) Scan the bottom 1K for a signature -+ * 2) Scan the top 1K of base RAM -+ * 3) Scan the 64K of bios -+ */ -+ if (smp_scan_config(0x0,0x400) || -+ smp_scan_config(639*0x400,0x400) || -+ smp_scan_config(0xF0000,0x10000)) -+ return; -+ /* -+ * If it is an SMP machine we should know now, unless the -+ * configuration is in an EISA/MCA bus machine with an -+ * extended bios data area. -+ * -+ * there is a real-mode segmented pointer pointing to the -+ * 4K EBDA area at 0x40E, calculate and scan it here. -+ * -+ * NOTE! There are Linux loaders that will corrupt the EBDA -+ * area, and as such this kind of SMP config may be less -+ * trustworthy, simply because the SMP table may have been -+ * stomped on during early boot. These loaders are buggy and -+ * should be fixed. -+ * -+ * MP1.4 SPEC states to only scan first 1K of 4K EBDA. -+ */ -+ -+#ifndef CONFIG_XEN -+ address = get_bios_ebda(); -+ if (address) -+ smp_scan_config(address, 0x400); -+#endif -+} -+ -+/* -------------------------------------------------------------------------- -+ ACPI-based MP Configuration -+ -------------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_ACPI -+ -+void __init mp_register_lapic_address ( -+ u64 address) -+{ -+#ifndef CONFIG_XEN -+ mp_lapic_addr = (unsigned long) address; -+ -+ set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); -+ -+ if (boot_cpu_physical_apicid == -1U) -+ boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); -+ -+ Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); -+#endif -+} -+ -+ -+void __devinit mp_register_lapic ( -+ u8 id, -+ u8 enabled) -+{ -+ struct mpc_config_processor processor; -+ int boot_cpu = 0; -+ -+ if (MAX_APICS - id <= 0) { -+ printk(KERN_WARNING "Processor #%d invalid (max %d)\n", -+ id, MAX_APICS); -+ return; -+ } -+ -+ if (id == boot_cpu_physical_apicid) -+ boot_cpu = 1; -+ -+#ifndef CONFIG_XEN -+ processor.mpc_type = MP_PROCESSOR; -+ processor.mpc_apicid = id; -+ processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR)); -+ processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0); -+ processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0); -+ processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | -+ (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; -+ processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; -+ processor.mpc_reserved[0] = 0; -+ processor.mpc_reserved[1] = 0; -+#endif -+ -+ MP_processor_info(&processor); -+} -+ -+#ifdef CONFIG_X86_IO_APIC -+ -+#define MP_ISA_BUS 0 -+#define MP_MAX_IOAPIC_PIN 127 -+ -+static struct mp_ioapic_routing { -+ int apic_id; -+ int gsi_base; -+ int gsi_end; -+ u32 pin_programmed[4]; -+} mp_ioapic_routing[MAX_IO_APICS]; -+ -+ -+static int mp_find_ioapic ( -+ int gsi) -+{ -+ int i = 0; -+ -+ /* Find the IOAPIC that manages this GSI. */ -+ for (i = 0; i < nr_ioapics; i++) { -+ if ((gsi >= mp_ioapic_routing[i].gsi_base) -+ && (gsi <= mp_ioapic_routing[i].gsi_end)) -+ return i; -+ } -+ -+ printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); -+ -+ return -1; -+} -+ -+ -+void __init mp_register_ioapic ( -+ u8 id, -+ u32 address, -+ u32 gsi_base) -+{ -+ int idx = 0; -+ int tmpid; -+ -+ if (nr_ioapics >= MAX_IO_APICS) { -+ printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " -+ "(found %d)\n", MAX_IO_APICS, nr_ioapics); -+ panic("Recompile kernel with bigger MAX_IO_APICS!\n"); -+ } -+ if (!address) { -+ printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" -+ " found in MADT table, skipping!\n"); -+ return; -+ } -+ -+ idx = nr_ioapics++; -+ -+ mp_ioapics[idx].mpc_type = MP_IOAPIC; -+ mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE; -+ mp_ioapics[idx].mpc_apicaddr = address; -+ -+#ifndef CONFIG_XEN -+ set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); -+#endif -+ if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15)) -+ tmpid = io_apic_get_unique_id(idx, id); -+ else -+ tmpid = id; -+ if (tmpid == -1) { -+ nr_ioapics--; -+ return; -+ } -+ mp_ioapics[idx].mpc_apicid = tmpid; -+ mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); -+ -+ /* -+ * Build basic GSI lookup table to facilitate gsi->io_apic lookups -+ * and to prevent reprogramming of IOAPIC pins (PCI GSIs). -+ */ -+ mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid; -+ mp_ioapic_routing[idx].gsi_base = gsi_base; -+ mp_ioapic_routing[idx].gsi_end = gsi_base + -+ io_apic_get_redir_entries(idx); -+ -+ printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, " -+ "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, -+ mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, -+ mp_ioapic_routing[idx].gsi_base, -+ mp_ioapic_routing[idx].gsi_end); -+ -+ return; -+} -+ -+ -+void __init mp_override_legacy_irq ( -+ u8 bus_irq, -+ u8 polarity, -+ u8 trigger, -+ u32 gsi) -+{ -+ struct mpc_config_intsrc intsrc; -+ int ioapic = -1; -+ int pin = -1; -+ -+ /* -+ * Convert 'gsi' to 'ioapic.pin'. -+ */ -+ ioapic = mp_find_ioapic(gsi); -+ if (ioapic < 0) -+ return; -+ pin = gsi - mp_ioapic_routing[ioapic].gsi_base; -+ -+ /* -+ * TBD: This check is for faulty timer entries, where the override -+ * erroneously sets the trigger to level, resulting in a HUGE -+ * increase of timer interrupts! -+ */ -+ if ((bus_irq == 0) && (trigger == 3)) -+ trigger = 1; -+ -+ intsrc.mpc_type = MP_INTSRC; -+ intsrc.mpc_irqtype = mp_INT; -+ intsrc.mpc_irqflag = (trigger << 2) | polarity; -+ intsrc.mpc_srcbus = MP_ISA_BUS; -+ intsrc.mpc_srcbusirq = bus_irq; /* IRQ */ -+ intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; /* APIC ID */ -+ intsrc.mpc_dstirq = pin; /* INTIN# */ -+ -+ Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n", -+ intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, -+ (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, -+ intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq); -+ -+ mp_irqs[mp_irq_entries] = intsrc; -+ if (++mp_irq_entries == MAX_IRQ_SOURCES) -+ panic("Max # of irq sources exceeded!\n"); -+ -+ return; -+} -+ -+int es7000_plat; -+ -+void __init mp_config_acpi_legacy_irqs (void) -+{ -+ struct mpc_config_intsrc intsrc; -+ int i = 0; -+ int ioapic = -1; -+ -+ /* -+ * Fabricate the legacy ISA bus (bus #31). -+ */ -+ mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; -+ Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); -+ -+ /* -+ * Older generations of ES7000 have no legacy identity mappings -+ */ -+ if (es7000_plat == 1) -+ return; -+ -+ /* -+ * Locate the IOAPIC that manages the ISA IRQs (0-15). -+ */ -+ ioapic = mp_find_ioapic(0); -+ if (ioapic < 0) -+ return; -+ -+ intsrc.mpc_type = MP_INTSRC; -+ intsrc.mpc_irqflag = 0; /* Conforming */ -+ intsrc.mpc_srcbus = MP_ISA_BUS; -+ intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid; -+ -+ /* -+ * Use the default configuration for the IRQs 0-15. Unless -+ * overriden by (MADT) interrupt source override entries. -+ */ -+ for (i = 0; i < 16; i++) { -+ int idx; -+ -+ for (idx = 0; idx < mp_irq_entries; idx++) { -+ struct mpc_config_intsrc *irq = mp_irqs + idx; -+ -+ /* Do we already have a mapping for this ISA IRQ? */ -+ if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i) -+ break; -+ -+ /* Do we already have a mapping for this IOAPIC pin */ -+ if ((irq->mpc_dstapic == intsrc.mpc_dstapic) && -+ (irq->mpc_dstirq == i)) -+ break; -+ } -+ -+ if (idx != mp_irq_entries) { -+ printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i); -+ continue; /* IRQ already used */ -+ } -+ -+ intsrc.mpc_irqtype = mp_INT; -+ intsrc.mpc_srcbusirq = i; /* Identity mapped */ -+ intsrc.mpc_dstirq = i; -+ -+ Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, " -+ "%d-%d\n", intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, -+ (intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, -+ intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, -+ intsrc.mpc_dstirq); -+ -+ mp_irqs[mp_irq_entries] = intsrc; -+ if (++mp_irq_entries == MAX_IRQ_SOURCES) -+ panic("Max # of irq sources exceeded!\n"); -+ } -+} -+ -+#define MAX_GSI_NUM 4096 -+ -+int mp_register_gsi (u32 gsi, int triggering, int polarity) -+{ -+ int ioapic = -1; -+ int ioapic_pin = 0; -+ int idx, bit = 0; -+ static int pci_irq = 16; -+ /* -+ * Mapping between Global System Interrups, which -+ * represent all possible interrupts, and IRQs -+ * assigned to actual devices. -+ */ -+ static int gsi_to_irq[MAX_GSI_NUM]; -+ -+ /* Don't set up the ACPI SCI because it's already set up */ -+ if (acpi_fadt.sci_int == gsi) -+ return gsi; -+ -+ ioapic = mp_find_ioapic(gsi); -+ if (ioapic < 0) { -+ printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi); -+ return gsi; -+ } -+ -+ ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base; -+ -+ if (ioapic_renumber_irq) -+ gsi = ioapic_renumber_irq(ioapic, gsi); -+ -+ /* -+ * Avoid pin reprogramming. PRTs typically include entries -+ * with redundant pin->gsi mappings (but unique PCI devices); -+ * we only program the IOAPIC on the first. -+ */ -+ bit = ioapic_pin % 32; -+ idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32); -+ if (idx > 3) { -+ printk(KERN_ERR "Invalid reference to IOAPIC pin " -+ "%d-%d\n", mp_ioapic_routing[ioapic].apic_id, -+ ioapic_pin); -+ return gsi; -+ } -+ if ((1< 15) -+ gsi = pci_irq++; -+ /* -+ * Don't assign IRQ used by ACPI SCI -+ */ -+ if (gsi == acpi_fadt.sci_int) -+ gsi = pci_irq++; -+ gsi_to_irq[irq] = gsi; -+ } else { -+ printk(KERN_ERR "GSI %u is too high\n", gsi); -+ return gsi; -+ } -+ } -+ -+ io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, -+ triggering == ACPI_EDGE_SENSITIVE ? 0 : 1, -+ polarity == ACPI_ACTIVE_HIGH ? 0 : 1); -+ return gsi; -+} -+ -+#endif /* CONFIG_X86_IO_APIC */ -+#endif /* CONFIG_ACPI */ -diff --git a/arch/i386/kernel/pci-dma-xen.c b/arch/i386/kernel/pci-dma-xen.c -new file mode 100644 -index 0000000..a707f24 ---- /dev/null -+++ b/arch/i386/kernel/pci-dma-xen.c -@@ -0,0 +1,326 @@ -+/* -+ * Dynamic DMA mapping support. -+ * -+ * On i386 there is no hardware dynamic DMA address translation, -+ * so consistent alloc/free are merely page allocation/freeing. -+ * The rest of the dynamic DMA mapping interface is implemented -+ * in asm/pci.h. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __x86_64__ -+int iommu_merge __read_mostly = 0; -+EXPORT_SYMBOL(iommu_merge); -+ -+dma_addr_t bad_dma_address __read_mostly; -+EXPORT_SYMBOL(bad_dma_address); -+ -+/* This tells the BIO block layer to assume merging. Default to off -+ because we cannot guarantee merging later. */ -+int iommu_bio_merge __read_mostly = 0; -+EXPORT_SYMBOL(iommu_bio_merge); -+ -+__init int iommu_setup(char *p) -+{ -+ return 1; -+} -+#endif -+ -+struct dma_coherent_mem { -+ void *virt_base; -+ u32 device_base; -+ int size; -+ int flags; -+ unsigned long *bitmap; -+}; -+ -+#define IOMMU_BUG_ON(test) \ -+do { \ -+ if (unlikely(test)) { \ -+ printk(KERN_ALERT "Fatal DMA error! " \ -+ "Please use 'swiotlb=force'\n"); \ -+ BUG(); \ -+ } \ -+} while (0) -+ -+int -+dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, -+ enum dma_data_direction direction) -+{ -+ int i, rc; -+ -+ if (direction == DMA_NONE) -+ BUG(); -+ WARN_ON(nents == 0 || sg[0].length == 0); -+ -+ if (swiotlb) { -+ rc = swiotlb_map_sg(hwdev, sg, nents, direction); -+ } else { -+ for (i = 0; i < nents; i++ ) { -+ sg[i].dma_address = -+ page_to_phys(sg[i].page) + sg[i].offset; -+ sg[i].dma_length = sg[i].length; -+ BUG_ON(!sg[i].page); -+ IOMMU_BUG_ON(address_needs_mapping( -+ hwdev, sg[i].dma_address)); -+ } -+ rc = nents; -+ } -+ -+ flush_write_buffers(); -+ return rc; -+} -+EXPORT_SYMBOL(dma_map_sg); -+ -+void -+dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, -+ enum dma_data_direction direction) -+{ -+ BUG_ON(direction == DMA_NONE); -+ if (swiotlb) -+ swiotlb_unmap_sg(hwdev, sg, nents, direction); -+} -+EXPORT_SYMBOL(dma_unmap_sg); -+ -+dma_addr_t -+dma_map_page(struct device *dev, struct page *page, unsigned long offset, -+ size_t size, enum dma_data_direction direction) -+{ -+ dma_addr_t dma_addr; -+ -+ BUG_ON(direction == DMA_NONE); -+ -+ if (swiotlb) { -+ dma_addr = swiotlb_map_page( -+ dev, page, offset, size, direction); -+ } else { -+ dma_addr = page_to_phys(page) + offset; -+ IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr)); -+ } -+ -+ return dma_addr; -+} -+EXPORT_SYMBOL(dma_map_page); -+ -+void -+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, -+ enum dma_data_direction direction) -+{ -+ BUG_ON(direction == DMA_NONE); -+ if (swiotlb) -+ swiotlb_unmap_page(dev, dma_address, size, direction); -+} -+EXPORT_SYMBOL(dma_unmap_page); -+ -+int -+dma_mapping_error(dma_addr_t dma_addr) -+{ -+ if (swiotlb) -+ return swiotlb_dma_mapping_error(dma_addr); -+ return 0; -+} -+EXPORT_SYMBOL(dma_mapping_error); -+ -+int -+dma_supported(struct device *dev, u64 mask) -+{ -+ if (swiotlb) -+ return swiotlb_dma_supported(dev, mask); -+ /* -+ * By default we'll BUG when an infeasible DMA is requested, and -+ * request swiotlb=force (see IOMMU_BUG_ON). -+ */ -+ return 1; -+} -+EXPORT_SYMBOL(dma_supported); -+ -+void *dma_alloc_coherent(struct device *dev, size_t size, -+ dma_addr_t *dma_handle, gfp_t gfp) -+{ -+ void *ret; -+ struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; -+ unsigned int order = get_order(size); -+ unsigned long vstart; -+ /* ignore region specifiers */ -+ gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); -+ -+ if (mem) { -+ int page = bitmap_find_free_region(mem->bitmap, mem->size, -+ order); -+ if (page >= 0) { -+ *dma_handle = mem->device_base + (page << PAGE_SHIFT); -+ ret = mem->virt_base + (page << PAGE_SHIFT); -+ memset(ret, 0, size); -+ return ret; -+ } -+ if (mem->flags & DMA_MEMORY_EXCLUSIVE) -+ return NULL; -+ } -+ -+ if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) -+ gfp |= GFP_DMA; -+ -+ vstart = __get_free_pages(gfp, order); -+ ret = (void *)vstart; -+ -+ if (ret != NULL) { -+ /* NB. Hardcode 31 address bits for now: aacraid limitation. */ -+ if (xen_create_contiguous_region(vstart, order, 31) != 0) { -+ free_pages(vstart, order); -+ return NULL; -+ } -+ memset(ret, 0, size); -+ *dma_handle = virt_to_bus(ret); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(dma_alloc_coherent); -+ -+void dma_free_coherent(struct device *dev, size_t size, -+ void *vaddr, dma_addr_t dma_handle) -+{ -+ struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; -+ int order = get_order(size); -+ -+ if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { -+ int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; -+ -+ bitmap_release_region(mem->bitmap, page, order); -+ } else { -+ xen_destroy_contiguous_region((unsigned long)vaddr, order); -+ free_pages((unsigned long)vaddr, order); -+ } -+} -+EXPORT_SYMBOL(dma_free_coherent); -+ -+int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, -+ dma_addr_t device_addr, size_t size, int flags) -+{ -+ void __iomem *mem_base; -+ int pages = size >> PAGE_SHIFT; -+ int bitmap_size = (pages + 31)/32; -+ -+ if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) -+ goto out; -+ if (!size) -+ goto out; -+ if (dev->dma_mem) -+ goto out; -+ -+ /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ -+ -+ mem_base = ioremap(bus_addr, size); -+ if (!mem_base) -+ goto out; -+ -+ dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); -+ if (!dev->dma_mem) -+ goto out; -+ memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem)); -+ dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL); -+ if (!dev->dma_mem->bitmap) -+ goto free1_out; -+ memset(dev->dma_mem->bitmap, 0, bitmap_size); -+ -+ dev->dma_mem->virt_base = mem_base; -+ dev->dma_mem->device_base = device_addr; -+ dev->dma_mem->size = pages; -+ dev->dma_mem->flags = flags; -+ -+ if (flags & DMA_MEMORY_MAP) -+ return DMA_MEMORY_MAP; -+ -+ return DMA_MEMORY_IO; -+ -+ free1_out: -+ kfree(dev->dma_mem->bitmap); -+ out: -+ return 0; -+} -+EXPORT_SYMBOL(dma_declare_coherent_memory); -+ -+void dma_release_declared_memory(struct device *dev) -+{ -+ struct dma_coherent_mem *mem = dev->dma_mem; -+ -+ if(!mem) -+ return; -+ dev->dma_mem = NULL; -+ iounmap(mem->virt_base); -+ kfree(mem->bitmap); -+ kfree(mem); -+} -+EXPORT_SYMBOL(dma_release_declared_memory); -+ -+void *dma_mark_declared_memory_occupied(struct device *dev, -+ dma_addr_t device_addr, size_t size) -+{ -+ struct dma_coherent_mem *mem = dev->dma_mem; -+ int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ int pos, err; -+ -+ if (!mem) -+ return ERR_PTR(-EINVAL); -+ -+ pos = (device_addr - mem->device_base) >> PAGE_SHIFT; -+ err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); -+ if (err != 0) -+ return ERR_PTR(err); -+ return mem->virt_base + (pos << PAGE_SHIFT); -+} -+EXPORT_SYMBOL(dma_mark_declared_memory_occupied); -+ -+dma_addr_t -+dma_map_single(struct device *dev, void *ptr, size_t size, -+ enum dma_data_direction direction) -+{ -+ dma_addr_t dma; -+ -+ if (direction == DMA_NONE) -+ BUG(); -+ WARN_ON(size == 0); -+ -+ if (swiotlb) { -+ dma = swiotlb_map_single(dev, ptr, size, direction); -+ } else { -+ dma = virt_to_bus(ptr); -+ IOMMU_BUG_ON(range_straddles_page_boundary(ptr, size)); -+ IOMMU_BUG_ON(address_needs_mapping(dev, dma)); -+ } -+ -+ flush_write_buffers(); -+ return dma; -+} -+EXPORT_SYMBOL(dma_map_single); -+ -+void -+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction direction) -+{ -+ if (direction == DMA_NONE) -+ BUG(); -+ if (swiotlb) -+ swiotlb_unmap_single(dev, dma_addr, size, direction); -+} -+EXPORT_SYMBOL(dma_unmap_single); -+ -+/* -+ * Local variables: -+ * c-file-style: "linux" -+ * indent-tabs-mode: t -+ * c-indent-level: 8 -+ * c-basic-offset: 8 -+ * tab-width: 8 -+ * End: -+ */ -diff --git a/arch/i386/kernel/process-xen.c b/arch/i386/kernel/process-xen.c -new file mode 100644 -index 0000000..47cde96 ---- /dev/null -+++ b/arch/i386/kernel/process-xen.c -@@ -0,0 +1,833 @@ -+/* -+ * linux/arch/i386/kernel/process.c -+ * -+ * Copyright (C) 1995 Linus Torvalds -+ * -+ * Pentium III FXSR, SSE support -+ * Gareth Hughes , May 2000 -+ */ -+ -+/* -+ * This file handles the architecture-dependent parts of process handling.. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_MATH_EMULATION -+#include -+#endif -+ -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); -+ -+static int hlt_counter; -+ -+unsigned long boot_option_idle_override = 0; -+EXPORT_SYMBOL(boot_option_idle_override); -+ -+/* -+ * Return saved PC of a blocked thread. -+ */ -+unsigned long thread_saved_pc(struct task_struct *tsk) -+{ -+ return ((unsigned long *)tsk->thread.esp)[3]; -+} -+ -+/* -+ * Powermanagement idle function, if any.. -+ */ -+void (*pm_idle)(void); -+EXPORT_SYMBOL(pm_idle); -+static DEFINE_PER_CPU(unsigned int, cpu_idle_state); -+ -+void disable_hlt(void) -+{ -+ hlt_counter++; -+} -+ -+EXPORT_SYMBOL(disable_hlt); -+ -+void enable_hlt(void) -+{ -+ hlt_counter--; -+} -+ -+EXPORT_SYMBOL(enable_hlt); -+ -+/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */ -+extern void stop_hz_timer(void); -+extern void start_hz_timer(void); -+void xen_idle(void) -+{ -+ local_irq_disable(); -+ -+ if (need_resched()) -+ local_irq_enable(); -+ else { -+ clear_thread_flag(TIF_POLLING_NRFLAG); -+ smp_mb__after_clear_bit(); -+ stop_hz_timer(); -+ /* Blocking includes an implicit local_irq_enable(). */ -+ HYPERVISOR_sched_op(SCHEDOP_block, 0); -+ start_hz_timer(); -+ set_thread_flag(TIF_POLLING_NRFLAG); -+ } -+} -+#ifdef CONFIG_APM_MODULE -+EXPORT_SYMBOL(default_idle); -+#endif -+ -+#ifdef CONFIG_HOTPLUG_CPU -+extern cpumask_t cpu_initialized; -+static inline void play_dead(void) -+{ -+ idle_task_exit(); -+ local_irq_disable(); -+ cpu_clear(smp_processor_id(), cpu_initialized); -+ preempt_enable_no_resched(); -+ HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL); -+ /* Same as drivers/xen/core/smpboot.c:cpu_bringup(). */ -+ cpu_init(); -+ touch_softlockup_watchdog(); -+ preempt_disable(); -+ local_irq_enable(); -+} -+#else -+static inline void play_dead(void) -+{ -+ BUG(); -+} -+#endif /* CONFIG_HOTPLUG_CPU */ -+ -+/* -+ * The idle thread. There's no useful work to be -+ * done, so just try to conserve power and have a -+ * low exit latency (ie sit in a loop waiting for -+ * somebody to say that they'd like to reschedule) -+ */ -+void cpu_idle(void) -+{ -+ int cpu = smp_processor_id(); -+ -+ set_thread_flag(TIF_POLLING_NRFLAG); -+ -+ /* endless idle loop with no priority at all */ -+ while (1) { -+ while (!need_resched()) { -+ -+ if (__get_cpu_var(cpu_idle_state)) -+ __get_cpu_var(cpu_idle_state) = 0; -+ -+ rmb(); -+ -+ if (cpu_is_offline(cpu)) -+ play_dead(); -+ -+ __get_cpu_var(irq_stat).idle_timestamp = jiffies; -+ xen_idle(); -+ } -+ preempt_enable_no_resched(); -+ schedule(); -+ preempt_disable(); -+ } -+} -+ -+void cpu_idle_wait(void) -+{ -+ unsigned int cpu, this_cpu = get_cpu(); -+ cpumask_t map; -+ -+ set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); -+ put_cpu(); -+ -+ cpus_clear(map); -+ for_each_online_cpu(cpu) { -+ per_cpu(cpu_idle_state, cpu) = 1; -+ cpu_set(cpu, map); -+ } -+ -+ __get_cpu_var(cpu_idle_state) = 0; -+ -+ wmb(); -+ do { -+ ssleep(1); -+ for_each_online_cpu(cpu) { -+ if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) -+ cpu_clear(cpu, map); -+ } -+ cpus_and(map, map, cpu_online_map); -+ } while (!cpus_empty(map)); -+} -+EXPORT_SYMBOL_GPL(cpu_idle_wait); -+ -+/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */ -+/* Always use xen_idle() instead. */ -+void __devinit select_idle_routine(const struct cpuinfo_x86 *c) {} -+ -+void show_regs(struct pt_regs * regs) -+{ -+ unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; -+ -+ printk("\n"); -+ printk("Pid: %d, comm: %20s\n", current->pid, current->comm); -+ printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); -+ print_symbol("EIP is at %s\n", regs->eip); -+ -+ if (user_mode(regs)) -+ printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); -+ printk(" EFLAGS: %08lx %s (%s %.*s)\n", -+ regs->eflags, print_tainted(), system_utsname.release, -+ (int)strcspn(system_utsname.version, " "), -+ system_utsname.version); -+ printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", -+ regs->eax,regs->ebx,regs->ecx,regs->edx); -+ printk("ESI: %08lx EDI: %08lx EBP: %08lx", -+ regs->esi, regs->edi, regs->ebp); -+ printk(" DS: %04x ES: %04x\n", -+ 0xffff & regs->xds,0xffff & regs->xes); -+ -+ cr0 = read_cr0(); -+ cr2 = read_cr2(); -+ cr3 = read_cr3(); -+ cr4 = read_cr4_safe(); -+ printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); -+ show_trace(NULL, ®s->esp); -+} -+ -+/* -+ * This gets run with %ebx containing the -+ * function to call, and %edx containing -+ * the "args". -+ */ -+extern void kernel_thread_helper(void); -+__asm__(".section .text\n" -+ ".align 4\n" -+ "kernel_thread_helper:\n\t" -+ "movl %edx,%eax\n\t" -+ "pushl %edx\n\t" -+ "call *%ebx\n\t" -+ "pushl %eax\n\t" -+ "call do_exit\n" -+ ".previous"); -+ -+/* -+ * Create a kernel thread -+ */ -+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -+{ -+ struct pt_regs regs; -+ -+ memset(®s, 0, sizeof(regs)); -+ -+ regs.ebx = (unsigned long) fn; -+ regs.edx = (unsigned long) arg; -+ -+ regs.xds = __USER_DS; -+ regs.xes = __USER_DS; -+ regs.orig_eax = -1; -+ regs.eip = (unsigned long) kernel_thread_helper; -+ regs.xcs = GET_KERNEL_CS(); -+ regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; -+ -+ /* Ok, create the new process.. */ -+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -+} -+EXPORT_SYMBOL(kernel_thread); -+ -+/* -+ * Free current thread data structures etc.. -+ */ -+void exit_thread(void) -+{ -+ struct task_struct *tsk = current; -+ struct thread_struct *t = &tsk->thread; -+ -+ /* -+ * Remove function-return probe instances associated with this task -+ * and put them back on the free list. Do not insert an exit probe for -+ * this function, it will be disabled by kprobe_flush_task if you do. -+ */ -+ kprobe_flush_task(tsk); -+ -+ /* The process may have allocated an io port bitmap... nuke it. */ -+ if (unlikely(NULL != t->io_bitmap_ptr)) { -+ physdev_op_t op = { 0 }; -+ op.cmd = PHYSDEVOP_SET_IOBITMAP; -+ HYPERVISOR_physdev_op(&op); -+ kfree(t->io_bitmap_ptr); -+ t->io_bitmap_ptr = NULL; -+ } -+} -+ -+void flush_thread(void) -+{ -+ struct task_struct *tsk = current; -+ -+ memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); -+ memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); -+ /* -+ * Forget coprocessor state.. -+ */ -+ clear_fpu(tsk); -+ clear_used_math(); -+} -+ -+void release_thread(struct task_struct *dead_task) -+{ -+ BUG_ON(dead_task->mm); -+ release_vm86_irqs(dead_task); -+} -+ -+/* -+ * This gets called before we allocate a new thread and copy -+ * the current task into it. -+ */ -+void prepare_to_copy(struct task_struct *tsk) -+{ -+ unlazy_fpu(tsk); -+} -+ -+int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, -+ unsigned long unused, -+ struct task_struct * p, struct pt_regs * regs) -+{ -+ struct pt_regs * childregs; -+ struct task_struct *tsk; -+ int err; -+ -+ childregs = task_pt_regs(p); -+ *childregs = *regs; -+ childregs->eax = 0; -+ childregs->esp = esp; -+ -+ p->thread.esp = (unsigned long) childregs; -+ p->thread.esp0 = (unsigned long) (childregs+1); -+ -+ p->thread.eip = (unsigned long) ret_from_fork; -+ -+ savesegment(fs,p->thread.fs); -+ savesegment(gs,p->thread.gs); -+ -+ tsk = current; -+ if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) { -+ p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); -+ if (!p->thread.io_bitmap_ptr) { -+ p->thread.io_bitmap_max = 0; -+ return -ENOMEM; -+ } -+ memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr, -+ IO_BITMAP_BYTES); -+ } -+ -+ /* -+ * Set a new TLS for the child thread? -+ */ -+ if (clone_flags & CLONE_SETTLS) { -+ struct desc_struct *desc; -+ struct user_desc info; -+ int idx; -+ -+ err = -EFAULT; -+ if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info))) -+ goto out; -+ err = -EINVAL; -+ if (LDT_empty(&info)) -+ goto out; -+ -+ idx = info.entry_number; -+ if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) -+ goto out; -+ -+ desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; -+ desc->a = LDT_entry_a(&info); -+ desc->b = LDT_entry_b(&info); -+ } -+ -+ p->thread.iopl = current->thread.iopl; -+ -+ err = 0; -+ out: -+ if (err && p->thread.io_bitmap_ptr) { -+ kfree(p->thread.io_bitmap_ptr); -+ p->thread.io_bitmap_max = 0; -+ } -+ return err; -+} -+ -+/* -+ * fill in the user structure for a core dump.. -+ */ -+void dump_thread(struct pt_regs * regs, struct user * dump) -+{ -+ int i; -+ -+/* changed the size calculations - should hopefully work better. lbt */ -+ dump->magic = CMAGIC; -+ dump->start_code = 0; -+ dump->start_stack = regs->esp & ~(PAGE_SIZE - 1); -+ dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; -+ dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; -+ dump->u_dsize -= dump->u_tsize; -+ dump->u_ssize = 0; -+ for (i = 0; i < 8; i++) -+ dump->u_debugreg[i] = current->thread.debugreg[i]; -+ -+ if (dump->start_stack < TASK_SIZE) -+ dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; -+ -+ dump->regs.ebx = regs->ebx; -+ dump->regs.ecx = regs->ecx; -+ dump->regs.edx = regs->edx; -+ dump->regs.esi = regs->esi; -+ dump->regs.edi = regs->edi; -+ dump->regs.ebp = regs->ebp; -+ dump->regs.eax = regs->eax; -+ dump->regs.ds = regs->xds; -+ dump->regs.es = regs->xes; -+ savesegment(fs,dump->regs.fs); -+ savesegment(gs,dump->regs.gs); -+ dump->regs.orig_eax = regs->orig_eax; -+ dump->regs.eip = regs->eip; -+ dump->regs.cs = regs->xcs; -+ dump->regs.eflags = regs->eflags; -+ dump->regs.esp = regs->esp; -+ dump->regs.ss = regs->xss; -+ -+ dump->u_fpvalid = dump_fpu (regs, &dump->i387); -+} -+EXPORT_SYMBOL(dump_thread); -+ -+/* -+ * Capture the user space registers if the task is not running (in user space) -+ */ -+int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) -+{ -+ struct pt_regs ptregs = *task_pt_regs(tsk); -+ ptregs.xcs &= 0xffff; -+ ptregs.xds &= 0xffff; -+ ptregs.xes &= 0xffff; -+ ptregs.xss &= 0xffff; -+ -+ elf_core_copy_regs(regs, &ptregs); -+ -+ return 1; -+} -+ -+/* -+ * This function selects if the context switch from prev to next -+ * has to tweak the TSC disable bit in the cr4. -+ */ -+static inline void disable_tsc(struct task_struct *prev_p, -+ struct task_struct *next_p) -+{ -+ struct thread_info *prev, *next; -+ -+ /* -+ * gcc should eliminate the ->thread_info dereference if -+ * has_secure_computing returns 0 at compile time (SECCOMP=n). -+ */ -+ prev = task_thread_info(prev_p); -+ next = task_thread_info(next_p); -+ -+ if (has_secure_computing(prev) || has_secure_computing(next)) { -+ /* slow path here */ -+ if (has_secure_computing(prev) && -+ !has_secure_computing(next)) { -+ write_cr4(read_cr4() & ~X86_CR4_TSD); -+ } else if (!has_secure_computing(prev) && -+ has_secure_computing(next)) -+ write_cr4(read_cr4() | X86_CR4_TSD); -+ } -+} -+ -+/* -+ * switch_to(x,yn) should switch tasks from x to y. -+ * -+ * We fsave/fwait so that an exception goes off at the right time -+ * (as a call from the fsave or fwait in effect) rather than to -+ * the wrong process. Lazy FP saving no longer makes any sense -+ * with modern CPU's, and this simplifies a lot of things (SMP -+ * and UP become the same). -+ * -+ * NOTE! We used to use the x86 hardware context switching. The -+ * reason for not using it any more becomes apparent when you -+ * try to recover gracefully from saved state that is no longer -+ * valid (stale segment register values in particular). With the -+ * hardware task-switch, there is no way to fix up bad state in -+ * a reasonable manner. -+ * -+ * The fact that Intel documents the hardware task-switching to -+ * be slow is a fairly red herring - this code is not noticeably -+ * faster. However, there _is_ some room for improvement here, -+ * so the performance issues may eventually be a valid point. -+ * More important, however, is the fact that this allows us much -+ * more flexibility. -+ * -+ * The return value (in %eax) will be the "prev" task after -+ * the task-switch, and shows up in ret_from_fork in entry.S, -+ * for example. -+ */ -+struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) -+{ -+ struct thread_struct *prev = &prev_p->thread, -+ *next = &next_p->thread; -+ int cpu = smp_processor_id(); -+#ifndef CONFIG_X86_NO_TSS -+ struct tss_struct *tss = &per_cpu(init_tss, cpu); -+#endif -+ physdev_op_t iopl_op, iobmp_op; -+ multicall_entry_t _mcl[8], *mcl = _mcl; -+ -+ /* XEN NOTE: FS/GS saved in switch_mm(), not here. */ -+ -+ /* -+ * This is basically '__unlazy_fpu', except that we queue a -+ * multicall to indicate FPU task switch, rather than -+ * synchronously trapping to Xen. -+ */ -+ if (prev_p->thread_info->status & TS_USEDFPU) { -+ __save_init_fpu(prev_p); /* _not_ save_init_fpu() */ -+ mcl->op = __HYPERVISOR_fpu_taskswitch; -+ mcl->args[0] = 1; -+ mcl++; -+ } -+#if 0 /* lazy fpu sanity check */ -+ else BUG_ON(!(read_cr0() & 8)); -+#endif -+ -+ /* -+ * Reload esp0. -+ * This is load_esp0(tss, next) with a multicall. -+ */ -+ mcl->op = __HYPERVISOR_stack_switch; -+ mcl->args[0] = __KERNEL_DS; -+ mcl->args[1] = next->esp0; -+ mcl++; -+ -+ /* -+ * Load the per-thread Thread-Local Storage descriptor. -+ * This is load_TLS(next, cpu) with multicalls. -+ */ -+#define C(i) do { \ -+ if (unlikely(next->tls_array[i].a != prev->tls_array[i].a || \ -+ next->tls_array[i].b != prev->tls_array[i].b)) { \ -+ mcl->op = __HYPERVISOR_update_descriptor; \ -+ *(u64 *)&mcl->args[0] = virt_to_machine( \ -+ &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i]);\ -+ *(u64 *)&mcl->args[2] = *(u64 *)&next->tls_array[i]; \ -+ mcl++; \ -+ } \ -+} while (0) -+ C(0); C(1); C(2); -+#undef C -+ -+ if (unlikely(prev->iopl != next->iopl)) { -+ iopl_op.cmd = PHYSDEVOP_SET_IOPL; -+ iopl_op.u.set_iopl.iopl = (next->iopl == 0) ? 1 : -+ (next->iopl >> 12) & 3; -+ mcl->op = __HYPERVISOR_physdev_op; -+ mcl->args[0] = (unsigned long)&iopl_op; -+ mcl++; -+ } -+ -+ if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { -+ iobmp_op.cmd = -+ PHYSDEVOP_SET_IOBITMAP; -+ iobmp_op.u.set_iobitmap.bitmap = -+ (char *)next->io_bitmap_ptr; -+ iobmp_op.u.set_iobitmap.nr_ports = -+ next->io_bitmap_ptr ? IO_BITMAP_BITS : 0; -+ mcl->op = __HYPERVISOR_physdev_op; -+ mcl->args[0] = (unsigned long)&iobmp_op; -+ mcl++; -+ } -+ -+ (void)HYPERVISOR_multicall(_mcl, mcl - _mcl); -+ -+ /* -+ * Restore %fs and %gs if needed. -+ * -+ * Glibc normally makes %fs be zero, and %gs is one of -+ * the TLS segments. -+ */ -+ if (unlikely(next->fs)) -+ loadsegment(fs, next->fs); -+ -+ if (next->gs) -+ loadsegment(gs, next->gs); -+ -+ /* -+ * Now maybe reload the debug registers -+ */ -+ if (unlikely(next->debugreg[7])) { -+ set_debugreg(next->debugreg[0], 0); -+ set_debugreg(next->debugreg[1], 1); -+ set_debugreg(next->debugreg[2], 2); -+ set_debugreg(next->debugreg[3], 3); -+ /* no 4 and 5 */ -+ set_debugreg(next->debugreg[6], 6); -+ set_debugreg(next->debugreg[7], 7); -+ } -+ -+ disable_tsc(prev_p, next_p); -+ -+ return prev_p; -+} -+ -+asmlinkage int sys_fork(struct pt_regs regs) -+{ -+ return do_fork(SIGCHLD, regs.esp, ®s, 0, NULL, NULL); -+} -+ -+asmlinkage int sys_clone(struct pt_regs regs) -+{ -+ unsigned long clone_flags; -+ unsigned long newsp; -+ int __user *parent_tidptr, *child_tidptr; -+ -+ clone_flags = regs.ebx; -+ newsp = regs.ecx; -+ parent_tidptr = (int __user *)regs.edx; -+ child_tidptr = (int __user *)regs.edi; -+ if (!newsp) -+ newsp = regs.esp; -+ return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); -+} -+ -+/* -+ * This is trivial, and on the face of it looks like it -+ * could equally well be done in user mode. -+ * -+ * Not so, for quite unobvious reasons - register pressure. -+ * In user mode vfork() cannot have a stack frame, and if -+ * done by calling the "clone()" system call directly, you -+ * do not have enough call-clobbered registers to hold all -+ * the information you need. -+ */ -+asmlinkage int sys_vfork(struct pt_regs regs) -+{ -+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL, NULL); -+} -+ -+/* -+ * sys_execve() executes a new program. -+ */ -+asmlinkage int sys_execve(struct pt_regs regs) -+{ -+ int error; -+ char * filename; -+ -+ filename = getname((char __user *) regs.ebx); -+ error = PTR_ERR(filename); -+ if (IS_ERR(filename)) -+ goto out; -+ error = do_execve(filename, -+ (char __user * __user *) regs.ecx, -+ (char __user * __user *) regs.edx, -+ ®s); -+ if (error == 0) { -+ task_lock(current); -+ current->ptrace &= ~PT_DTRACE; -+ task_unlock(current); -+ /* Make sure we don't return using sysenter.. */ -+ set_thread_flag(TIF_IRET); -+ } -+ putname(filename); -+out: -+ return error; -+} -+ -+#define top_esp (THREAD_SIZE - sizeof(unsigned long)) -+#define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) -+ -+unsigned long get_wchan(struct task_struct *p) -+{ -+ unsigned long ebp, esp, eip; -+ unsigned long stack_page; -+ int count = 0; -+ if (!p || p == current || p->state == TASK_RUNNING) -+ return 0; -+ stack_page = (unsigned long)task_stack_page(p); -+ esp = p->thread.esp; -+ if (!stack_page || esp < stack_page || esp > top_esp+stack_page) -+ return 0; -+ /* include/asm-i386/system.h:switch_to() pushes ebp last. */ -+ ebp = *(unsigned long *) esp; -+ do { -+ if (ebp < stack_page || ebp > top_ebp+stack_page) -+ return 0; -+ eip = *(unsigned long *) (ebp+4); -+ if (!in_sched_functions(eip)) -+ return eip; -+ ebp = *(unsigned long *) ebp; -+ } while (count++ < 16); -+ return 0; -+} -+EXPORT_SYMBOL(get_wchan); -+ -+/* -+ * sys_alloc_thread_area: get a yet unused TLS descriptor index. -+ */ -+static int get_free_idx(void) -+{ -+ struct thread_struct *t = ¤t->thread; -+ int idx; -+ -+ for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) -+ if (desc_empty(t->tls_array + idx)) -+ return idx + GDT_ENTRY_TLS_MIN; -+ return -ESRCH; -+} -+ -+/* -+ * Set a given TLS descriptor: -+ */ -+asmlinkage int sys_set_thread_area(struct user_desc __user *u_info) -+{ -+ struct thread_struct *t = ¤t->thread; -+ struct user_desc info; -+ struct desc_struct *desc; -+ int cpu, idx; -+ -+ if (copy_from_user(&info, u_info, sizeof(info))) -+ return -EFAULT; -+ idx = info.entry_number; -+ -+ /* -+ * index -1 means the kernel should try to find and -+ * allocate an empty descriptor: -+ */ -+ if (idx == -1) { -+ idx = get_free_idx(); -+ if (idx < 0) -+ return idx; -+ if (put_user(idx, &u_info->entry_number)) -+ return -EFAULT; -+ } -+ -+ if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) -+ return -EINVAL; -+ -+ desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN; -+ -+ /* -+ * We must not get preempted while modifying the TLS. -+ */ -+ cpu = get_cpu(); -+ -+ if (LDT_empty(&info)) { -+ desc->a = 0; -+ desc->b = 0; -+ } else { -+ desc->a = LDT_entry_a(&info); -+ desc->b = LDT_entry_b(&info); -+ } -+ load_TLS(t, cpu); -+ -+ put_cpu(); -+ -+ return 0; -+} -+ -+/* -+ * Get the current Thread-Local Storage area: -+ */ -+ -+#define GET_BASE(desc) ( \ -+ (((desc)->a >> 16) & 0x0000ffff) | \ -+ (((desc)->b << 16) & 0x00ff0000) | \ -+ ( (desc)->b & 0xff000000) ) -+ -+#define GET_LIMIT(desc) ( \ -+ ((desc)->a & 0x0ffff) | \ -+ ((desc)->b & 0xf0000) ) -+ -+#define GET_32BIT(desc) (((desc)->b >> 22) & 1) -+#define GET_CONTENTS(desc) (((desc)->b >> 10) & 3) -+#define GET_WRITABLE(desc) (((desc)->b >> 9) & 1) -+#define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1) -+#define GET_PRESENT(desc) (((desc)->b >> 15) & 1) -+#define GET_USEABLE(desc) (((desc)->b >> 20) & 1) -+ -+asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) -+{ -+ struct user_desc info; -+ struct desc_struct *desc; -+ int idx; -+ -+ if (get_user(idx, &u_info->entry_number)) -+ return -EFAULT; -+ if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) -+ return -EINVAL; -+ -+ memset(&info, 0, sizeof(info)); -+ -+ desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; -+ -+ info.entry_number = idx; -+ info.base_addr = GET_BASE(desc); -+ info.limit = GET_LIMIT(desc); -+ info.seg_32bit = GET_32BIT(desc); -+ info.contents = GET_CONTENTS(desc); -+ info.read_exec_only = !GET_WRITABLE(desc); -+ info.limit_in_pages = GET_LIMIT_PAGES(desc); -+ info.seg_not_present = !GET_PRESENT(desc); -+ info.useable = GET_USEABLE(desc); -+ -+ if (copy_to_user(u_info, &info, sizeof(info))) -+ return -EFAULT; -+ return 0; -+} -+ -+unsigned long arch_align_stack(unsigned long sp) -+{ -+ if (randomize_va_space) -+ sp -= get_random_int() % 8192; -+ return sp & ~0xf; -+} -diff --git a/arch/i386/kernel/quirks-xen.c b/arch/i386/kernel/quirks-xen.c -new file mode 100644 -index 0000000..39d9ed1 ---- /dev/null -+++ b/arch/i386/kernel/quirks-xen.c -@@ -0,0 +1,48 @@ -+/* -+ * This file contains work-arounds for x86 and x86_64 platform bugs. -+ */ -+#include -+#include -+#include -+ -+#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) -+ -+static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) -+{ -+ u8 config, rev; -+ u32 word; -+ -+ /* BIOS may enable hardware IRQ balancing for -+ * E7520/E7320/E7525(revision ID 0x9 and below) -+ * based platforms. -+ * Disable SW irqbalance/affinity on those platforms. -+ */ -+ pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); -+ if (rev > 0x9) -+ return; -+ -+ printk(KERN_INFO "Intel E7520/7320/7525 detected."); -+ -+ /* enable access to config space*/ -+ pci_read_config_byte(dev, 0xf4, &config); -+ pci_write_config_byte(dev, 0xf4, config|0x2); -+ -+ /* read xTPR register */ -+ raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); -+ -+ if (!(word & (1 << 13))) { -+ dom0_op_t op; -+ printk(KERN_INFO "Disabling irq balancing and affinity\n"); -+ op.cmd = DOM0_PLATFORM_QUIRK; -+ op.u.platform_quirk.quirk_id = QUIRK_NOIRQBALANCING; -+ (void)HYPERVISOR_dom0_op(&op); -+ } -+ -+ /* put back the original value for config space*/ -+ if (!(config & 0x2)) -+ pci_write_config_byte(dev, 0xf4, config); -+} -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); -+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); -+#endif -diff --git a/arch/i386/kernel/setup-xen.c b/arch/i386/kernel/setup-xen.c -new file mode 100644 -index 0000000..1e0bd6f ---- /dev/null -+++ b/arch/i386/kernel/setup-xen.c -@@ -0,0 +1,1878 @@ -+/* -+ * linux/arch/i386/kernel/setup.c -+ * -+ * Copyright (C) 1995 Linus Torvalds -+ * -+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 -+ * -+ * Memory region support -+ * David Parsons , July-August 1999 -+ * -+ * Added E820 sanitization routine (removes overlapping memory regions); -+ * Brian Moyle , February 2001 -+ * -+ * Moved CPU detection code to cpu/${cpu}.c -+ * Patrick Mochel , March 2002 -+ * -+ * Provisions for empty E820 memory regions (reported by certain BIOSes). -+ * Alex Achenbach , December 2002. -+ * -+ */ -+ -+/* -+ * This file handles the architecture-dependent parts of initialization -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include