aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2013-05-02 11:37:49 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2013-05-02 11:54:19 -0400
commitc032862fba51a3ca504752d3a25186b324c5ce83 (patch)
tree955dc2ba4ab3df76ecc2bb780ee84aca04967e8d /arch/um
parentfda76e074c7737fc57855dd17c762e50ed526052 (diff)
parent8700c95adb033843fc163d112b9d21d4fda78018 (diff)
Merge commit '8700c95adb03' into timers/nohz
The full dynticks tree needs the latest RCU and sched upstream updates in order to fix some dependencies. Merge a common upstream merge point that has these updates. Conflicts: include/linux/perf_event.h kernel/rcutree.h kernel/rcutree_plugin.h Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/drivers/chan.h2
-rw-r--r--arch/um/drivers/chan_kern.c10
-rw-r--r--arch/um/drivers/chan_user.c12
-rw-r--r--arch/um/drivers/chan_user.h6
-rw-r--r--arch/um/drivers/line.c50
-rw-r--r--arch/um/drivers/net_kern.c2
-rw-r--r--arch/um/drivers/ssl.c1
-rw-r--r--arch/um/drivers/stdio_console.c1
-rw-r--r--arch/um/kernel/early_printk.c8
-rw-r--r--arch/um/kernel/mem.c26
-rw-r--r--arch/um/kernel/process.c27
-rw-r--r--arch/um/os-Linux/signal.c2
-rw-r--r--arch/um/os-Linux/start_up.c2
13 files changed, 56 insertions, 93 deletions
diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h
index 78f1b8999964..c512b0306dd4 100644
--- a/arch/um/drivers/chan.h
+++ b/arch/um/drivers/chan.h
@@ -37,7 +37,7 @@ extern int console_write_chan(struct chan *chan, const char *buf,
37extern int console_open_chan(struct line *line, struct console *co); 37extern int console_open_chan(struct line *line, struct console *co);
38extern void deactivate_chan(struct chan *chan, int irq); 38extern void deactivate_chan(struct chan *chan, int irq);
39extern void reactivate_chan(struct chan *chan, int irq); 39extern void reactivate_chan(struct chan *chan, int irq);
40extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty); 40extern void chan_enable_winch(struct chan *chan, struct tty_port *port);
41extern int enable_chan(struct line *line); 41extern int enable_chan(struct line *line);
42extern void close_chan(struct line *line); 42extern void close_chan(struct line *line);
43extern int chan_window_size(struct line *line, 43extern int chan_window_size(struct line *line,
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 15c553c239a1..acbe6c67afba 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -122,10 +122,10 @@ static int open_chan(struct list_head *chans)
122 return err; 122 return err;
123} 123}
124 124
125void chan_enable_winch(struct chan *chan, struct tty_struct *tty) 125void chan_enable_winch(struct chan *chan, struct tty_port *port)
126{ 126{
127 if (chan && chan->primary && chan->ops->winch) 127 if (chan && chan->primary && chan->ops->winch)
128 register_winch(chan->fd, tty); 128 register_winch(chan->fd, port);
129} 129}
130 130
131static void line_timer_cb(struct work_struct *work) 131static void line_timer_cb(struct work_struct *work)
@@ -568,11 +568,7 @@ void chan_interrupt(struct line *line, int irq)
568 reactivate_fd(chan->fd, irq); 568 reactivate_fd(chan->fd, irq);
569 if (err == -EIO) { 569 if (err == -EIO) {
570 if (chan->primary) { 570 if (chan->primary) {
571 struct tty_struct *tty = tty_port_tty_get(&line->port); 571 tty_port_tty_hangup(&line->port, false);
572 if (tty != NULL) {
573 tty_hangup(tty);
574 tty_kref_put(tty);
575 }
576 if (line->chan_out != chan) 572 if (line->chan_out != chan)
577 close_one_chan(line->chan_out, 1); 573 close_one_chan(line->chan_out, 1);
578 } 574 }
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 9be670ad23b5..3fd7c3efdb18 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -216,7 +216,7 @@ static int winch_thread(void *arg)
216 } 216 }
217} 217}
218 218
219static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out, 219static int winch_tramp(int fd, struct tty_port *port, int *fd_out,
220 unsigned long *stack_out) 220 unsigned long *stack_out)
221{ 221{
222 struct winch_data data; 222 struct winch_data data;
@@ -271,7 +271,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
271 return err; 271 return err;
272} 272}
273 273
274void register_winch(int fd, struct tty_struct *tty) 274void register_winch(int fd, struct tty_port *port)
275{ 275{
276 unsigned long stack; 276 unsigned long stack;
277 int pid, thread, count, thread_fd = -1; 277 int pid, thread, count, thread_fd = -1;
@@ -281,17 +281,17 @@ void register_winch(int fd, struct tty_struct *tty)
281 return; 281 return;
282 282
283 pid = tcgetpgrp(fd); 283 pid = tcgetpgrp(fd);
284 if (is_skas_winch(pid, fd, tty)) { 284 if (is_skas_winch(pid, fd, port)) {
285 register_winch_irq(-1, fd, -1, tty, 0); 285 register_winch_irq(-1, fd, -1, port, 0);
286 return; 286 return;
287 } 287 }
288 288
289 if (pid == -1) { 289 if (pid == -1) {
290 thread = winch_tramp(fd, tty, &thread_fd, &stack); 290 thread = winch_tramp(fd, port, &thread_fd, &stack);
291 if (thread < 0) 291 if (thread < 0)
292 return; 292 return;
293 293
294 register_winch_irq(thread_fd, fd, thread, tty, stack); 294 register_winch_irq(thread_fd, fd, thread, port, stack);
295 295
296 count = write(thread_fd, &c, sizeof(c)); 296 count = write(thread_fd, &c, sizeof(c));
297 if (count != sizeof(c)) 297 if (count != sizeof(c))
diff --git a/arch/um/drivers/chan_user.h b/arch/um/drivers/chan_user.h
index dc693298eb8f..03f1b565c5f9 100644
--- a/arch/um/drivers/chan_user.h
+++ b/arch/um/drivers/chan_user.h
@@ -38,10 +38,10 @@ extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
38 unsigned short *cols_out); 38 unsigned short *cols_out);
39extern void generic_free(void *data); 39extern void generic_free(void *data);
40 40
41struct tty_struct; 41struct tty_port;
42extern void register_winch(int fd, struct tty_struct *tty); 42extern void register_winch(int fd, struct tty_port *port);
43extern void register_winch_irq(int fd, int tty_fd, int pid, 43extern void register_winch_irq(int fd, int tty_fd, int pid,
44 struct tty_struct *tty, unsigned long stack); 44 struct tty_port *port, unsigned long stack);
45 45
46#define __channel_help(fn, prefix) \ 46#define __channel_help(fn, prefix) \
47__uml_help(fn, prefix "[0-9]*=<channel description>\n" \ 47__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index f1b38571f94e..8035145f043b 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -248,7 +248,6 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
248{ 248{
249 struct chan *chan = data; 249 struct chan *chan = data;
250 struct line *line = chan->line; 250 struct line *line = chan->line;
251 struct tty_struct *tty;
252 int err; 251 int err;
253 252
254 /* 253 /*
@@ -267,12 +266,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
267 } 266 }
268 spin_unlock(&line->lock); 267 spin_unlock(&line->lock);
269 268
270 tty = tty_port_tty_get(&line->port); 269 tty_port_tty_wakeup(&line->port);
271 if (tty == NULL)
272 return IRQ_NONE;
273
274 tty_wakeup(tty);
275 tty_kref_put(tty);
276 270
277 return IRQ_HANDLED; 271 return IRQ_HANDLED;
278} 272}
@@ -305,7 +299,7 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty)
305 return ret; 299 return ret;
306 300
307 if (!line->sigio) { 301 if (!line->sigio) {
308 chan_enable_winch(line->chan_out, tty); 302 chan_enable_winch(line->chan_out, port);
309 line->sigio = 1; 303 line->sigio = 1;
310 } 304 }
311 305
@@ -315,8 +309,22 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty)
315 return 0; 309 return 0;
316} 310}
317 311
312static void unregister_winch(struct tty_struct *tty);
313
314static void line_destruct(struct tty_port *port)
315{
316 struct tty_struct *tty = tty_port_tty_get(port);
317 struct line *line = tty->driver_data;
318
319 if (line->sigio) {
320 unregister_winch(tty);
321 line->sigio = 0;
322 }
323}
324
318static const struct tty_port_operations line_port_ops = { 325static const struct tty_port_operations line_port_ops = {
319 .activate = line_activate, 326 .activate = line_activate,
327 .destruct = line_destruct,
320}; 328};
321 329
322int line_open(struct tty_struct *tty, struct file *filp) 330int line_open(struct tty_struct *tty, struct file *filp)
@@ -340,18 +348,6 @@ int line_install(struct tty_driver *driver, struct tty_struct *tty,
340 return 0; 348 return 0;
341} 349}
342 350
343static void unregister_winch(struct tty_struct *tty);
344
345void line_cleanup(struct tty_struct *tty)
346{
347 struct line *line = tty->driver_data;
348
349 if (line->sigio) {
350 unregister_winch(tty);
351 line->sigio = 0;
352 }
353}
354
355void line_close(struct tty_struct *tty, struct file * filp) 351void line_close(struct tty_struct *tty, struct file * filp)
356{ 352{
357 struct line *line = tty->driver_data; 353 struct line *line = tty->driver_data;
@@ -601,7 +597,7 @@ struct winch {
601 int fd; 597 int fd;
602 int tty_fd; 598 int tty_fd;
603 int pid; 599 int pid;
604 struct tty_struct *tty; 600 struct tty_port *port;
605 unsigned long stack; 601 unsigned long stack;
606 struct work_struct work; 602 struct work_struct work;
607}; 603};
@@ -655,7 +651,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
655 goto out; 651 goto out;
656 } 652 }
657 } 653 }
658 tty = winch->tty; 654 tty = tty_port_tty_get(winch->port);
659 if (tty != NULL) { 655 if (tty != NULL) {
660 line = tty->driver_data; 656 line = tty->driver_data;
661 if (line != NULL) { 657 if (line != NULL) {
@@ -663,6 +659,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
663 &tty->winsize.ws_col); 659 &tty->winsize.ws_col);
664 kill_pgrp(tty->pgrp, SIGWINCH, 1); 660 kill_pgrp(tty->pgrp, SIGWINCH, 1);
665 } 661 }
662 tty_kref_put(tty);
666 } 663 }
667 out: 664 out:
668 if (winch->fd != -1) 665 if (winch->fd != -1)
@@ -670,7 +667,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
670 return IRQ_HANDLED; 667 return IRQ_HANDLED;
671} 668}
672 669
673void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, 670void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port,
674 unsigned long stack) 671 unsigned long stack)
675{ 672{
676 struct winch *winch; 673 struct winch *winch;
@@ -685,7 +682,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
685 .fd = fd, 682 .fd = fd,
686 .tty_fd = tty_fd, 683 .tty_fd = tty_fd,
687 .pid = pid, 684 .pid = pid,
688 .tty = tty, 685 .port = port,
689 .stack = stack }); 686 .stack = stack });
690 687
691 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 688 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
@@ -714,15 +711,18 @@ static void unregister_winch(struct tty_struct *tty)
714{ 711{
715 struct list_head *ele, *next; 712 struct list_head *ele, *next;
716 struct winch *winch; 713 struct winch *winch;
714 struct tty_struct *wtty;
717 715
718 spin_lock(&winch_handler_lock); 716 spin_lock(&winch_handler_lock);
719 717
720 list_for_each_safe(ele, next, &winch_handlers) { 718 list_for_each_safe(ele, next, &winch_handlers) {
721 winch = list_entry(ele, struct winch, list); 719 winch = list_entry(ele, struct winch, list);
722 if (winch->tty == tty) { 720 wtty = tty_port_tty_get(winch->port);
721 if (wtty == tty) {
723 free_winch(winch); 722 free_winch(winch);
724 break; 723 break;
725 } 724 }
725 tty_kref_put(wtty);
726 } 726 }
727 spin_unlock(&winch_handler_lock); 727 spin_unlock(&winch_handler_lock);
728} 728}
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index d8926c303629..39f186252e02 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -218,6 +218,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
218 spin_lock_irqsave(&lp->lock, flags); 218 spin_lock_irqsave(&lp->lock, flags);
219 219
220 len = (*lp->write)(lp->fd, skb, lp); 220 len = (*lp->write)(lp->fd, skb, lp);
221 skb_tx_timestamp(skb);
221 222
222 if (len == skb->len) { 223 if (len == skb->len) {
223 dev->stats.tx_packets++; 224 dev->stats.tx_packets++;
@@ -281,6 +282,7 @@ static void uml_net_get_drvinfo(struct net_device *dev,
281static const struct ethtool_ops uml_net_ethtool_ops = { 282static const struct ethtool_ops uml_net_ethtool_ops = {
282 .get_drvinfo = uml_net_get_drvinfo, 283 .get_drvinfo = uml_net_get_drvinfo,
283 .get_link = ethtool_op_get_link, 284 .get_link = ethtool_op_get_link,
285 .get_ts_info = ethtool_op_get_ts_info,
284}; 286};
285 287
286static void uml_net_user_timer_expire(unsigned long _conn) 288static void uml_net_user_timer_expire(unsigned long _conn)
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 16fdd0a0f9d6..b8d14fa52059 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -105,7 +105,6 @@ static const struct tty_operations ssl_ops = {
105 .throttle = line_throttle, 105 .throttle = line_throttle,
106 .unthrottle = line_unthrottle, 106 .unthrottle = line_unthrottle,
107 .install = ssl_install, 107 .install = ssl_install,
108 .cleanup = line_cleanup,
109 .hangup = line_hangup, 108 .hangup = line_hangup,
110}; 109};
111 110
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 827777af3f6d..7b361f36ca96 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -110,7 +110,6 @@ static const struct tty_operations console_ops = {
110 .set_termios = line_set_termios, 110 .set_termios = line_set_termios,
111 .throttle = line_throttle, 111 .throttle = line_throttle,
112 .unthrottle = line_unthrottle, 112 .unthrottle = line_unthrottle,
113 .cleanup = line_cleanup,
114 .hangup = line_hangup, 113 .hangup = line_hangup,
115}; 114};
116 115
diff --git a/arch/um/kernel/early_printk.c b/arch/um/kernel/early_printk.c
index 49480f092456..4a0800bc37b2 100644
--- a/arch/um/kernel/early_printk.c
+++ b/arch/um/kernel/early_printk.c
@@ -16,7 +16,7 @@ static void early_console_write(struct console *con, const char *s, unsigned int
16 um_early_printk(s, n); 16 um_early_printk(s, n);
17} 17}
18 18
19static struct console early_console = { 19static struct console early_console_dev = {
20 .name = "earlycon", 20 .name = "earlycon",
21 .write = early_console_write, 21 .write = early_console_write,
22 .flags = CON_BOOT, 22 .flags = CON_BOOT,
@@ -25,8 +25,10 @@ static struct console early_console = {
25 25
26static int __init setup_early_printk(char *buf) 26static int __init setup_early_printk(char *buf)
27{ 27{
28 register_console(&early_console); 28 if (!early_console) {
29 29 early_console = &early_console_dev;
30 register_console(&early_console_dev);
31 }
30 return 0; 32 return 0;
31} 33}
32 34
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 5abcbfbe7e25..9df292b270a8 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -42,17 +42,12 @@ static unsigned long brk_end;
42static void setup_highmem(unsigned long highmem_start, 42static void setup_highmem(unsigned long highmem_start,
43 unsigned long highmem_len) 43 unsigned long highmem_len)
44{ 44{
45 struct page *page;
46 unsigned long highmem_pfn; 45 unsigned long highmem_pfn;
47 int i; 46 int i;
48 47
49 highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT; 48 highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
50 for (i = 0; i < highmem_len >> PAGE_SHIFT; i++) { 49 for (i = 0; i < highmem_len >> PAGE_SHIFT; i++)
51 page = &mem_map[highmem_pfn + i]; 50 free_highmem_page(&mem_map[highmem_pfn + i]);
52 ClearPageReserved(page);
53 init_page_count(page);
54 __free_page(page);
55 }
56} 51}
57#endif 52#endif
58 53
@@ -73,18 +68,13 @@ void __init mem_init(void)
73 totalram_pages = free_all_bootmem(); 68 totalram_pages = free_all_bootmem();
74 max_low_pfn = totalram_pages; 69 max_low_pfn = totalram_pages;
75#ifdef CONFIG_HIGHMEM 70#ifdef CONFIG_HIGHMEM
76 totalhigh_pages = highmem >> PAGE_SHIFT; 71 setup_highmem(end_iomem, highmem);
77 totalram_pages += totalhigh_pages;
78#endif 72#endif
79 num_physpages = totalram_pages; 73 num_physpages = totalram_pages;
80 max_pfn = totalram_pages; 74 max_pfn = totalram_pages;
81 printk(KERN_INFO "Memory: %luk available\n", 75 printk(KERN_INFO "Memory: %luk available\n",
82 nr_free_pages() << (PAGE_SHIFT-10)); 76 nr_free_pages() << (PAGE_SHIFT-10));
83 kmalloc_ok = 1; 77 kmalloc_ok = 1;
84
85#ifdef CONFIG_HIGHMEM
86 setup_highmem(end_iomem, highmem);
87#endif
88} 78}
89 79
90/* 80/*
@@ -254,15 +244,7 @@ void free_initmem(void)
254#ifdef CONFIG_BLK_DEV_INITRD 244#ifdef CONFIG_BLK_DEV_INITRD
255void free_initrd_mem(unsigned long start, unsigned long end) 245void free_initrd_mem(unsigned long start, unsigned long end)
256{ 246{
257 if (start < end) 247 free_reserved_area(start, end, 0, "initrd");
258 printk(KERN_INFO "Freeing initrd memory: %ldk freed\n",
259 (end - start) >> 10);
260 for (; start < end; start += PAGE_SIZE) {
261 ClearPageReserved(virt_to_page(start));
262 init_page_count(virt_to_page(start));
263 free_page(start);
264 totalram_pages++;
265 }
266} 248}
267#endif 249#endif
268 250
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index b462b13c5bae..bbcef522bcb1 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -210,33 +210,14 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
210 kmalloc_ok = save_kmalloc_ok; 210 kmalloc_ok = save_kmalloc_ok;
211} 211}
212 212
213void default_idle(void) 213void arch_cpu_idle(void)
214{ 214{
215 unsigned long long nsecs; 215 unsigned long long nsecs;
216 216
217 while (1) {
218 /* endless idle loop with no priority at all */
219
220 /*
221 * although we are an idle CPU, we do not want to
222 * get into the scheduler unnecessarily.
223 */
224 if (need_resched())
225 schedule();
226
227 tick_nohz_idle_enter();
228 rcu_idle_enter();
229 nsecs = disable_timer();
230 idle_sleep(nsecs);
231 rcu_idle_exit();
232 tick_nohz_idle_exit();
233 }
234}
235
236void cpu_idle(void)
237{
238 cpu_tasks[current_thread_info()->cpu].pid = os_getpid(); 217 cpu_tasks[current_thread_info()->cpu].pid = os_getpid();
239 default_idle(); 218 nsecs = disable_timer();
219 idle_sleep(nsecs);
220 local_irq_enable();
240} 221}
241 222
242int __cant_sleep(void) { 223int __cant_sleep(void) {
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index b1469fe93295..9d9f1b4bf826 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -15,7 +15,7 @@
15#include <sysdep/mcontext.h> 15#include <sysdep/mcontext.h>
16#include "internal.h" 16#include "internal.h"
17 17
18void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = { 18void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
19 [SIGTRAP] = relay_signal, 19 [SIGTRAP] = relay_signal,
20 [SIGFPE] = relay_signal, 20 [SIGFPE] = relay_signal,
21 [SIGILL] = relay_signal, 21 [SIGILL] = relay_signal,
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index da4b9e9999fd..337518c5042a 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -15,6 +15,8 @@
15#include <sys/mman.h> 15#include <sys/mman.h>
16#include <sys/stat.h> 16#include <sys/stat.h>
17#include <sys/wait.h> 17#include <sys/wait.h>
18#include <sys/time.h>
19#include <sys/resource.h>
18#include <asm/unistd.h> 20#include <asm/unistd.h>
19#include <init.h> 21#include <init.h>
20#include <os.h> 22#include <os.h>