diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
commit | 230e5ab6a084ed50470f101934782dbf54b0d06b (patch) | |
tree | 5dd821c8d33f450470588e7a543f74bf74306e9e /arch | |
parent | c9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff) |
Merge with Linux 2.1.67.
Diffstat (limited to 'arch')
35 files changed, 329 insertions, 99 deletions
diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 71c310aa1..9c74cc091 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -154,6 +154,8 @@ endmenu source fs/Config.in +source fs/nls/Config.in + source drivers/char/Config.in if [ "$CONFIG_RTC" != "n" ]; then bool ' ARC console time' CONFIG_RTC_ARC y diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index e22313036..75c0665a7 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -10,7 +10,7 @@ #define rti .long PAL_rti #define SIGCHLD 20 -#define NR_SYSCALLS 350 +#define NR_SYSCALLS 352 #define osf_vfork sys_fork /* @@ -771,4 +771,5 @@ sys_call_table: .quad sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, do_entSys /* sys_afs_syscall */, sys_newuname .quad sys_nanosleep, sys_mremap, sys_nfsservctl, sys_setresuid, sys_getresuid .quad sys_pciconfig_read, sys_pciconfig_write, sys_query_module + .quad sys_prctl, sys_pread, sys_pwrite .quad do_entSys, do_entSys diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 133c27828..3291f4603 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -37,6 +37,18 @@ # error Unable to handle more than 64 irq levels. #endif +/* PROBE_MASK is the bitset of irqs that we consider for autoprobing: */ +#if defined(CONFIG_ALPHA_P2K) + /* always mask out unused timer irq 0 and RTC irq 8 */ +# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0x101UL) +#elif defined(CONFIG_ALPHA_ALCOR) + /* always mask out unused timer irq 0, "irqs" 20-30, and the EISA cascade: */ +# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0xfff000000001UL) +#else + /* always mask out unused timer irq 0: */ +# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~1UL) +#endif + /* Reserved interrupts. These must NEVER be requested by any driver! */ #define IS_RESERVED_IRQ(irq) ((irq)==2) /* IRQ 2 used by hw cascade */ @@ -644,10 +656,13 @@ unsigned long probe_irq_on(void) unsigned int i; for (i = NR_IRQS - 1; i > 0; i--) { + if (!(PROBE_MASK & (1UL << i))) { + continue; + } action = irq_action[i]; if (!action) { enable_irq(i); - irqs |= (1 << i); + irqs |= (1UL << i); } } /* @@ -668,14 +683,10 @@ unsigned long probe_irq_on(void) */ int probe_irq_off(unsigned long irqs) { + unsigned long delay; int i; - /* as irq 0 & 8 handling don't use this function, i didn't - * bother changing the following: */ - irqs &= irq_mask & ~1; /* always mask out irq 0---it's the unused timer */ -#ifdef CONFIG_ALPHA_P2K - irqs &= ~(1 << 8); /* mask out irq 8 since that's the unused RTC input to PIC */ -#endif + irqs &= irq_mask; if (!irqs) return 0; i = ffz(~irqs); diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index b289d4f82..2b0870c3b 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -12,6 +12,10 @@ * precision CMOS clock update * 1997-01-09 Adrian Sun * use interval timer if CONFIG_RTC=y + * 1997-10-29 John Bowman (bowman@math.ualberta.ca) + * fixed tick loss calculation in timer_interrupt + * (round system clock to nearest tick instead of truncating) + * fixed algorithm in time_init for getting time from CMOS clock */ #include <linux/errno.h> #include <linux/sched.h> @@ -23,6 +27,7 @@ #include <asm/uaccess.h> #include <asm/io.h> #include <asm/hwrpb.h> +#include <asm/delay.h> #include <linux/mc146818rtc.h> #include <linux/timex.h> @@ -48,7 +53,6 @@ static int set_rtc_mmss(unsigned long); /* lump static variables together for more efficient access: */ static struct { __u32 last_time; /* cycle counter last time it got invoked */ - __u32 max_cycles_per_tick; /* more makes us think we lost an interrupt */ unsigned long scaled_ticks_per_cycle; /* ticks/cycle * 2^48 */ long last_rtc_update; /* last time the cmos clock got updated */ } state; @@ -70,19 +74,20 @@ static inline __u32 rpcc(void) void timer_interrupt(int irq, void *dev, struct pt_regs * regs) { __u32 delta, now; + int i, nticks; now = rpcc(); delta = now - state.last_time; state.last_time = now; - if (delta > state.max_cycles_per_tick) { - int i, missed_ticks; - - missed_ticks = ((delta * state.scaled_ticks_per_cycle) >> FIX_SHIFT) - 1; - for (i = 0; i < missed_ticks; ++i) { - do_timer(regs); - } + if(hwrpb->cycle_freq) { + nticks = (delta * state.scaled_ticks_per_cycle) >> (FIX_SHIFT-1); + nticks = (nticks+1) >> 1; + } + else nticks=1; /* No way to estimate lost ticks if we don't know + the cycle frequency. */ + for (i = 0; i < nticks; ++i) { + do_timer(regs); } - do_timer(regs); /* * If we have an externally synchronized Linux clock, then update @@ -136,7 +141,6 @@ void time_init(void) #endif void (*irq_handler)(int, void *, struct pt_regs *); unsigned int year, mon, day, hour, min, sec; - int i; /* The Linux interpretation of the CMOS clock register contents: * When the Update-In-Progress (UIP) flag goes from 1 to 0, the @@ -144,20 +148,24 @@ void time_init(void) * Let's hope other operating systems interpret the RTC the same way. */ /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); + /* Wait for rise.... (may take up to 1 second) */ + + do {} while(!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)); + +/* Jay Estabook <jestabro@amt.tay1.dec.com>: + * Wait for the Update Done Interrupt bit (0x10) in reg C (12) to be set, + * which (hopefully) indicates that the update is really done. + */ + + do {} while(!CMOS_READ(RTC_REG_C) & RTC_UIP); + + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BCD_TO_BIN(sec); @@ -185,8 +193,8 @@ void time_init(void) __you_loose(); } state.last_time = rpcc(); + if(hwrpb->cycle_freq) state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq; - state.max_cycles_per_tick = (2 * hwrpb->cycle_freq) / HZ; state.last_rtc_update = 0; #ifdef CONFIG_RTC diff --git a/arch/alpha/lib/strrchr.S b/arch/alpha/lib/strrchr.S index dbfedc504..88bca0ee9 100644 --- a/arch/alpha/lib/strrchr.S +++ b/arch/alpha/lib/strrchr.S @@ -21,7 +21,7 @@ strrchr: zapnot a1, 1, a1 # e0 : zero extend our test character mov zero, t6 # .. e1 : t6 is last match aligned addr sll a1, 8, t5 # e0 : replicate our test character - mov zero, t7 # .. e1 : t7 is last match byte compare mask + mov zero, t8 # .. e1 : t8 is last match byte compare mask or t5, a1, a1 # e0 : ldq_u t0, 0(a0) # .. e1 : load first quadword sll a1, 16, t5 # e0 : @@ -43,7 +43,7 @@ strrchr: $loop: ldq t0, 8(v0) # e0 : load next quadword cmovne t3, v0, t6 # .. e1 : save previous comparisons match - cmovne t3, t3, t7 # e0 : + cmovne t3, t3, t8 # e0 : addq v0, 8, v0 # .. e1 : xor t0, a1, t2 # e0 : cmpbge zero, t0, t1 # .. e1 : bits set iff byte == zero @@ -58,22 +58,22 @@ $eos: or t4, t5, t4 # e1 : ... and including the null and t3, t4, t3 # e0 : mask out char matches after null - cmovne t3, t3, t7 # .. e1 : save it, if match found + cmovne t3, t3, t8 # .. e1 : save it, if match found cmovne t3, v0, t6 # e0 : /* Locate the address of the last matched character */ /* Retain the early exit for the ev4 -- the ev5 mispredict penalty is 5 cycles -- the same as just falling through. */ - beq t7, $retnull # .. e1 : + beq t8, $retnull # .. e1 : - and t7, 0xf0, t2 # e0 : binary search for the high bit set - cmovne t2, t2, t7 # .. e1 (zdb) + and t8, 0xf0, t2 # e0 : binary search for the high bit set + cmovne t2, t2, t8 # .. e1 (zdb) cmovne t2, 4, t2 # e0 : - and t7, 0xcc, t1 # .. e1 : - cmovne t1, t1, t7 # e0 : + and t8, 0xcc, t1 # .. e1 : + cmovne t1, t1, t8 # e0 : cmovne t1, 2, t1 # .. e1 : - and t7, 0xaa, t0 # e0 : + and t8, 0xaa, t0 # e0 : cmovne t0, 1, t0 # .. e1 (zdb) addq t2, t1, t1 # e0 : addq t6, t0, v0 # .. e1 : add our aligned base ptr to the mix diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index fd835f5c0..9a556baf4 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -75,6 +75,9 @@ static void gzip_release(void **); * This is set up by the setup-routine at boot-time */ #define EXT_MEM_K (*(unsigned short *)0x90002) +#ifndef STANDARD_MEMORY_BIOS_CALL +#define ALT_MEM_K (*(unsigned long *) 0x901e0) +#endif #define SCREEN_INFO (*(struct screen_info *)0x90000) extern char input_data[]; @@ -287,9 +290,9 @@ struct { void setup_normal_output_buffer() { #ifdef STANDARD_MEMORY_BIOS_CALL - if (EXT_MEM_K < 1024) error("<2M of mem\n"); + if (EXT_MEM_K < 1024) error("Less than 2MB of memory.\n"); #else - if (EXT_MEM_K*64 < 1024) error("<2M of mem\n"); + if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory.\n"); #endif output_data = (char *)0x100000; /* Points to 1M */ } @@ -305,7 +308,7 @@ void setup_output_buffer_if_we_run_high(struct moveparams *mv) #ifdef STANDARD_MEMORY_BIOS_CALL if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n"); #else - if (EXT_MEM_K*64 < (3*1024)) error("Less than 4MB of memory.\n"); + if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory.\n"); #endif mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START; high_loaded = 1; diff --git a/arch/i386/config.in b/arch/i386/config.in index 50d9de2a7..f7042fa33 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -104,6 +104,8 @@ endmenu source fs/Config.in +source fs/nls/Config.in + source drivers/char/Config.in mainmenu_option next_comment diff --git a/arch/i386/defconfig b/arch/i386/defconfig index d4118f63f..bd100e08d 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -137,11 +137,15 @@ CONFIG_SCSI_OMIT_FLASHPOINT=y # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_SEAGATE is not set @@ -198,18 +202,19 @@ CONFIG_EEXPRESS_PRO100=y # CONFIG_QUOTA is not set # CONFIG_MINIX_FS is not set CONFIG_EXT2_FS=y +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set CONFIG_PROC_FS=y CONFIG_NFS_FS=y # CONFIG_ROOT_NFS is not set -# CONFIG_NFSD is not set +CONFIG_NFSD=y CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set -CONFIG_ISO9660_FS=y # CONFIG_HPFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_AFFS_FS is not set @@ -219,6 +224,11 @@ CONFIG_AUTOFS_FS=y # CONFIG_MAC_PARTITION is not set # +# Native Language Support +# +# CONFIG_NLS is not set + +# # Character devices # CONFIG_VT=y @@ -235,12 +245,20 @@ CONFIG_82C710_MOUSE=y # CONFIG_PC110_PAD is not set # CONFIG_UMISC is not set # CONFIG_QIC02_TAPE is not set -# CONFIG_FTAPE is not set # CONFIG_APM is not set # CONFIG_WATCHDOG is not set # CONFIG_RTC is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_PMS is not set # CONFIG_NVRAM is not set # CONFIG_JOYSTICK is not set +# CONFIG_MISC_RADIO is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set # # Sound diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 21bf04709..dffc13795 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -528,6 +528,7 @@ ENTRY(sys_call_table) .long SYMBOL_NAME(sys_nfsservctl) .long SYMBOL_NAME(sys_setresgid) /* 170 */ .long SYMBOL_NAME(sys_getresgid) - .rept NR_syscalls-171 + .long SYMBOL_NAME(sys_prctl) + .rept NR_syscalls-172 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index ef2cfa9a2..00a8e122e 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -289,7 +289,7 @@ setup_idt: movw %dx,%ax /* selector = 0x0010 = cs */ movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ - lea SYMBOL_NAME(idt),%edi + lea SYMBOL_NAME(idt_table),%edi mov $256,%ecx rp_sidt: movl %eax,(%edi) @@ -328,23 +328,33 @@ ignore_int: iret /* - * The interrupt descriptor table has room for 256 idt's + * The interrupt descriptor table has room for 256 idt's, + * the global descriptor table is dependent on the number + * of tasks we can have.. */ +#define IDT_ENTRIES 256 +#ifdef CONFIG_APM +#define GDT_ENTRIES (11+2*NR_TASKS) +#else +#define GDT_ENTRIES (8+2*NR_TASKS) +#endif + + +.globl SYMBOL_NAME(idt) +.globl SYMBOL_NAME(gdt) + ALIGN -.word 0 + .word 0 idt_descr: - .word 256*8-1 # idt contains 256 entries - .long SYMBOL_NAME(idt) + .word IDT_ENTRIES*8-1 # idt contains 256 entries +SYMBOL_NAME(idt): + .long SYMBOL_NAME(idt_table) - ALIGN -.word 0 + .word 0 gdt_descr: -#ifdef CONFIG_APM - .word (11+2*NR_TASKS)*8-1 -#else - .word (8+2*NR_TASKS)*8-1 -#endif - .long SYMBOL_NAME(gdt) + .word GDT_ENTRIES*8-1 +SYMBOL_NAME(gdt): + .long SYMBOL_NAME(gdt_table) /* * This is initialized to create a identity-mapping at 0-4M (for bootup @@ -515,7 +525,7 @@ ENTRY(this_must_match_init_task) ALIGN /* 256 quadwords - 2048 bytes of idt */ -ENTRY(idt) +ENTRY(idt_table) .fill 256,8,0 # idt is uninitialized /* @@ -528,7 +538,7 @@ ENTRY(idt) * NOTE! Make sure the gdt descriptor in head.S matches this if you * change anything. */ -ENTRY(gdt) +ENTRY(gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* not used */ .quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index b740eb0ce..e71177c3c 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -15,6 +15,7 @@ #include <asm/checksum.h> #include <asm/io.h> #include <asm/hardirq.h> +#include <asm/delay.h> extern void dump_thread(struct pt_regs *, struct user *); extern int dump_fpu(elf_fpregset_t *); @@ -42,6 +43,11 @@ EXPORT_SYMBOL_NOVERS(__up_wakeup); EXPORT_SYMBOL(__intel_bh_counter); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy); +/* Delay loops */ +EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(__delay); +EXPORT_SYMBOL(__const_udelay); + #ifdef __SMP__ EXPORT_SYMBOL(apic_reg); /* Needed internally for the I386 inlines */ @@ -63,6 +69,7 @@ EXPORT_SYMBOL(__global_restore_flags); #ifdef CONFIG_MCA /* Adapter probing and info methods. */ +EXPORT_SYMBOL(machine_id); EXPORT_SYMBOL(mca_find_adapter); EXPORT_SYMBOL(mca_write_pos); EXPORT_SYMBOL(mca_read_pos); diff --git a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c index 8f929f603..9bb150075 100644 --- a/arch/i386/kernel/ioport.c +++ b/arch/i386/kernel/ioport.c @@ -75,17 +75,15 @@ unsigned int *stack; * code. */ -asmlinkage int sys_iopl(long ebx,long ecx,long edx, - long esi, long edi, long ebp, long eax, long ds, - long es, long orig_eax, long eip, long cs, - long eflags, long esp, long ss) +asmlinkage int sys_iopl(unsigned long unused) { - unsigned int level = ebx; + struct pt_regs * regs = (struct pt_regs *) &unused; + unsigned int level = regs->ebx; if (level > 3) return -EINVAL; if (!suser()) return -EPERM; - *(&eflags) = (eflags & 0xffffcfff) | (level << 12); + regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12); return 0; } diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 590b69c38..9868811a6 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -42,6 +42,7 @@ char x86_model = 0; /* set by kernel/head.S */ char x86_mask = 0; /* set by kernel/head.S */ int x86_capability = 0; /* set by kernel/head.S */ int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */ +int pentium_f00f_bug = 0; /* set if Pentium(TM) with F00F bug */ int have_cpuid = 0; /* set if CPUID instruction works */ char x86_vendor_id[13] = "unknown"; @@ -359,6 +360,7 @@ int get_cpuinfo(char * buffer) "fdiv_bug\t: %s\n" "hlt_bug\t\t: %s\n" "sep_bug\t\t: %s\n" + "f00f_bug\t: %s\n" "fpu\t\t: %s\n" "fpu_exception\t: %s\n" "cpuid\t\t: %s\n" @@ -367,6 +369,7 @@ int get_cpuinfo(char * buffer) CD(fdiv_bug) ? "yes" : "no", CD(hlt_works_ok) ? "no" : "yes", sep_bug ? "yes" : "no", + pentium_f00f_bug ? "yes" : "no", CD(hard_math) ? "yes" : "no", (CD(hard_math) && ignore_irq13) ? "yes" : "no", diff --git a/arch/i386/kernel/trampoline.S b/arch/i386/kernel/trampoline.S index d0a726f6b..f44b9abde 100644 --- a/arch/i386/kernel/trampoline.S +++ b/arch/i386/kernel/trampoline.S @@ -62,7 +62,7 @@ idt_48: gdt_48: .word 0x0800 # gdt limit = 2048, 256 GDT entries - .long gdt-0xc0000000 # gdt base = gdt (first SMP CPU) + .long gdt_table-0xc0000000 # gdt base = gdt (first SMP CPU) .globl SYMBOL_NAME(trampoline_end) SYMBOL_NAME_LABEL(trampoline_end) diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 6fb18dc35..f08b7de6b 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -413,6 +413,39 @@ asmlinkage void math_emulate(long arg) #endif /* CONFIG_MATH_EMULATION */ +__initfunc(void trap_init_f00f_bug(void)) +{ + unsigned long page; + pgd_t * pgd; + pmd_t * pmd; + pte_t * pte; + + /* + * Allocate a new page in virtual address space, + * and move the IDT to have entry #7 starting at + * the beginning of the page. We'll force a page + * fault for IDT entries #0-#6.. + */ + page = (unsigned long) vmalloc(PAGE_SIZE); + memcpy((void *) page, idt_table, 256*8); + + pgd = pgd_offset(&init_mm, page); + pmd = pmd_offset(pgd, page); + pte = pte_offset(pmd, page); + *pte = pte_wrprotect(*pte); + local_flush_tlb(); + + /* + * "idt" is magic - it overlaps the idt_descr + * variable so that updating idt will automatically + * update the idt descriptor.. + */ + idt = (struct desc_struct *)page; + __asm__ __volatile__("lidt %0": "=m" (idt_descr)); +} + + + __initfunc(void trap_init(void)) { int i; diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile index 7ea3f1e29..6b76e32d6 100644 --- a/arch/i386/lib/Makefile +++ b/arch/i386/lib/Makefile @@ -11,6 +11,6 @@ else endif L_TARGET = lib.a -L_OBJS = checksum.o semaphore.o locks.o +L_OBJS = checksum.o semaphore.o locks.o delay.o include $(TOPDIR)/Rules.make diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c new file mode 100644 index 000000000..c3c29a7d9 --- /dev/null +++ b/arch/i386/lib/delay.c @@ -0,0 +1,45 @@ +/* + * Precise Delay Loops for i386 + * + * Copyright (C) 1993 Linus Torvalds + * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> + * + * The __delay function must _NOT_ be inlined as its execution time + * depends wildly on alignment on many x86 processors. + */ + +#include <linux/sched.h> +#include <asm/delay.h> + +#ifdef __SMP__ +#include <asm/smp.h> +#endif + +#ifdef __SMP__ +#define __udelay_val cpu_data[smp_processor_id()].udelay_val +#else +#define __udelay_val loops_per_sec +#endif + +void __delay(unsigned long loops) +{ + __asm__ __volatile__( + "1:\tdecl %0\n\tjns 1b" + :/* no outputs */ + :"a" (loops) + :"ax"); +} + +inline void __const_udelay(unsigned long xloops) +{ + __asm__("mull %0" + :"=d" (xloops) + :"a" (xloops),"0" (__udelay_val) + :"ax"); + __delay(xloops); +} + +void __udelay(unsigned long usecs) +{ + __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ +} diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 8181fd6c7..beb9f91a4 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -74,6 +74,10 @@ bad_area: return 0; } +asmlinkage void do_invalid_op (struct pt_regs *, unsigned long); + +extern int pentium_f00f_bug; + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -86,18 +90,21 @@ bad_area: */ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) { - struct task_struct *tsk = current; - struct mm_struct *mm = tsk->mm; + struct task_struct *tsk; + struct mm_struct *mm; struct vm_area_struct * vma; unsigned long address; unsigned long page; unsigned long fixup; int write; - lock_kernel(); - /* get the address */ __asm__("movl %%cr2,%0":"=r" (address)); + + lock_kernel(); + tsk = current; + mm = tsk->mm; + down(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -170,11 +177,27 @@ bad_area: goto out; } + /* + * Pentium F0 0F C7 C8 bug workaround. + */ + if (pentium_f00f_bug) { + unsigned long nr; + + nr = (address - (unsigned long) idt) >> 3; + + if (nr == 6) { + unlock_kernel(); + do_invalid_op(regs, 0); + return; + } + } + /* Are we prepared to handle this kernel fault? */ if ((fixup = search_exception_table(regs->eip)) != 0) { - printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n", + printk(KERN_DEBUG "%s: Exception at [<%lx>] cr2=%lx (fixup: %lx)\n", tsk->comm, regs->eip, + address, fixup); regs->eip = fixup; goto out; @@ -192,6 +215,7 @@ bad_area: flush_tlb(); goto out; } + if (address < PAGE_SIZE) printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); else diff --git a/arch/m68k/config.in b/arch/m68k/config.in index 25d6ded04..569da18ce 100644 --- a/arch/m68k/config.in +++ b/arch/m68k/config.in @@ -209,6 +209,8 @@ fi source fs/Config.in +source fs/nls/Config.in + mainmenu_option next_comment comment 'Character devices' diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 459e9e93a..10b1581ea 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -568,6 +568,7 @@ SYMBOL_NAME_LABEL(sys_call_table) .long SYMBOL_NAME(sys_query_module) .long SYMBOL_NAME(sys_poll) .long SYMBOL_NAME(sys_nfsservctl) + .long SYMBOL_NAME(sys_prctl) .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4 .long SYMBOL_NAME(sys_ni_syscall) .endr diff --git a/arch/mips/config.in b/arch/mips/config.in index a986350da..44c78e270 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -195,6 +195,8 @@ fi source fs/Config.in +source fs/nls/Config.in + if [ "$CONFIG_SGI" != "y" ]; then source drivers/char/Config.in diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 5c94da263..147145db6 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -161,10 +161,12 @@ CONFIG_PCNET32=y # CONFIG_QUOTA is not set # CONFIG_MINIX_FS is not set CONFIG_EXT2_FS=y -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y CONFIG_PROC_FS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y @@ -174,7 +176,6 @@ CONFIG_NFSD=y CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set -CONFIG_ISO9660_FS=y # CONFIG_HPFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_AFFS_FS is not set @@ -184,6 +185,37 @@ CONFIG_ISO9660_FS=y # CONFIG_MAC_PARTITION is not set # +# Native Language Support +# +CONFIG_NLS=y +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_KOI8_R is not set + +# # Character devices # CONFIG_VT=y @@ -193,12 +225,17 @@ CONFIG_SERIAL=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_MOUSE is not set # CONFIG_QIC02_TAPE is not set -# CONFIG_FTAPE is not set # CONFIG_APM is not set # CONFIG_WATCHDOG is not set # CONFIG_RTC is not set # CONFIG_NVRAM is not set # CONFIG_JOYSTICK is not set +# CONFIG_MISC_RADIO is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set # # Sound diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index a7c7bb7df..a64ebd1f6 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -714,9 +714,12 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, } } - /* OK, This is the point of no return. */ - flush_old_exec(bprm); + /* Flush all traces of the currently running executable */ + retval = flush_old_exec(bprm); + if (retval) + return retval; + /* OK, This is the point of no return */ current->mm->end_data = 0; current->mm->end_code = 0; current->mm->start_mmap = ELF_START_MMAP; @@ -866,7 +869,8 @@ static inline int do_load_irix_library(int fd) file->f_pos = 0; set_fs(KERNEL_DS); - error = file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)); + error = file->f_op->read(file, (char *) &elf_ex, sizeof(elf_ex), + &file->f_pos); set_fs(USER_DS); if (error != sizeof(elf_ex)) return -ENOEXEC; @@ -1021,7 +1025,7 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) */ static int dump_write(struct file *file, const void *addr, int nr) { - return file->f_op->write(file->f_dentry->d_inode, file, addr, nr) == nr; + return file->f_op->write(file, addr, nr, &file->f_pos) == nr; } static int dump_seek(struct file *file, off_t off) diff --git a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c index 22c90047c..3fa785b1d 100644 --- a/arch/mips/kernel/irixinv.c +++ b/arch/mips/kernel/irixinv.c @@ -4,8 +4,9 @@ * use the linked lists for the inventory yet. * * Miguel de Icaza, 1997. + * + * $Id$ */ -#include <linux/config.h> #include <linux/mm.h> #include <linux/slab.h> #include <asm/uaccess.h> diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index c84a391a7..76c5abf71 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c @@ -1,4 +1,4 @@ -/* $Id: irixsig.c,v 1.4 1997/08/05 09:43:10 ralf Exp $ +/* $Id: irixsig.c,v 1.5 1997/12/01 17:57:27 ralf Exp $ * irixsig.c: WHEEE, IRIX signals! YOW, am I compatable or what?!?! * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) @@ -565,7 +565,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, timeo = 1; break; } - if(current->signal & ~(current->blocked)) return -EINTR; + if(signal_pending(current)) return -EINTR; } if(timeo) return -EAGAIN; @@ -692,7 +692,7 @@ repeat: if(options & W_NOHANG) goto end_waitsys; retval = -ERESTARTSYS; - if(current->signal & ~current->blocked) + if(signal_pending(current)) goto end_waitsys; current->state = TASK_INTERRUPTIBLE; schedule(); diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h index 159931b4b..6b0e2d3c6 100644 --- a/arch/mips/kernel/syscalls.h +++ b/arch/mips/kernel/syscalls.h @@ -7,7 +7,7 @@ * * Copyright (C) 1995, 1996 by Ralf Baechle * - * $Id: syscalls.h,v 1.5 1997/09/11 01:57:38 ralf Exp $ + * $Id: syscalls.h,v 1.8 1997/12/01 17:57:32 ralf Exp $ */ /* @@ -210,3 +210,4 @@ SYS(sys_poll, 3) SYS(sys_nfsservctl, 3) SYS(sys_setresgid, 3) /* 4190 */ SYS(sys_getresgid, 3) +SYS(sys_prctl, 5) diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 1cea7ce3f..cdd5c4a03 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -108,6 +108,8 @@ endmenu source fs/Config.in +source fs/nls/Config.in + source drivers/char/Config.in mainmenu_option next_comment diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 9c6d013b6..f4174df38 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -539,6 +539,7 @@ sys_call_table: .long sys_query_module .long sys_poll .long sys_nfsservctl + .long sys_prctl .long sys_debug - .space (NR_syscalls-170)*4 + .space (NR_syscalls-171)*4 diff --git a/arch/sparc/ap1000/aplib.c b/arch/sparc/ap1000/aplib.c index 8bd67e530..453427162 100644 --- a/arch/sparc/ap1000/aplib.c +++ b/arch/sparc/ap1000/aplib.c @@ -457,7 +457,7 @@ static inline int aplib_poll(unsigned counter) tnet_check_completion(); if (resched_needed()) break; - if (current->signal & ~current->blocked) break; + if (signal_pending(current)) break; } return 0; } diff --git a/arch/sparc/ap1000/util.c b/arch/sparc/ap1000/util.c index 18a65c538..5185fdea9 100644 --- a/arch/sparc/ap1000/util.c +++ b/arch/sparc/ap1000/util.c @@ -376,7 +376,7 @@ int wait_on_int(volatile int *p,int x,int interval) add_timer(timer); interruptible_sleep_on(&timer_wait); del_timer(timer); - if (current->signal & ~current->blocked) + if (signal_pending(current)) return -EINTR; } kfree_s(timer,sizeof(*timer)); diff --git a/arch/sparc/config.in b/arch/sparc/config.in index fa8267db1..ae8568b25 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -68,7 +68,8 @@ bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then tristate ' Linear (append) mode' CONFIG_MD_LINEAR tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED -# tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING + tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING + tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 fi tristate 'RAM disk support' CONFIG_BLK_DEV_RAM @@ -145,6 +146,8 @@ fi source fs/Config.in +source fs/nls/Config.in + mainmenu_option next_comment comment 'Watchdog' diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index a166e3490..055b85b21 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -125,6 +125,7 @@ C_LABEL(sys_call_table): .long C_LABEL(sys_fdatasync) .long C_LABEL(sys_nfsservctl) /*255*/ .long C_LABEL(sys_aplib) + .long C_LABEL(sys_prctl) .long C_LABEL(sys_nis_syscall) /* Now the SunOS syscall table. */ @@ -219,3 +220,4 @@ C_LABEL(sunos_sys_table): .long C_LABEL(sunos_nosys), C_LABEL(sunos_nosys) /*250*/ .long C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys) .long C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sys_aplib) + .long C_LABEL(sunos_nosys) diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index c3c438dc6..13f056050 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -183,6 +183,8 @@ fi source fs/Config.in +source fs/nls/Config.in + mainmenu_option next_comment comment 'Kernel hacking' diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index 215aaf06f..98066a321 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -256,6 +256,7 @@ static inline int do_load_aout32_binary(struct linux_binprm * bprm, unsigned long p = bprm->p; unsigned long fd_offset; unsigned long rlim; + int retval; ex = *((struct exec *) bprm->buf); /* exec-header */ if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && @@ -278,8 +279,12 @@ static inline int do_load_aout32_binary(struct linux_binprm * bprm, if (ex.a_data + ex.a_bss > rlim) return -ENOMEM; + /* Flush all traces of the currently running executable */ + retval = flush_old_exec(bprm); + if (retval) + return retval; + /* OK, This is the point of no return */ - flush_old_exec(bprm); memcpy(¤t->tss.core_exec, &ex, sizeof(struct exec)); current->mm->end_code = ex.a_text + diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 9b00175a3..ec2c3c9b6 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -68,7 +68,7 @@ sys_call_table32: /*240*/ .word sys_munlockall, sys32_sched_setparam, sys32_sched_getparam, sys_nis_syscall, sys_nis_syscall .word sys_nis_syscall, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep /*250*/ .word sys32_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl - .word sys_aplib + .word sys_aplib, sys_prctl /* Now the 64-bit native Linux syscall table. */ @@ -127,7 +127,7 @@ sys_call_table: /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_nis_syscall, sys_nis_syscall .word sys_nis_syscall, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .word sys_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl - .word sys_aplib + .word sys_aplib, sys_prctl /* Now the 32-bit SunOS syscall table. */ @@ -221,3 +221,4 @@ sunos_sys_table: .word sunos_nosys, sunos_nosys /*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sys_aplib + .word sunos_nosys |