Commit 97267ce0 authored by Jeff Dike's avatar Jeff Dike

A number of bug fixes from UML 2.4.19-6 -

Fixed the net crash seen when slab debugging is enabled
Fixed PROT_NONE
Fixed the 'tracing myself' bug seen on umlcoop.  This was caused by
a number of SIGALRM handlers nesting on the idle thread stack because
the system was busy enough that UML couldn't clear one before the
next arrived.
parent f20bf018
...@@ -280,11 +280,6 @@ static int eth_configure(struct uml_net *device, int n) ...@@ -280,11 +280,6 @@ static int eth_configure(struct uml_net *device, int n)
device->dev = dev; device->dev = dev;
(*device->kern->init)(dev, device->transport_index); (*device->kern->init)(dev, device->transport_index);
rtnl_lock();
err = register_netdevice(dev);
rtnl_unlock();
if(err)
return(1);
dev->mtu = device->user->max_packet; dev->mtu = device->user->max_packet;
dev->open = uml_net_open; dev->open = uml_net_open;
...@@ -298,7 +293,36 @@ static int eth_configure(struct uml_net *device, int n) ...@@ -298,7 +293,36 @@ static int eth_configure(struct uml_net *device, int n)
dev->do_ioctl = uml_net_ioctl; dev->do_ioctl = uml_net_ioctl;
dev->watchdog_timeo = (HZ >> 1); dev->watchdog_timeo = (HZ >> 1);
dev->irq = UM_ETH_IRQ; dev->irq = UM_ETH_IRQ;
dev->init = NULL;
dev->master = NULL;
dev->neigh_setup = NULL;
dev->owner = NULL;
dev->state = 0;
dev->next_sched = 0;
dev->get_wireless_stats = 0;
dev->wireless_handlers = 0;
dev->gflags = 0;
dev->mc_list = NULL;
dev->mc_count = 0;
dev->promiscuity = 0;
dev->atalk_ptr = NULL;
dev->ip_ptr = NULL;
dev->dn_ptr = NULL;
dev->ip6_ptr = NULL;
dev->ec_ptr = NULL;
atomic_set(&dev->refcnt, 0);
dev->features = 0;
dev->uninit = NULL;
dev->destructor = NULL;
dev->set_config = NULL;
dev->accept_fastpath = 0;
dev->br_port = 0;
rtnl_lock();
err = register_netdevice(dev);
rtnl_unlock();
if(err)
return(1);
lp = dev->priv; lp = dev->priv;
/* lp.user is the first four bytes of the transport data, which /* lp.user is the first four bytes of the transport data, which
......
...@@ -53,7 +53,7 @@ static void pipe_interrupt(int irq, void *data, struct pt_regs *regs) ...@@ -53,7 +53,7 @@ static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
if(fd < 0){ if(fd < 0){
printk("os_accept_connection returned %d\n", -fd); printk("os_rcv_fd returned %d\n", -fd);
os_close_file(conn->fd); os_close_file(conn->fd);
} }
conn->fd = fd; conn->fd = fd;
......
...@@ -25,6 +25,7 @@ extern void *sbrk(int increment); ...@@ -25,6 +25,7 @@ extern void *sbrk(int increment);
extern void *malloc(int size); extern void *malloc(int size);
extern void perror(char *err); extern void perror(char *err);
extern int kill(int pid, int sig); extern int kill(int pid, int sig);
extern int getpid(void);
extern int getuid(void); extern int getuid(void);
extern int pause(void); extern int pause(void);
extern int write(int, const void *, int); extern int write(int, const void *, int);
......
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __TIME_USER_H__
#define __TIME_USER_H__
extern void timer(void);
extern void get_profile_timer(void);
extern void disable_profile_timer(void);
extern void switch_timers(int to_real);
extern void user_time_init(void);
extern void set_timers(int set_signal);
extern void idle_sleep(int secs);
#endif
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "irq_user.h" #include "irq_user.h"
#include "syscall_user.h" #include "syscall_user.h"
#include "ptrace_user.h" #include "ptrace_user.h"
#include "time_user.h"
#include "init.h" #include "init.h"
#include "os.h" #include "os.h"
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "init.h" #include "init.h"
#include "irq_user.h" #include "irq_user.h"
#include "mem_user.h" #include "mem_user.h"
#include "time_user.h"
#include "tlb.h" #include "tlb.h"
#include "frame_kern.h" #include "frame_kern.h"
#include "sigcontext.h" #include "sigcontext.h"
......
...@@ -53,6 +53,28 @@ static void set_interval(int timer_type) ...@@ -53,6 +53,28 @@ static void set_interval(int timer_type)
panic("setitimer failed - errno = %d\n", errno); panic("setitimer failed - errno = %d\n", errno);
} }
void switch_timers(int to_real)
{
struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
{ 0, 1000000/hz() }});
int old, new;
if(to_real){
old = ITIMER_VIRTUAL;
new = ITIMER_REAL;
}
else {
old = ITIMER_REAL;
new = ITIMER_VIRTUAL;
}
if((setitimer(old, &disable, NULL) < 0) ||
(setitimer(new, &enable, NULL)))
printk("switch_timers - setitimer failed, errno = %d\n",
errno);
}
void idle_timer(void) void idle_timer(void)
{ {
if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "asm/current.h" #include "asm/current.h"
#include "kern_util.h" #include "kern_util.h"
#include "user_util.h" #include "user_util.h"
#include "time_user.h"
u64 jiffies_64; u64 jiffies_64;
......
...@@ -99,7 +99,7 @@ void flush_kernel_range(unsigned long start, unsigned long end, int update_seq) ...@@ -99,7 +99,7 @@ void flush_kernel_range(unsigned long start, unsigned long end, int update_seq)
int updated = 0, err; int updated = 0, err;
mm = &init_mm; mm = &init_mm;
for(addr = start_vm; addr < end_vm;){ for(addr = start; addr < end;){
pgd = pgd_offset(mm, addr); pgd = pgd_offset(mm, addr);
pmd = pmd_offset(pgd, addr); pmd = pmd_offset(pgd, addr);
if(pmd_present(*pmd)){ if(pmd_present(*pmd)){
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "frame_user.h" #include "frame_user.h"
#include "syscall_user.h" #include "syscall_user.h"
#include "ptrace_user.h" #include "ptrace_user.h"
#include "time_user.h"
#include "task.h" #include "task.h"
#include "os.h" #include "os.h"
...@@ -517,7 +518,14 @@ void alarm_handler(int sig, struct sigcontext sc) ...@@ -517,7 +518,14 @@ void alarm_handler(int sig, struct sigcontext sc)
user = user_context(SC_SP(&sc)); user = user_context(SC_SP(&sc));
if(!user && !kern_timer_on) return; if(!user && !kern_timer_on) return;
if(!user && jail_timer_off) return; if(!user && jail_timer_off) return;
if(sig == SIGALRM)
switch_timers(0);
sig_handler_common(sig, &sc); sig_handler_common(sig, &sc);
if(sig == SIGALRM)
switch_timers(1);
} }
void do_longjmp(void *p) void do_longjmp(void *p)
......
...@@ -226,11 +226,25 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval) ...@@ -226,11 +226,25 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval)
* The following only work if pte_present() is true. * The following only work if pte_present() is true.
* Undefined behaviour if not.. * Undefined behaviour if not..
*/ */
static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } static inline int pte_read(pte_t pte)
static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } {
return((pte_val(pte) & _PAGE_USER) &&
!(pte_val(pte) & _PAGE_PROTNONE));
}
static inline int pte_exec(pte_t pte){
return((pte_val(pte) & _PAGE_USER) &&
!(pte_val(pte) & _PAGE_PROTNONE));
}
static inline int pte_write(pte_t pte)
{
return((pte_val(pte) & _PAGE_RW) &&
!(pte_val(pte) & _PAGE_PROTNONE));
}
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; } static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
static inline int pte_newprot(pte_t pte) static inline int pte_newprot(pte_t pte)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment