Re: Report on 2.1.63 - Pentium bug workaround..

Linus Torvalds (torvalds@transmeta.com)
Wed, 12 Nov 1997 21:20:25 -0800 (PST)


On Thu, 13 Nov 1997, linux kernel account wrote:
>
> Opon execution of the F00F crash program, the computer still crashes.
> HOWEVER, the previous crash was a complete hard lock, this one allowed
> console interaction.
>
> Magic-sysrequest showed that the 'bash' that had forked off the 'Process
> of Doom' was stuck as 'current' process.
>
> An improvement, but not quite yet. I would guess that, softdog could have
> rebooted the computer in this case..
>
> Maby some SMP lock isn't being acquired by the handler.

I'm re-posting the patches to v2.1.63 that should get it working with SMP
too, as too many people seem to have missed them. These pre-64 patches
apply to a clean 2.1.63, and _should_ fix the SMP Pentium problem (but
while I do have an SMP machine, it's not a Pentium, so again I can't
actually test them..)

Sorry for the re-post, but I really really want to get this tested..

Linus

----
diff -u --recursive --new-file v2.1.63/linux/Makefile linux/Makefile
--- v2.1.63/linux/Makefile Wed Nov 12 13:34:25 1997
+++ linux/Makefile Wed Nov 12 12:11:41 1997
@@ -1,6 +1,6 @@
VERSION = 2
PATCHLEVEL = 1
-SUBLEVEL = 63
+SUBLEVEL = 64

ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)

diff -u --recursive --new-file v2.1.63/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- v2.1.63/linux/arch/i386/mm/fault.c Wed Nov 12 13:34:25 1997
+++ linux/arch/i386/mm/fault.c Wed Nov 12 13:33:48 1997
@@ -74,14 +74,6 @@
return 0;
}

-asmlinkage void divide_error(void);
-asmlinkage void debug(void);
-asmlinkage void nmi(void);
-asmlinkage void int3(void);
-asmlinkage void overflow(void);
-asmlinkage void bounds(void);
-asmlinkage void invalid_op(void);
-
asmlinkage void do_divide_error (struct pt_regs *, unsigned long);
asmlinkage void do_debug (struct pt_regs *, unsigned long);
asmlinkage void do_nmi (struct pt_regs *, unsigned long);
@@ -189,44 +181,27 @@
goto out;
}

- printk("<%p/%p>\n", idt2, (void *)address);
/*
* Pentium F0 0F C7 C8 bug workaround:
*/
- if ( pentium_f00f_bug && (address >= (unsigned long)idt2) &&
- (address < (unsigned long)idt2+256*8) ) {
-
- void (*handler) (void);
- int nr = (address-(unsigned long)idt2)/8;
- unsigned long low, high;
-
- low = idt[nr].a;
- high = idt[nr].b;
-
- handler = (void (*) (void)) ((low&0x0000ffff) | (high&0xffff0000));
- printk("<handler %p... ", handler);
- unlock_kernel();
-
- if (handler==divide_error)
- do_divide_error(regs,error_code);
- else if (handler==debug)
- do_debug(regs,error_code);
- else if (handler==nmi)
- do_nmi(regs,error_code);
- else if (handler==int3)
- do_int3(regs,error_code);
- else if (handler==overflow)
- do_overflow(regs,error_code);
- else if (handler==bounds)
- do_bounds(regs,error_code);
- else if (handler==invalid_op)
- do_invalid_op(regs,error_code);
- else {
- printk("INVALID HANDLER!\n");
- for (;;) __cli();
+ if ( pentium_f00f_bug ) {
+ unsigned long nr;
+
+ nr = (address - (unsigned long) idt2) >> 3;
+
+ if (nr < 7) {
+ static void (*handler[])(struct pt_regs *, unsigned long) = {
+ do_divide_error, /* 0 - divide overflow */
+ do_debug, /* 1 - debug trap */
+ do_nmi, /* 2 - NMI */
+ do_int3, /* 3 - int 3 */
+ do_overflow, /* 4 - overflow */
+ do_bounds, /* 5 - bound range */
+ do_invalid_op }; /* 6 - invalid opcode */
+ unlock_kernel();
+ handler[nr](regs, error_code);
+ return;
}
- printk("... done>\n");
- goto out;
}

/* Are we prepared to handle this kernel fault? */
diff -u --recursive --new-file v2.1.63/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c
--- v2.1.63/linux/drivers/char/atixlmouse.c Tue Sep 23 16:48:47 1997
+++ linux/drivers/char/atixlmouse.c Wed Nov 12 20:28:26 1997
@@ -136,16 +136,16 @@
}


-static long write_mouse(struct inode * inode, struct file * file,
- const char * buffer, unsigned long count)
+static ssize_t write_mouse(struct file * file, const char * buffer,
+ size_t count, loff_t *ppos)
{
return -EINVAL;
}

-static long read_mouse(struct inode * inode, struct file * file,
- char * buffer, unsigned long count)
+static ssize_t read_mouse(struct file * file, char * buffer,
+ size_t count, loff_t *ppos)
{
- int i;
+ ssize_t i;

if (count < 3)
return -EINVAL;
diff -u --recursive --new-file v2.1.63/linux/drivers/scsi/psi_chip.h linux/drivers/scsi/psi_chip.h
--- v2.1.63/linux/drivers/scsi/psi_chip.h Wed Nov 12 13:34:26 1997
+++ linux/drivers/scsi/psi_chip.h Wed Nov 12 13:36:53 1997
@@ -192,3 +192,4 @@
} SETUP, *PSETUP;

#endif
+
diff -u --recursive --new-file v2.1.63/linux/drivers/sound/Config.in linux/drivers/sound/Config.in
--- v2.1.63/linux/drivers/sound/Config.in Wed Nov 12 13:34:26 1997
+++ linux/drivers/sound/Config.in Wed Nov 12 13:43:41 1997
@@ -1,15 +1,311 @@
-#
-# Sound driver configuration
-#
-#--------
-# There is another confic script which is compatible with rest of
-# the kernel. It can be activated by running 'make mkscript' in this
-# directory. Please note that this is an _experimental_ feature which
-# doesn't work with all cards (PSS, SM Wave, AudioTriX Pro, Maui).
-#--------
-#
-$MAKE -C drivers/sound config || exit 1
+bool 'ProAudioSpectrum 16 support' CONFIG_PAS
+bool '100%% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SB
+bool 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_ADLIB
+bool 'Gravis Ultrasound support' CONFIG_GUS
+bool 'MPU-401 support (NOT for SB16)' CONFIG_MPU401
+bool 'PSS (ECHO-ADI2111) support' CONFIG_PSS
+bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16
+bool 'GUS MAX support' CONFIG_GUSMAX
+bool 'Microsoft Sound System support' CONFIG_MSS
+bool 'Ensoniq SoundScape support' CONFIG_SSCAPE
+bool 'MediaTrix AudioTrix Pro support' CONFIG_TRIX
+bool 'Support for OPTi MAD16 and/or Mozart based cards' CONFIG_MAD16
+bool 'Support for Crystal CS4232 based (PnP) cards' CONFIG_CS4232
+bool 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_MAUI
+bool 'Yamaha OPL3-SA1 audio controller' CONFIG_OPL3SA1
+bool 'SoftOSS software wave table engine' CONFIG_SOFTOSS
+bool 'FM synthesizer (YM3812/OPL-3) support' CONFIG_YM3812
+
+if [ "$CONFIG_AEDSP16" = "y" ]; then
+hex 'I/O base for Audio Excel DSP 16 220 or 240' AEDSP16_BASE 220
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+hex 'I/O base for SB Check from manual of the card' SBC_BASE 220
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster IRQ Check from manual of the card' SBC_IRQ 7
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster DMA 0, 1 or 3' SBC_DMA 1
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster 16 bit DMA (SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' SB_DMA2 5
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' SB_MPU_BASE 330
+fi
+
+
+if [ "$CONFIG_SB" = "y" ]; then
+comment 'MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688.'
+fi
+
+
+if [ "$CONFIG_SB" = "y" ]; then
+comment 'Enter -1 to the following question if you have something else such as SB16/32.'
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Check from manual of the card' SB_MPU_IRQ -1
+fi
+
+if [ "$CONFIG_PAS" = "y" ]; then
+int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' PAS_IRQ 10
+fi
+
+if [ "$CONFIG_PAS" = "y" ]; then
+int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' PAS_DMA 3
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' GUS_BASE 220
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' GUS_IRQ 15
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'GUS DMA 1, 3, 5, 6 or 7' GUS_DMA 6
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' GUS_DMA2 -1
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' GUS16_BASE 530
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' GUS16_IRQ 7
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+int 'GUS DMA 0, 1 or 3' GUS16_DMA 3
+fi
+
+if [ "$CONFIG_MPU401" = "y" ]; then
+hex 'I/O base for MPU401 Check from manual of the card' MPU_BASE 330
+fi
+
+if [ "$CONFIG_MPU401" = "y" ]; then
+int 'MPU401 IRQ Check from manual of the card' MPU_IRQ 9
+fi
+
+
+if [ "$CONFIG_MAUI" = "y" ]; then
+comment 'ERROR! You have to use old sound configuration method with Maui.'
+fi
+
+if [ "$CONFIG_MAUI" = "y" ]; then
+hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' MAUI_BASE 330
+fi
+
+if [ "$CONFIG_MAUI" = "y" ]; then
+int 'Maui IRQ 5, 9, 12 or 15' MAUI_IRQ 9
+fi
+
+if [ "$CONFIG_UART6850" = "y" ]; then
+hex 'I/O base for UART 6850 MIDI port (Unknown)' U6850_BASE 0
+fi
+
+if [ "$CONFIG_UART6850" = "y" ]; then
+int 'UART6850 IRQ (Unknown)' U6850_IRQ -1
+fi
+
+
+if [ "$CONFIG_PSS" = "y" ]; then
+comment 'ERROR! You have to use old sound configuration method with PSS cards.'
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS I/O base 220 or 240' PSS_BASE 220
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS audio I/O base 530, 604, E80 or F40' PSS_MSS_BASE 530
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS audio IRQ 7, 9, 10 or 11' PSS_MSS_IRQ 11
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS audio DMA 0, 1 or 3' PSS_MSS_DMA 3
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS MIDI I/O base ' PSS_MPU_BASE 330
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS MIDI IRQ 3, 4, 5, 7 or 9' PSS_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_MSS" = "y" ]; then
+hex 'MSS/WSS I/O base 530, 604, E80 or F40' MSS_BASE 530
+fi

+if [ "$CONFIG_MSS" = "y" ]; then
+int 'MSS/WSS IRQ 7, 9, 10 or 11' MSS_IRQ 11
+fi
+
+if [ "$CONFIG_MSS" = "y" ]; then
+int 'MSS/WSS DMA 0, 1 or 3' MSS_DMA 3
+fi
+
+if [ "$CONFIG_MSS" = "y" ]; then
+int 'MSS/WSS second DMA (if possible) 0, 1 or 3' MSS_DMA2 -1
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' SSCAPE_BASE 330
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape MIDI IRQ ' SSCAPE_IRQ 9
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape initialization DMA 0, 1 or 3' SSCAPE_DMA 3
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+hex 'SoundScape audio I/O base 534, 608, E84 or F44' SSCAPE_MSS_BASE 534
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape audio IRQ 7, 9, 10 or 11' SSCAPE_MSS_IRQ 11
+fi
+
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+comment 'ERROR! You have to use old sound configuration method with OPL3-SA1.'
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' TRIX_BASE 530
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' TRIX_IRQ 11
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'OPL3-SA1 audio DMA 0, 1 or 3' TRIX_DMA 0
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' TRIX_DMA2 3
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' TRIX_MPU_BASE 330
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' TRIX_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'OPL3-SA1 SB I/O base 220, 210, 230, 240, 250, 260 or 270' TRIX_SB_BASE 220
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'OPL3-SA1 SB IRQ 3, 4, 5 or 7' TRIX_SB_IRQ 7
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'OPL3-SA1 SB DMA 1 or 3' TRIX_SB_DMA 1
+fi
+
+if [ "$CONFIG_OPL3SA1" = "y" ]; then
+hex 'OPL3-SA1 audio I/O base 530, 604, E80 or F40' OPL3SA1_BASE 530
+fi
+
+if [ "$CONFIG_OPL3SA1" = "y" ]; then
+int 'OPL3-SA1 audio IRQ 7, 9, 10 or 11' OPL3SA1_IRQ 11
+fi
+
+if [ "$CONFIG_OPL3SA1" = "y" ]; then
+int 'OPL3-SA1 audio DMA 0, 1 or 3' OPL3SA1_DMA 0
+fi
+
+if [ "$CONFIG_OPL3SA1" = "y" ]; then
+int 'OPL3-SA1 second (duplex) DMA 0, 1 or 3' OPL3SA1_DMA2 3
+fi
+
+if [ "$CONFIG_OPL3SA1" = "y" ]; then
+hex 'OPL3-SA1 MIDI I/O base 330, 370, 3B0 or 3F0' OPL3SA1_MPU_BASE 330
+fi
+
+if [ "$CONFIG_OPL3SA1" = "y" ]; then
+int 'OPL3-SA1 MIDI IRQ 3, 4, 5, 7 or 9' OPL3SA1_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+hex 'CS4232 audio I/O base 530, 604, E80 or F40' CS4232_BASE 530
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CS4232_IRQ 11
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 audio DMA 0, 1 or 3' CS4232_DMA 0
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 second (duplex) DMA 0, 1 or 3' CS4232_DMA2 3
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CS4232_MPU_BASE 330
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CS4232_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+hex 'MAD16 audio I/O base 530, 604, E80 or F40' MAD16_BASE 530
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 audio IRQ 7, 9, 10 or 11' MAD16_IRQ 11
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 audio DMA 0, 1 or 3' MAD16_DMA 3
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 second (duplex) DMA 0, 1 or 3' MAD16_DMA2 0
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' MAD16_MPU_BASE 330
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 MIDI IRQ 5, 7, 9 or 10' MAD16_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_SOFTOSS" = "y" ]; then
+int 'Sampling rate for SoftOSS 8000 to 48000' SOFTOSS_RATE 22050
+fi
+
+if [ "$CONFIG_SOFTOSS" = "y" ]; then
+int 'Max # of concurrent voices for SoftOSS 4 to 32' SOFTOSS_VOICES 32
+fi
+#
+$MAKE -C drivers/sound kernelconfig || exit 1
bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND

if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
diff -u --recursive --new-file v2.1.63/linux/fs/ext2/fsync.c linux/fs/ext2/fsync.c
--- v2.1.63/linux/fs/ext2/fsync.c Tue Sep 23 16:48:48 1997
+++ linux/fs/ext2/fsync.c Wed Nov 12 13:03:27 1997
@@ -57,72 +57,6 @@
return 0;
}

-#ifndef __LITTLE_ENDIAN
-static int sync_block_swab32 (struct inode * inode, u32 * block, int wait)
-{
- struct buffer_head * bh;
-
- if (!le32_to_cpu(*block))
- return 0;
- bh = get_hash_table (inode->i_dev, le32_to_cpu(*block), blocksize);
- if (!bh)
- return 0;
- if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
- brelse (bh);
- return -1;
- }
- if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
- brelse (bh);
- return 0;
- }
- ll_rw_block (WRITE, 1, &bh);
- bh->b_count--;
- return 0;
-}
-#else
-#define sync_block_swab32 sync_block
-#endif
-
-
-static int sync_iblock (struct inode * inode, u32 * iblock,
- struct buffer_head ** bh, int wait)
-{
- int rc, tmp;
-
- *bh = NULL;
- tmp = *iblock;
- if (!tmp)
- return 0;
- rc = sync_block (inode, iblock, wait);
- if (rc)
- return rc;
- *bh = bread (inode->i_dev, tmp, blocksize);
- if (!*bh)
- return -1;
- return 0;
-}
-
-#ifndef __LITTLE_ENDIAN
-static int sync_iblock_swab32 (struct inode * inode, u32 * iblock,
- struct buffer_head ** bh, int wait)
-{
- int rc, tmp;
-
- *bh = NULL;
- tmp = le32_to_cpu(*iblock);
- if (!tmp)
- return 0;
- rc = sync_block_swab32 (inode, iblock, wait);
- if (rc)
- return rc;
- *bh = bread (inode->i_dev, tmp, blocksize);
- if (!*bh)
- return -1;
- return 0;
-}
-#else
-#define sync_iblock_swab32 sync_iblock
-#endif

static int sync_direct (struct inode * inode, int wait)
{
@@ -137,122 +71,15 @@
return err;
}

-static int sync_indirect (struct inode * inode, u32 * iblock, int wait)
-{
- int i;
- struct buffer_head * ind_bh;
- int rc, err = 0;
-
- rc = sync_iblock (inode, iblock, &ind_bh, wait);
- if (rc || !ind_bh)
- return rc;
-
- for (i = 0; i < addr_per_block; i++) {
- rc = sync_block_swab32 (inode,
- ((u32 *) ind_bh->b_data) + i,
- wait);
- if (rc)
- err = rc;
- }
- brelse (ind_bh);
- return err;
-}
-
-#ifndef __LITTLE_ENDIAN
-static __inline__ int sync_indirect_swab32 (struct inode * inode, u32 * iblock, int wait)
-{
- int i;
- struct buffer_head * ind_bh;
- int rc, err = 0;
-
- rc = sync_iblock_swab32 (inode, iblock, &ind_bh, wait);
- if (rc || !ind_bh)
- return rc;
-
- for (i = 0; i < addr_per_block; i++) {
- rc = sync_block_swab32 (inode,
- ((u32 *) ind_bh->b_data) + i,
- wait);
- if (rc)
- err = rc;
- }
- brelse (ind_bh);
- return err;
-}
-#else
-#define sync_indirect_swab32 sync_indirect
-#endif
-
-static int sync_dindirect (struct inode * inode, u32 * diblock, int wait)
-{
- int i;
- struct buffer_head * dind_bh;
- int rc, err = 0;
-
- rc = sync_iblock (inode, diblock, &dind_bh, wait);
- if (rc || !dind_bh)
- return rc;
-
- for (i = 0; i < addr_per_block; i++) {
- rc = sync_indirect_swab32 (inode,
- ((u32 *) dind_bh->b_data) + i,
- wait);
- if (rc)
- err = rc;
- }
- brelse (dind_bh);
- return err;
-}
-
-#ifndef __LITTLE_ENDIAN
-static __inline__ int sync_dindirect_swab32 (struct inode * inode, u32 * diblock, int wait)
-{
- int i;
- struct buffer_head * dind_bh;
- int rc, err = 0;
-
- rc = sync_iblock_swab32 (inode, diblock, &dind_bh, wait);
- if (rc || !dind_bh)
- return rc;
-
- for (i = 0; i < addr_per_block; i++) {
- rc = sync_indirect_swab32 (inode,
- ((u32 *) dind_bh->b_data) + i,
- wait);
- if (rc)
- err = rc;
- }
- brelse (dind_bh);
- return err;
-}
-#else
-#define sync_dindirect_swab32 sync_dindirect
-#endif
-
-static int sync_tindirect (struct inode * inode, u32 * tiblock, int wait)
-{
- int i;
- struct buffer_head * tind_bh;
- int rc, err = 0;
-
- rc = sync_iblock (inode, tiblock, &tind_bh, wait);
- if (rc || !tind_bh)
- return rc;
-
- for (i = 0; i < addr_per_block; i++) {
- rc = sync_dindirect_swab32 (inode,
- ((u32 *) tind_bh->b_data) + i,
- wait);
- if (rc)
- err = rc;
- }
- brelse (tind_bh);
- return err;
-}
-
/*
* File may be NULL when we are called. Perhaps we shouldn't
* even pass file to fsync ?
+ *
+ * This currently falls back to synching the whole device when
+ * the file is larger than can fit directly in the inode. This
+ * is because dirty-buffer handling is indexed by the device
+ * of the buffer, which makes it much faster to sync the whole
+ * device than to sync just one large file.
*/

int ext2_sync_file(struct file * file, struct dentry *dentry)
@@ -269,18 +96,14 @@
*/
goto skip;

+ if (inode->i_size > EXT2_NDIR_BLOCKS*blocksize) {
+ err = fsync_dev(inode->i_dev);
+ goto skip;
+ }
+
for (wait=0; wait<=1; wait++)
{
err |= sync_direct (inode, wait);
- err |= sync_indirect (inode,
- inode->u.ext2_i.i_data+EXT2_IND_BLOCK,
- wait);
- err |= sync_dindirect (inode,
- inode->u.ext2_i.i_data+EXT2_DIND_BLOCK,
- wait);
- err |= sync_tindirect (inode,
- inode->u.ext2_i.i_data+EXT2_TIND_BLOCK,
- wait);
}
skip:
err |= ext2_sync_inode (inode);
diff -u --recursive --new-file v2.1.63/linux/include/asm-i386/bugs.h linux/include/asm-i386/bugs.h
--- v2.1.63/linux/include/asm-i386/bugs.h Wed Nov 12 13:34:27 1997
+++ linux/include/asm-i386/bugs.h Wed Nov 12 17:24:07 1997
@@ -142,7 +142,7 @@
: "edx" (inp)
: "eax", "ecx", "edx", "edi" );
/* If this fails, it means that any user program may lock CPU hard. Too bad. */
- if (res != 12345678) printk( "Bad.\n" );
+ if (res != 12345678) printk( "Buggy.\n" );
else printk( "Ok.\n" );
#endif
}
@@ -172,23 +172,19 @@
*/

extern int pentium_f00f_bug;
+extern void trap_init_f00f_bug(void);
+

__initfunc(static void check_pentium_f00f(void))
{
/*
* Pentium and Pentium MMX
*/
- printk("checking for F00F bug ...");
- if(x86==5 && !memcmp(x86_vendor_id, "GenuineIntel", 12))
- {
- extern void trap_init_f00f_bug(void);
-
- printk(KERN_INFO "\nIntel Pentium/[MMX] F0 0F bug detected - turning on workaround.\n");
+ pentium_f00f_bug = 0;
+ if (x86==5 && !memcmp(x86_vendor_id, "GenuineIntel", 12)) {
+ printk(KERN_INFO "Intel Pentium with F0 0F bug - workaround enabled.\n");
pentium_f00f_bug = 1;
trap_init_f00f_bug();
- } else {
- printk(KERN_INFO " no F0 0F bug in this CPU, great!\n");
- pentium_f00f_bug = 0;
}
}