Commit de3d8010 authored by Jeff Dike's avatar Jeff Dike

A bunch of miscellaneous changes - mostly fixes from 2.4 and updates

to 2.5.43.
Added some Makefile fixes so the build works.
Brought the xterm not hanging fix from 2.4.
Updated the signal code from 2.4.
Fixed port_interrupt to not allocate IRQs.
The idle threads for the secondary processors are now killed off
on shutdown.
Some rwlock symbols are exported.
Added a system call entry for lookup_dcookie.
parent 5a7728c6
ARCH_DIR = arch/um ARCH_DIR = arch/um
OS := $(shell uname -s) OS := $(shell uname -s)
include $(ARCH_DIR)/Makefile-$(SUBARCH)
include $(ARCH_DIR)/Makefile-os-$(OS)
EXTRAVERSION := $(EXTRAVERSION)-1um EXTRAVERSION := $(EXTRAVERSION)-1um
include/linux/version.h: arch/$(ARCH)/Makefile include/linux/version.h: arch/$(ARCH)/Makefile
...@@ -59,6 +56,9 @@ ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \ ...@@ -59,6 +56,9 @@ ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
GEN_HEADERS = $(ARCH_DIR)/include/task.h GEN_HEADERS = $(ARCH_DIR)/include/task.h
include $(ARCH_DIR)/Makefile-$(SUBARCH)
include $(ARCH_DIR)/Makefile-os-$(OS)
$(ARCH_DIR)/vmlinux.lds.S : $(ARCH_DIR)/vmlinux.lds.S :
touch $@ touch $@
...@@ -69,8 +69,7 @@ LDFLAGS_vmlinux = -r $(ARCH_DIR)/main.o ...@@ -69,8 +69,7 @@ LDFLAGS_vmlinux = -r $(ARCH_DIR)/main.o
vmlinux: $(ARCH_DIR)/main.o vmlinux: $(ARCH_DIR)/main.o
$(ARCH_DIR)/uml.lds.s : $(ARCH_DIR)/uml.lds.S scripts
$(ARCH_DIR)/uml.lds.s : $(ARCH_DIR)/uml.lds.S
$(call if_changed_dep,as_s_S) $(call if_changed_dep,as_s_S)
AFLAGS_uml.lds.o = -U$(SUBARCH) -DSTART=$$(($(TOP_ADDR) - $(SIZE))) \ AFLAGS_uml.lds.o = -U$(SUBARCH) -DSTART=$$(($(TOP_ADDR) - $(SIZE))) \
......
...@@ -21,11 +21,14 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc ...@@ -21,11 +21,14 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
$< > $@ $< > $@
$(SYS_UTIL_DIR)/mk_sc $(SYS_UTIL_DIR)/mk_thread: $(SYS_UTIL_DIR) FORCE ; $(SYS_UTIL_DIR)/mk_sc: FORCE ;
@$(call descend,$(SYS_UTIL_DIR),$@)
$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) FORCE ;
@$(call descend,$(SYS_UTIL_DIR),$@)
$(SYS_UTIL_DIR): include/asm FORCE $(SYS_UTIL_DIR): include/asm FORCE
@$(call descend,$@,) @$(call descend,$@,)
sysclean : sysclean :
rm -f $(SYS_HEADERS) rm -f $(SYS_HEADERS)
@$(call descend,$(SYS_DIR),clean)
...@@ -219,13 +219,16 @@ CONFIG_EXT2_FS=y ...@@ -219,13 +219,16 @@ CONFIG_EXT2_FS=y
# CONFIG_INTERMEZZO_FS is not set # CONFIG_INTERMEZZO_FS is not set
# CONFIG_NFS_FS is not set # CONFIG_NFS_FS is not set
# CONFIG_NFS_V3 is not set # CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
# CONFIG_ROOT_NFS is not set # CONFIG_ROOT_NFS is not set
# CONFIG_NFSD is not set # CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set # CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set # CONFIG_NFSD_TCP is not set
# CONFIG_SUNRPC is not set # CONFIG_SUNRPC is not set
# CONFIG_LOCKD is not set # CONFIG_LOCKD is not set
# CONFIG_EXPORTFS is not set # CONFIG_EXPORTFS is not set
# CONFIG_CIFS is not set
# CONFIG_SMB_FS is not set # CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set # CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_PACKET_SIGNING is not set
...@@ -236,6 +239,7 @@ CONFIG_EXT2_FS=y ...@@ -236,6 +239,7 @@ CONFIG_EXT2_FS=y
# CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set # CONFIG_NCPFS_EXTRAS is not set
# CONFIG_AFS_FS is not set
# CONFIG_ZISOFS_FS is not set # CONFIG_ZISOFS_FS is not set
# #
...@@ -332,7 +336,9 @@ CONFIG_SCSI_DEBUG=y ...@@ -332,7 +336,9 @@ CONFIG_SCSI_DEBUG=y
CONFIG_MTD=y CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set # CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_PARTITIONS is not set # CONFIG_MTD_PARTITIONS is not set
# CONFIG_MTD_CONCAT is not set
# CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# #
# User Modules And Translation Layers # User Modules And Translation Layers
...@@ -362,6 +368,8 @@ CONFIG_MTD_BLOCK=y ...@@ -362,6 +368,8 @@ CONFIG_MTD_BLOCK=y
# Mapping drivers for chip access # Mapping drivers for chip access
# #
# CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_PHYSMAP is not set
# CONFIG_MTD_PCI is not set
# CONFIG_MTD_PCMCIA is not set
# #
# Self-contained MTD device drivers # Self-contained MTD device drivers
......
...@@ -47,7 +47,7 @@ obj-$(CONFIG_NULL_CHAN) += null.o ...@@ -47,7 +47,7 @@ obj-$(CONFIG_NULL_CHAN) += null.o
obj-$(CONFIG_PORT_CHAN) += port.o obj-$(CONFIG_PORT_CHAN) += port.o
obj-$(CONFIG_PTY_CHAN) += pty.o obj-$(CONFIG_PTY_CHAN) += pty.o
obj-$(CONFIG_TTY_CHAN) += tty.o obj-$(CONFIG_TTY_CHAN) += tty.o
obj-$(CONFIG_XTERM_CHAN) += xterm.o obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
obj-$(CONFIG_UML_WATCHDOG) += harddog.o obj-$(CONFIG_UML_WATCHDOG) += harddog.o
CFLAGS_pcap_user.o = -I/usr/include/pcap CFLAGS_pcap_user.o = -I/usr/include/pcap
......
...@@ -111,6 +111,8 @@ void mconsole_version(struct mc_request *req) ...@@ -111,6 +111,8 @@ void mconsole_version(struct mc_request *req)
remove <dev> - Remove a device from UML remove <dev> - Remove a device from UML
sysrq <letter> - Performs the SysRq action controlled by the letter sysrq <letter> - Performs the SysRq action controlled by the letter
cad - invoke the Ctl-Alt-Del handler cad - invoke the Ctl-Alt-Del handler
stop - pause the UML; it will do nothing until it receives a 'go'
go - continue the UML after a 'stop'
" "
void mconsole_help(struct mc_request *req) void mconsole_help(struct mc_request *req)
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
struct port_list { struct port_list {
struct list_head list; struct list_head list;
int has_connection;
struct semaphore sem; struct semaphore sem;
int port; int port;
int fd; int fd;
...@@ -62,15 +63,15 @@ static void pipe_interrupt(int irq, void *data, struct pt_regs *regs) ...@@ -62,15 +63,15 @@ static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
up(&conn->port->sem); up(&conn->port->sem);
} }
static void port_interrupt(int irq, void *data, struct pt_regs *regs) static int port_accept(struct port_list *port)
{ {
struct port_list *port = data;
struct connection *conn; struct connection *conn;
int fd, socket[2], pid; int fd, socket[2], pid, ret = 0;
fd = port_connection(port->fd, socket, &pid); fd = port_connection(port->fd, socket, &pid);
if(fd < 0){ if(fd < 0){
printk("port_connection returned %d\n", -fd); if(fd != -EAGAIN)
printk("port_connection returned %d\n", -fd);
goto out; goto out;
} }
...@@ -94,6 +95,7 @@ static void port_interrupt(int irq, void *data, struct pt_regs *regs) ...@@ -94,6 +95,7 @@ static void port_interrupt(int irq, void *data, struct pt_regs *regs)
} }
list_add(&conn->list, &port->pending); list_add(&conn->list, &port->pending);
ret = 1;
goto out; goto out;
out_free: out_free:
...@@ -102,17 +104,45 @@ static void port_interrupt(int irq, void *data, struct pt_regs *regs) ...@@ -102,17 +104,45 @@ static void port_interrupt(int irq, void *data, struct pt_regs *regs)
os_close_file(fd); os_close_file(fd);
if(pid != -1) os_kill_process(pid); if(pid != -1) os_kill_process(pid);
out: out:
reactivate_fd(port->fd, ACCEPT_IRQ); return(ret);
} }
DECLARE_MUTEX(ports_sem); DECLARE_MUTEX(ports_sem);
struct list_head ports = LIST_HEAD_INIT(ports); struct list_head ports = LIST_HEAD_INIT(ports);
void port_work_proc(void *unused)
{
struct port_list *port;
struct list_head *ele;
unsigned long flags;
local_irq_save(flags);
list_for_each(ele, &ports){
port = list_entry(ele, struct port_list, list);
if(!port->has_connection)
continue;
reactivate_fd(port->fd, ACCEPT_IRQ);
while(port_accept(port)) ;
port->has_connection = 0;
}
local_irq_restore(flags);
}
DECLARE_WORK(port_work, port_work_proc, NULL);
static void port_interrupt(int irq, void *data, struct pt_regs *regs)
{
struct port_list *port = data;
port->has_connection = 1;
schedule_work(&port_work);
}
void *port_data(int port_num) void *port_data(int port_num)
{ {
struct list_head *ele; struct list_head *ele;
struct port_list *port; struct port_list *port;
struct port_dev *dev; struct port_dev *dev = NULL;
int fd; int fd;
down(&ports_sem); down(&ports_sem);
...@@ -140,13 +170,14 @@ void *port_data(int port_num) ...@@ -140,13 +170,14 @@ void *port_data(int port_num)
} }
*port = ((struct port_list) *port = ((struct port_list)
{ list : LIST_HEAD_INIT(port->list), { list : LIST_HEAD_INIT(port->list),
sem : __SEMAPHORE_INITIALIZER(port->sem, 0), has_connection : 0,
lock : SPIN_LOCK_UNLOCKED, sem : __SEMAPHORE_INITIALIZER(port->sem, 0),
port : port_num, lock : SPIN_LOCK_UNLOCKED,
fd : fd, port : port_num,
pending : LIST_HEAD_INIT(port->pending), fd : fd,
connections : LIST_HEAD_INIT(port->connections) }); pending : LIST_HEAD_INIT(port->pending),
connections : LIST_HEAD_INIT(port->connections) });
list_add(&port->list, &ports); list_add(&port->list, &ports);
found: found:
...@@ -159,8 +190,7 @@ void *port_data(int port_num) ...@@ -159,8 +190,7 @@ void *port_data(int port_num)
*dev = ((struct port_dev) { port : port, *dev = ((struct port_dev) { port : port,
fd : -1, fd : -1,
helper_pid : -1 }); helper_pid : -1 });
up(&ports_sem); goto out;
return(dev);
out_free: out_free:
kfree(port); kfree(port);
...@@ -168,7 +198,7 @@ void *port_data(int port_num) ...@@ -168,7 +198,7 @@ void *port_data(int port_num)
os_close_file(fd); os_close_file(fd);
out: out:
up(&ports_sem); up(&ports_sem);
return(NULL); return(dev);
} }
void port_remove_dev(void *d) void port_remove_dev(void *d)
......
...@@ -44,6 +44,7 @@ static struct chan_opts opts = { ...@@ -44,6 +44,7 @@ static struct chan_opts opts = {
xterm_title: "Serial Line #%d", xterm_title: "Serial Line #%d",
raw: 1, raw: 1,
tramp_stack : 0, tramp_stack : 0,
in_kernel : 1,
}; };
static struct line_driver driver = { static struct line_driver driver = {
......
...@@ -75,6 +75,7 @@ static struct chan_opts opts = { ...@@ -75,6 +75,7 @@ static struct chan_opts opts = {
xterm_title: "Virtual Console #%d", xterm_title: "Virtual Console #%d",
raw: 1, raw: 1,
tramp_stack : 0, tramp_stack : 0,
in_kernel : 1,
}; };
static struct line_driver driver = { static struct line_driver driver = {
......
...@@ -700,7 +700,8 @@ static int ubd_open(struct inode *inode, struct file *filp) ...@@ -700,7 +700,8 @@ static int ubd_open(struct inode *inode, struct file *filp)
{ {
int n = DEVICE_NR(inode->i_rdev); int n = DEVICE_NR(inode->i_rdev);
struct ubd *dev = &ubd_dev[n]; struct ubd *dev = &ubd_dev[n];
int err; int err = 0;
if(dev->is_dir == 1) if(dev->is_dir == 1)
goto out; goto out;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "user_util.h" #include "user_util.h"
#include "user.h" #include "user.h"
#include "os.h" #include "os.h"
#include "xterm.h"
struct xterm_chan { struct xterm_chan {
int pid; int pid;
...@@ -28,6 +29,7 @@ struct xterm_chan { ...@@ -28,6 +29,7 @@ struct xterm_chan {
int raw; int raw;
struct termios tt; struct termios tt;
unsigned long stack; unsigned long stack;
int direct_rcv;
}; };
void *xterm_init(char *str, int device, struct chan_opts *opts) void *xterm_init(char *str, int device, struct chan_opts *opts)
...@@ -40,7 +42,8 @@ void *xterm_init(char *str, int device, struct chan_opts *opts) ...@@ -40,7 +42,8 @@ void *xterm_init(char *str, int device, struct chan_opts *opts)
device : device, device : device,
title : opts->xterm_title, title : opts->xterm_title,
raw : opts->raw, raw : opts->raw,
stack : opts->tramp_stack } ); stack : opts->tramp_stack,
direct_rcv : !opts->in_kernel } );
return(data); return(data);
} }
...@@ -84,7 +87,7 @@ int xterm_open(int input, int output, int primary, void *d) ...@@ -84,7 +87,7 @@ int xterm_open(int input, int output, int primary, void *d)
{ {
struct xterm_chan *data = d; struct xterm_chan *data = d;
unsigned long stack; unsigned long stack;
int pid, fd, new; int pid, fd, new, err;
char title[256], file[] = "/tmp/xterm-pipeXXXXXX"; char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
char *argv[] = { terminal_emulator, title_switch, title, exec_switch, char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
"/usr/lib/uml/port-helper", "-uml-socket", "/usr/lib/uml/port-helper", "-uml-socket",
...@@ -105,21 +108,30 @@ int xterm_open(int input, int output, int primary, void *d) ...@@ -105,21 +108,30 @@ int xterm_open(int input, int output, int primary, void *d)
fd = create_unix_socket(file, sizeof(file)); fd = create_unix_socket(file, sizeof(file));
if(fd < 0){ if(fd < 0){
printk("xterm_open : create_unix_socket failed, errno = %d\n", printk("xterm_open : create_unix_socket failed, errno = %d\n",
errno); -fd);
return(-errno); return(-fd);
} }
sprintf(title, data->title, data->device); sprintf(title, data->title, data->device);
stack = data->stack; stack = data->stack;
pid = run_helper(NULL, NULL, argv, &stack); pid = run_helper(NULL, NULL, argv, &stack);
if(pid < 0){ if(pid < 0){
printk("xterm_open : run_helper failed\n"); printk("xterm_open : run_helper failed, errno = %d\n", -pid);
return(-1); return(pid);
} }
if(data->stack == 0) free_stack(stack, 0); if(data->stack == 0) free_stack(stack, 0);
new = os_rcv_fd(fd, &data->helper_pid); if(data->direct_rcv)
new = os_rcv_fd(fd, &data->helper_pid);
else {
if((err = os_set_fd_block(fd, 0)) != 0){
printk("xterm_open : failed to set descriptor "
"non-blocking, errno = %d\n", err);
return(err);
}
new = xterm_fd(fd, &data->helper_pid);
}
if(new < 0){ if(new < 0){
printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new); printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
return(new); return(new);
......
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __XTERM_H__
#define __XTERM_H__
extern int xterm_fd(int socket, int *pid_out);
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include "linux/errno.h"
#include "linux/slab.h"
#include "asm/semaphore.h"
#include "asm/irq.h"
#include "irq_user.h"
#include "os.h"
#include "xterm.h"
struct xterm_wait {
struct semaphore sem;
int fd;
int pid;
int new_fd;
};
static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
{
struct xterm_wait *xterm = data;
xterm->new_fd = os_rcv_fd(xterm->fd, &xterm->pid);
up(&xterm->sem);
}
int xterm_fd(int socket, int *pid_out)
{
struct xterm_wait *data;
int err, ret;
data = kmalloc(sizeof(*data), GFP_KERNEL);
if(data == NULL){
printk(KERN_ERR "xterm_fd - failed to allocate semaphore\n");
return(-ENOMEM);
}
*data = ((struct xterm_wait)
{ sem : __SEMAPHORE_INITIALIZER(data->sem, 0),
fd : socket,
pid : -1,
new_fd : -1 });
err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
"xterm", data);
if(err){
printk(KERN_ERR "Failed to get IRQ for xterm, err = %d\n",
err);
return(err);
}
down(&data->sem);
ret = data->new_fd;
*pid_out = data->pid;
kfree(data);
return(ret);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
...@@ -13,6 +13,7 @@ struct chan_opts { ...@@ -13,6 +13,7 @@ struct chan_opts {
char *xterm_title; char *xterm_title;
int raw; int raw;
unsigned long tramp_stack; unsigned long tramp_stack;
int in_kernel;
}; };
enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE }; enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#ifndef __KERN_UTIL_H__ #ifndef __KERN_UTIL_H__
#define __KERN_UTIL_H__ #define __KERN_UTIL_H__
#include "linux/threads.h"
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
extern int ncpus; extern int ncpus;
...@@ -14,6 +15,7 @@ extern char *gdb_init; ...@@ -14,6 +15,7 @@ extern char *gdb_init;
extern int kmalloc_ok; extern int kmalloc_ok;
extern int timer_irq_inited; extern int timer_irq_inited;
extern int jail; extern int jail;
extern struct task_struct *idle_threads[NR_CPUS];
#define ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK)) #define ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
#define ROUND_UP(addr) ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) #define ROUND_UP(addr) ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
......
...@@ -17,6 +17,7 @@ enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; ...@@ -17,6 +17,7 @@ enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
struct cpu_task { struct cpu_task {
int pid; int pid;
void *task; void *task;
void *idle;
}; };
extern struct cpu_task cpu_tasks[]; extern struct cpu_task cpu_tasks[];
......
EXTRA_TARGETS := unmap_fin.o EXTRA_TARGETS := unmap_fin.o
obj-y = config.o exec_kern.o exec_user.o exitcode.o frame_kern.o frame.o \ obj-y = config.o exec_kern.o exec_user.o exitcode.o frame_kern.o frame.o \
...@@ -51,6 +50,9 @@ arch/um/kernel/unmap.o: arch/um/kernel/unmap.c ...@@ -51,6 +50,9 @@ arch/um/kernel/unmap.o: arch/um/kernel/unmap.c
arch/um/kernel/unmap_fin.o : arch/um/kernel/unmap.o arch/um/kernel/unmap_fin.o : arch/um/kernel/unmap.o
ld -r -o $@ $< -lc -L/usr/lib ld -r -o $@ $< -lc -L/usr/lib
# This has to be separate because it needs be compiled with frame pointers
# regardless of how the rest of the kernel is built.
arch/um/kernel/frame.o: arch/um/kernel/frame.c arch/um/kernel/frame.o: arch/um/kernel/frame.c
$(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $< $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
......
...@@ -209,7 +209,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id) ...@@ -209,7 +209,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
out_unlock: out_unlock:
irq_unlock(flags); irq_unlock(flags);
out_free:
kfree(new_fd); kfree(new_fd);
out: out:
return(err); return(err);
......
#include "linux/config.h"
#include "linux/module.h" #include "linux/module.h"
#include "linux/string.h" #include "linux/string.h"
#include "linux/smp_lock.h"
#include "linux/spinlock.h"
#include "asm/current.h" #include "asm/current.h"
#include "asm/delay.h" #include "asm/delay.h"
#include "asm/processor.h" #include "asm/processor.h"
...@@ -58,3 +61,14 @@ EXPORT_SYMBOL(sys_lseek); ...@@ -58,3 +61,14 @@ EXPORT_SYMBOL(sys_lseek);
EXPORT_SYMBOL(sys_read); EXPORT_SYMBOL(sys_read);
EXPORT_SYMBOL(sys_wait4); EXPORT_SYMBOL(sys_wait4);
#ifdef CONFIG_SMP
/* required for SMP */
extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
EXPORT_SYMBOL_NOVERS(__write_lock_failed);
extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
EXPORT_SYMBOL_NOVERS(__read_lock_failed);
#endif
/* /*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com) * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL * Licensed under the GPL
*/ */
...@@ -9,6 +9,20 @@ ...@@ -9,6 +9,20 @@
#include "kern.h" #include "kern.h"
#include "os.h" #include "os.h"
#ifdef CONFIG_SMP
static void kill_idlers(int me)
{
struct task_struct *p;
int i;
for(i = 0; i < sizeof(idle_threads)/sizeof(idle_threads[0]); i++){
p = idle_threads[i];
if((p != NULL) && (p->thread.extern_pid != me))
os_kill_process(p->thread.extern_pid);
}
}
#endif
static void kill_off_processes(void) static void kill_off_processes(void)
{ {
struct task_struct *p; struct task_struct *p;
...@@ -21,6 +35,9 @@ static void kill_off_processes(void) ...@@ -21,6 +35,9 @@ static void kill_off_processes(void)
} }
if(init_task.thread.extern_pid != me) if(init_task.thread.extern_pid != me)
os_kill_process(init_task.thread.extern_pid); os_kill_process(init_task.thread.extern_pid);
#ifdef CONFIG_SMP
kill_idlers(me);
#endif
} }
void uml_cleanup(void) void uml_cleanup(void)
......
...@@ -84,13 +84,13 @@ void unblock_signals(void) ...@@ -84,13 +84,13 @@ void unblock_signals(void)
#define SIGIO_BIT 0 #define SIGIO_BIT 0
#define SIGVTALRM_BIT 1 #define SIGVTALRM_BIT 1
static int disable_mask(sigset_t *mask) static int enable_mask(sigset_t *mask)
{ {
int sigs; int sigs;
sigs = sigismember(mask, SIGIO) ? 1 << SIGIO_BIT : 0; sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
sigs |= sigismember(mask, SIGVTALRM) ? 1 << SIGVTALRM_BIT : 0; sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
sigs |= sigismember(mask, SIGALRM) ? 1 << SIGVTALRM_BIT : 0; sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
return(sigs); return(sigs);
} }
...@@ -100,30 +100,28 @@ int get_signals(void) ...@@ -100,30 +100,28 @@ int get_signals(void)
if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0) if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
panic("Failed to get signal mask"); panic("Failed to get signal mask");
return(disable_mask(&mask)); return(enable_mask(&mask));
} }
int set_signals(int disable) int set_signals(int enable)
{ {
sigset_t mask; sigset_t mask;
int ret; int ret;
sigemptyset(&mask); sigemptyset(&mask);
if(!(disable & (1 << SIGIO_BIT))) if(enable & (1 << SIGIO_BIT))
sigaddset(&mask, SIGIO); sigaddset(&mask, SIGIO);
if(!(disable & (1 << SIGVTALRM_BIT))){ if(enable & (1 << SIGVTALRM_BIT)){
sigaddset(&mask, SIGVTALRM); sigaddset(&mask, SIGVTALRM);
sigaddset(&mask, SIGALRM); sigaddset(&mask, SIGALRM);
} }
if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0) if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
panic("Failed to enable signals"); panic("Failed to enable signals");
ret = enable_mask(&mask);
ret = disable_mask(&mask);
sigemptyset(&mask); sigemptyset(&mask);
if(disable & (1 << SIGIO_BIT)) if((enable & (1 << SIGIO_BIT)) == 0)
sigaddset(&mask, SIGIO); sigaddset(&mask, SIGIO);
if(disable & (1 << SIGVTALRM_BIT)){ if((enable & (1 << SIGVTALRM_BIT)) == 0){
sigaddset(&mask, SIGVTALRM); sigaddset(&mask, SIGVTALRM);
sigaddset(&mask, SIGALRM); sigaddset(&mask, SIGALRM);
} }
......
...@@ -47,6 +47,9 @@ int num_reschedules_sent = 0; ...@@ -47,6 +47,9 @@ int num_reschedules_sent = 0;
/* Small, random number, never changed */ /* Small, random number, never changed */
unsigned long cache_decay_ticks = 5; unsigned long cache_decay_ticks = 5;
/* Not changed after boot */
struct task_struct *idle_threads[NR_CPUS];
void smp_send_reschedule(int cpu) void smp_send_reschedule(int cpu)
{ {
write(cpu_data[cpu].ipi_pipe[1], "R", 1); write(cpu_data[cpu].ipi_pipe[1], "R", 1);
...@@ -142,6 +145,7 @@ static struct task_struct *idle_thread(int cpu) ...@@ -142,6 +145,7 @@ static struct task_struct *idle_thread(int cpu)
cpu_tasks[cpu] = ((struct cpu_task) cpu_tasks[cpu] = ((struct cpu_task)
{ .pid = new_task->thread.extern_pid, { .pid = new_task->thread.extern_pid,
.task = new_task } ); .task = new_task } );
idle_threads[cpu] = new_task;
write(new_task->thread.switch_pipe[1], &c, sizeof(c)); write(new_task->thread.switch_pipe[1], &c, sizeof(c));
return(new_task); return(new_task);
} }
......
...@@ -229,6 +229,7 @@ extern syscall_handler_t sys_io_getevents; ...@@ -229,6 +229,7 @@ extern syscall_handler_t sys_io_getevents;
extern syscall_handler_t sys_io_submit; extern syscall_handler_t sys_io_submit;
extern syscall_handler_t sys_io_cancel; extern syscall_handler_t sys_io_cancel;
extern syscall_handler_t sys_exit_group; extern syscall_handler_t sys_exit_group;
extern syscall_handler_t sys_lookup_dcookie;
#if CONFIG_NFSD #if CONFIG_NFSD
#define NFSSERVCTL sys_nfsserctl #define NFSSERVCTL sys_nfsserctl
...@@ -240,7 +241,7 @@ extern syscall_handler_t um_mount; ...@@ -240,7 +241,7 @@ extern syscall_handler_t um_mount;
extern syscall_handler_t um_time; extern syscall_handler_t um_time;
extern syscall_handler_t um_stime; extern syscall_handler_t um_stime;
#define LAST_GENERIC_SYSCALL __NR_exit_group #define LAST_GENERIC_SYSCALL __NR_lookup_dcookie
#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
#define LAST_SYSCALL LAST_GENERIC_SYSCALL #define LAST_SYSCALL LAST_GENERIC_SYSCALL
...@@ -479,6 +480,7 @@ syscall_handler_t *sys_call_table[] = { ...@@ -479,6 +480,7 @@ syscall_handler_t *sys_call_table[] = {
[ __NR_alloc_hugepages ] = sys_ni_syscall, [ __NR_alloc_hugepages ] = sys_ni_syscall,
[ __NR_free_hugepages ] = sys_ni_syscall, [ __NR_free_hugepages ] = sys_ni_syscall,
[ __NR_exit_group ] = sys_exit_group, [ __NR_exit_group ] = sys_exit_group,
[ __NR_lookup_dcookie ] = sys_lookup_dcookie,
ARCH_SYSCALLS ARCH_SYSCALLS
[ LAST_SYSCALL + 1 ... NR_syscalls ] = [ LAST_SYSCALL + 1 ... NR_syscalls ] =
......
...@@ -211,6 +211,7 @@ static struct chan_opts opts = { ...@@ -211,6 +211,7 @@ static struct chan_opts opts = {
xterm_title : "UML kernel debugger", xterm_title : "UML kernel debugger",
raw : 0, raw : 0,
tramp_stack : 0, tramp_stack : 0,
in_kernel : 0,
}; };
/* Accessed by the tracing thread, which automatically serializes access */ /* Accessed by the tracing thread, which automatically serializes access */
......
...@@ -23,8 +23,9 @@ struct task_struct; ...@@ -23,8 +23,9 @@ struct task_struct;
#define WINCH_IRQ 10 #define WINCH_IRQ 10
#define SIGIO_WRITE_IRQ 11 #define SIGIO_WRITE_IRQ 11
#define TELNETD_IRQ 12 #define TELNETD_IRQ 12
#define XTERM_IRQ 13
#define LAST_IRQ TELNETD_IRQ #define LAST_IRQ XTERM_IRQ
#define NR_IRQS (LAST_IRQ + 1) #define NR_IRQS (LAST_IRQ + 1)
extern int um_request_irq(unsigned int irq, int fd, int type, extern int um_request_irq(unsigned int irq, int fd, int type,
......
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
extern void *switch_to(void *prev, void *next, void *last); extern void *switch_to(void *prev, void *next, void *last);
extern int set_signals(int enable); extern int set_signals(int enable);
extern int get_signals(void);
extern void block_signals(void); extern void block_signals(void);
extern void unblock_signals(void); extern void unblock_signals(void);
extern int get_signals(void);
#define local_save_flags(flags) do { (flags) = get_signals(); } while(0) #define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
#define local_irq_restore(flags) do { set_signals(flags); } while(0) #define local_irq_restore(flags) do { set_signals(flags); } while(0)
...@@ -31,11 +31,11 @@ extern int get_signals(void); ...@@ -31,11 +31,11 @@ extern int get_signals(void);
#define local_irq_enable() unblock_signals() #define local_irq_enable() unblock_signals()
#define local_irq_disable() block_signals() #define local_irq_disable() block_signals()
#define irqs_disabled() \ #define irqs_disabled() \
({ \ ({ \
unsigned long flags; \ unsigned long flags; \
local_save_flags(flags); \ local_save_flags(flags); \
(flags != 0); \ (flags == 0); \
}) })
#endif #endif
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