Commit 7f555b11 authored by Jeff Dike's avatar Jeff Dike

Merged conflicts between 2.5.45 and my 2.5.44.

parents b1b782f7 48a6f198
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 $@
......
...@@ -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
......
...@@ -15,7 +15,7 @@ CHAN_OBJS := chan_kern.o chan_user.o line.o ...@@ -15,7 +15,7 @@ CHAN_OBJS := chan_kern.o chan_user.o line.o
# So, what this does is figure out by hand (crudely) what file -lpcap really # So, what this does is figure out by hand (crudely) what file -lpcap really
# is and just use it. # is and just use it.
PCAP = $(shell for f in echo {/lib,/usr/lib}/libpcap.{a,so}; do \ PCAP = $(shell for f in echo {/lib,/usr/lib}/libpcap.a; do \
[ -f $$f ] && echo $$f ; done | head -1) [ -f $$f ] && echo $$f ; done | head -1)
slip-objs := slip_kern.o slip_user.o slip-objs := slip_kern.o slip_user.o
...@@ -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;
...@@ -49,27 +50,31 @@ static void pipe_interrupt(int irq, void *data, struct pt_regs *regs) ...@@ -49,27 +50,31 @@ static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
struct connection *conn = data; struct connection *conn = data;
int fd; int fd;
list_del(&conn->list);
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){
if(fd == -EAGAIN)
return;
printk("os_rcv_fd returned %d\n", -fd); printk("os_rcv_fd returned %d\n", -fd);
os_close_file(conn->fd); os_close_file(conn->fd);
} }
list_del(&conn->list);
conn->fd = fd; conn->fd = fd;
list_add(&conn->list, &conn->port->connections); list_add(&conn->list, &conn->port->connections);
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){
if(fd != -EAGAIN)
printk("port_connection returned %d\n", -fd); printk("port_connection returned %d\n", -fd);
goto out; goto out;
} }
...@@ -94,6 +99,7 @@ static void port_interrupt(int irq, void *data, struct pt_regs *regs) ...@@ -94,6 +99,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 +108,45 @@ static void port_interrupt(int irq, void *data, struct pt_regs *regs) ...@@ -102,17 +108,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);
...@@ -141,6 +175,7 @@ void *port_data(int port_num) ...@@ -141,6 +175,7 @@ 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),
has_connection : 0,
sem : __SEMAPHORE_INITIALIZER(port->sem, 0), sem : __SEMAPHORE_INITIALIZER(port->sem, 0),
lock : SPIN_LOCK_UNLOCKED, lock : SPIN_LOCK_UNLOCKED,
port : port_num, port : port_num,
...@@ -159,8 +194,7 @@ void *port_data(int port_num) ...@@ -159,8 +194,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 +202,7 @@ void *port_data(int port_num) ...@@ -168,7 +202,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 = {
......
This diff is collapsed.
...@@ -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);
if(data->direct_rcv)
new = os_rcv_fd(fd, &data->helper_pid); 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 "kern_util.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);
if(xterm->new_fd == -EAGAIN)
return;
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);
free_irq(XTERM_IRQ, data);
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)
......
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 <linux/highmem.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"
...@@ -36,12 +40,15 @@ EXPORT_SYMBOL(page_mem_map); ...@@ -36,12 +40,15 @@ EXPORT_SYMBOL(page_mem_map);
EXPORT_SYMBOL(get_signals); EXPORT_SYMBOL(get_signals);
EXPORT_SYMBOL(page_to_phys); EXPORT_SYMBOL(page_to_phys);
EXPORT_SYMBOL(phys_to_page); EXPORT_SYMBOL(phys_to_page);
EXPORT_SYMBOL(high_physmem);
EXPORT_SYMBOL(os_open_file); EXPORT_SYMBOL(os_open_file);
EXPORT_SYMBOL(os_read_file); EXPORT_SYMBOL(os_read_file);
EXPORT_SYMBOL(os_write_file); EXPORT_SYMBOL(os_write_file);
EXPORT_SYMBOL(os_seek_file); EXPORT_SYMBOL(os_seek_file);
EXPORT_SYMBOL(os_pipe); EXPORT_SYMBOL(os_pipe);
EXPORT_SYMBOL(os_file_type);
EXPORT_SYMBOL(os_close_file);
EXPORT_SYMBOL(helper_wait); EXPORT_SYMBOL(helper_wait);
EXPORT_SYMBOL(os_shutdown_socket); EXPORT_SYMBOL(os_shutdown_socket);
EXPORT_SYMBOL(os_connect_socket); EXPORT_SYMBOL(os_connect_socket);
...@@ -58,3 +65,23 @@ EXPORT_SYMBOL(sys_lseek); ...@@ -58,3 +65,23 @@ 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
#ifdef CONFIG_HIGHMEM
EXPORT_SYMBOL(kmap);
EXPORT_SYMBOL(kunmap);
EXPORT_SYMBOL(kmap_atomic);
EXPORT_SYMBOL(kunmap_atomic);
EXPORT_SYMBOL(kmap_atomic_to_page);
#endif
...@@ -767,8 +767,8 @@ void set_thread_sc(void *sc) ...@@ -767,8 +767,8 @@ void set_thread_sc(void *sc)
int smp_sigio_handler(void) int smp_sigio_handler(void)
{ {
int cpu = current->thread_info->cpu;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
int cpu = current->thread_info->cpu;
IPI_handler(cpu); IPI_handler(cpu);
if(cpu != 0) if(cpu != 0)
return(1); return(1);
......
/* /*
* 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 ] =
......
...@@ -76,6 +76,16 @@ void show_trace(unsigned long * stack) ...@@ -76,6 +76,16 @@ void show_trace(unsigned long * stack)
printk("\n"); printk("\n");
} }
/*
* The architecture-independent dump_stack generator
*/
void dump_stack(void)
{
unsigned long stack;
show_trace(&stack);
}
void show_trace_task(struct task_struct *tsk) void show_trace_task(struct task_struct *tsk)
{ {
unsigned long esp = PT_REGS_SP(&tsk->thread.regs); unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
......
...@@ -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 */
......
...@@ -283,10 +283,9 @@ int os_rcv_fd(int fd, int *helper_pid_out) ...@@ -283,10 +283,9 @@ int os_rcv_fd(int fd, int *helper_pid_out)
msg.msg_flags = 0; msg.msg_flags = 0;
n = recvmsg(fd, &msg, 0); n = recvmsg(fd, &msg, 0);
if(n < 0){ if(n < 0)
printk("rcv_fd : recvmsg failed - errno = %d\n", errno); return(-errno);
return(-1);
}
else if(n != sizeof(iov.iov_len)) else if(n != sizeof(iov.iov_len))
*helper_pid_out = -1; *helper_pid_out = -1;
......
obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o old-checksum.o \ obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o \
ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
obj-$(CONFIG_HIGHMEM) += highmem.o
export-objs = ksyms.o export-objs = ksyms.o
USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/sys-i386/$(file)) USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/sys-i386/$(file))
SYMLINKS = semaphore.c old-checksum.c checksum.S extable.c SYMLINKS = semaphore.c checksum.S extable.c highmem.c
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
$(USER_OBJS) : %.o: %.c $(USER_OBJS) : %.o: %.c
$(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
arch/um/sys-i386/checksum.S arch/um/sys-i386/old-checksum.c: arch/um/sys-i386/checksum.S:
-rm -f $@ -rm -f $@
-ln -s $(TOPDIR)/arch/i386/lib/$(notdir $@) $@ -ln -s $(TOPDIR)/arch/i386/lib/$(notdir $@) $@
...@@ -25,6 +27,9 @@ arch/um/sys-i386/extable.c: ...@@ -25,6 +27,9 @@ arch/um/sys-i386/extable.c:
-rm -f $@ -rm -f $@
-ln -s $(TOPDIR)/arch/i386/mm/$(notdir $@) $@ -ln -s $(TOPDIR)/arch/i386/mm/$(notdir $@) $@
arch/um/sys-i386/highmem.c:
-rm -f $@
-ln -s $(TOPDIR)/arch/i386/mm/$(notdir $@) $@
clean: clean:
$(MAKE) -C util clean $(MAKE) -C util clean
......
...@@ -65,7 +65,7 @@ SECTIONS ...@@ -65,7 +65,7 @@ SECTIONS
.uml.postsetup.init : { *(.uml.postsetup.init) } .uml.postsetup.init : { *(.uml.postsetup.init) }
__uml_postsetup_end = .; __uml_postsetup_end = .;
__setup_start = .; __setup_start = .;
.setup.init : { *(.setup.init) } .init.setup : { *(.init.setup) }
__setup_end = .; __setup_end = .;
__per_cpu_start = . ; __per_cpu_start = . ;
.data.percpu : { *(.data.percpu) } .data.percpu : { *(.data.percpu) }
......
...@@ -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)
...@@ -35,7 +35,7 @@ extern int get_signals(void); ...@@ -35,7 +35,7 @@ extern int get_signals(void);
({ \ ({ \
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