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
OS := $(shell uname -s)
include $(ARCH_DIR)/Makefile-$(SUBARCH)
include $(ARCH_DIR)/Makefile-os-$(OS)
EXTRAVERSION := $(EXTRAVERSION)-1um
include/linux/version.h: arch/$(ARCH)/Makefile
......@@ -59,6 +56,9 @@ ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
GEN_HEADERS = $(ARCH_DIR)/include/task.h
include $(ARCH_DIR)/Makefile-$(SUBARCH)
include $(ARCH_DIR)/Makefile-os-$(OS)
$(ARCH_DIR)/vmlinux.lds.S :
touch $@
......@@ -69,8 +69,7 @@ LDFLAGS_vmlinux = -r $(ARCH_DIR)/main.o
vmlinux: $(ARCH_DIR)/main.o
$(ARCH_DIR)/uml.lds.s : $(ARCH_DIR)/uml.lds.S
$(ARCH_DIR)/uml.lds.s : $(ARCH_DIR)/uml.lds.S scripts
$(call if_changed_dep,as_s_S)
AFLAGS_uml.lds.o = -U$(SUBARCH) -DSTART=$$(($(TOP_ADDR) - $(SIZE))) \
......
......@@ -21,11 +21,14 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
$(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
@$(call descend,$@,)
sysclean :
rm -f $(SYS_HEADERS)
@$(call descend,$(SYS_DIR),clean)
......@@ -219,13 +219,16 @@ CONFIG_EXT2_FS=y
# CONFIG_INTERMEZZO_FS is not set
# CONFIG_NFS_FS is not set
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
# CONFIG_ROOT_NFS is not set
# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
# CONFIG_SUNRPC is not set
# CONFIG_LOCKD is not set
# CONFIG_EXPORTFS is not set
# CONFIG_CIFS is not set
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
......@@ -236,6 +239,7 @@ CONFIG_EXT2_FS=y
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
# CONFIG_AFS_FS is not set
# CONFIG_ZISOFS_FS is not set
#
......@@ -332,7 +336,9 @@ CONFIG_SCSI_DEBUG=y
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_PARTITIONS is not set
# CONFIG_MTD_CONCAT is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
#
# User Modules And Translation Layers
......@@ -362,6 +368,8 @@ CONFIG_MTD_BLOCK=y
# Mapping drivers for chip access
#
# CONFIG_MTD_PHYSMAP is not set
# CONFIG_MTD_PCI is not set
# CONFIG_MTD_PCMCIA is not set
#
# Self-contained MTD device drivers
......
......@@ -47,7 +47,7 @@ obj-$(CONFIG_NULL_CHAN) += null.o
obj-$(CONFIG_PORT_CHAN) += port.o
obj-$(CONFIG_PTY_CHAN) += pty.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
CFLAGS_pcap_user.o = -I/usr/include/pcap
......
......@@ -111,6 +111,8 @@ void mconsole_version(struct mc_request *req)
remove <dev> - Remove a device from UML
sysrq <letter> - Performs the SysRq action controlled by the letter
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)
......
......@@ -20,6 +20,7 @@
struct port_list {
struct list_head list;
int has_connection;
struct semaphore sem;
int port;
int fd;
......@@ -62,15 +63,15 @@ static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
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;
int fd, socket[2], pid;
int fd, socket[2], pid, ret = 0;
fd = port_connection(port->fd, socket, &pid);
if(fd < 0){
printk("port_connection returned %d\n", -fd);
if(fd != -EAGAIN)
printk("port_connection returned %d\n", -fd);
goto out;
}
......@@ -94,6 +95,7 @@ static void port_interrupt(int irq, void *data, struct pt_regs *regs)
}
list_add(&conn->list, &port->pending);
ret = 1;
goto out;
out_free:
......@@ -102,17 +104,45 @@ static void port_interrupt(int irq, void *data, struct pt_regs *regs)
os_close_file(fd);
if(pid != -1) os_kill_process(pid);
out:
reactivate_fd(port->fd, ACCEPT_IRQ);
return(ret);
}
DECLARE_MUTEX(ports_sem);
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)
{
struct list_head *ele;
struct port_list *port;
struct port_dev *dev;
struct port_dev *dev = NULL;
int fd;
down(&ports_sem);
......@@ -140,13 +170,14 @@ void *port_data(int port_num)
}
*port = ((struct port_list)
{ list : LIST_HEAD_INIT(port->list),
sem : __SEMAPHORE_INITIALIZER(port->sem, 0),
lock : SPIN_LOCK_UNLOCKED,
port : port_num,
fd : fd,
pending : LIST_HEAD_INIT(port->pending),
connections : LIST_HEAD_INIT(port->connections) });
{ list : LIST_HEAD_INIT(port->list),
has_connection : 0,
sem : __SEMAPHORE_INITIALIZER(port->sem, 0),
lock : SPIN_LOCK_UNLOCKED,
port : port_num,
fd : fd,
pending : LIST_HEAD_INIT(port->pending),
connections : LIST_HEAD_INIT(port->connections) });
list_add(&port->list, &ports);
found:
......@@ -159,8 +190,7 @@ void *port_data(int port_num)
*dev = ((struct port_dev) { port : port,
fd : -1,
helper_pid : -1 });
up(&ports_sem);
return(dev);
goto out;
out_free:
kfree(port);
......@@ -168,7 +198,7 @@ void *port_data(int port_num)
os_close_file(fd);
out:
up(&ports_sem);
return(NULL);
return(dev);
}
void port_remove_dev(void *d)
......
......@@ -44,6 +44,7 @@ static struct chan_opts opts = {
xterm_title: "Serial Line #%d",
raw: 1,
tramp_stack : 0,
in_kernel : 1,
};
static struct line_driver driver = {
......
......@@ -75,6 +75,7 @@ static struct chan_opts opts = {
xterm_title: "Virtual Console #%d",
raw: 1,
tramp_stack : 0,
in_kernel : 1,
};
static struct line_driver driver = {
......
......@@ -700,7 +700,8 @@ static int ubd_open(struct inode *inode, struct file *filp)
{
int n = DEVICE_NR(inode->i_rdev);
struct ubd *dev = &ubd_dev[n];
int err;
int err = 0;
if(dev->is_dir == 1)
goto out;
......
......@@ -19,6 +19,7 @@
#include "user_util.h"
#include "user.h"
#include "os.h"
#include "xterm.h"
struct xterm_chan {
int pid;
......@@ -28,6 +29,7 @@ struct xterm_chan {
int raw;
struct termios tt;
unsigned long stack;
int direct_rcv;
};
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,
title : opts->xterm_title,
raw : opts->raw,
stack : opts->tramp_stack } );
stack : opts->tramp_stack,
direct_rcv : !opts->in_kernel } );
return(data);
}
......@@ -84,7 +87,7 @@ int xterm_open(int input, int output, int primary, void *d)
{
struct xterm_chan *data = d;
unsigned long stack;
int pid, fd, new;
int pid, fd, new, err;
char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
"/usr/lib/uml/port-helper", "-uml-socket",
......@@ -105,21 +108,30 @@ int xterm_open(int input, int output, int primary, void *d)
fd = create_unix_socket(file, sizeof(file));
if(fd < 0){
printk("xterm_open : create_unix_socket failed, errno = %d\n",
errno);
return(-errno);
-fd);
return(-fd);
}
sprintf(title, data->title, data->device);
stack = data->stack;
pid = run_helper(NULL, NULL, argv, &stack);
if(pid < 0){
printk("xterm_open : run_helper failed\n");
return(-1);
printk("xterm_open : run_helper failed, errno = %d\n", -pid);
return(pid);
}
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){
printk("xterm_open : os_rcv_fd failed, errno = %d\n", -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 {
char *xterm_title;
int raw;
unsigned long tramp_stack;
int in_kernel;
};
enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
......
......@@ -6,6 +6,7 @@
#ifndef __KERN_UTIL_H__
#define __KERN_UTIL_H__
#include "linux/threads.h"
#include "sysdep/ptrace.h"
extern int ncpus;
......@@ -14,6 +15,7 @@ extern char *gdb_init;
extern int kmalloc_ok;
extern int timer_irq_inited;
extern int jail;
extern struct task_struct *idle_threads[NR_CPUS];
#define ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
#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 };
struct cpu_task {
int pid;
void *task;
void *idle;
};
extern struct cpu_task cpu_tasks[];
......
EXTRA_TARGETS := unmap_fin.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
arch/um/kernel/unmap_fin.o : arch/um/kernel/unmap.o
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
$(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
......
......@@ -209,7 +209,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
out_unlock:
irq_unlock(flags);
out_free:
kfree(new_fd);
out:
return(err);
......
#include "linux/config.h"
#include "linux/module.h"
#include "linux/string.h"
#include "linux/smp_lock.h"
#include "linux/spinlock.h"
#include "asm/current.h"
#include "asm/delay.h"
#include "asm/processor.h"
......@@ -58,3 +61,14 @@ EXPORT_SYMBOL(sys_lseek);
EXPORT_SYMBOL(sys_read);
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
*/
......@@ -9,6 +9,20 @@
#include "kern.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)
{
struct task_struct *p;
......@@ -21,6 +35,9 @@ static void kill_off_processes(void)
}
if(init_task.thread.extern_pid != me)
os_kill_process(init_task.thread.extern_pid);
#ifdef CONFIG_SMP
kill_idlers(me);
#endif
}
void uml_cleanup(void)
......
......@@ -84,13 +84,13 @@ void unblock_signals(void)
#define SIGIO_BIT 0
#define SIGVTALRM_BIT 1
static int disable_mask(sigset_t *mask)
static int enable_mask(sigset_t *mask)
{
int sigs;
sigs = sigismember(mask, SIGIO) ? 1 << SIGIO_BIT : 0;
sigs |= sigismember(mask, SIGVTALRM) ? 1 << SIGVTALRM_BIT : 0;
sigs |= sigismember(mask, SIGALRM) ? 1 << SIGVTALRM_BIT : 0;
sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
return(sigs);
}
......@@ -100,30 +100,28 @@ int get_signals(void)
if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
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;
int ret;
sigemptyset(&mask);
if(!(disable & (1 << SIGIO_BIT)))
if(enable & (1 << SIGIO_BIT))
sigaddset(&mask, SIGIO);
if(!(disable & (1 << SIGVTALRM_BIT))){
if(enable & (1 << SIGVTALRM_BIT)){
sigaddset(&mask, SIGVTALRM);
sigaddset(&mask, SIGALRM);
}
if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
panic("Failed to enable signals");
ret = disable_mask(&mask);
ret = enable_mask(&mask);
sigemptyset(&mask);
if(disable & (1 << SIGIO_BIT))
if((enable & (1 << SIGIO_BIT)) == 0)
sigaddset(&mask, SIGIO);
if(disable & (1 << SIGVTALRM_BIT)){
if((enable & (1 << SIGVTALRM_BIT)) == 0){
sigaddset(&mask, SIGVTALRM);
sigaddset(&mask, SIGALRM);
}
......
......@@ -47,6 +47,9 @@ int num_reschedules_sent = 0;
/* Small, random number, never changed */
unsigned long cache_decay_ticks = 5;
/* Not changed after boot */
struct task_struct *idle_threads[NR_CPUS];
void smp_send_reschedule(int cpu)
{
write(cpu_data[cpu].ipi_pipe[1], "R", 1);
......@@ -142,6 +145,7 @@ static struct task_struct *idle_thread(int cpu)
cpu_tasks[cpu] = ((struct cpu_task)
{ .pid = new_task->thread.extern_pid,
.task = new_task } );
idle_threads[cpu] = new_task;
write(new_task->thread.switch_pipe[1], &c, sizeof(c));
return(new_task);
}
......
......@@ -229,6 +229,7 @@ extern syscall_handler_t sys_io_getevents;
extern syscall_handler_t sys_io_submit;
extern syscall_handler_t sys_io_cancel;
extern syscall_handler_t sys_exit_group;
extern syscall_handler_t sys_lookup_dcookie;
#if CONFIG_NFSD
#define NFSSERVCTL sys_nfsserctl
......@@ -240,7 +241,7 @@ extern syscall_handler_t um_mount;
extern syscall_handler_t um_time;
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
#define LAST_SYSCALL LAST_GENERIC_SYSCALL
......@@ -479,6 +480,7 @@ syscall_handler_t *sys_call_table[] = {
[ __NR_alloc_hugepages ] = sys_ni_syscall,
[ __NR_free_hugepages ] = sys_ni_syscall,
[ __NR_exit_group ] = sys_exit_group,
[ __NR_lookup_dcookie ] = sys_lookup_dcookie,
ARCH_SYSCALLS
[ LAST_SYSCALL + 1 ... NR_syscalls ] =
......
......@@ -211,6 +211,7 @@ static struct chan_opts opts = {
xterm_title : "UML kernel debugger",
raw : 0,
tramp_stack : 0,
in_kernel : 0,
};
/* Accessed by the tracing thread, which automatically serializes access */
......
......@@ -23,8 +23,9 @@ struct task_struct;
#define WINCH_IRQ 10
#define SIGIO_WRITE_IRQ 11
#define TELNETD_IRQ 12
#define XTERM_IRQ 13
#define LAST_IRQ TELNETD_IRQ
#define LAST_IRQ XTERM_IRQ
#define NR_IRQS (LAST_IRQ + 1)
extern int um_request_irq(unsigned int irq, int fd, int type,
......
......@@ -18,9 +18,9 @@
extern void *switch_to(void *prev, void *next, void *last);
extern int set_signals(int enable);
extern int get_signals(void);
extern void block_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_irq_restore(flags) do { set_signals(flags); } while(0)
......@@ -31,11 +31,11 @@ extern int get_signals(void);
#define local_irq_enable() unblock_signals()
#define local_irq_disable() block_signals()
#define irqs_disabled() \
({ \
unsigned long flags; \
local_save_flags(flags); \
(flags != 0); \
#define irqs_disabled() \
({ \
unsigned long flags; \
local_save_flags(flags); \
(flags == 0); \
})
#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