]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.8 1.1.8
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:28 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:28 +0000 (15:09 -0500)
25 files changed:
Makefile
drivers/block/genhd.c
drivers/char/serial.c
drivers/scsi/sd.c
fs/buffer.c
fs/exec.c
fs/filesystems.c
fs/inode.c
fs/super.c
include/asm/segment.h
include/linux/fs.h
include/linux/kernel.h
include/linux/ptrace.h
include/linux/sched.h
include/linux/signal.h
include/linux/vm86.h
init/main.c
kernel/Makefile
kernel/ksyms.c
kernel/signal.c
kernel/sys.c
kernel/traps.c
kernel/vm86.c [new file with mode: 0644]
lib/string.c
mm/swap.c

index ee548aa9e11eaa8b6bdcc9dcfefd224343efa75a..57c04edae3a54cd4689137b271353c1d24903189 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 7
+SUBLEVEL = 8
 
 all:   Version zImage
 
index 1681d2b273d13dbc0aa40e104a91b856ea001534..7d3978d87694d4c91cbf66714c8dccefae97ef7a 100644 (file)
@@ -193,17 +193,11 @@ static void setup_dev(struct gendisk *dev)
        blk_size[dev->major] = dev->sizes;
 }
        
-/* This may be used only once, enforced by 'static int callable' */
-asmlinkage int sys_setup(void * BIOS)
+void device_setup(void * BIOS)
 {
-       static int callable = 1;
        struct gendisk *p;
        int nr=0;
 
-       if (!callable)
-               return -1;
-       callable = 0;
-
        for (p = gendisk_head ; p ; p=p->next) {
                setup_dev(p);
                nr += p->nr_real;
@@ -211,6 +205,4 @@ asmlinkage int sys_setup(void * BIOS)
                
        if (ramdisk_size)
                rd_load();
-       mount_root();
-       return (0);
 }
index 6a9f27d556cf7d65510f7502f9b4f3c9b65ce637..e563013b6f3c715be414fd7e1f7d3b935dccca3a 100644 (file)
 #include <asm/segment.h>
 #include <asm/bitops.h>
 
-/*
- * Serial driver configuration section.  Here are the various options:
- *
- * CONFIG_AUTO_IRQ
- *             Enables automatic IRQ detection.  I've put in some
- *             fixes to this which should make this work much more
- *             cleanly than it used to in 0.98pl2-6.  It should be
- *             much less vulnerable to false IRQs now.
- * 
- * CONFIG_AST_FOURPORT
- *             Enables support for the AST Fourport serial port.
- * 
- * CONFIG_ACCENT_ASYNC
- *             Enables support for the Accent Async 4 port serial
- *             port.
- *
- * CONFIG_HUB6
- *             Enables support for the venerable Bell Technologies
- *             HUB6 card.
- */
-
 #undef ISR_HACK
 
 /*
index ccfbcb39030e1d87d6160e0f5a8ca951dee6e02c..0038246bbadc3584bab5ff0a25ce1eaacf5e3f54 100644 (file)
@@ -460,7 +460,7 @@ repeat:
            ((int) SCpnt->request.bh->b_data) + (SCpnt->request.nr_sectors << 9) - 1 > 
            ISA_DMA_THRESHOLD && SCpnt->host->unchecked_isa_dma) {
          if(((int) SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD)
-           bounce_buffer = scsi_malloc(bounce_size);
+           bounce_buffer = (char *) scsi_malloc(bounce_size);
          if(!bounce_buffer) contiguous = 0;
        };
 
@@ -606,7 +606,7 @@ repeat:
 
                if(!sgpnt[count].alt_address) {count--; continue; }
                if(dma_free_sectors > 10)
-                 tmp = scsi_malloc(sgpnt[count].length + bhp->b_size);
+                 tmp = (char *) scsi_malloc(sgpnt[count].length + bhp->b_size);
                else {
                  tmp = NULL;
                  max_sg = SCpnt->use_sg;
index 5cb9039b02542d4f823cf39d3d27fde1b46198a3..471fc7c21a6ff1ba14e0414caef1e1f2424cd7a0 100644 (file)
@@ -1767,7 +1767,7 @@ asmlinkage int sync_old_buffers(void)
        repeat:
                bh = lru_list[nlist];
                if(bh) 
-                        for (i = nr_buffers_type[nlist]; --i > 0; bh = next) {
+                        for (i = nr_buffers_type[nlist]; i-- > 0; bh = next) {
                                 /* We may have stalled while waiting for I/O to complete. */
                                 if(bh->b_list != nlist) goto repeat;
                                 next = bh->b_next_free;
@@ -1909,6 +1909,9 @@ asmlinkage int sys_bdflush(int func, int data)
                
                if(nr_buffers_type[BUF_DIRTY] < (nr_buffers - nr_buffers_type[BUF_SHARED]) * 
                   bdf_prm.b_un.nfract/100) {
+                       if (current->signal & (1 << (SIGKILL-1)))
+                               return 0;
+                       current->signal = 0;
                        interruptible_sleep_on(&bdflush_wait);
                }
        }
index db46a74bdbe5625de260d98e15decfda93bbd614..340083cf2a91ae627ddefabe4ff3e5d322dcea99 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -754,6 +754,17 @@ struct linux_binfmt formats[] = {
        {NULL, NULL}
 };
 
+static void set_brk(unsigned long start, unsigned long end)
+{
+       start = PAGE_ALIGN(start);
+       end = PAGE_ALIGN(end);
+       if (end <= start)
+               return;
+       do_mmap(NULL, start, end - start,
+               PROT_READ | PROT_WRITE | PROT_EXEC,
+               MAP_FIXED | MAP_PRIVATE, 0);
+}
+
 /*
  * These are the functions used to load a.out style executables and shared
  * libraries.  There is no binary dependent code anywhere else.
@@ -790,7 +801,8 @@ int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
 
        current->end_code = N_TXTADDR(ex) + ex.a_text;
        current->end_data = ex.a_data + current->end_code;
-       current->start_brk = current->brk = current->end_data;
+       current->start_brk = current->end_data;
+       current->brk = current->start_brk + ex.a_bss;
        current->start_code += N_TXTADDR(ex);
        current->rss = 0;
        current->suid = current->euid = bprm->e_uid;
@@ -842,7 +854,7 @@ int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                bprm->inode->i_count++;
        }
 beyond_if:
-       sys_brk(current->brk+ex.a_bss);
+       set_brk(current->start_brk, current->brk);
        
        p += change_ldt(ex.a_text,bprm->page);
        p -= MAX_ARG_PAGES*PAGE_SIZE;
index 4d59fb7c130fc197fa7e1ec9e9810f0cc77f2a63..958d1d96b8e456b40f25281c731706eb69210098 100644 (file)
@@ -8,69 +8,87 @@
 
 #include <linux/config.h>
 #include <linux/fs.h>
-#ifdef CONFIG_MINIX_FS
+
 #include <linux/minix_fs.h>
-#endif
-#ifdef CONFIG_XIA_FS
-#include <linux/xia_fs.h>
-#endif
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#endif
-#ifdef CONFIG_EXT2_FS
-#include <linux/ext2_fs.h>
-#endif
-#ifdef CONFIG_EXT_FS
 #include <linux/ext_fs.h>
-#endif
-#ifdef CONFIG_MSDOS_FS
+#include <linux/ext2_fs.h>
+#include <linux/xia_fs.h>
 #include <linux/msdos_fs.h>
-#endif
-#ifdef CONFIG_NFS_FS
+#include <linux/proc_fs.h>
 #include <linux/nfs_fs.h>
-#endif
-#ifdef CONFIG_ISO9660_FS
 #include <linux/iso_fs.h>
-#endif
-#ifdef CONFIG_HPFS_FS
-#include <linux/hpfs_fs.h>
-#endif
-#ifdef CONFIG_SYSV_FS
 #include <linux/sysv_fs.h>
-#endif
+#include <linux/hpfs_fs.h>
+
+extern void device_setup(void);
+
+/* This may be used only once, enforced by 'static int callable' */
+asmlinkage int sys_setup(void)
+{
+       static int callable = 1;
+
+       if (!callable)
+               return -1;
+       callable = 0;
+
+       device_setup();
 
-struct file_system_type file_systems[] = {
 #ifdef CONFIG_MINIX_FS
-       {minix_read_super,      "minix",        1},
+       register_filesystem(&(struct file_system_type)
+               {minix_read_super, "minix", 1, NULL});
 #endif
+
 #ifdef CONFIG_EXT_FS
-       {ext_read_super,        "ext",          1},
+       register_filesystem(&(struct file_system_type)
+               {ext_read_super, "ext", 1, NULL});
 #endif
+
 #ifdef CONFIG_EXT2_FS
-       {ext2_read_super,       "ext2",         1},
+       register_filesystem(&(struct file_system_type)
+               {ext2_read_super, "ext2", 1, NULL});
 #endif
+
 #ifdef CONFIG_XIA_FS
-       {xiafs_read_super,      "xiafs",        1},
+       register_filesystem(&(struct file_system_type)
+               {xiafs_read_super, "xiafs", 1, NULL});
 #endif
+
 #ifdef CONFIG_MSDOS_FS
-       {msdos_read_super,      "msdos",        1},
+       register_filesystem(&(struct file_system_type)
+               {msdos_read_super, "msdos", 1, NULL});
 #endif
+
 #ifdef CONFIG_PROC_FS
-       {proc_read_super,       "proc",         0},
+       register_filesystem(&(struct file_system_type)
+               {proc_read_super, "proc", 0, NULL});
 #endif
+
 #ifdef CONFIG_NFS_FS
-       {nfs_read_super,        "nfs",          0},
+       register_filesystem(&(struct file_system_type)
+               {nfs_read_super, "nfs", 0, NULL});
 #endif
+
 #ifdef CONFIG_ISO9660_FS
-       {isofs_read_super,      "iso9660",      1},
+       register_filesystem(&(struct file_system_type)
+               {isofs_read_super, "iso9660", 1, NULL});
 #endif
+
 #ifdef CONFIG_SYSV_FS
-       {sysv_read_super,       "xenix",        1},
-       {sysv_read_super,       "sysv",         1},
-       {sysv_read_super,       "coherent",     1},
+       register_filesystem(&(struct file_system_type)
+               {sysv_read_super, "xenix", 1, NULL});
+
+       register_filesystem(&(struct file_system_type)
+               {sysv_read_super, "sysv", 1, NULL});
+
+       register_filesystem(&(struct file_system_type)
+               {sysv_read_super, "coherent", 1, NULL});
 #endif
+
 #ifdef CONFIG_HPFS_FS
-       {hpfs_read_super,       "hpfs",         1},
+       register_filesystem(&(struct file_system_type)
+               {hpfs_read_super, "hpfs", 1, NULL});
 #endif
-       {NULL,                  NULL,           0}
-};
+
+       mount_root();
+       return 0;
+}
index b95e9c957dd2949d833bc1f6355b30e211c19403..9e3347ed7592b0b0abef70a5df0dd0c9e4c7f46e 100644 (file)
@@ -419,11 +419,6 @@ struct inode * get_pipe_inode(void)
        return inode;
 }
 
-struct inode * iget(struct super_block * sb,int nr)
-{
-       return __iget(sb,nr,1);
-}
-
 struct inode * __iget(struct super_block * sb, int nr, int crossmntp)
 {
        static struct wait_queue * update_wait = NULL;
index 81c1d08175446f5bcc5c21f74f64c3437a1da4d0..690b048cf7c49c10a7105c4cea1f1a5a676553ad 100644 (file)
 #include <asm/segment.h>
 
  
-/*
- * The definition of file_systems that used to be here is now in
- * filesystems.c.  Now super.c contains no fs specific code.  -- jrs
- */
-
-extern struct file_system_type file_systems[];
 extern struct file_operations * get_blkfops(unsigned int);
 extern struct file_operations * get_chrfops(unsigned int);
 
@@ -41,16 +35,54 @@ static int do_remount_sb(struct super_block *sb, int flags, char * data);
 /* this is initialized in init/main.c */
 dev_t ROOT_DEV = 0;
 
+static struct file_system_type * file_systems = NULL;
+
+int register_filesystem(struct file_system_type * fs)
+{
+       struct file_system_type ** tmp;
+
+       if (!fs)
+               return -EINVAL;
+       if (fs->next)
+               return -EBUSY;
+       tmp = &file_systems;
+       while (*tmp) {
+               if (strcmp((*tmp)->name, fs->name) == 0)
+                       return -EBUSY;
+               tmp = &(*tmp)->next;
+       }
+       *tmp = fs;
+       return 0;
+}
+
+int unregister_filesystem(struct file_system_type * fs)
+{
+       struct file_system_type ** tmp;
+
+       tmp = &file_systems;
+       while (*tmp) {
+               if (fs == *tmp) {
+                       *tmp = fs->next;
+                       fs->next = NULL;
+                       return 0;
+               }
+               tmp = &(*tmp)->next;
+       }
+       return -EINVAL;
+}
+
 struct file_system_type *get_fs_type(char *name)
 {
-       int a;
+       struct file_system_type * fs = file_systems;
        
        if (!name)
-               return &file_systems[0];
-       for(a = 0 ; file_systems[a].read_super ; a++)
-               if (!strcmp(name,file_systems[a].name))
-                       return(&file_systems[a]);
-       return NULL;
+               return fs;
+       while (fs) {
+               if (!strcmp(name,fs->name))
+                       break;
+               fs = fs->next;
+       }
+       return fs;
 }
 
 void __wait_on_super(struct super_block * sb)
@@ -516,7 +548,7 @@ void mount_root(void)
                printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
                wait_for_keypress();
        }
-       for (fs_type = file_systems; fs_type->read_super; fs_type++) {
+       for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
                if (!fs_type->requires_dev)
                        continue;
                sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
index ec85292da441cb541669eb60808fb647218f84dd..2406d874822f011b65f1354807c6fc883ed5e48e 100644 (file)
@@ -52,6 +52,20 @@ __asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
 
 #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
 
+static inline void and_user_long(unsigned long val,int * addr)
+{
+__asm__ ("andl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
+}
+
+#define and_fs_long(x,addr) and_user_long((x),(int *)(addr))
+
+static inline void or_user_long(unsigned long val,int * addr)
+{
+__asm__ ("orl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
+}
+
+#define or_fs_long(x,addr) or_user_long((x),(int *)(addr))
+
 static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
 {
 __asm__("cld\n\t"
index 846dbe9560355c11004f397947397093d1a46771..3bd8d574466306a99958d266d7f02a724ba81c2d 100644 (file)
@@ -316,10 +316,14 @@ struct file_system_type {
        struct super_block *(*read_super) (struct super_block *, void *, int);
        char *name;
        int requires_dev;
+       struct file_system_type * next;
 };
 
 #ifdef __KERNEL__
 
+extern int register_filesystem(struct file_system_type *);
+extern int unregister_filesystem(struct file_system_type *);
+
 asmlinkage int sys_open(const char *, int, int);
 asmlinkage int sys_close(unsigned int);                /* yes, it's really unsigned */
 
@@ -359,12 +363,11 @@ extern int nr_files;
 extern struct super_block super_blocks[NR_SUPER];
 
 extern int shrink_buffers(unsigned int priority);
-
 extern void refile_buffer(struct buffer_head * buf);
-void set_writetime(struct buffer_head * buf, int flag);
-
-struct buffer_head ** buffer_pages;
+extern void set_writetime(struct buffer_head * buf, int flag);
+extern void refill_freelist(int size);
 
+extern struct buffer_head ** buffer_pages;
 extern int nr_buffers;
 extern int buffermem;
 extern int nr_buffer_heads;
@@ -413,7 +416,6 @@ extern int open_namei(const char * pathname, int flag, int mode,
 extern int do_mknod(const char * filename, int mode, dev_t dev);
 extern void iput(struct inode * inode);
 extern struct inode * __iget(struct super_block * sb,int nr,int crsmnt);
-extern struct inode * iget(struct super_block * sb,int nr);
 extern struct inode * get_empty_inode(void);
 extern void insert_inode_hash(struct inode *);
 extern void clear_inode(struct inode *);
@@ -449,6 +451,11 @@ extern int generic_mmap(struct inode *, struct file *, unsigned long, size_t, in
 extern int block_fsync(struct inode *, struct file *);
 extern int file_fsync(struct inode *, struct file *);
 
+extern inline struct inode * iget(struct super_block * sb,int nr)
+{
+       return __iget(sb,nr,1);
+}
+
 #endif /* __KERNEL__ */
 
 #endif
index 49a7096594b4a7459e47e80a4813ceca156c3b33..85a579a0bdb21b3306567cbba90d17da1f0f688c 100644 (file)
@@ -7,6 +7,7 @@
 
 #ifdef __KERNEL__
 
+#include <stdarg.h>
 #include <linux/linkage.h>
 
 #define INT_MAX                ((int)(~0U>>1))
@@ -40,14 +41,15 @@ NORET_TYPE void panic(const char * fmt, ...)
        __attribute__ ((NORET_AND format (printf, 1, 2)));
 NORET_TYPE void do_exit(long error_code)
        ATTRIB_NORET;
-unsigned long simple_strtoul(const char *,char **,unsigned int);
-int sprintf(char * buf, const char * fmt, ...);
+extern unsigned long simple_strtoul(const char *,char **,unsigned int);
+extern int sprintf(char * buf, const char * fmt, ...);
+extern int vsprintf(char *buf, const char *, va_list);
 
-int session_of_pgrp(int pgrp);
+extern int session_of_pgrp(int pgrp);
 
-int kill_proc(int pid, int sig, int priv);
-int kill_pg(int pgrp, int sig, int priv);
-int kill_sl(int sess, int sig, int priv);
+extern int kill_proc(int pid, int sig, int priv);
+extern int kill_pg(int pgrp, int sig, int priv);
+extern int kill_sl(int sess, int sig, int priv);
 
 asmlinkage int printk(const char * fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
index c20f6e19ec60480eb59d674d9f4c1f720ed9ad6b..6718860e0fb777882924b0c984bde8db42968566 100644 (file)
    stack during a system call. */
 
 struct pt_regs {
-  long ebx;
-  long ecx;
-  long edx;
-  long esi;
-  long edi;
-  long ebp;
-  long eax;
-  unsigned short ds, __dsu;
-  unsigned short es, __esu;
-  unsigned short fs, __fsu;
-  unsigned short gs, __gsu;
-  long orig_eax;
-  long eip;
-  unsigned short cs, __csu;
-  long eflags;
-  long esp;
-  unsigned short ss, __ssu;
+       long ebx;
+       long ecx;
+       long edx;
+       long esi;
+       long edi;
+       long ebp;
+       long eax;
+       unsigned short ds, __dsu;
+       unsigned short es, __esu;
+       unsigned short fs, __fsu;
+       unsigned short gs, __gsu;
+       long orig_eax;
+       long eip;
+       unsigned short cs, __csu;
+       long eflags;
+       long esp;
+       unsigned short ss, __ssu;
 };
 
 #endif
index 9a089c4488d5d8d2d90c6d4def5ca9a23b6b3603..ea2179064ef7025546444d946c532ead0c81141a 100644 (file)
@@ -492,6 +492,9 @@ extern inline void select_wait(struct wait_queue ** wait_address, select_table *
 
 extern void __down(struct semaphore * sem);
 
+/*
+ * These are not yet interrupt-safe
+ */
 extern inline void down(struct semaphore * sem)
 {
        if (sem->count <= 0)
index 21ad9e7aac43c0282db09a5d64660a3596594292..d27681471c1a7648d99e5be59e3d1ea7af81fb22 100644 (file)
@@ -89,4 +89,33 @@ struct sigaction {
        void (*sa_restorer)(void);
 };
 
+#ifdef __KERNEL__
+
+struct sigcontext_struct {
+       unsigned short gs, __gsh;
+       unsigned short fs, __fsh;
+       unsigned short es, __esh;
+       unsigned short ds, __dsh;
+       unsigned long edi;
+       unsigned long esi;
+       unsigned long ebp;
+       unsigned long esp;
+       unsigned long ebx;
+       unsigned long edx;
+       unsigned long ecx;
+       unsigned long eax;
+       unsigned long trapno;
+       unsigned long err;
+       unsigned long eip;
+       unsigned short cs, __csh;
+       unsigned long eflags;
+       unsigned long esp_at_signal;
+       unsigned short ss, __ssh;
+       unsigned long i387;
+       unsigned long oldmask;
+       unsigned long cr2;
+};
+
+#endif
+
 #endif
index 0ef4c227221cbc0f7c8c59830cf4ca3d5c9e9f1e..f535a8404637ef24862daea485177b80bfd7f2c0 100644 (file)
@@ -1,7 +1,18 @@
 #ifndef _LINUX_VM86_H
 #define _LINUX_VM86_H
 
-#define VM_MASK 0x00020000
+#define TF_MASK                0x00000100
+#define IF_MASK                0x00000200
+#define IOPL_MASK      0x00003000
+#define NT_MASK                0x00004000
+#define VM_MASK                0x00020000
+#define AC_MASK                0x00040000
+
+#define BIOSSEG                0x0f000
+
+#define CPU_286                2
+#define CPU_386                3
+#define CPU_486                4
 
 /*
  * This is the stack-layout when we have done a "SAVE_ALL" from vm86
@@ -29,23 +40,28 @@ struct vm86_regs {
        long __null_gs;
        long orig_eax;
        long eip;
-       long cs;
+       unsigned short cs, __csh;
        long eflags;
        long esp;
-       long ss;
+       unsigned short ss, __ssh;
 /*
  * these are specific to v86 mode:
  */
-       long es;
-       long ds;
-       long fs;
-       long gs;
+       unsigned short es, __esh;
+       unsigned short ds, __dsh;
+       unsigned short fs, __fsh;
+       unsigned short gs, __gsh;
 };
 
 struct vm86_struct {
        struct vm86_regs regs;
        unsigned long flags;
        unsigned long screen_bitmap;
+       unsigned long v_eflags;
+       unsigned long cpu_type;
+       unsigned long return_if_iflag;
+       unsigned char int_revectored[0x100];
+       unsigned char int21_revectored[0x100];
 };
 
 /*
@@ -53,4 +69,10 @@ struct vm86_struct {
  */
 #define VM86_SCREEN_BITMAP 1
 
+#ifdef __KERNEL__
+
+void handle_vm86_fault(struct vm86_regs *, long);
+
+#endif
+
 #endif
index a46b8259f387e0719c74b70404e6beaaa1851111..dcc3e53a93b988e81287de815a098284b869d06c 100644 (file)
@@ -47,7 +47,7 @@ struct desc_struct default_ldt;
 static inline _syscall0(int,idle)
 static inline _syscall0(int,fork)
 static inline _syscall0(int,pause)
-static inline _syscall1(int,setup,void *,BIOS)
+static inline _syscall0(int,setup)
 static inline _syscall0(int,sync)
 static inline _syscall0(pid_t,setsid)
 static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
@@ -488,7 +488,7 @@ void init(void)
 {
        int pid,i;
 
-       setup((void *) &drive_info);
+       setup();
        sprintf(term, "TERM=con%dx%d", ORIG_VIDEO_COLS, ORIG_VIDEO_LINES);
        (void) open("/dev/tty1",O_RDWR,0);
        (void) dup(0);
index 861173b5b3404c9812217d2974776cdcb09fe822..fcb7860f9c57fa10127706b2b9a729c34f1f48a2 100644 (file)
@@ -19,7 +19,7 @@
 OBJS  = sched.o sys_call.o traps.o irq.o dma.o fork.o \
        panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o \
        signal.o mktime.o ptrace.o ioport.o itimer.o \
-       info.o ldt.o time.o
+       info.o ldt.o time.o vm86.o
 
 all: kernel.o
 
index e83874b7bb422943092ac7a668509b0794f6a53e..eb4a3e8a905f33168030880c56dfa6919ddacb0b 100644 (file)
@@ -8,6 +8,8 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
 
 #define X(name)        { (void *) &name, "_" #name }
 
@@ -20,26 +22,56 @@ struct {
        void *addr;
        const char *name;
 } symbol_table[] = {
+       /* process memory management */
+       X(wp_works_ok),
+       X(__verify_write),
+       X(do_mmap),
+       X(do_munmap),
+
+       /* internal kernel memory management */
+       X(__get_free_pages),
+       X(free_pages),
+       X(kmalloc),
+       X(kfree_s),
+       X(vmalloc),
+       X(vfree),
+
+       /* filesystem internal functions */
+       X(getname),
+       X(putname),
+       X(__iget),
+       X(iput),
+       X(namei),
+       X(lnamei),
+
+       /* device registration */
        X(register_chrdev),
        X(unregister_chrdev),
        X(register_blkdev),
        X(unregister_blkdev),
-       X(wake_up_interruptible),
 
-       X(wp_works_ok),
-       X(__verify_write),
+       /* interrupt handling */
+       X(request_irq),
+       X(free_irq),
 
+       /* process management */
+       X(wake_up),
+       X(wake_up_interruptible),
+       X(schedule),
        X(current),
        X(jiffies),
+       X(xtime),
+
+       /* misc */
        X(printk),
-       X(schedule),
+       X(sprintf),
+       X(vsprintf),
 
 #ifdef CONFIG_FTAPE
        /* The next labels are needed for ftape driver.  */
        X(ftape_big_buffer),
        X(do_floppy),
 #endif
-
 };
 
 int symbol_table_size = sizeof (symbol_table) / sizeof (symbol_table[0]);
index 5352421aa24e8347c67039eee011929f340abe81..33aec214b3b933947013760bac2331d85fdfbde6 100644 (file)
@@ -22,31 +22,6 @@ extern int core_dump(long signr,struct pt_regs * regs);
 
 asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs);
 
-struct sigcontext_struct {
-       unsigned short gs, __gsh;
-       unsigned short fs, __fsh;
-       unsigned short es, __esh;
-       unsigned short ds, __dsh;
-       unsigned long edi;
-       unsigned long esi;
-       unsigned long ebp;
-       unsigned long esp;
-       unsigned long ebx;
-       unsigned long edx;
-       unsigned long ecx;
-       unsigned long eax;
-       unsigned long trapno;
-       unsigned long err;
-       unsigned long eip;
-       unsigned short cs, __csh;
-       unsigned long eflags;
-       unsigned long esp_at_signal;
-       unsigned short ss, __ssh;
-       unsigned long i387;
-       unsigned long oldmask;
-       unsigned long cr2;
-};
-
 asmlinkage int sys_sigprocmask(int how, sigset_t *set, sigset_t *oset)
 {
        sigset_t new_set, old_set = current->blocked;
index b41de5a7c95143bc02b5c915dbd379047fd819b3..396b139a5d1dc93a7c85d865bb81065e020b56eb 100644 (file)
@@ -131,84 +131,6 @@ asmlinkage int sys_prof(void)
        return -ENOSYS;
 }
 
-asmlinkage unsigned long save_v86_state(struct vm86_regs * regs)
-{
-       unsigned long stack;
-
-       if (!current->vm86_info) {
-               printk("no vm86_info: BAD\n");
-               do_exit(SIGSEGV);
-       }
-       memcpy_tofs(&(current->vm86_info->regs),regs,sizeof(*regs));
-       put_fs_long(current->screen_bitmap,&(current->vm86_info->screen_bitmap));
-       stack = current->tss.esp0;
-       current->tss.esp0 = current->saved_kernel_stack;
-       current->saved_kernel_stack = 0;
-       return stack;
-}
-
-static void mark_screen_rdonly(struct task_struct * tsk)
-{
-       unsigned long tmp;
-       unsigned long *pg_table;
-
-       if ((tmp = tsk->tss.cr3) != 0) {
-               tmp = *(unsigned long *) tmp;
-               if (tmp & PAGE_PRESENT) {
-                       tmp &= PAGE_MASK;
-                       pg_table = (0xA0000 >> PAGE_SHIFT) + (unsigned long *) tmp;
-                       tmp = 32;
-                       while (tmp--) {
-                               if (PAGE_PRESENT & *pg_table)
-                                       *pg_table &= ~PAGE_RW;
-                               pg_table++;
-                       }
-               }
-       }
-}
-
-asmlinkage int sys_vm86(struct vm86_struct * v86)
-{
-       struct vm86_struct info;
-       struct pt_regs * pt_regs = (struct pt_regs *) &v86;
-       int error;
-
-       if (current->saved_kernel_stack)
-               return -EPERM;
-       /* v86 must be readable (now) and writable (for save_v86_state) */
-       error = verify_area(VERIFY_WRITE,v86,sizeof(*v86));
-       if (error)
-               return error;
-       memcpy_fromfs(&info,v86,sizeof(info));
-/*
- * make sure the vm86() system call doesn't try to do anything silly
- */
-       info.regs.__null_ds = 0;
-       info.regs.__null_es = 0;
-       info.regs.__null_fs = 0;
-       info.regs.__null_gs = 0;
-/*
- * The eflags register is also special: we cannot trust that the user
- * has set it up safely, so this makes sure interrupt etc flags are
- * inherited from protected mode.
- */
-       info.regs.eflags &= 0x00000dd5;
-       info.regs.eflags |= ~0x00000dd5 & pt_regs->eflags;
-       info.regs.eflags |= VM_MASK;
-       current->saved_kernel_stack = current->tss.esp0;
-       current->tss.esp0 = (unsigned long) pt_regs;
-       current->vm86_info = v86;
-       current->screen_bitmap = info.screen_bitmap;
-       if (info.flags & VM86_SCREEN_BITMAP)
-               mark_screen_rdonly(current);
-       __asm__ __volatile__("movl %0,%%esp\n\t"
-               "pushl $ret_from_sys_call\n\t"
-               "ret"
-               : /* no outputs */
-               :"g" ((long) &(info.regs)),"a" (info.regs.eax));
-       return 0;
-}
-
 extern void hard_reset_now(void);
 
 /*
index 89efdd3696c566497b93c2584594e19518f22042..e5fe375cf8c89e981841f64e28b959aa8d2e7e7e 100644 (file)
@@ -125,10 +125,21 @@ DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun
 DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS, current)
 DO_ERROR(11, SIGSEGV, "segment not present", segment_not_present, current)
 DO_ERROR(12, SIGSEGV, "stack segment", stack_segment, current)
-DO_ERROR(13, SIGSEGV, "general protection", general_protection, current)
 DO_ERROR(15, SIGSEGV, "reserved", reserved, current)
 DO_ERROR(17, SIGSEGV, "alignment check", alignment_check, current)
 
+asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
+{
+       if (regs->eflags & VM_MASK) {
+               handle_vm86_fault((struct vm86_regs *) regs, error_code);
+               return;
+       }
+       current->tss.error_code = error_code;
+       current->tss.trap_no = 13;
+       send_sig(SIGSEGV, current, 1);
+       die_if_kernel("general protection",regs,error_code);
+}
+
 asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
 {
        printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
diff --git a/kernel/vm86.c b/kernel/vm86.c
new file mode 100644 (file)
index 0000000..5cf8c49
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ *  linux/kernel/vm86.c
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+
+asmlinkage struct pt_regs * save_v86_state(struct vm86_regs * regs)
+{
+       unsigned long stack;
+
+       if (!current->vm86_info) {
+               printk("no vm86_info: BAD\n");
+               do_exit(SIGSEGV);
+       }
+       memcpy_tofs(&(current->vm86_info->regs),regs,sizeof(*regs));
+       put_fs_long(current->screen_bitmap,&(current->vm86_info->screen_bitmap));
+       stack = current->tss.esp0;
+       current->tss.esp0 = current->saved_kernel_stack;
+       current->saved_kernel_stack = 0;
+       return (struct pt_regs *) stack;
+}
+
+static void mark_screen_rdonly(struct task_struct * tsk)
+{
+       unsigned long tmp;
+       unsigned long *pg_table;
+
+       if ((tmp = tsk->tss.cr3) != 0) {
+               tmp = *(unsigned long *) tmp;
+               if (tmp & PAGE_PRESENT) {
+                       tmp &= PAGE_MASK;
+                       pg_table = (0xA0000 >> PAGE_SHIFT) + (unsigned long *) tmp;
+                       tmp = 32;
+                       while (tmp--) {
+                               if (PAGE_PRESENT & *pg_table)
+                                       *pg_table &= ~PAGE_RW;
+                               pg_table++;
+                       }
+               }
+       }
+}
+
+asmlinkage int sys_vm86(struct vm86_struct * v86)
+{
+       struct vm86_struct info;
+       struct pt_regs * pt_regs = (struct pt_regs *) &v86;
+       int error;
+
+       if (current->saved_kernel_stack)
+               return -EPERM;
+       /* v86 must be readable (now) and writable (for save_v86_state) */
+       error = verify_area(VERIFY_WRITE,v86,sizeof(*v86));
+       if (error)
+               return error;
+       memcpy_fromfs(&info,v86,sizeof(info));
+/*
+ * make sure the vm86() system call doesn't try to do anything silly
+ */
+       info.regs.__null_ds = 0;
+       info.regs.__null_es = 0;
+       info.regs.__null_fs = 0;
+       info.regs.__null_gs = 0;
+/*
+ * The eflags register is also special: we cannot trust that the user
+ * has set it up safely, so this makes sure interrupt etc flags are
+ * inherited from protected mode.
+ */
+       info.regs.eflags &= 0x00000dd5;
+       info.regs.eflags |= ~0x00000dd5 & pt_regs->eflags;
+       info.regs.eflags |= VM_MASK;
+       current->saved_kernel_stack = current->tss.esp0;
+       current->tss.esp0 = (unsigned long) pt_regs;
+       current->vm86_info = v86;
+       current->screen_bitmap = info.screen_bitmap;
+       if (info.flags & VM86_SCREEN_BITMAP)
+               mark_screen_rdonly(current);
+       __asm__ __volatile__("movl %0,%%esp\n\t"
+               "pushl $ret_from_sys_call\n\t"
+               "ret"
+               : /* no outputs */
+               :"g" ((long) &(info.regs)),"a" (info.regs.eax));
+       return 0;
+}
+
+static inline void return_to_32bit(struct vm86_regs * regs16, int retval)
+{
+       struct pt_regs * regs32;
+
+       regs32 = save_v86_state(regs16);
+       regs32->eax = retval;
+       __asm__("movl %0,%%esp\n\t"
+               "jmp ret_from_sys_call"
+               : : "r" (regs32));
+}
+
+void handle_vm86_fault(struct vm86_regs * regs, long error_code)
+{
+       unsigned char *csp;
+       unsigned short *ssp;
+       unsigned short flags;
+       unsigned char i;
+
+       csp = (unsigned char *) ((regs->cs << 4) + (regs->eip & 0xffff));
+       ssp = (unsigned short *) ((regs->ss << 4) + (regs->esp & 0xffff));
+
+       switch (get_fs_byte(csp)) {
+
+       /* operand size override */
+       case 0x66:
+               switch (get_fs_byte(++csp)) {
+
+               /* pushfd */
+               case 0x9c:
+                       regs->esp -= 4;
+                       regs->eip += 2;
+                       if (get_fs_long(&(current->vm86_info->cpu_type)) == CPU_386)
+                         put_fs_long(((regs->eflags) & ~(AC_MASK|NT_MASK|IOPL_MASK|IF_MASK)) |
+                               (get_fs_long(&(current->vm86_info->v_eflags)) & (NT_MASK|IOPL_MASK|IF_MASK)), ssp-2);
+                       else
+                         put_fs_long(((regs->eflags) & ~(AC_MASK|NT_MASK|IOPL_MASK|IF_MASK)) |
+                               (get_fs_long(&(current->vm86_info->v_eflags)) & (AC_MASK|NT_MASK|IOPL_MASK|IF_MASK)), ssp-2);
+                       return;
+
+               /* popfd */
+               case 0x9d:
+                       regs->esp += 4;
+                       regs->eip += 2;
+                       flags = get_fs_word(ssp+1);
+                       put_fs_word(flags, (unsigned short *) &(current->vm86_info->v_eflags) +1);
+                       goto return_from_popf;
+               }
+
+       /* pushf */
+       case 0x9c:
+               regs->esp -= 2;
+               regs->eip++;
+               if (get_fs_long(&(current->vm86_info->cpu_type)) == CPU_286)
+                 put_fs_word(((regs->eflags) & 0x0dd5) |
+                       (get_fs_word(&(current->vm86_info->v_eflags)) & ~0xfdd5), --ssp);
+               else
+                 put_fs_word(((regs->eflags) & ~(NT_MASK|IOPL_MASK|IF_MASK)) |
+                       (get_fs_word(&(current->vm86_info->v_eflags)) & (NT_MASK|IOPL_MASK|IF_MASK)), --ssp);
+               return;
+
+       /* popf */
+       case 0x9d:
+               regs->esp += 2;
+               regs->eip++;
+       return_from_popf:
+               flags = get_fs_word(ssp);
+               regs->eflags &= ~0x00000dd5;
+               regs->eflags |= flags & 0x00000dd5;
+               put_fs_word(flags, &(current->vm86_info->v_eflags));
+               goto do_dosemu_timer;
+
+       /* int 3 */
+       case 0xcc:
+               if (get_fs_word((void *)14) == BIOSSEG || regs->cs == BIOSSEG
+                       || get_fs_byte(&(current->vm86_info->int_revectored[3])))
+                       return_to_32bit(regs, SIGSEGV);
+               i = 3;
+               regs->eip++;
+               goto return_from_int_xx;
+
+       /* int xx */
+       case 0xcd:
+               i = get_fs_byte(++csp);
+               if (get_fs_word((void *)((i<<2)+2)) == BIOSSEG
+                       || regs->cs == BIOSSEG
+                       || get_fs_byte(&(current->vm86_info->int_revectored[i])))
+                       return_to_32bit(regs, SIGSEGV);
+               if ((i==0x21) && get_fs_byte(&(current->vm86_info->int21_revectored[((regs->eax >> 4) & 0xff)])))
+                       return_to_32bit(regs, SIGSEGV);
+               regs->eip+=2;
+               return_from_int_xx:
+               regs->esp -= 6;
+               if (get_fs_long(&(current->vm86_info->cpu_type)) == CPU_286)
+                 put_fs_word(((regs->eflags) & 0x0dd5) |
+                       (get_fs_word(&(current->vm86_info->v_eflags)) & ~0xfdd5), --ssp);
+               else
+                 put_fs_word(((regs->eflags) & ~IF_MASK) |
+                       (get_fs_word(&(current->vm86_info->v_eflags)) & IF_MASK), --ssp);
+               put_fs_word(regs->cs, --ssp);
+               put_fs_word((unsigned short)(regs->eip), --ssp);
+               regs->cs = get_fs_word((void *)((i<<2)+2));
+               regs->eip = (unsigned long) get_fs_word((void *)(i<<2));
+               regs->eflags &= ~TF_MASK;
+               and_fs_long(~IF_MASK, &(current->vm86_info->v_eflags));
+               return;
+
+       /* iret */
+       case 0xcf:
+               regs->esp += 6;
+               regs->eip = get_fs_word(ssp++);
+               regs->cs = get_fs_word(ssp++);
+               goto return_from_popf;
+
+       /* cli */
+       case 0xfa:
+               regs->eip++;
+               and_fs_long(~IF_MASK, &(current->vm86_info->v_eflags));
+               return;
+
+       /* sti */
+       case 0xfb:
+               regs->eip++;
+               or_fs_long(IF_MASK, &(current->vm86_info->v_eflags));
+       do_dosemu_timer:
+               if ((get_fs_long(&(current->vm86_info->v_eflags)) & IF_MASK) &&
+                   get_fs_long(&(current->vm86_info->return_if_iflag)))
+                       break;
+               return;
+
+       default:
+               return_to_32bit(regs, SIGSEGV);
+       }
+       return_to_32bit(regs, SIGALRM);
+}
index 658489eb7ae3e0e5ed83adffcb5bcab934df6bbc..8c69ff0c39f5106875c1024d788de83e30e47249 100644 (file)
@@ -4,25 +4,8 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
-#ifndef __GNUC__
-#error I want gcc!
-#endif
-
-#include <linux/types.h>
-
-#ifdef __cplusplus
-#define C_BEGIN extern "C" {
-#define C_END }
-#else
-#define C_BEGIN
-#define C_END
-#endif
+#include <linux/string.h>
 
-#undef __cplusplus
-#define extern
-#define inline
-#define __LIBRARY__
+/* all the actual functions should be inline anyway, so.. */
 
-C_BEGIN
-#include <linux/string.h>
-C_END
+char * ___strtok = NULL;
index a81cdd146be25535701b39b0e4a84c982bee50ef..03540bc2ee9e9ca1137bcd2bf5c7f33fcb439808 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -596,7 +596,7 @@ do { unsigned long size = PAGE_SIZE << high; \
                add_mem_queue(free_area_list+high, addr); \
                mark_used((unsigned long) addr, high); \
                restore_flags(flags); \
-               addr = (void *) (size + (unsigned long) addr); \
+               addr = (struct mem_list *) (size + (unsigned long) addr); \
        } mem_map[MAP_NR((unsigned long) addr)] = 1; \
 } while (0)