aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-07-03 13:49:45 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-07-03 13:49:45 -0400
commit026477c1141b67e98e3bd8bdedb7d4b88a3ecd09 (patch)
tree2624a44924c625c367f3cebf937853b9da2de282 /arch/um/kernel
parent9f2fa466383ce100b90fe52cb4489d7a26bf72a9 (diff)
parent29454dde27d8e340bb1987bad9aa504af7081eba (diff)
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/irq.c8
-rw-r--r--arch/um/kernel/sigio_kern.c2
-rw-r--r--arch/um/kernel/skas/mmu.c2
-rw-r--r--arch/um/kernel/skas/uaccess.c15
-rw-r--r--arch/um/kernel/time.c172
-rw-r--r--arch/um/kernel/time_kern.c34
-rw-r--r--arch/um/kernel/vmlinux.lds.S3
7 files changed, 26 insertions, 210 deletions
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 2ffda012385e..bfd0bdc8cd40 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -63,7 +63,7 @@ int show_interrupts(struct seq_file *p, void *v)
63 for_each_online_cpu(j) 63 for_each_online_cpu(j)
64 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 64 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
65#endif 65#endif
66 seq_printf(p, " %14s", irq_desc[i].handler->typename); 66 seq_printf(p, " %14s", irq_desc[i].chip->typename);
67 seq_printf(p, " %s", action->name); 67 seq_printf(p, " %s", action->name);
68 68
69 for (action=action->next; action; action = action->next) 69 for (action=action->next; action; action = action->next)
@@ -451,13 +451,13 @@ void __init init_IRQ(void)
451 irq_desc[TIMER_IRQ].status = IRQ_DISABLED; 451 irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
452 irq_desc[TIMER_IRQ].action = NULL; 452 irq_desc[TIMER_IRQ].action = NULL;
453 irq_desc[TIMER_IRQ].depth = 1; 453 irq_desc[TIMER_IRQ].depth = 1;
454 irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; 454 irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type;
455 enable_irq(TIMER_IRQ); 455 enable_irq(TIMER_IRQ);
456 for (i = 1; i < NR_IRQS; i++) { 456 for (i = 1; i < NR_IRQS; i++) {
457 irq_desc[i].status = IRQ_DISABLED; 457 irq_desc[i].status = IRQ_DISABLED;
458 irq_desc[i].action = NULL; 458 irq_desc[i].action = NULL;
459 irq_desc[i].depth = 1; 459 irq_desc[i].depth = 1;
460 irq_desc[i].handler = &normal_irq_type; 460 irq_desc[i].chip = &normal_irq_type;
461 enable_irq(i); 461 enable_irq(i);
462 } 462 }
463} 463}
@@ -474,7 +474,7 @@ int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *,
474 } 474 }
475 475
476 err = um_request_irq(irq, fds[0], IRQ_READ, handler, 476 err = um_request_irq(irq, fds[0], IRQ_READ, handler,
477 SA_INTERRUPT | SA_SAMPLE_RANDOM, name, 477 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name,
478 (void *) (long) fds[0]); 478 (void *) (long) fds[0]);
479 if (err) { 479 if (err) {
480 printk("init_aio_irq - : um_request_irq failed, err = %d\n", 480 printk("init_aio_irq - : um_request_irq failed, err = %d\n",
diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
index 1c1300fb1e95..51b677083948 100644
--- a/arch/um/kernel/sigio_kern.c
+++ b/arch/um/kernel/sigio_kern.c
@@ -31,7 +31,7 @@ int write_sigio_irq(int fd)
31 int err; 31 int err;
32 32
33 err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, 33 err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
34 SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", 34 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "write sigio",
35 NULL); 35 NULL);
36 if(err){ 36 if(err){
37 printk("write_sigio_irq : um_request_irq failed, err = %d\n", 37 printk("write_sigio_irq : um_request_irq failed, err = %d\n",
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index c5c9885a8297..624ca238d1fd 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -152,7 +152,7 @@ void destroy_context_skas(struct mm_struct *mm)
152 free_page(mmu->id.stack); 152 free_page(mmu->id.stack);
153 pte_lock_deinit(virt_to_page(mmu->last_page_table)); 153 pte_lock_deinit(virt_to_page(mmu->last_page_table));
154 pte_free_kernel((pte_t *) mmu->last_page_table); 154 pte_free_kernel((pte_t *) mmu->last_page_table);
155 dec_page_state(nr_page_table_pages); 155 dec_zone_page_state(virt_to_page(mmu->last_page_table), NR_PAGETABLE);
156#ifdef CONFIG_3_LEVEL_PGTABLES 156#ifdef CONFIG_3_LEVEL_PGTABLES
157 pmd_free((pmd_t *) mmu->last_pmd); 157 pmd_free((pmd_t *) mmu->last_pmd);
158#endif 158#endif
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 5992c3257167..8912cec0fe43 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -8,6 +8,7 @@
8#include "linux/kernel.h" 8#include "linux/kernel.h"
9#include "linux/string.h" 9#include "linux/string.h"
10#include "linux/fs.h" 10#include "linux/fs.h"
11#include "linux/hardirq.h"
11#include "linux/highmem.h" 12#include "linux/highmem.h"
12#include "asm/page.h" 13#include "asm/page.h"
13#include "asm/pgtable.h" 14#include "asm/pgtable.h"
@@ -38,7 +39,7 @@ static unsigned long maybe_map(unsigned long virt, int is_write)
38 return((unsigned long) phys); 39 return((unsigned long) phys);
39} 40}
40 41
41static int do_op(unsigned long addr, int len, int is_write, 42static int do_op_one_page(unsigned long addr, int len, int is_write,
42 int (*op)(unsigned long addr, int len, void *arg), void *arg) 43 int (*op)(unsigned long addr, int len, void *arg), void *arg)
43{ 44{
44 struct page *page; 45 struct page *page;
@@ -49,9 +50,11 @@ static int do_op(unsigned long addr, int len, int is_write,
49 return(-1); 50 return(-1);
50 51
51 page = phys_to_page(addr); 52 page = phys_to_page(addr);
52 addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); 53 addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + (addr & ~PAGE_MASK);
54
53 n = (*op)(addr, len, arg); 55 n = (*op)(addr, len, arg);
54 kunmap(page); 56
57 kunmap_atomic(page, KM_UML_USERCOPY);
55 58
56 return(n); 59 return(n);
57} 60}
@@ -77,7 +80,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
77 remain = len; 80 remain = len;
78 81
79 current->thread.fault_catcher = jmpbuf; 82 current->thread.fault_catcher = jmpbuf;
80 n = do_op(addr, size, is_write, op, arg); 83 n = do_op_one_page(addr, size, is_write, op, arg);
81 if(n != 0){ 84 if(n != 0){
82 *res = (n < 0 ? remain : 0); 85 *res = (n < 0 ? remain : 0);
83 goto out; 86 goto out;
@@ -91,7 +94,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
91 } 94 }
92 95
93 while(addr < ((addr + remain) & PAGE_MASK)){ 96 while(addr < ((addr + remain) & PAGE_MASK)){
94 n = do_op(addr, PAGE_SIZE, is_write, op, arg); 97 n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg);
95 if(n != 0){ 98 if(n != 0){
96 *res = (n < 0 ? remain : 0); 99 *res = (n < 0 ? remain : 0);
97 goto out; 100 goto out;
@@ -105,7 +108,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
105 goto out; 108 goto out;
106 } 109 }
107 110
108 n = do_op(addr, remain, is_write, op, arg); 111 n = do_op_one_page(addr, remain, is_write, op, arg);
109 if(n != 0) 112 if(n != 0)
110 *res = (n < 0 ? remain : 0); 113 *res = (n < 0 ? remain : 0);
111 else *res = 0; 114 else *res = 0;
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
deleted file mode 100644
index 8fa2ae7f3026..000000000000
--- a/arch/um/kernel/time.c
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9#include <time.h>
10#include <sys/time.h>
11#include <signal.h>
12#include <errno.h>
13#include "user_util.h"
14#include "kern_util.h"
15#include "user.h"
16#include "process.h"
17#include "time_user.h"
18#include "kern_constants.h"
19#include "os.h"
20
21/* XXX This really needs to be declared and initialized in a kernel file since
22 * it's in <linux/time.h>
23 */
24extern struct timespec wall_to_monotonic;
25
26extern struct timeval xtime;
27
28struct timeval local_offset = { 0, 0 };
29
30void timer(void)
31{
32 gettimeofday(&xtime, NULL);
33 timeradd(&xtime, &local_offset, &xtime);
34}
35
36static void set_interval(int timer_type)
37{
38 int usec = 1000000/hz();
39 struct itimerval interval = ((struct itimerval) { { 0, usec },
40 { 0, usec } });
41
42 if(setitimer(timer_type, &interval, NULL) == -1)
43 panic("setitimer failed - errno = %d\n", errno);
44}
45
46void enable_timer(void)
47{
48 set_interval(ITIMER_VIRTUAL);
49}
50
51void prepare_timer(void * ptr)
52{
53 int usec = 1000000/hz();
54 *(struct itimerval *)ptr = ((struct itimerval) { { 0, usec },
55 { 0, usec }});
56}
57
58void disable_timer(void)
59{
60 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
61 if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
62 (setitimer(ITIMER_REAL, &disable, NULL) < 0))
63 printk("disnable_timer - setitimer failed, errno = %d\n",
64 errno);
65 /* If there are signals already queued, after unblocking ignore them */
66 set_handler(SIGALRM, SIG_IGN, 0, -1);
67 set_handler(SIGVTALRM, SIG_IGN, 0, -1);
68}
69
70void switch_timers(int to_real)
71{
72 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
73 struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
74 { 0, 1000000/hz() }});
75 int old, new;
76
77 if(to_real){
78 old = ITIMER_VIRTUAL;
79 new = ITIMER_REAL;
80 }
81 else {
82 old = ITIMER_REAL;
83 new = ITIMER_VIRTUAL;
84 }
85
86 if((setitimer(old, &disable, NULL) < 0) ||
87 (setitimer(new, &enable, NULL)))
88 printk("switch_timers - setitimer failed, errno = %d\n",
89 errno);
90}
91
92void uml_idle_timer(void)
93{
94 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
95 panic("Couldn't unset SIGVTALRM handler");
96
97 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
98 SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
99 set_interval(ITIMER_REAL);
100}
101
102extern void ktime_get_ts(struct timespec *ts);
103#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
104
105void time_init(void)
106{
107 struct timespec now;
108
109 if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
110 panic("Couldn't set SIGVTALRM handler");
111 set_interval(ITIMER_VIRTUAL);
112
113 do_posix_clock_monotonic_gettime(&now);
114 wall_to_monotonic.tv_sec = -now.tv_sec;
115 wall_to_monotonic.tv_nsec = -now.tv_nsec;
116}
117
118/* Defined in linux/ktimer.h, which can't be included here */
119#define clock_was_set() do { } while (0)
120
121void do_gettimeofday(struct timeval *tv)
122{
123 unsigned long flags;
124
125 flags = time_lock();
126 gettimeofday(tv, NULL);
127 timeradd(tv, &local_offset, tv);
128 time_unlock(flags);
129 clock_was_set();
130}
131
132int do_settimeofday(struct timespec *tv)
133{
134 struct timeval now;
135 unsigned long flags;
136 struct timeval tv_in;
137
138 if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
139 return -EINVAL;
140
141 tv_in.tv_sec = tv->tv_sec;
142 tv_in.tv_usec = tv->tv_nsec / 1000;
143
144 flags = time_lock();
145 gettimeofday(&now, NULL);
146 timersub(&tv_in, &now, &local_offset);
147 time_unlock(flags);
148
149 return(0);
150}
151
152void idle_sleep(int secs)
153{
154 struct timespec ts;
155
156 ts.tv_sec = secs;
157 ts.tv_nsec = 0;
158 nanosleep(&ts, NULL);
159}
160
161/* XXX This partly duplicates init_irq_signals */
162
163void user_time_init(void)
164{
165 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
166 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
167 SIGALRM, SIGUSR2, -1);
168 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
169 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
170 SIGVTALRM, SIGUSR2, -1);
171 set_interval(ITIMER_VIRTUAL);
172}
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 87cdbc560d36..d7e044b5e5ee 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -96,11 +96,15 @@ void time_init_kern(void)
96 96
97void do_boot_timer_handler(struct sigcontext * sc) 97void do_boot_timer_handler(struct sigcontext * sc)
98{ 98{
99 unsigned long flags;
99 struct pt_regs regs; 100 struct pt_regs regs;
100 101
101 CHOOSE_MODE((void) (UPT_SC(&regs.regs) = sc), 102 CHOOSE_MODE((void) (UPT_SC(&regs.regs) = sc),
102 (void) (regs.regs.skas.is_user = 0)); 103 (void) (regs.regs.skas.is_user = 0));
104
105 write_seqlock_irqsave(&xtime_lock, flags);
103 do_timer(&regs); 106 do_timer(&regs);
107 write_sequnlock_irqrestore(&xtime_lock, flags);
104} 108}
105 109
106static DEFINE_SPINLOCK(timer_spinlock); 110static DEFINE_SPINLOCK(timer_spinlock);
@@ -125,25 +129,17 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
125 unsigned long long nsecs; 129 unsigned long long nsecs;
126 unsigned long flags; 130 unsigned long flags;
127 131
132 write_seqlock_irqsave(&xtime_lock, flags);
133
128 do_timer(regs); 134 do_timer(regs);
129 135
130 write_seqlock_irqsave(&xtime_lock, flags);
131 nsecs = get_time() + local_offset; 136 nsecs = get_time() + local_offset;
132 xtime.tv_sec = nsecs / NSEC_PER_SEC; 137 xtime.tv_sec = nsecs / NSEC_PER_SEC;
133 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; 138 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
134 write_sequnlock_irqrestore(&xtime_lock, flags);
135
136 return(IRQ_HANDLED);
137}
138 139
139long um_time(int __user *tloc) 140 write_sequnlock_irqrestore(&xtime_lock, flags);
140{
141 long ret = get_time() / NSEC_PER_SEC;
142
143 if((tloc != NULL) && put_user(ret, tloc))
144 return -EFAULT;
145 141
146 return ret; 142 return IRQ_HANDLED;
147} 143}
148 144
149void do_gettimeofday(struct timeval *tv) 145void do_gettimeofday(struct timeval *tv)
@@ -174,18 +170,6 @@ static inline void set_time(unsigned long long nsecs)
174 clock_was_set(); 170 clock_was_set();
175} 171}
176 172
177long um_stime(int __user *tptr)
178{
179 int value;
180
181 if (get_user(value, tptr))
182 return -EFAULT;
183
184 set_time((unsigned long long) value * NSEC_PER_SEC);
185
186 return 0;
187}
188
189int do_settimeofday(struct timespec *tv) 173int do_settimeofday(struct timespec *tv)
190{ 174{
191 set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec); 175 set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec);
@@ -211,7 +195,7 @@ int __init timer_init(void)
211 int err; 195 int err;
212 196
213 user_time_init(); 197 user_time_init();
214 err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); 198 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
215 if(err != 0) 199 if(err != 0)
216 printk(KERN_ERR "timer_init : request_irq failed - " 200 printk(KERN_ERR "timer_init : request_irq failed - "
217 "errno = %d\n", -err); 201 "errno = %d\n", -err);
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S
index 1660a769674b..72acdce205e0 100644
--- a/arch/um/kernel/vmlinux.lds.S
+++ b/arch/um/kernel/vmlinux.lds.S
@@ -1,4 +1,5 @@
1#include <linux/config.h> 1/* in case the preprocessor is a 32bit one */
2#undef i386
2#ifdef CONFIG_LD_SCRIPT_STATIC 3#ifdef CONFIG_LD_SCRIPT_STATIC
3#include "uml.lds.S" 4#include "uml.lds.S"
4#else 5#else