summaryrefslogtreecommitdiff
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig2
-rw-r--r--arch/um/Kconfig.char19
-rw-r--r--arch/um/drivers/chan_kern.c12
-rw-r--r--arch/um/drivers/daemon_kern.c2
-rw-r--r--arch/um/drivers/daemon_user.c17
-rw-r--r--arch/um/drivers/line.c6
-rw-r--r--arch/um/drivers/mcast_kern.c2
-rw-r--r--arch/um/drivers/mcast_user.c10
-rw-r--r--arch/um/drivers/mconsole_kern.c3
-rw-r--r--arch/um/drivers/net_kern.c2
-rw-r--r--arch/um/drivers/pcap_kern.c2
-rw-r--r--arch/um/drivers/slip_kern.c2
-rw-r--r--arch/um/drivers/slirp_kern.c2
-rw-r--r--arch/um/drivers/ssl.c2
-rw-r--r--arch/um/drivers/stdio_console.c2
-rw-r--r--arch/um/drivers/ubd_kern.c13
-rw-r--r--arch/um/include/mconsole.h2
-rw-r--r--arch/um/include/os.h3
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h4
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/mem.c3
-rw-r--r--arch/um/kernel/signal.c6
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c2
-rw-r--r--arch/um/os-Linux/elf_aux.c3
-rw-r--r--arch/um/os-Linux/process.c3
-rw-r--r--arch/um/os-Linux/sigio.c5
-rw-r--r--arch/um/os-Linux/signal.c5
-rw-r--r--arch/um/os-Linux/skas/mem.c10
-rw-r--r--arch/um/os-Linux/skas/process.c11
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c5
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c4
-rw-r--r--arch/um/os-Linux/trap.c1
-rw-r--r--arch/um/scripts/Makefile.rules4
-rw-r--r--arch/um/sys-i386/delay.c11
-rw-r--r--arch/um/sys-i386/ldt.c35
-rw-r--r--arch/um/sys-x86_64/delay.c11
-rw-r--r--arch/um/sys-x86_64/syscalls.c6
38 files changed, 136 insertions, 99 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index b3a21ba77cd2..354cc6b70530 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -44,7 +44,7 @@ config LOCKDEP_SUPPORT
config STACKTRACE_SUPPORT
bool
- default y
+ default n
config GENERIC_CALIBRATE_DELAY
bool
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index e03e40c7aac3..a5b079d5e865 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -146,6 +146,25 @@ config LEGACY_PTYS
security. This option enables these legacy devices; on most
systems, it is safe to say N.
+config RAW_DRIVER
+ tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
+ help
+ The raw driver permits block devices to be bound to /dev/raw/rawN.
+ Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
+ See the raw(8) manpage for more details.
+
+ The raw driver is deprecated and will be removed soon.
+ Applications should simply open the device (eg /dev/hda1)
+ with the O_DIRECT flag.
+
+config MAX_RAW_DEVS
+ int "Maximum number of RAW devices to support (1-8192)"
+ depends on RAW_DRIVER
+ default "256"
+ help
+ The maximum number of RAW devices that are supported.
+ Default is 256. Increase this number in case you need lots of
+ raw devices.
config LEGACY_PTY_COUNT
int "Maximum number of legacy PTY in use"
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 7b8baf146acc..9fdfad649536 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -236,11 +236,11 @@ void free_irqs(void)
struct chan *chan;
LIST_HEAD(list);
struct list_head *ele;
+ unsigned long flags;
- spin_lock_irq(&irqs_to_free_lock);
+ spin_lock_irqsave(&irqs_to_free_lock, flags);
list_splice_init(&irqs_to_free, &list);
- INIT_LIST_HEAD(&irqs_to_free);
- spin_unlock_irq(&irqs_to_free_lock);
+ spin_unlock_irqrestore(&irqs_to_free_lock, flags);
list_for_each(ele, &list){
chan = list_entry(ele, struct chan, free_list);
@@ -255,13 +255,15 @@ void free_irqs(void)
static void close_one_chan(struct chan *chan, int delay_free_irq)
{
+ unsigned long flags;
+
if(!chan->opened)
return;
if(delay_free_irq){
- spin_lock_irq(&irqs_to_free_lock);
+ spin_lock_irqsave(&irqs_to_free_lock, flags);
list_add(&chan->free_list, &irqs_to_free);
- spin_unlock_irq(&irqs_to_free_lock);
+ spin_unlock_irqrestore(&irqs_to_free_lock, flags);
}
else {
if(chan->input)
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index 9c2e7a758f21..adeece11e596 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -46,7 +46,7 @@ static int daemon_read(int fd, struct sk_buff **skb,
{
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
if(*skb == NULL) return(-ENOMEM);
- return(net_recvfrom(fd, (*skb)->mac.raw,
+ return(net_recvfrom(fd, skb_mac_header(*skb),
(*skb)->dev->mtu + ETH_HEADER_OTHER));
}
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 310af0f1e49e..021b82c7a759 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -56,30 +56,31 @@ static int connect_to_switch(struct daemon_data *pri)
pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
if(pri->control < 0){
+ err = -errno;
printk("daemon_open : control socket failed, errno = %d\n",
- errno);
- return(-errno);
+ -err);
+ return err;
}
if(connect(pri->control, (struct sockaddr *) ctl_addr,
sizeof(*ctl_addr)) < 0){
- printk("daemon_open : control connect failed, errno = %d\n",
- errno);
err = -errno;
+ printk("daemon_open : control connect failed, errno = %d\n",
+ -err);
goto out;
}
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if(fd < 0){
- printk("daemon_open : data socket failed, errno = %d\n",
- errno);
err = -errno;
+ printk("daemon_open : data socket failed, errno = %d\n",
+ -err);
goto out;
}
if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
- printk("daemon_open : data bind failed, errno = %d\n",
- errno);
err = -errno;
+ printk("daemon_open : data bind failed, errno = %d\n",
+ -err);
goto out_close;
}
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 01d4ab6b0ef1..f75d7b05c481 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -370,10 +370,10 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
struct tty_struct *tty = line->tty;
int err;
- /* Interrupts are enabled here because we registered the interrupt with
+ /* Interrupts are disabled here because we registered the interrupt with
* IRQF_DISABLED (see line_setup_irq).*/
- spin_lock_irq(&line->lock);
+ spin_lock(&line->lock);
err = flush_buffer(line);
if (err == 0) {
return IRQ_NONE;
@@ -381,7 +381,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
line->head = line->buffer;
line->tail = line->buffer;
}
- spin_unlock_irq(&line->lock);
+ spin_unlock(&line->lock);
if(tty == NULL)
return IRQ_NONE;
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index 52ccb7b53cd2..e6b8e0dd72a8 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -50,7 +50,7 @@ static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
{
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
if(*skb == NULL) return(-ENOMEM);
- return(net_recvfrom(fd, (*skb)->mac.raw,
+ return(net_recvfrom(fd, skb_mac_header(*skb),
(*skb)->dev->mtu + ETH_HEADER_OTHER));
}
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 8138f5ea1bf7..b827e82884c9 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -50,6 +50,14 @@ static void mcast_user_init(void *data, void *dev)
pri->dev = dev;
}
+static void mcast_remove(void *data)
+{
+ struct mcast_data *pri = data;
+
+ kfree(pri->mcast_addr);
+ pri->mcast_addr = NULL;
+}
+
static int mcast_open(void *data)
{
struct mcast_data *pri = data;
@@ -157,7 +165,7 @@ const struct net_user_info mcast_user_info = {
.init = mcast_user_init,
.open = mcast_open,
.close = mcast_close,
- .remove = NULL,
+ .remove = mcast_remove,
.set_mtu = mcast_set_mtu,
.add_address = NULL,
.delete_address = NULL,
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 178b2eff4a8c..65ad2932672c 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -615,6 +615,9 @@ void mconsole_remove(struct mc_request *req)
err_msg = NULL;
err = (*dev->remove)(n, &err_msg);
switch(err){
+ case 0:
+ err_msg = "";
+ break;
case -ENODEV:
if(err_msg == NULL)
err_msg = "Device doesn't exist";
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 04e31f86c10a..859303730b2f 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -55,7 +55,7 @@ static int uml_net_rx(struct net_device *dev)
skb->dev = dev;
skb_put(skb, dev->mtu);
- skb->mac.raw = skb->data;
+ skb_reset_mac_header(skb);
pkt_len = (*lp->read)(lp->fd, &skb, lp);
if (pkt_len > 0) {
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index e67362acf0e7..948849343ca4 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -36,7 +36,7 @@ static int pcap_read(int fd, struct sk_buff **skb,
{
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
if(*skb == NULL) return(-ENOMEM);
- return(pcap_user_read(fd, (*skb)->mac.raw,
+ return(pcap_user_read(fd, skb_mac_header(*skb),
(*skb)->dev->mtu + ETH_HEADER_OTHER,
(struct pcap_data *) &lp->user));
}
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 25634bd1f585..125c44f77638 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -49,7 +49,7 @@ static unsigned short slip_protocol(struct sk_buff *skbuff)
static int slip_read(int fd, struct sk_buff **skb,
struct uml_net_private *lp)
{
- return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
+ return(slip_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu,
(struct slip_data *) &lp->user));
}
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index b3ed8fb874ab..0a0324a6d290 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -53,7 +53,7 @@ static unsigned short slirp_protocol(struct sk_buff *skbuff)
static int slirp_read(int fd, struct sk_buff **skb,
struct uml_net_private *lp)
{
- return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu,
+ return(slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu,
(struct slirp_data *) &lp->user));
}
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index fc22b9bd9153..4b382a6e710f 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -179,7 +179,7 @@ static struct console ssl_cons = {
.write = ssl_console_write,
.device = ssl_console_device,
.setup = ssl_console_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER|CON_ANYTIME,
.index = -1,
};
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 7ff0b0fc37e7..76d1f1c980ef 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -153,7 +153,7 @@ static struct console stdiocons = {
.write = uml_console_write,
.device = uml_console_device,
.setup = uml_console_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER|CON_ANYTIME,
.index = -1,
};
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index f98d26e51381..8bd9204ac1ab 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -109,10 +109,6 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
static DEFINE_MUTEX(ubd_lock);
-/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and
- * probably it doesn't make sense even for that. */
-static int do_ubd;
-
static int ubd_open(struct inode * inode, struct file * filp);
static int ubd_release(struct inode * inode, struct file * file);
static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -169,6 +165,7 @@ struct ubd {
struct platform_device pdev;
struct request_queue *queue;
spinlock_t lock;
+ int active;
};
#define DEFAULT_COW { \
@@ -190,6 +187,7 @@ struct ubd {
.shared = 0, \
.cow = DEFAULT_COW, \
.lock = SPIN_LOCK_UNLOCKED, \
+ .active = 0, \
}
/* Protected by ubd_lock */
@@ -507,7 +505,6 @@ static void ubd_handler(void)
struct ubd *dev;
int n;
- do_ubd = 0;
n = os_read_file(thread_fd, &req, sizeof(req));
if(n != sizeof(req)){
printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
@@ -517,6 +514,7 @@ static void ubd_handler(void)
rq = req.req;
dev = rq->rq_disk->private_data;
+ dev->active = 0;
ubd_finish(rq, req.error);
reactivate_fd(thread_fd, UBD_IRQ);
@@ -1081,11 +1079,12 @@ static void do_ubd_request(request_queue_t *q)
}
}
else {
- if(do_ubd || (req = elv_next_request(q)) == NULL)
+ struct ubd *dev = q->queuedata;
+ if(dev->active || (req = elv_next_request(q)) == NULL)
return;
err = prepare_request(req, &io_req);
if(!err){
- do_ubd = 1;
+ dev->active = 1;
n = os_write_file(thread_fd, (char *) &io_req,
sizeof(io_req));
if(n != sizeof(io_req))
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 2666815b6af5..b282839c1625 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -12,6 +12,8 @@
#define u32 uint32_t
#endif
+#include "sysdep/ptrace.h"
+
#define MCONSOLE_MAGIC (0xcafebabe)
#define MCONSOLE_MAX_DATA (512)
#define MCONSOLE_VERSION 2
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 8629bd191492..5c74da410451 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -192,7 +192,9 @@ extern int os_process_parent(int pid);
extern void os_stop_process(int pid);
extern void os_kill_process(int pid, int reap_child);
extern void os_kill_ptraced_process(int pid, int reap_child);
+#ifdef UML_CONFIG_MODE_TT
extern void os_usr1_process(int pid);
+#endif
extern long os_ptrace_ldt(long pid, long addr, long data);
extern int os_getpid(void);
@@ -261,7 +263,6 @@ extern void block_signals(void);
extern void unblock_signals(void);
extern int get_signals(void);
extern int set_signals(int enable);
-extern void os_usr1_signal(int on);
/* trap.c */
extern void os_fill_handlinfo(struct kern_handlers h);
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 66cb400c2c92..62403bd99661 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -104,10 +104,6 @@ union uml_pt_regs {
#endif
#ifdef UML_CONFIG_MODE_SKAS
struct skas_regs {
- /* x86_64 ptrace uses sizeof(user_regs_struct) as its register
- * file size, while i386 uses FRAME_SIZE. Therefore, we need
- * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE.
- */
unsigned long regs[MAX_REG_NR];
unsigned long fp[HOST_FP_SIZE];
struct faultinfo faultinfo;
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 50a288bb875a..dbf2f5bc842f 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -142,6 +142,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
.events = events,
.current_events = 0 } );
+ err = -EBUSY;
spin_lock_irqsave(&irq_lock, flags);
for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index e85d65deea0d..df7d662b98ce 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -64,8 +64,6 @@ static void setup_highmem(unsigned long highmem_start,
void mem_init(void)
{
- max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT;
-
/* clear the zero-page */
memset((void *) empty_zero_page, 0, PAGE_SIZE);
@@ -80,6 +78,7 @@ void mem_init(void)
/* this will put all low memory onto the freelists */
totalram_pages = free_all_bootmem();
+ max_low_pfn = totalram_pages;
#ifdef CONFIG_HIGHMEM
totalhigh_pages = highmem >> PAGE_SHIFT;
totalram_pages += totalhigh_pages;
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index 2a32e5e8e9c9..3c798cdde550 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -158,12 +158,12 @@ static int kern_do_signal(struct pt_regs *regs)
clear_thread_flag(TIF_RESTORE_SIGMASK);
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
}
- return(handled_sig);
+ return handled_sig;
}
int do_signal(void)
{
- return(kern_do_signal(&current->thread.regs));
+ return kern_do_signal(&current->thread.regs);
}
/*
@@ -186,5 +186,5 @@ long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
{
- return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
+ return do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs));
}
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 70541821775f..12689141414d 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -43,7 +43,7 @@ static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
*skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
if(*skb == NULL) return(-ENOMEM);
- len = net_recvfrom(fd, (*skb)->mac.raw,
+ len = net_recvfrom(fd, skb_mac_header(*skb),
(*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
if(len <= 0) return(len);
skb_pull(*skb, 2);
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index 76570a2c25c3..f1714e7fb1d0 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -43,7 +43,7 @@ static int tuntap_read(int fd, struct sk_buff **skb,
{
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
if(*skb == NULL) return(-ENOMEM);
- return(net_read(fd, (*skb)->mac.raw,
+ return(net_read(fd, skb_mac_header(*skb),
(*skb)->dev->mtu + ETH_HEADER_OTHER));
}
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 3a8d7e3aae0a..608784d4ec57 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -39,6 +39,9 @@ __init void scan_elf_aux( char **envp)
switch ( auxv->a_type ) {
case AT_SYSINFO:
__kernel_vsyscall = auxv->a_un.a_val;
+ /* See if the page is under TASK_SIZE */
+ if (__kernel_vsyscall < (unsigned long) envp)
+ __kernel_vsyscall = 0;
break;
case AT_SYSINFO_EHDR:
vsyscall_ehdr = auxv->a_un.a_val;
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index c692a192957a..76bdd6712417 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -21,6 +21,7 @@
#include "longjmp.h"
#include "skas_ptrace.h"
#include "kern_constants.h"
+#include "uml-config.h"
#define ARBITRARY_ADDR -1
#define FAILURE_PID -1
@@ -131,10 +132,12 @@ void os_kill_ptraced_process(int pid, int reap_child)
CATCH_EINTR(waitpid(pid, NULL, 0));
}
+#ifdef UML_CONFIG_MODE_TT
void os_usr1_process(int pid)
{
kill(pid, SIGUSR1);
}
+#endif
/* Don't use the glibc version, which caches the result in TLS. It misses some
* syscalls, and also breaks with clone(), which does not unshare the TLS.
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index b2e1fd8e3571..3fc43b33db66 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -334,8 +334,11 @@ void maybe_sigio_broken(int fd, int read)
sigio_lock();
err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
- if(err)
+ if(err){
+ printk("maybe_sigio_broken - failed to add pollfd for "
+ "descriptor %d\n", fd);
goto out;
+ }
all_sigio_fds.poll[all_sigio_fds.used++] =
((struct pollfd) { .fd = fd,
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index b897e8592d77..266768629fee 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -243,8 +243,3 @@ int set_signals(int enable)
return ret;
}
-
-void os_usr1_signal(int on)
-{
- change_sig(SIGUSR1, on);
-}
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index b3c11cfa995a..9383e8751ae7 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -48,7 +48,7 @@ int multi_op_count = 0;
static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
{
unsigned long regs[MAX_REG_NR];
- int n;
+ int n, i;
long ret, offset;
unsigned long * data;
unsigned long * syscall;
@@ -66,9 +66,13 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
(unsigned long) &__syscall_stub_start);
n = ptrace_setregs(pid, regs);
- if(n < 0)
+ if(n < 0){
+ printk("Registers - \n");
+ for(i = 0; i < MAX_REG_NR; i++)
+ printk("\t%d\t0x%lx\n", i, regs[i]);
panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
- n);
+ -n);
+ }
wait_stub_done(pid, 0, "do_syscall_stub");
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 9b34fe65949a..0564422c155f 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -67,7 +67,7 @@ void wait_stub_done(int pid, int sig, char * fname)
if((n < 0) || !WIFSTOPPED(status) ||
(WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
- unsigned long regs[HOST_FRAME_SIZE];
+ unsigned long regs[MAX_REG_NR];
if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
printk("Failed to get registers from stub, "
@@ -76,7 +76,7 @@ void wait_stub_done(int pid, int sig, char * fname)
int i;
printk("Stub registers -\n");
- for(i = 0; i < HOST_FRAME_SIZE; i++)
+ for(i = 0; i < ARRAY_SIZE(regs); i++)
printk("\t%d - %lx\n", i, regs[i]);
}
panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
@@ -328,7 +328,7 @@ void userspace(union uml_pt_regs *regs)
int copy_context_skas0(unsigned long new_stack, int pid)
{
int err;
- unsigned long regs[HOST_FRAME_SIZE];
+ unsigned long regs[MAX_REG_NR];
unsigned long fp_regs[HOST_FP_SIZE];
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
@@ -419,9 +419,12 @@ void map_stub_pages(int fd, unsigned long code,
.offset = code_offset
} } });
n = os_write_file(fd, &mmop, sizeof(mmop));
- if(n != sizeof(mmop))
+ if(n != sizeof(mmop)){
+ printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n",
+ code, code_fd, (unsigned long long) code_offset);
panic("map_stub_pages : /proc/mm map for code failed, "
"err = %d\n", -n);
+ }
if ( stack ) {
__u64 map_offset;
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 79cd93c8c5ed..84b44f9cd42a 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -15,7 +15,7 @@
/* These are set once at boot time and not changed thereafter */
-static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_regs[MAX_REG_NR];
static unsigned long exec_fp_regs[HOST_FP_SIZE];
static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
static int have_fpx_regs = 1;
@@ -101,6 +101,7 @@ void init_registers(int pid)
{
int err;
+ memset(exec_regs, 0, sizeof(exec_regs));
err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
if(err)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
@@ -124,7 +125,7 @@ void init_registers(int pid)
void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
- memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+ memcpy(regs, exec_regs, sizeof(exec_regs));
if(fp_regs != NULL)
memcpy(fp_regs, exec_fp_regs,
HOST_FP_SIZE * sizeof(unsigned long));
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index a2d7e0c603f7..e6fc2179d1bc 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -14,7 +14,7 @@
/* These are set once at boot time and not changed thereafter */
-static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_regs[MAX_REG_NR];
static unsigned long exec_fp_regs[HOST_FP_SIZE];
void init_thread_registers(union uml_pt_regs *to)
@@ -72,7 +72,7 @@ void init_registers(int pid)
void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
{
- memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+ memcpy(regs, exec_regs, sizeof(exec_regs));
if(fp_regs != NULL)
memcpy(fp_regs, exec_fp_regs,
HOST_FP_SIZE * sizeof(unsigned long));
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index 1df231a26244..d221214d2ed5 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -16,6 +16,7 @@ void usr2_handler(int sig, union uml_pt_regs *regs)
CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
}
+/* Initialized from linux_main() */
void (*sig_info[NSIG])(int, union uml_pt_regs *);
void os_fill_handlinfo(struct kern_handlers h)
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 813077fb1e5b..a9a4b85ca516 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -10,7 +10,7 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
$(USER_OBJS:.o=.%): \
c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o)
$(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
- -Dunix -D__unix__ -D__$(SUBARCH)__
+ -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
# These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
# using it directly.
@@ -19,7 +19,7 @@ UNPROFILE_OBJS := $(foreach file,$(UNPROFILE_OBJS),$(obj)/$(file))
$(UNPROFILE_OBJS:.o=.%): \
c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(basetarget).o)
$(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
- -Dunix -D__unix__ -D__$(SUBARCH)__
+ -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
# The stubs and unmap.o can't try to call mcount or update basic block data
define unprofile
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
index 2c11b9770e8b..d623e074f41d 100644
--- a/arch/um/sys-i386/delay.c
+++ b/arch/um/sys-i386/delay.c
@@ -27,14 +27,3 @@ void __udelay(unsigned long usecs)
}
EXPORT_SYMBOL(__udelay);
-
-void __const_udelay(unsigned long usecs)
-{
- int i, n;
-
- n = (loops_per_jiffy * HZ * usecs) / MILLION;
- for(i=0;i<n;i++)
- cpu_relax();
-}
-
-EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 5db7737df0ff..a939a7ef0227 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -7,6 +7,7 @@
#include "linux/slab.h"
#include "linux/types.h"
#include "linux/errno.h"
+#include "linux/spinlock.h"
#include "asm/uaccess.h"
#include "asm/smp.h"
#include "asm/ldt.h"
@@ -386,23 +387,34 @@ static long do_modify_ldt_skas(int func, void __user *ptr,
return ret;
}
-short dummy_list[9] = {0, -1};
-short * host_ldt_entries = NULL;
+static DEFINE_SPINLOCK(host_ldt_lock);
+static short dummy_list[9] = {0, -1};
+static short * host_ldt_entries = NULL;
-void ldt_get_host_info(void)
+static void ldt_get_host_info(void)
{
long ret;
struct ldt_entry * ldt;
+ short *tmp;
int i, size, k, order;
+ spin_lock(&host_ldt_lock);
+
+ if(host_ldt_entries != NULL){
+ spin_unlock(&host_ldt_lock);
+ return;
+ }
host_ldt_entries = dummy_list+1;
+ spin_unlock(&host_ldt_lock);
+
for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++);
ldt = (struct ldt_entry *)
__get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
if(ldt == NULL) {
- printk("ldt_get_host_info: couldn't allocate buffer for host ldt\n");
+ printk("ldt_get_host_info: couldn't allocate buffer for host "
+ "ldt\n");
return;
}
@@ -426,11 +438,13 @@ void ldt_get_host_info(void)
host_ldt_entries = dummy_list;
else {
size = (size + 1) * sizeof(dummy_list[0]);
- host_ldt_entries = kmalloc(size, GFP_KERNEL);
- if(host_ldt_entries == NULL) {
- printk("ldt_get_host_info: couldn't allocate host ldt list\n");
+ tmp = kmalloc(size, GFP_KERNEL);
+ if(tmp == NULL) {
+ printk("ldt_get_host_info: couldn't allocate host ldt "
+ "list\n");
goto out_free;
}
+ host_ldt_entries = tmp;
}
for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){
@@ -480,8 +494,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
* inherited from the host. All ldt-entries found
* will be reset in the following loop
*/
- if(host_ldt_entries == NULL)
- ldt_get_host_info();
+ ldt_get_host_info();
for(num_p=host_ldt_entries; *num_p != -1; num_p++){
desc.entry_number = *num_p;
err = write_ldt_entry(&new_mm->id, 1, &desc,
@@ -560,6 +573,6 @@ void free_ldt(struct mmu_context_skas * mm)
int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
{
- return(CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
- ptr, bytecount));
+ return CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
+ ptr, bytecount);
}
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
index 137f4446b439..dee5be66da82 100644
--- a/arch/um/sys-x86_64/delay.c
+++ b/arch/um/sys-x86_64/delay.c
@@ -28,14 +28,3 @@ void __udelay(unsigned long usecs)
}
EXPORT_SYMBOL(__udelay);
-
-void __const_udelay(unsigned long usecs)
-{
- unsigned long i, n;
-
- n = (loops_per_jiffy * HZ * usecs) / MILLION;
- for(i=0;i<n;i++)
- cpu_relax();
-}
-
-EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 01b91f9fa789..b3f6350cac44 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -103,6 +103,9 @@ long arch_prctl_skas(struct task_struct *task, int code,
switch(code){
case ARCH_SET_FS:
+ current->thread.arch.fs = (unsigned long) ptr;
+ save_registers(pid, &current->thread.regs.regs);
+ break;
case ARCH_SET_GS:
save_registers(pid, &current->thread.regs.regs);
break;
@@ -140,9 +143,8 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
{
- if(to->thread.arch.fs == 0)
+ if((to->thread.arch.fs == 0) || (to->mm == NULL))
return;
arch_prctl_skas(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
}
-