summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
commit546db14ee74118296f425f3b91634fb767d67290 (patch)
tree22b613a3da8d4bf663eec5e155af01b87fdf9094 /kernel
parent1e25e41c4f5474e14452094492dbc169b800e4c8 (diff)
Merge with Linux 2.3.23. The new bootmem stuff has broken various
platforms. At this time I've only verified that IP22 support compiles and IP27 actually works.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exit.c34
-rw-r--r--kernel/fork.c11
-rw-r--r--kernel/ksyms.c8
-rw-r--r--kernel/ptrace.c48
-rw-r--r--kernel/time.c22
5 files changed, 83 insertions, 40 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 39103a683..2ca64035c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -135,7 +135,9 @@ static inline void forget_original_parent(struct task_struct * father)
read_lock(&tasklist_lock);
for_each_task(p) {
if (p->p_opptr == father) {
+ /* We dont want people slaying init */
p->exit_signal = SIGCHLD;
+ p->self_exec_id++;
p->p_opptr = child_reaper; /* init */
if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
}
@@ -288,7 +290,7 @@ void exit_mm(struct task_struct *tsk)
*/
static void exit_notify(void)
{
- struct task_struct * p;
+ struct task_struct * p, *t;
forget_original_parent(current);
/*
@@ -300,15 +302,39 @@ static void exit_notify(void)
* and we were the only connection outside, so our pgrp
* is about to become orphaned.
*/
- if ((current->p_pptr->pgrp != current->pgrp) &&
- (current->p_pptr->session == current->session) &&
+
+ t = current->p_pptr;
+
+ if ((t->pgrp != current->pgrp) &&
+ (t->session == current->session) &&
will_become_orphaned_pgrp(current->pgrp, current) &&
has_stopped_jobs(current->pgrp)) {
kill_pg(current->pgrp,SIGHUP,1);
kill_pg(current->pgrp,SIGCONT,1);
}
- /* Let father know we died */
+ /* Let father know we died
+ *
+ * Thread signals are configurable, but you aren't going to use
+ * that to send signals to arbitary processes.
+ * That stops right now.
+ *
+ * If the parent exec id doesn't match the exec id we saved
+ * when we started then we know the parent has changed security
+ * domain.
+ *
+ * If our self_exec id doesn't match our parent_exec_id then
+ * we have changed execution domain as these two values started
+ * the same after a fork.
+ *
+ */
+
+ if(current->exit_signal != SIGCHLD &&
+ ( current->parent_exec_id != t->self_exec_id ||
+ current->self_exec_id != current->parent_exec_id)
+ && !capable(CAP_KILL))
+ current->exit_signal = SIGCHLD;
+
notify_parent(current, current->exit_signal);
/*
diff --git a/kernel/fork.c b/kernel/fork.c
index e341615f2..9f3d9f507 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -19,8 +19,8 @@
#include <linux/vmalloc.h>
#include <asm/pgtable.h>
-#include <asm/mmu_context.h>
#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
/* The idle threads do not count.. */
int nr_threads=0;
@@ -157,7 +157,7 @@ int alloc_uid(struct task_struct *p)
return 0;
}
-void __init fork_init(unsigned long memsize)
+void __init fork_init(unsigned long mempages)
{
int i;
@@ -175,7 +175,7 @@ void __init fork_init(unsigned long memsize)
* value: the thread structures can take up at most half
* of memory.
*/
- max_threads = memsize / THREAD_SIZE / 2;
+ max_threads = mempages / (THREAD_SIZE/PAGE_SIZE) / 2;
init_task.rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
@@ -693,6 +693,11 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
if (retval)
goto bad_fork_cleanup_sighand;
p->semundo = NULL;
+
+ /* Our parent execution domain becomes current domain
+ These must match for thread signalling to apply */
+
+ p->parent_exec_id = p->self_exec_id;
/* ok, now we should be set up.. */
p->swappable = 1;
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 910341fc6..d4480e717 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -36,6 +36,7 @@
#include <linux/swap.h>
#include <linux/ctype.h>
#include <linux/file.h>
+#include <linux/iobuf.h>
#include <linux/console.h>
#include <linux/poll.h>
#include <linux/mm.h>
@@ -118,11 +119,13 @@ EXPORT_SYMBOL(in_group_p);
EXPORT_SYMBOL(update_atime);
EXPORT_SYMBOL(get_super);
EXPORT_SYMBOL(get_fs_type);
+EXPORT_SYMBOL(get_empty_super);
+EXPORT_SYMBOL(remove_vfsmnt);
EXPORT_SYMBOL(getname);
EXPORT_SYMBOL(_fput);
EXPORT_SYMBOL(igrab);
EXPORT_SYMBOL(iunique);
-EXPORT_SYMBOL(iget);
+EXPORT_SYMBOL(iget4);
EXPORT_SYMBOL(iput);
EXPORT_SYMBOL(__namei);
EXPORT_SYMBOL(lookup_dentry);
@@ -140,6 +143,9 @@ EXPORT_SYMBOL(d_lookup);
EXPORT_SYMBOL(d_path);
EXPORT_SYMBOL(__mark_buffer_dirty);
EXPORT_SYMBOL(__mark_inode_dirty);
+EXPORT_SYMBOL(free_kiovec);
+EXPORT_SYMBOL(brw_kiovec);
+EXPORT_SYMBOL(alloc_kiovec);
EXPORT_SYMBOL(get_empty_filp);
EXPORT_SYMBOL(init_private_file);
EXPORT_SYMBOL(filp_open);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 35fa9768d..4945a0223 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -10,7 +10,7 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/mm.h>
-#include <linux/bigmem.h>
+#include <linux/highmem.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -23,7 +23,9 @@ static int access_one_page(struct task_struct * tsk, struct vm_area_struct * vma
pgd_t * pgdir;
pmd_t * pgmiddle;
pte_t * pgtable;
- unsigned long page;
+ unsigned long mapnr;
+ unsigned long maddr;
+ struct page *page;
repeat:
pgdir = pgd_offset(vma->vm_mm, addr);
@@ -39,27 +41,25 @@ repeat:
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable))
goto fault_in_page;
- page = pte_page(*pgtable);
+ mapnr = pte_pagenr(*pgtable);
if (write && (!pte_write(*pgtable) || !pte_dirty(*pgtable)))
goto fault_in_page;
- if (MAP_NR(page) >= max_mapnr)
+ if (mapnr >= max_mapnr)
return 0;
+ page = mem_map + mapnr;
flush_cache_page(vma, addr);
- {
- void *src = (void *) (page + (addr & ~PAGE_MASK));
- void *dst = buf;
- if (write) {
- dst = src;
- src = buf;
- }
- src = (void *) kmap((unsigned long) src, KM_READ);
- dst = (void *) kmap((unsigned long) dst, KM_WRITE);
- memcpy(dst, src, len);
- kunmap((unsigned long) src, KM_READ);
- kunmap((unsigned long) dst, KM_WRITE);
+ if (write) {
+ maddr = kmap(page, KM_WRITE);
+ memcpy((char *)maddr + (addr & ~PAGE_MASK), buf, len);
+ flush_page_to_ram(page);
+ kunmap(maddr, KM_WRITE);
+ } else {
+ maddr = kmap(page, KM_READ);
+ memcpy(buf, (char *)maddr + (addr & ~PAGE_MASK), len);
+ flush_page_to_ram(page);
+ kunmap(maddr, KM_READ);
}
- flush_page_to_ram(page);
return len;
fault_in_page:
@@ -69,23 +69,25 @@ fault_in_page:
return 0;
bad_pgd:
- printk("ptrace: bad pgd in '%s' at %08lx (%08lx)\n", tsk->comm, addr, pgd_val(*pgdir));
+ pgd_ERROR(*pgdir);
return 0;
bad_pmd:
- printk("ptrace: bad pmd in '%s' at %08lx (%08lx)\n", tsk->comm, addr, pmd_val(*pgmiddle));
+ pmd_ERROR(*pgmiddle);
return 0;
}
int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
{
int copied;
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- if (!vma)
- return 0;
+ struct vm_area_struct * vma;
down(&tsk->mm->mmap_sem);
+ vma = find_extend_vma(tsk, addr);
+ if (!vma) {
+ up(&tsk->mm->mmap_sem);
+ return 0;
+ }
copied = 0;
for (;;) {
unsigned long offset = addr & ~PAGE_MASK;
diff --git a/kernel/time.c b/kernel/time.c
index 1517d6d9d..3585e1cc8 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -54,6 +54,10 @@ void get_fast_time(struct timeval * t)
do_get_fast_time(t);
}
+/* The xtime_lock is not only serializing the xtime read/writes but it's also
+ serializing all accesses to the global NTP variables now. */
+extern rwlock_t xtime_lock;
+
#if !defined(__alpha__) && !defined(__ia64__)
/*
@@ -93,14 +97,14 @@ asmlinkage long sys_stime(int * tptr)
return -EPERM;
if (get_user(value, tptr))
return -EFAULT;
- cli();
+ write_lock_irq(&xtime_lock);
xtime.tv_sec = value;
xtime.tv_usec = 0;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
- sti();
+ write_unlock_irq(&xtime_lock);
return 0;
}
@@ -139,9 +143,9 @@ asmlinkage long sys_gettimeofday(struct timeval *tv, struct timezone *tz)
*/
inline static void warp_clock(void)
{
- cli();
+ write_lock_irq(&xtime_lock);
xtime.tv_sec += sys_tz.tz_minuteswest * 60;
- sti();
+ write_unlock_irq(&xtime_lock);
}
/*
@@ -222,7 +226,7 @@ void (*hardpps_ptr)(struct timeval *) = (void (*)(struct timeval *))0;
int do_adjtimex(struct timex *txc)
{
long ltemp, mtemp, save_adjust;
- int result = time_state; /* mostly `TIME_OK' */
+ int result;
/* In order to modify anything, you gotta be super-user! */
if (txc->modes && !capable(CAP_SYS_TIME))
@@ -240,7 +244,8 @@ int do_adjtimex(struct timex *txc)
if (txc->tick < 900000/HZ || txc->tick > 1100000/HZ)
return -EINVAL;
- cli(); /* SMP: global cli() is enough protection. */
+ write_lock_irq(&xtime_lock);
+ result = time_state; /* mostly `TIME_OK' */
/* Save for later - semantics of adjtime is to return old value */
save_adjust = time_adjust;
@@ -385,7 +390,6 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
txc->constant = time_constant;
txc->precision = time_precision;
txc->tolerance = time_tolerance;
- do_gettimeofday(&txc->time);
txc->tick = tick;
txc->ppsfreq = pps_freq;
txc->jitter = pps_jitter >> PPS_AVG;
@@ -395,8 +399,8 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
txc->calcnt = pps_calcnt;
txc->errcnt = pps_errcnt;
txc->stbcnt = pps_stbcnt;
-
- sti();
+ write_unlock_irq(&xtime_lock);
+ do_gettimeofday(&txc->time);
return(result);
}