VERSION = 2
PATCHLEVEL = 3
-SUBLEVEL = 11
+SUBLEVEL = 12
EXTRAVERSION =
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
@@ -688,12+688,8 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */
default:
@@ -543,12+543,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */
default:
#include <asm/ldt.h>
#include <asm/processor.h>
#include <asm/desc.h>
+#include <asm/mmu_context.h>
#ifdef CONFIG_MATH_EMULATION
#include <asm/math_emu.h>
#endif
@@ -327,7+328,8 @@ void machine_restart(char * __unused) * seldom used feature ;)
*/
- SET_PAGE_DIR(current,swapper_pg_dir);
+ current->mm->pgd = swapper_pg_dir;
+ activate_context();
/* Write 0x1234 to absolute memory location 0x472. The BIOS reads
this on booting to tell it to "Bypass memory test (also warm
@@ -687,12+687,8 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */
default:
@@ -1084,9+1084,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGIOT: case SIGFPE: case SIGSEGV:
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
@@ -48,11+48,13 @@ static int irix_core_dump(long signr, struct pt_regs * regs); extern int dump_fpu (elf_fpregset_t *);
static struct linux_binfmt irix_format = {
+ NULL,
#ifndef MODULE
- NULL, NULL, load_irix_binary, load_irix_library, irix_core_dump
+ NULL,
#else
- NULL, &__this_module.usecount, load_irix_binary, load_irix_library, irix_core_dump
+ &__this_module.usecount,
#endif
+ load_irix_binary, load_irix_library, irix_core_dump, PAGE_SIZE
};
#ifndef elf_addr_t
@@ -1105,24+1107,20 @@ static int writenote(struct memelfnote *men, struct file *file)
#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (addr), (nr))) \
- goto close_coredump;
+ goto end_coredump;
#define DUMP_SEEK(off) \
if (!dump_seek(file, (off))) \
- goto close_coredump;
+ goto end_coredump;
/* Actual dumper.
*
* This is a two-pass process; first we find the offsets of the bits,
* and then they are actually written out. If we run out of core limit
* we just truncate.
*/
-static int irix_core_dump(long signr, struct pt_regs * regs)
+static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
int has_dumped = 0;
- struct file *file;
- struct dentry *dentry;
- struct inode *inode;
mm_segment_t fs;
- char corefile[6+sizeof(current->comm)];
int segs;
int i;
size_t size;
@@ -1135,10+1133,6 @@ static int irix_core_dump(long signr, struct pt_regs * regs) struct elf_prstatus prstatus; /* NT_PRSTATUS */
elf_fpregset_t fpu; /* NT_PRFPREG */
struct elf_prpsinfo psinfo; /* NT_PRPSINFO */
-
- if (!current->dumpable || limit < PAGE_SIZE)
- return 0;
- current->dumpable = 0;
#ifndef CONFIG_BINFMT_IRIX
MOD_INC_USE_COUNT;
@@ -1188,27+1182,6 @@ static int irix_core_dump(long signr, struct pt_regs * regs) fs = get_fs();
set_fs(KERNEL_DS);
- memcpy(corefile,"core.", 5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
- file = filp_open(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(file))
- goto end_coredump;
- dentry = file->f_dentry;
- inode = dentry->d_inode;
- if (inode->i_nlink > 1)
- goto close_coredump; /* multiple links - don't dump */
-
- if (!S_ISREG(inode->i_mode))
- goto close_coredump;
- if (!inode->i_op || !inode->i_op->default_file_ops)
- goto close_coredump;
- if (!file->f_op->write)
- goto close_coredump;
-
has_dumped = 1;
current->flags |= PF_DUMPCORE;
@@ -1345,7+1318,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs)
for(i = 0; i < numnote; i++)
if (!writenote(¬es[i], file))
- goto close_coredump;
+ goto end_coredump;
set_fs(fs);
@@ -1372,9+1345,6 @@ static int irix_core_dump(long signr, struct pt_regs * regs) (off_t) file->f_pos, offset);
}
- close_coredump:
- filp_close(file, NULL);
-
end_coredump:
set_fs(fs);
#ifndef CONFIG_BINFMT_ELF
@@ -261,12+261,8 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */
default:
@@ -493,12+493,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */
default:
@@ -444,12+444,8 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- lock_kernel();
- if (current->binfmt
- && current->binfmt->core_dump
- && current->binfmt->core_dump(signr, regs))
+ if (do_coredump(signr, regs))
exit_code |= 0x80;
- unlock_kernel();
/* FALLTHRU */
default:
@@ -1160,14+1160,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
- if(current->binfmt && current->binfmt->core_dump) {
- lock_kernel();
- if(current->binfmt &&
- current->binfmt->core_dump &&
- current->binfmt->core_dump(signr, regs))
- exit_code |= 0x80;
- unlock_kernel();
- }
+ if (do_coredump(signr, regs))
+ exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
@@ -39,7+39,8 @@ static int aout32_core_dump(long signr, struct pt_regs * regs); extern void dump_thread(struct pt_regs *, struct user *);
static struct linux_binfmt aout32_format = {
- NULL, NULL, load_aout32_binary, load_aout32_library, aout32_core_dump
+ NULL, NULL, load_aout32_binary, load_aout32_library, aout32_core_dump,
+ PAGE_SIZE
};
static void set_brk(unsigned long start, unsigned long end)
@@ -63,12+64,12 @@ static int dump_write(struct file *file, const void *addr, int nr)
#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (void *)(addr), (nr))) \
- goto close_coredump;
+ goto end_coredump;
#define DUMP_SEEK(offset) \
if (file->f_op->llseek) { \
if (file->f_op->llseek(file,(offset),0) != (offset)) \
- goto close_coredump; \
+ goto end_coredump; \
} else file->f_pos = (offset)
/*
@@ -82,45+83,17 @@ if (file->f_op->llseek) { \ */
static inline int
-do_aout32_core_dump(long signr, struct pt_regs * regs)
+do_aout32_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
- struct dentry * dentry = NULL;
- struct inode * inode = NULL;
- struct file * file;
mm_segment_t fs;
int has_dumped = 0;
- char corefile[6+sizeof(current->comm)];
unsigned long dump_start, dump_size;
struct user dump;
# define START_DATA(u) (u.u_tsize)
# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1))
- if (!current->dumpable || atomic_read(¤t->mm->count) != 1)
- return 0;
- current->dumpable = 0;
-
-/* See if we have enough room to write the upage. */
- if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
- return 0;
fs = get_fs();
set_fs(KERNEL_DS);
- memcpy(corefile,"core.",5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
- file = filp_open(corefile,O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(file))
- goto end_coredump;
- dentry = file->f_dentry;
- inode = dentry->d_inode;
- if (!S_ISREG(inode->i_mode))
- goto close_coredump;
- if (!inode->i_op || !inode->i_op->default_file_ops)
- goto close_coredump;
- if (!file->f_op->write)
- goto close_coredump;
has_dumped = 1;
current->flags |= PF_DUMPCORE;
strncpy(dump.u_comm, current->comm, sizeof(current->comm));
@@ -165,20+138,18 @@ do_aout32_core_dump(long signr, struct pt_regs * regs) /* Finally dump the task struct. Not be used by gdb, but could be useful */
set_fs(KERNEL_DS);
DUMP_WRITE(current,sizeof(*current));
-close_coredump:
- filp_close(file, NULL);
end_coredump:
set_fs(fs);
return has_dumped;
}
static int
-aout32_core_dump(long signr, struct pt_regs * regs)
+aout32_core_dump(long signr, struct pt_regs * regs, struct file * file)
{
int retval;
MOD_INC_USE_COUNT;
- retval = do_aout32_core_dump(signr, regs);
+ retval = do_aout32_core_dump(signr, regs, file);
MOD_DEC_USE_COUNT;
return retval;
}
@@ -866,12+866,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
- if(current->binfmt && current->binfmt->core_dump) {
- lock_kernel();
- if(current->binfmt->core_dump(signr, regs))
- exit_code |= 0x80;
- unlock_kernel();
- }
+ if (do_coredump(signr, regs))
+ exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug the dynamic linker */
printk ("Sig %d going...\n", (int)signr);
@@ -1291,14+1291,8 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
- if(current->binfmt && current->binfmt->core_dump) {
- lock_kernel();
- if(current->binfmt &&
- current->binfmt->core_dump &&
- current->binfmt->core_dump(signr, regs))
- exit_code |= 0x80;
- unlock_kernel();
- }
+ if (do_coredump(signr, regs))
+ exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
@@ -85,8+85,10 @@ static ssize_t do_read (struct pp_struct *pp, void *buf, size_t len) {
size_t (*fn) (struct parport *, void *, size_t, int);
struct parport *port = pp->pdev->port;
+ int addr = pp->mode & IEEE1284_ADDR;
+ int mode = pp->mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);
- switch (pp->mode) {
+ switch (mode) {
case IEEE1284_MODE_COMPAT:
/* This is a write-only mode. */
return -EIO;
@@ -100,7+102,10 @@ static ssize_t do_read (struct pp_struct *pp, void *buf, size_t len) break;
case IEEE1284_MODE_EPP:
- fn = port->ops->epp_read_data;
+ if (addr)
+ fn = port->ops->epp_read_addr;
+ else
+ fn = port->ops->epp_read_data;
break;
case IEEE1284_MODE_ECP:
@@ -128,8+133,10 @@ static ssize_t do_write (struct pp_struct *pp, const void *buf, size_t len) {
size_t (*fn) (struct parport *, const void *, size_t, int);
struct parport *port = pp->pdev->port;
+ int addr = pp->mode & IEEE1284_ADDR;
+ int mode = pp->mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);
- switch (pp->mode) {
+ switch (mode) {
case IEEE1284_MODE_NIBBLE:
case IEEE1284_MODE_BYTE:
/* Read-only modes. */
@@ -140,16+147,25 @@ static ssize_t do_write (struct pp_struct *pp, const void *buf, size_t len) break;
case IEEE1284_MODE_EPP:
- fn = port->ops->epp_write_data;
+ if (addr)
+ fn = port->ops->epp_write_addr;
+ else
+ fn = port->ops->epp_write_data;
break;
case IEEE1284_MODE_ECP:
case IEEE1284_MODE_ECPRLE:
- fn = port->ops->ecp_write_data;
+ if (addr)
+ fn = port->ops->ecp_write_addr;
+ else
+ fn = port->ops->ecp_write_data;
break;
case IEEE1284_MODE_ECPSWE:
- fn = parport_ieee1284_ecp_write_data;
+ if (addr)
+ fn = parport_ieee1284_ecp_write_addr;
+ else
+ fn = parport_ieee1284_ecp_write_data;
break;
default:
static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout_library(int fd);
-static int aout_core_dump(long signr, struct pt_regs * regs);
+static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
extern void dump_thread(struct pt_regs *, struct user *);
static struct linux_binfmt aout_format = {
+ NULL,
#ifndef MODULE
- NULL, NULL, load_aout_binary, load_aout_library, aout_core_dump
+ NULL,
#else
- NULL, &__this_module, load_aout_binary, load_aout_library, aout_core_dump
+ &__this_module,
#endif
+ load_aout_binary, load_aout_library, aout_core_dump, PAGE_SIZE
};
static void set_brk(unsigned long start, unsigned long end)
@@ -64,12+66,12 @@ static int dump_write(struct file *file, const void *addr, int nr)
#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (void *)(addr), (nr))) \
- goto close_coredump;
+ goto end_coredump;
#define DUMP_SEEK(offset) \
if (file->f_op->llseek) { \
if (file->f_op->llseek(file,(offset),0) != (offset)) \
- goto close_coredump; \
+ goto end_coredump; \
} else file->f_pos = (offset)
/*
@@ -83,14+85,10 @@ if (file->f_op->llseek) { \ */
static inline int
-do_aout_core_dump(long signr, struct pt_regs * regs)
+do_aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
- struct dentry * dentry = NULL;
- struct inode * inode = NULL;
- struct file * file;
mm_segment_t fs;
int has_dumped = 0;
- char corefile[6+sizeof(current->comm)];
unsigned long dump_start, dump_size;
struct user dump;
#if defined(__alpha__)
@@ -106,32+104,8 @@ do_aout_core_dump(long signr, struct pt_regs * regs) # define START_STACK(u) (u.start_stack)
#endif
- if (!current->dumpable || atomic_read(¤t->mm->mm_users) != 1)
- return 0;
- current->dumpable = 0;
-
-/* See if we have enough room to write the upage. */
- if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
- return 0;
fs = get_fs();
set_fs(KERNEL_DS);
- memcpy(corefile,"core.",5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
- file = filp_open(corefile,O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(file))
- goto end_coredump;
- dentry = file->f_dentry;
- inode = dentry->d_inode;
- if (!S_ISREG(inode->i_mode))
- goto close_coredump;
- if (!inode->i_op || !inode->i_op->default_file_ops)
- goto close_coredump;
- if (!file->f_op->write)
- goto close_coredump;
has_dumped = 1;
current->flags |= PF_DUMPCORE;
strncpy(dump.u_comm, current->comm, sizeof(current->comm));
@@ -210,20+184,18 @@ do_aout_core_dump(long signr, struct pt_regs * regs) /* Finally dump the task struct. Not be used by gdb, but could be useful */
set_fs(KERNEL_DS);
DUMP_WRITE(current,sizeof(*current));
-close_coredump:
- filp_close(file, NULL);
end_coredump:
set_fs(fs);
return has_dumped;
}
static int
-aout_core_dump(long signr, struct pt_regs * regs)
+aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
int retval;
MOD_INC_USE_COUNT;
- retval = do_aout_core_dump(signr, regs);
+ retval = do_aout_core_dump(signr, regs, file);
MOD_DEC_USE_COUNT;
return retval;
}
@@ -54,7+54,7 @@ extern void dump_thread(struct pt_regs *, struct user *); * don't even try.
*/
#ifdef USE_ELF_CORE_DUMP
-static int elf_core_dump(long signr, struct pt_regs * regs);
+static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file);
#else
#define elf_core_dump NULL
#endif
@@ -64,11+64,13 @@ static int elf_core_dump(long signr, struct pt_regs * regs); #define ELF_PAGEALIGN(_v) (((_v) + ELF_EXEC_PAGESIZE - 1) & ~(ELF_EXEC_PAGESIZE - 1))
static struct linux_binfmt elf_format = {
+ NULL,
#ifndef MODULE
- NULL, NULL, load_elf_binary, load_elf_library, elf_core_dump
+ NULL,
#else
- NULL, &__this_module, load_elf_binary, load_elf_library, elf_core_dump
+ &__this_module,
#endif
+ load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE
};
static void set_brk(unsigned long start, unsigned long end)
@@ -1026,10+1028,10 @@ static int writenote(struct memelfnote *men, struct file *file)
#define DUMP_WRITE(addr, nr) \
if (!dump_write(file, (addr), (nr))) \
- goto close_coredump;
+ goto end_coredump;
#define DUMP_SEEK(off) \
if (!dump_seek(file, (off))) \
- goto close_coredump;
+ goto end_coredump;
/*
* Actual dumper
*
@@ -1037,14+1039,10 @@ static int writenote(struct memelfnote *men, struct file *file) * and then they are actually written out. If we run out of core limit
* we just truncate.
*/
-static int elf_core_dump(long signr, struct pt_regs * regs)
+static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
{
int has_dumped = 0;
- struct file *file;
- struct dentry *dentry;
- struct inode *inode;
mm_segment_t fs;
- char corefile[6+sizeof(current->comm)];
int segs;
int i;
size_t size;
@@ -1058,12+1056,6 @@ static int elf_core_dump(long signr, struct pt_regs * regs) elf_fpregset_t fpu; /* NT_PRFPREG */
struct elf_prpsinfo psinfo; /* NT_PRPSINFO */
- if (!current->dumpable ||
- limit < ELF_EXEC_PAGESIZE ||
- atomic_read(¤t->mm->mm_users) != 1)
- return 0;
- current->dumpable = 0;
-
#ifndef CONFIG_BINFMT_ELF
MOD_INC_USE_COUNT;
#endif
@@ -1112,27+1104,6 @@ static int elf_core_dump(long signr, struct pt_regs * regs) fs = get_fs();
set_fs(KERNEL_DS);
- memcpy(corefile,"core.",5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
- file = filp_open(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
- if (IS_ERR(file))
- goto end_coredump;
- dentry = file->f_dentry;
- inode = dentry->d_inode;
- if (inode->i_nlink > 1)
- goto close_coredump; /* multiple links - don't dump */
-
- if (!S_ISREG(inode->i_mode))
- goto close_coredump;
- if (!inode->i_op || !inode->i_op->default_file_ops)
- goto close_coredump;
- if (!file->f_op->write)
- goto close_coredump;
-
has_dumped = 1;
current->flags |= PF_DUMPCORE;
@@ -1289,7+1260,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
for(i = 0; i < numnote; i++)
if (!writenote(¬es[i], file))
- goto close_coredump;
+ goto end_coredump;
set_fs(fs);
@@ -1316,9+1287,6 @@ static int elf_core_dump(long signr, struct pt_regs * regs) (off_t) file->f_pos, offset);
}
- close_coredump:
- filp_close(file, NULL);
-
end_coredump:
set_fs(fs);
#ifndef CONFIG_BINFMT_ELF
@@ -105,11+105,13 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs) }
struct linux_binfmt em86_format = {
+ NULL,
#ifndef MODULE
- NULL, 0, load_em86, NULL, NULL
+ NULL,
#else
- NULL, &__this_module, load_em86, NULL, NULL
+ &__this_module,
#endif
+ load_em86, NULL, NULL, 0
};
int __init init_em86_binfmt(void)
@@ -64,11+64,13 @@ static void entry_proc_cleanup(struct binfmt_entry *e); static int entry_proc_setup(struct binfmt_entry *e);
static struct linux_binfmt misc_format = {
+ NULL,
#ifndef MODULE
- NULL, 0, load_misc_binary, NULL, NULL
+ NULL,
#else
- NULL, &__this_module, load_misc_binary, NULL, NULL
+ &__this_module,
#endif
+ load_misc_binary, NULL, NULL, 0
};
static struct proc_dir_entry *bm_dir = NULL;
@@ -101,11+101,13 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) }
struct linux_binfmt script_format = {
+ NULL,
#ifndef MODULE
- NULL, 0, load_script, NULL, NULL
+ NULL,
#else
- NULL, &__this_module, load_script, NULL, NULL
+ &__this_module,
#endif
+ load_script, NULL, NULL, 0
};
int __init init_script_binfmt(void)
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/bitops.h>
+#include <asm/mmu_context.h>
#define NR_SIZES 7
static char buffersize_index[65] =
@@ -1955,6+1956,26 @@ static int sync_old_buffers(void) return 0;
}
+struct mm_struct * start_lazy_tlb(void)
+{
+ struct mm_struct *mm = current->mm;
+ atomic_inc(&mm->mm_count);
+ current->mm = NULL;
+ /* active_mm is still 'mm' */
+ return mm;
+}
+
+void end_lazy_tlb(struct mm_struct *mm)
+{
+ struct mm_struct *active_mm = current->active_mm;
+
+ current->mm = mm;
+ if (mm != active_mm) {
+ current->active_mm = mm;
+ activate_context();
+ }
+ mmdrop(active_mm);
+}
/* This is the interface to bdflush. As we get more sophisticated, we can
* pass tuning parameters to this "process", to adjust how it behaves.
@@ -1963,57+1984,45 @@ static int sync_old_buffers(void)
asmlinkage int sys_bdflush(int func, long data)
{
- int i, error = -EPERM;
-
if (!capable(CAP_SYS_ADMIN))
- goto out;
+ return -EPERM;
if (func == 1) {
+ int error;
struct mm_struct *user_mm;
+
/*
* bdflush will spend all of it's time in kernel-space,
* without touching user-space, so we can switch it into
* 'lazy TLB mode' to reduce the cost of context-switches
* to and from bdflush.
*/
- user_mm = current->mm;
- atomic_inc(&user_mm->mm_count);
- current->mm = NULL;
- /* active_mm is still 'user_mm' */
-
+ user_mm = start_lazy_tlb();
error = sync_old_buffers();
-
- current->mm = user_mm;
- mmdrop(current->active_mm);
- current->active_mm = user_mm;
-
- goto out;
+ end_lazy_tlb(user_mm);
+ return error;
}
/* Basically func 1 means read param 1, 2 means write param 1, etc */
if (func >= 2) {
- i = (func-2) >> 1;
- error = -EINVAL;
- if (i < 0 || i >= N_PARAM)
- goto out;
- if((func & 1) == 0) {
- error = put_user(bdf_prm.data[i], (int*)data);
- goto out;
+ int i = (func-2) >> 1;
+ if (i >= 0 && i < N_PARAM) {
+ if ((func & 1) == 0)
+ return put_user(bdf_prm.data[i], (int*)data);
+
+ if (data >= bdflush_min[i] && data <= bdflush_max[i]) {
+ bdf_prm.data[i] = data;
+ return 0;
+ }
}
- if (data < bdflush_min[i] || data > bdflush_max[i])
- goto out;
- bdf_prm.data[i] = data;
- error = 0;
- goto out;
- };
+ return -EINVAL;
+ }
/* Having func 0 used to launch the actual bdflush and then never
* return (unless explicitly killed). We return zero here to
* remain semi-compatible with present update(8) programs.
*/
- error = 0;
-out:
- return error;
+ return 0;
}
/*
@@ -388,8+388,7 @@ static int exec_mmap(void)
current->mm = mm;
current->active_mm = mm;
- SET_PAGE_DIR(current, mm->pgd);
- activate_context(current);
+ activate_context();
mm_release();
if (old_mm) {
mmput(old_mm);
return retval;
}
+
+int do_coredump(long signr, struct pt_regs * regs)
+{
+ struct linux_binfmt * binfmt;
+ char corename[6+sizeof(current->comm)];
+ struct file * file;
+ struct dentry * dentry;
+ struct inode * inode;
+
+ lock_kernel();
+ binfmt = current->binfmt;
+ if (!binfmt || !binfmt->core_dump)
+ goto fail;
+ if (!current->dumpable || atomic_read(¤t->mm->mm_users) != 1)
+ current->dumpable = 0;
+ if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
+ goto fail;
+
+ memcpy(corename,"core.", 5);
+#if 0
+ memcpy(corename+5,current->comm,sizeof(current->comm));
+#else
+ corename[4] = '\0';
+#endif
+ file = filp_open(corename, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
+ if (IS_ERR(file))
+ goto fail;
+ dentry = file->f_dentry;
+ inode = dentry->d_inode;
+ if (inode->i_nlink > 1)
+ goto close_fail; /* multiple links - don't dump */
+
+ if (!S_ISREG(inode->i_mode))
+ goto close_fail;
+ if (!inode->i_op || !inode->i_op->default_file_ops)
+ goto close_fail;
+ if (!file->f_op->write)
+ goto close_fail;
+ if (!binfmt->core_dump(signr, regs, file))
+ goto close_fail;
+ filp_close(file, NULL);
+ unlock_kernel();
+ return 1;
+
+close_fail:
+ filp_close(file, NULL);
+fail:
+ unlock_kernel();
+ return 0;
+}
#define MAX(a,b) (((a)>(b))?(a):(b))
#include <linux/fs.h>
+#include <linux/minix_fs.h>
/*
* Write to a file (through the page cache).
#define get_mmu_context(next) do { } while (0)
#define set_mmu_context(prev,next) do { next->thread.cr3 = prev->thread.cr3; } while(0)
-#define init_new_context(mm) do { } while(0)
/*
* possibly do the LDT unload here?
*/
-#define destroy_context(mm) do { } while(0)
-#define activate_context(x) load_LDT((x)->mm)
+#define destroy_context(mm) do { } while(0)
+#define init_new_context(tsk,mm) do { (tsk)->thread.cr3 = __pa((mm)->pgd); } while (0)
+
+static inline void activate_context(void)
+{
+ struct task_struct *tsk = current;
+ struct mm_struct *mm = tsk->mm;
+ unsigned long cr3;
+
+ load_LDT(mm);
+ cr3 = __pa(mm->pgd);
+ tsk->thread.cr3 = cr3;
+ __asm__ __volatile__("movl %0,%%cr3": :"r" (cr3));
+}
#endif
@@ -56,21+56,21 @@ __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
static inline void flush_tlb_mm(struct mm_struct *mm)
{
- if (mm == current->mm)
+ if (mm == current->active_mm)
__flush_tlb();
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr)
{
- if (vma->vm_mm == current->mm)
+ if (vma->vm_mm == current->active_mm)
__flush_tlb_one(addr);
}
static inline void flush_tlb_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
- if (mm == current->mm)
+ if (mm == current->active_mm)
__flush_tlb();
}
@@ -302,15+302,6 @@ extern pte_t * __bad_pagetable(void); #define PAGE_PTR(address) \
((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-/* to set the page-dir */
-#define SET_PAGE_DIR(tsk,pgdir) \
-do { \
- unsigned long __pgdir = __pa(pgdir); \
- (tsk)->thread.cr3 = __pgdir; \
- if ((tsk) == current) \
- __asm__ __volatile__("movl %0,%%cr3": :"r" (__pgdir)); \
-} while (0)
-
#define pte_none(x) (!pte_val(x))
#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
#define pte_clear(xp) do { pte_val(*(xp)) = 0; } while (0)
@@ -38,7+38,8 @@ struct linux_binfmt { struct module *module;
int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
int (*load_shlib)(int fd);
- int (*core_dump)(long signr, struct pt_regs * regs);
+ int (*core_dump)(long signr, struct pt_regs * regs, struct file * file);
+ unsigned long min_coredump; /* minimal dump size */
};
extern int register_binfmt(struct linux_binfmt *);
@@ -66,6+67,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm); extern int copy_strings(int argc,char ** argv,struct linux_binprm *bprm);
extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
extern void compute_creds(struct linux_binprm *binprm);
+extern int do_coredump(long signr, struct pt_regs * regs);
#if 0
@@ -74,6+74,7 @@ typedef enum { * parport_negotiate to use address operations. They have no effect
* other than to make parport_read/write use address transfers. */
#define IEEE1284_ADDR (1<<13) /* This is a flag */
+#define IEEE1284_DATA 0 /* So is this */
/* The rest is for the kernel only */
#ifdef __KERNEL__
@@ -300,7+300,6 @@ struct mm_struct * mm_alloc(void) mm = kmem_cache_alloc(mm_cachep, SLAB_KERNEL);
if (mm) {
memset(mm, 0, sizeof(*mm));
- init_new_context(mm);
atomic_set(&mm->mm_users, 1);
atomic_set(&mm->mm_count, 1);
init_MUTEX(&mm->mmap_sem);
@@ -409,7+408,7 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk) good_mm:
tsk->mm = mm;
tsk->active_mm = mm;
- SET_PAGE_DIR(tsk, mm->pgd);
+ init_new_context(tsk,mm);
return 0;
free_mm:
@@ -401,10+401,9 @@ static struct sock *tcp_v4_lookup_listener(u32 daddr, unsigned short hnum, int d * The sockhash lock must be held as a reader here.
*/
static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport,
- u32 daddr, u16 dport, int dif)
+ u32 daddr, u16 hnum, int dif)
{
TCP_V4_ADDR_COOKIE(acookie, saddr, daddr)
- __u16 hnum = ntohs(dport);
__u32 ports = TCP_COMBINED_PORTS(sport, hnum);
struct sock *sk;
int hash;
@@ -439,7+438,7 @@ __inline__ struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport struct sock *sk;
SOCKHASH_LOCK_READ();
- sk = __tcp_v4_lookup(saddr, sport, daddr, dport, dif);
+ sk = __tcp_v4_lookup(saddr, sport, daddr, ntohs(dport), dif);
SOCKHASH_UNLOCK_READ();
return sk;
@@ -1729,7+1728,7 @@ int tcp_v4_rcv(struct sk_buff *skb, unsigned short len) #endif
SOCKHASH_LOCK_READ_BH();
sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source,
- skb->nh.iph->daddr, th->dest, skb->dev->ifindex);
+ skb->nh.iph->daddr, ntohs(th->dest), skb->dev->ifindex);
SOCKHASH_UNLOCK_READ_BH();
#ifdef CONFIG_IP_TRANSPARENT_PROXY
if (!sk)
# differ on your system.
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin:$PATH
-echo '-- Versions installed: (if some fields are empty or looks'
+echo '-- Versions installed: (if some fields are empty or look'
echo '-- unusual then possibly you have very old versions)'
uname -a
insmod -V 2>&1 | awk 'NR==1 {print "Kernel modules ",$NF}'