Commit b7cde760 authored by Jeff Dike's avatar Jeff Dike

Merge uml.karaya.com:/home/jdike/linux/2.5/linus-2.5

into uml.karaya.com:/home/jdike/linux/2.5/fixes-2.5
parents 5be2bc3c b3dd37c5
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,17 +56,18 @@ ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \ ...@@ -59,17 +56,18 @@ 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 $@
prepare: $(ARCH_SYMLINKS) $(GEN_HEADERS) prepare: $(ARCH_SYMLINKS) $(GEN_HEADERS)
LDFLAGS_vmlinux = -r $(ARCH_DIR)/main.o 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 FORCE $(ARCH_DIR)/uml.lds.s : $(ARCH_DIR)/uml.lds.S scripts FORCE
$(call if_changed_dep,as_s_S) $(call if_changed_dep,as_s_S)
......
...@@ -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,28 +50,32 @@ static void pipe_interrupt(int irq, void *data, struct pt_regs *regs) ...@@ -49,28 +50,32 @@ 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){
printk("port_connection returned %d\n", -fd); if(fd != -EAGAIN)
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);
...@@ -140,13 +174,14 @@ void *port_data(int port_num) ...@@ -140,13 +174,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 +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 = {
......
...@@ -6,12 +6,15 @@ ...@@ -6,12 +6,15 @@
/* 2001-09-28...2002-04-17 /* 2001-09-28...2002-04-17
* Partition stuff by James_McMechan@hotmail.com * Partition stuff by James_McMechan@hotmail.com
* old style ubd by setting UBD_SHIFT to 0 * old style ubd by setting UBD_SHIFT to 0
* 2002-09-27...2002-10-18 massive tinkering for 2.5
* partitions have changed in 2.5
*/ */
#define MAJOR_NR UBD_MAJOR #define MAJOR_NR UBD_MAJOR
#define UBD_SHIFT 4 #define UBD_SHIFT 4
#include "linux/config.h" #include "linux/config.h"
#include "linux/module.h"
#include "linux/blk.h" #include "linux/blk.h"
#include "linux/blkdev.h" #include "linux/blkdev.h"
#include "linux/hdreg.h" #include "linux/hdreg.h"
...@@ -51,15 +54,17 @@ static int ubd_open(struct inode * inode, struct file * filp); ...@@ -51,15 +54,17 @@ static int ubd_open(struct inode * inode, struct file * filp);
static int ubd_release(struct inode * inode, struct file * file); static int ubd_release(struct inode * inode, struct file * file);
static int ubd_ioctl(struct inode * inode, struct file * file, static int ubd_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
static int ubd_revalidate(struct gendisk *disk);
#define MAX_DEV (8) #define MAX_DEV (8)
#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
#define DEVICE_NR(n) (minor(n) >> UBD_SHIFT)
static struct block_device_operations ubd_blops = { static struct block_device_operations ubd_blops = {
.owner = THIS_MODULE,
.open = ubd_open, .open = ubd_open,
.release = ubd_release, .release = ubd_release,
.ioctl = ubd_ioctl, .ioctl = ubd_ioctl,
.revalidate_disk= ubd_revalidate,
}; };
/* Protected by the queue_lock */ /* Protected by the queue_lock */
...@@ -169,8 +174,6 @@ static void make_ide_entries(char *dev_name) ...@@ -169,8 +174,6 @@ static void make_ide_entries(char *dev_name)
struct proc_dir_entry *dir, *ent; struct proc_dir_entry *dir, *ent;
char name[64]; char name[64];
if(!fake_ide) return;
if(proc_ide_root == NULL) make_proc_ide(); if(proc_ide_root == NULL) make_proc_ide();
dir = proc_mkdir(dev_name, proc_ide); dir = proc_mkdir(dev_name, proc_ide);
...@@ -415,88 +418,135 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out) ...@@ -415,88 +418,135 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out)
return(os_file_size(file, size_out)); return(os_file_size(file, size_out));
} }
/* Initialized in an initcall, and unchanged thereafter */ static void ubd_close(struct ubd *dev)
devfs_handle_t ubd_dir_handle; {
devfs_handle_t ubd_fake_dir_handle; os_close_file(dev->fd);
if(dev->cow.file == NULL)
return;
static int ubd_add(int n) os_close_file(dev->cow.fd);
vfree(dev->cow.bitmap);
dev->cow.bitmap = NULL;
}
static int ubd_open_dev(struct ubd *dev)
{ {
devfs_handle_t real, fake; struct openflags flags;
char name[sizeof("nnnnnn\0")]; int err, n, create_cow, *create_ptr;
struct ubd *dev = &ubd_dev[n];
struct gendisk *disk, *fake_disk = NULL;
u64 size;
if (!dev->file) create_cow = 0;
goto out; create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
&dev->cow.bitmap_offset, &dev->cow.bitmap_len,
&dev->cow.data_offset, create_ptr);
disk = alloc_disk(1 << UBD_SHIFT); if((dev->fd == -ENOENT) && create_cow){
if (!disk) n = dev - ubd_dev;
return -1; dev->fd = create_cow_file(dev->file, dev->cow.file,
disk->major = MAJOR_NR; dev->openflags, 1 << 9,
disk->first_minor = n << UBD_SHIFT; &dev->cow.bitmap_offset,
disk->fops = &ubd_blops; &dev->cow.bitmap_len,
if (fakehd_set) &dev->cow.data_offset);
sprintf(disk->disk_name, "hd%c", n + 'a'); if(dev->fd >= 0){
else printk(KERN_INFO "Creating \"%s\" as COW file for "
sprintf(disk->disk_name, "ubd%d", n); "\"%s\"\n", dev->file, dev->cow.file);
if (fake_major) {
fake_disk = alloc_disk(1 << UBD_SHIFT);
if (!fake_disk) {
put_disk(disk);
return -1;
} }
fake_disk->major = fake_major;
fake_disk->first_minor = n << UBD_SHIFT;
fake_disk->fops = &ubd_blops;
sprintf(fake_disk->disk_name, "ubd%d", n);
fake_gendisk[n] = fake_disk;
} }
ubd_gendisk[n] = disk; if(dev->fd < 0) return(dev->fd);
if (!dev->is_dir && ubd_file_size(dev, &size) == 0) { if(dev->cow.file != NULL){
set_capacity(disk, size/512); err = -ENOMEM;
if (fake_major) dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
set_capacity(fake_disk, size/512); if(dev->cow.bitmap == NULL) goto error;
} flush_tlb_kernel_vm();
sprintf(name, "%d", n); err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
real = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE, dev->cow.bitmap_offset,
MAJOR_NR, n << UBD_SHIFT, dev->cow.bitmap_len);
S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP, if(err) goto error;
&ubd_blops, NULL);
if(real == NULL) flags = dev->openflags;
goto out; flags.w = 0;
ubd_dev[n].real = real; err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL,
NULL, NULL);
if (fake_major) { if(err < 0) goto error;
fake = devfs_register(ubd_fake_dir_handle, name, dev->cow.fd = err;
DEVFS_FL_REMOVABLE, fake_major,
n << UBD_SHIFT,
S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |
S_IWGRP, &ubd_blops, NULL);
if(fake == NULL)
goto out_unregister;
ubd_dev[n].fake = fake;
fake_disk->private_data = &ubd_dev[n];
fake_disk->queue = &ubd_queue;
add_disk(fake_disk);
} }
return(0);
disk->private_data = &ubd_dev[n]; error:
os_close_file(dev->fd);
return(err);
}
static int ubd_new_disk(int major, u64 size, char *name, int unit,
struct gendisk **disk_out, devfs_handle_t dir_handle,
devfs_handle_t *handle_out)
{
char devfs_name[sizeof("nnnnnn\0")];
struct gendisk *disk;
int minor = unit << UBD_SHIFT;
disk = alloc_disk(1 << UBD_SHIFT);
if(disk == NULL)
return(-ENOMEM);
disk->major = major;
disk->first_minor = minor;
disk->fops = &ubd_blops;
set_capacity(disk, size / 512);
/* needs to be ubd -> /dev/ubd/discX/disc */
sprintf(disk->disk_name, "ubd");
*disk_out = disk;
/* /dev/ubd/N style names */
sprintf(devfs_name, "%d", unit);
*handle_out = devfs_register(dir_handle, devfs_name,
DEVFS_FL_REMOVABLE, major, minor,
S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |
S_IWGRP, &ubd_blops, NULL);
disk->private_data = &ubd_dev[unit];
disk->queue = &ubd_queue; disk->queue = &ubd_queue;
add_disk(disk); add_disk(disk);
make_ide_entries(disk->disk_name);
return(0); return(0);
}
out_unregister: /* Initialized in an initcall, and unchanged thereafter */
devfs_unregister(real); devfs_handle_t ubd_dir_handle;
ubd_dev[n].real = NULL; devfs_handle_t ubd_fake_dir_handle;
out:
return(-1); static int ubd_add(int n)
{
struct ubd *dev = &ubd_dev[n];
int err;
if (!dev->file || dev->is_dir)
return(-ENODEV);
if (ubd_open_dev(dev))
return(-ENODEV);
err = ubd_file_size(dev, &dev->size);
if(err)
return(err);
err = ubd_new_disk(MAJOR_NR, dev->size, "ubd", n, &ubd_gendisk[n],
ubd_dir_handle, &dev->real);
if(err)
return(err);
if(fake_major)
ubd_new_disk(fake_major, dev->size, "ubd%d", n,
&fake_gendisk[n], ubd_fake_dir_handle,
&dev->fake);
/* perhaps this should also be under the "if (fake_major)" above */
/* using the fake_disk->disk_name and also the fakehd_set name */
if (fake_ide)
make_ide_entries(ubd_gendisk[n]->disk_name);
ubd_close(dev);
return 0;
} }
static int ubd_config(char *str) static int ubd_config(char *str)
...@@ -527,34 +577,39 @@ static int ubd_config(char *str) ...@@ -527,34 +577,39 @@ static int ubd_config(char *str)
static int ubd_remove(char *str) static int ubd_remove(char *str)
{ {
struct ubd *dev; struct ubd *dev;
int n, err; int n, err = -ENODEV;
if(!isdigit(*str))
return(err); /* it should be a number 0-7/a-h */
if(!isdigit(*str))
return(-1);
n = *str - '0'; n = *str - '0';
if(n > MAX_DEV) if(n > MAX_DEV)
return(-1); return(err);
dev = &ubd_dev[n]; dev = &ubd_dev[n];
if(dev->count > 0)
return(-EBUSY); /* you cannot remove a open disk */
err = 0; err = 0;
spin_lock(&ubd_lock); spin_lock(&ubd_lock);
if(ubd_gendisk[n] == NULL)
goto out;
del_gendisk(ubd_gendisk[n]); del_gendisk(ubd_gendisk[n]);
put_disk(ubd_gendisk[n]); put_disk(ubd_gendisk[n]);
ubd_gendisk[n] = NULL; ubd_gendisk[n] = NULL;
if (fake_major) { if(dev->real != NULL)
devfs_unregister(dev->real);
if(fake_gendisk[n] != NULL){
del_gendisk(fake_gendisk[n]); del_gendisk(fake_gendisk[n]);
put_disk(fake_gendisk[n]); put_disk(fake_gendisk[n]);
fake_gendisk[n] = NULL; fake_gendisk[n] = NULL;
if(dev->fake != NULL)
devfs_unregister(dev->fake);
} }
if(dev->file == NULL)
goto out;
err = -1;
if(dev->count > 0)
goto out;
if(dev->real != NULL)
devfs_unregister(dev->real);
if(dev->fake != NULL)
devfs_unregister(dev->fake);
*dev = ((struct ubd) DEFAULT_UBD); *dev = ((struct ubd) DEFAULT_UBD);
err = 0; err = 0;
out: out:
...@@ -563,9 +618,9 @@ static int ubd_remove(char *str) ...@@ -563,9 +618,9 @@ static int ubd_remove(char *str)
} }
static struct mc_device ubd_mc = { static struct mc_device ubd_mc = {
name: "ubd", .name = "ubd",
config: ubd_config, .config = ubd_config,
remove: ubd_remove, .remove = ubd_remove,
}; };
static int ubd_mc_init(void) static int ubd_mc_init(void)
...@@ -585,8 +640,10 @@ int ubd_init(void) ...@@ -585,8 +640,10 @@ int ubd_init(void)
printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR); printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
return -1; return -1;
} }
blk_init_queue(&ubd_queue, do_ubd_request, &ubd_io_lock); blk_init_queue(&ubd_queue, do_ubd_request, &ubd_io_lock);
elevator_init(&ubd_queue, &elevator_noop); elevator_init(&ubd_queue, &elevator_noop);
if(fake_major != 0){ if(fake_major != 0){
char name[sizeof("ubd_nnn\0")]; char name[sizeof("ubd_nnn\0")];
...@@ -631,81 +688,23 @@ int ubd_driver_init(void){ ...@@ -631,81 +688,23 @@ int ubd_driver_init(void){
device_initcall(ubd_driver_init); device_initcall(ubd_driver_init);
static void ubd_close(struct ubd *dev)
{
os_close_file(dev->fd);
if(dev->cow.file != NULL) {
os_close_file(dev->cow.fd);
vfree(dev->cow.bitmap);
dev->cow.bitmap = NULL;
}
}
static int ubd_open_dev(struct ubd *dev)
{
struct openflags flags;
int err, n, create_cow, *create_ptr;
create_cow = 0;
create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
&dev->cow.bitmap_offset, &dev->cow.bitmap_len,
&dev->cow.data_offset, create_ptr);
if((dev->fd == -ENOENT) && create_cow){
n = dev - ubd_dev;
dev->fd = create_cow_file(dev->file, dev->cow.file,
dev->openflags, 1 << 9,
&dev->cow.bitmap_offset,
&dev->cow.bitmap_len,
&dev->cow.data_offset);
if(dev->fd >= 0){
printk(KERN_INFO "Creating \"%s\" as COW file for "
"\"%s\"\n", dev->file, dev->cow.file);
}
}
if(dev->fd < 0) return(dev->fd);
if(dev->cow.file != NULL){
err = -ENOMEM;
dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
if(dev->cow.bitmap == NULL) goto error;
flush_tlb_kernel_vm();
err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
dev->cow.bitmap_offset,
dev->cow.bitmap_len);
if(err) goto error;
flags = dev->openflags;
flags.w = 0;
err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL,
NULL, NULL);
if(err < 0) goto error;
dev->cow.fd = err;
}
return(0);
error:
os_close_file(dev->fd);
return(err);
}
static int ubd_open(struct inode *inode, struct file *filp) static int ubd_open(struct inode *inode, struct file *filp)
{ {
struct gendisk *disk = inode->i_bdev->bd_disk; struct gendisk *disk = inode->i_bdev->bd_disk;
struct ubd *dev = disk->private_data; struct ubd *dev = disk->private_data;
int err; int err = -EISDIR;
if(dev->is_dir == 1) if(dev->is_dir == 1)
goto out; goto out;
err = 0;
if(dev->count == 0){ if(dev->count == 0){
dev->openflags = dev->boot_openflags; dev->openflags = dev->boot_openflags;
err = ubd_open_dev(dev); err = ubd_open_dev(dev);
if(err){ if(err){
printk(KERN_ERR "%s: Can't open \"%s\": " printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
"errno = %d\n", disk->disk_name, dev->file, -err); disk->disk_name, dev->file, -err);
goto out; goto out;
} }
} }
...@@ -722,7 +721,8 @@ static int ubd_release(struct inode * inode, struct file * file) ...@@ -722,7 +721,8 @@ static int ubd_release(struct inode * inode, struct file * file)
{ {
struct gendisk *disk = inode->i_bdev->bd_disk; struct gendisk *disk = inode->i_bdev->bd_disk;
struct ubd *dev = disk->private_data; struct ubd *dev = disk->private_data;
if(dev->count == 0)
if(--dev->count == 0)
ubd_close(dev); ubd_close(dev);
return(0); return(0);
} }
...@@ -772,7 +772,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) ...@@ -772,7 +772,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
__u64 block; __u64 block;
int nsect; int nsect;
if (req->rq_status == RQ_INACTIVE) return(1); if(req->rq_status == RQ_INACTIVE) return(1);
if(dev->is_dir){ if(dev->is_dir){
strcpy(req->buffer, "HOSTFS:"); strcpy(req->buffer, "HOSTFS:");
...@@ -784,7 +784,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) ...@@ -784,7 +784,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
} }
if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
printk("Write attempted on readonly ubd device %s\n", disk->disk_name); printk("Write attempted on readonly ubd device %s\n",
disk->disk_name);
spin_lock(&ubd_io_lock); spin_lock(&ubd_io_lock);
end_request(req, 0); end_request(req, 0);
spin_unlock(&ubd_io_lock); spin_unlock(&ubd_io_lock);
...@@ -848,7 +849,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file, ...@@ -848,7 +849,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
struct hd_geometry *loc = (struct hd_geometry *) arg; struct hd_geometry *loc = (struct hd_geometry *) arg;
struct ubd *dev = inode->i_bdev->bd_disk->private_data; struct ubd *dev = inode->i_bdev->bd_disk->private_data;
int err; int err;
struct ubd *dev;
struct hd_driveid ubd_id = { struct hd_driveid ubd_id = {
.cyls = 0, .cyls = 0,
.heads = 128, .heads = 128,
...@@ -868,7 +868,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file, ...@@ -868,7 +868,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
case HDIO_SET_UNMASKINTR: case HDIO_SET_UNMASKINTR:
if(!capable(CAP_SYS_ADMIN)) return(-EACCES); if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
if((arg > 1) || inode->i_bdev->bd_contains != inode->i_bdev) if((arg > 1) || (inode->i_bdev->bd_contains != inode->i_bdev))
return(-EINVAL); return(-EINVAL);
return(0); return(0);
...@@ -888,7 +888,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file, ...@@ -888,7 +888,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
case HDIO_SET_MULTCOUNT: case HDIO_SET_MULTCOUNT:
if(!capable(CAP_SYS_ADMIN)) return(-EACCES); if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
if (inode->i_bdev->bd_contains != inode->i_bdev) if(inode->i_bdev->bd_contains != inode->i_bdev)
return(-EINVAL); return(-EINVAL);
return(0); return(0);
...@@ -913,27 +913,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file, ...@@ -913,27 +913,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
return(-EINVAL); return(-EINVAL);
} }
static int ubd_revalidate(struct gendisk *disk)
{
__u64 size;
int err;
struct ubd *dev = disk->private_data;
err = 0;
spin_lock(&ubd_lock);
if(dev->is_dir)
goto out;
err = ubd_file_size(dev, &size);
if (!err) {
set_capacity(disk, size / 512);
dev->size = size;
}
out:
spin_unlock(&ubd_lock);
return err;
}
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
...@@ -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 "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,10 @@ extern syscall_handler_t sys_io_getevents; ...@@ -229,6 +229,10 @@ 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;
extern syscall_handler_t sys_epoll_create;
extern syscall_handler_t sys_epoll_ctl;
extern syscall_handler_t sys_epoll_wait;
#if CONFIG_NFSD #if CONFIG_NFSD
#define NFSSERVCTL sys_nfsserctl #define NFSSERVCTL sys_nfsserctl
...@@ -240,7 +244,7 @@ extern syscall_handler_t um_mount; ...@@ -240,7 +244,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_sys_epoll_wait
#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 +483,10 @@ syscall_handler_t *sys_call_table[] = { ...@@ -479,6 +483,10 @@ 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,
[ __NR_sys_epoll_create ] = sys_epoll_create,
[ __NR_sys_epoll_ctl ] = sys_epoll_ctl,
[ __NR_sys_epoll_wait ] = sys_epoll_wait,
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 */
......
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
obj-y = file.o process.o tty.o obj-y = file.o process.o tty.o
USER_OBJS := $(foreach file,$(obj-y),arch/um/os-Linux/$(file))
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
$(obj-y) : %.o: %.c $(USER_OBJS) : %.o: %.c
$(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
clean : clean :
......
...@@ -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)
...@@ -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