Whamcloud - gitweb
- configurable stack size fo x86_64
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-patch-2.4.20-6.patch
1 diff -Naur -X ../exclude-files orig/arch/um/common.ld.in um/arch/um/common.ld.in
2 --- orig/arch/um/common.ld.in   1969-12-31 19:00:00.000000000 -0500
3 +++ um/arch/um/common.ld.in     2003-02-04 19:35:13.000000000 -0500
4 @@ -0,0 +1,53 @@
5 +  .kstrtab : { *(.kstrtab) }
6 +
7 +  . = ALIGN(16);               /* Exception table */
8 +  __start___ex_table = .;
9 +  __ex_table : { *(__ex_table) }
10 +  __stop___ex_table = .;
11 +
12 +  __start___ksymtab = .;       /* Kernel symbol table */
13 +  __ksymtab : { *(__ksymtab) }
14 +  __stop___ksymtab = .;
15 +
16 +  .unprotected : { *(.unprotected) }
17 +  . = ALIGN(4096);
18 +  PROVIDE (_unprotected_end = .);
19 +
20 +  . = ALIGN(4096);
21 +  __uml_setup_start = .;
22 +  .uml.setup.init : { *(.uml.setup.init) }
23 +  __uml_setup_end = .;
24 +  __uml_help_start = .;
25 +  .uml.help.init : { *(.uml.help.init) }
26 +  __uml_help_end = .;
27 +  __uml_postsetup_start = .;
28 +  .uml.postsetup.init : { *(.uml.postsetup.init) }
29 +  __uml_postsetup_end = .;
30 +  __setup_start = .;
31 +  .setup.init : { *(.setup.init) }
32 +  __setup_end = .;
33 +  __initcall_start = .;
34 +  .initcall.init : { *(.initcall.init) }
35 +  __initcall_end = .;
36 +  __uml_initcall_start = .;
37 +  .uml.initcall.init : { *(.uml.initcall.init) }
38 +  __uml_initcall_end = .;
39 +  __init_end = .;
40 +  __exitcall_begin = .;
41 +  .exitcall : { *(.exitcall.exit) }
42 +  __exitcall_end = .;
43 +  __uml_exitcall_begin = .;
44 +  .uml.exitcall : { *(.uml.exitcall.exit) }
45 +  __uml_exitcall_end = .;
46 +
47 +  __preinit_array_start = .;
48 +  .preinit_array : { *(.preinit_array) }
49 +  __preinit_array_end = .;
50 +  __init_array_start = .;
51 +  .init_array : { *(.init_array) }
52 +  __init_array_end = .;
53 +  __fini_array_start = .;
54 +  .fini_array : { *(.fini_array) }
55 +  __fini_array_end = .;
56 +
57 +  .data.init : { *(.data.init) }
58 diff -Naur -X ../exclude-files orig/arch/um/config_block.in um/arch/um/config_block.in
59 --- orig/arch/um/config_block.in        1969-12-31 19:00:00.000000000 -0500
60 +++ um/arch/um/config_block.in  2002-10-23 21:08:04.000000000 -0400
61 @@ -0,0 +1,16 @@
62 +mainmenu_option next_comment
63 +comment 'Block Devices'
64 +
65 +bool 'Virtual block device' CONFIG_BLK_DEV_UBD
66 +dep_bool '  Always do synchronous disk IO for UBD' CONFIG_BLK_DEV_UBD_SYNC $CONFIG_BLK_DEV_UBD
67 +tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
68 +dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
69 +tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
70 +if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
71 +       int '   Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
72 +fi
73 +dep_bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
74 +
75 +tristate 'Example IO memory driver' CONFIG_MMAPPER
76 +
77 +endmenu
78 diff -Naur -X ../exclude-files orig/arch/um/config_char.in um/arch/um/config_char.in
79 --- orig/arch/um/config_char.in 1969-12-31 19:00:00.000000000 -0500
80 +++ um/arch/um/config_char.in   2002-10-23 21:08:04.000000000 -0400
81 @@ -0,0 +1,37 @@
82 +mainmenu_option next_comment
83 +comment 'Character Devices'
84 +
85 +define_bool CONFIG_STDIO_CONSOLE y
86 +
87 +bool 'Virtual serial line' CONFIG_SSL
88 +
89 +bool 'file descriptor channel support' CONFIG_FD_CHAN
90 +bool 'null channel support' CONFIG_NULL_CHAN
91 +bool 'port channel support' CONFIG_PORT_CHAN
92 +bool 'pty channel support' CONFIG_PTY_CHAN
93 +bool 'tty channel support' CONFIG_TTY_CHAN
94 +bool 'xterm channel support' CONFIG_XTERM_CHAN
95 +string 'Default main console channel initialization' CONFIG_CON_ZERO_CHAN \
96 +            "fd:0,fd:1"
97 +string 'Default console channel initialization' CONFIG_CON_CHAN "xterm"
98 +string 'Default serial line channel initialization' CONFIG_SSL_CHAN "pty"
99 +
100 +
101 +bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
102 +if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
103 +   int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
104 +fi
105 +
106 +bool 'Watchdog Timer Support' CONFIG_WATCHDOG
107 +dep_bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT \
108 +       $CONFIG_WATCHDOG
109 +dep_tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG $CONFIG_WATCHDOG
110 +dep_tristate '  UML watchdog' CONFIG_UML_WATCHDOG $CONFIG_WATCHDOG
111 +
112 +tristate 'Sound support' CONFIG_UML_SOUND
113 +define_tristate CONFIG_SOUND $CONFIG_UML_SOUND
114 +define_tristate CONFIG_HOSTAUDIO $CONFIG_UML_SOUND
115 +
116 +bool 'Enable tty logging' CONFIG_TTY_LOG
117 +
118 +endmenu
119 diff -Naur -X ../exclude-files orig/arch/um/config.in um/arch/um/config.in
120 --- orig/arch/um/config.in      1969-12-31 19:00:00.000000000 -0500
121 +++ um/arch/um/config.in        2003-02-27 13:12:39.000000000 -0500
122 @@ -0,0 +1,104 @@
123 +define_bool CONFIG_USERMODE y
124 +
125 +mainmenu_name "Linux/Usermode Kernel Configuration"
126 +
127 +define_bool CONFIG_ISA n
128 +define_bool CONFIG_SBUS n
129 +define_bool CONFIG_PCI n
130 +
131 +define_bool CONFIG_UID16 y
132 +
133 +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
134 +
135 +mainmenu_option next_comment
136 +comment 'Code maturity level options'
137 +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
138 +endmenu
139 +
140 +mainmenu_option next_comment
141 +comment 'General Setup'
142 +
143 +bool 'Separate kernel address space support' CONFIG_MODE_SKAS
144 +
145 +# This is to ensure that at least one of the modes is enabled.  When neither
146 +# is present in defconfig, they default to N, which is bad.
147 +if [ "$CONFIG_MODE_SKAS" != "y" ]; then
148 +   define_bool CONFIG_MODE_TT y
149 +fi
150 +
151 +bool 'Tracing thread support' CONFIG_MODE_TT
152 +if [ "$CONFIG_MODE_TT" != "y" ]; then
153 +   bool 'Statically linked binary when CONFIG_MODE_TT is disabled' CONFIG_STATIC_LINK
154 +fi
155 +bool 'Networking support' CONFIG_NET
156 +bool 'System V IPC' CONFIG_SYSVIPC
157 +bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
158 +bool 'Sysctl support' CONFIG_SYSCTL
159 +tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
160 +tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
161 +tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
162 +tristate 'Host filesystem' CONFIG_HOSTFS
163 +tristate 'Honeypot proc filesystem' CONFIG_HPPFS
164 +bool 'Management console' CONFIG_MCONSOLE
165 +dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_MCONSOLE
166 +bool '2G/2G host address space split' CONFIG_HOST_2G_2G
167 +bool 'Symmetric multi-processing support' CONFIG_UML_SMP
168 +define_bool CONFIG_SMP $CONFIG_UML_SMP
169 +int 'Nesting level' CONFIG_NEST_LEVEL 0
170 +int 'Kernel address space size (in .5G units)' CONFIG_KERNEL_HALF_GIGS 1
171 +bool 'Highmem support' CONFIG_HIGHMEM
172 +bool '/proc/mm' CONFIG_PROC_MM
173 +int 'Kernel stack size order' CONFIG_KERNEL_STACK_ORDER 2
174 +endmenu
175 +
176 +mainmenu_option next_comment
177 +comment 'Loadable module support'
178 +bool 'Enable loadable module support' CONFIG_MODULES
179 +if [ "$CONFIG_MODULES" = "y" ]; then
180 +# MODVERSIONS does not yet work in this architecture
181 +#   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
182 +    bool '  Kernel module loader' CONFIG_KMOD
183 +fi
184 +endmenu
185 +
186 +source arch/um/config_char.in
187 +
188 +source arch/um/config_block.in
189 +
190 +define_bool CONFIG_NETDEVICES $CONFIG_NET
191 +
192 +if [ "$CONFIG_NET" = "y" ]; then
193 +   source arch/um/config_net.in
194 +   source net/Config.in
195 +fi
196 +
197 +source fs/Config.in
198 +
199 +mainmenu_option next_comment
200 +comment 'SCSI support'
201 +
202 +tristate 'SCSI support' CONFIG_SCSI
203 +
204 +if [ "$CONFIG_SCSI" != "n" ]; then
205 +   source arch/um/config_scsi.in
206 +fi
207 +endmenu
208 +
209 +source drivers/md/Config.in
210 +
211 +source drivers/mtd/Config.in
212 +
213 +source lib/Config.in
214 +
215 +mainmenu_option next_comment
216 +comment 'Kernel hacking'
217 +bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
218 +bool 'Enable kernel debugging symbols' CONFIG_DEBUGSYM
219 +if [ "$CONFIG_XTERM_CHAN" = "y" ]; then
220 +   dep_bool 'Enable ptrace proxy' CONFIG_PT_PROXY $CONFIG_DEBUGSYM
221 +else 
222 +   define_bool CONFIG_PT_PROXY n
223 +fi
224 +dep_bool 'Enable gprof support' CONFIG_GPROF $CONFIG_DEBUGSYM
225 +dep_bool 'Enable gcov support' CONFIG_GCOV $CONFIG_DEBUGSYM
226 +endmenu
227 diff -Naur -X ../exclude-files orig/arch/um/config_net.in um/arch/um/config_net.in
228 --- orig/arch/um/config_net.in  1969-12-31 19:00:00.000000000 -0500
229 +++ um/arch/um/config_net.in    2002-10-23 21:08:04.000000000 -0400
230 @@ -0,0 +1,47 @@
231 +mainmenu_option next_comment
232 +comment 'Network Devices'
233 +
234 +# UML virtual driver
235 +bool 'Virtual network device' CONFIG_UML_NET
236 +
237 +dep_bool '  Ethertap transport' CONFIG_UML_NET_ETHERTAP $CONFIG_UML_NET
238 +dep_bool '  TUN/TAP transport' CONFIG_UML_NET_TUNTAP $CONFIG_UML_NET
239 +dep_bool '  SLIP transport' CONFIG_UML_NET_SLIP $CONFIG_UML_NET
240 +dep_bool '  SLiRP transport' CONFIG_UML_NET_SLIRP $CONFIG_UML_NET
241 +dep_bool '  Daemon transport' CONFIG_UML_NET_DAEMON $CONFIG_UML_NET
242 +dep_bool '  Multicast transport' CONFIG_UML_NET_MCAST $CONFIG_UML_NET
243 +dep_bool '  pcap transport' CONFIG_UML_NET_PCAP $CONFIG_UML_NET
244 +
245 +# Below are hardware-independent drivers mirrored from
246 +# drivers/net/Config.in. It would be nice if Linux
247 +# had HW independent drivers separated from the other
248 +# but it does not. Until then each non-ISA/PCI arch
249 +# needs to provide it's own menu of network drivers
250 +
251 +tristate 'Dummy net driver support' CONFIG_DUMMY
252 +tristate 'Bonding driver support' CONFIG_BONDING
253 +tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
254 +tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
255 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
256 +   if [ "$CONFIG_NETLINK" = "y" ]; then
257 +      tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
258 +   fi
259 +fi
260 +
261 +tristate 'PPP (point-to-point protocol) support' CONFIG_PPP
262 +if [ ! "$CONFIG_PPP" = "n" ]; then
263 +   dep_bool '  PPP multilink support (EXPERIMENTAL)' CONFIG_PPP_MULTILINK $CONFIG_EXPERIMENTAL
264 +   dep_bool '  PPP filtering' CONFIG_PPP_FILTER $CONFIG_FILTER
265 +   dep_tristate '  PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
266 +   dep_tristate '  PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
267 +   dep_tristate '  PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
268 +   dep_tristate '  PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
269 +   dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP $CONFIG_EXPERIMENTAL
270 +fi
271 +
272 +tristate 'SLIP (serial line) support' CONFIG_SLIP
273 +dep_bool '  CSLIP compressed headers' CONFIG_SLIP_COMPRESSED $CONFIG_SLIP
274 +dep_bool '  Keepalive and linefill' CONFIG_SLIP_SMART $CONFIG_SLIP
275 +dep_bool '  Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 $CONFIG_SLIP
276 +
277 +endmenu
278 diff -Naur -X ../exclude-files orig/arch/um/config.release um/arch/um/config.release
279 --- orig/arch/um/config.release 1969-12-31 19:00:00.000000000 -0500
280 +++ um/arch/um/config.release   2002-10-23 21:08:04.000000000 -0400
281 @@ -0,0 +1,302 @@
282 +#
283 +# Automatically generated make config: don't edit
284 +#
285 +CONFIG_USERMODE=y
286 +# CONFIG_ISA is not set
287 +# CONFIG_SBUS is not set
288 +# CONFIG_PCI is not set
289 +CONFIG_UID16=y
290 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
291 +
292 +#
293 +# Code maturity level options
294 +#
295 +CONFIG_EXPERIMENTAL=y
296 +
297 +#
298 +# General Setup
299 +#
300 +CONFIG_NET=y
301 +CONFIG_SYSVIPC=y
302 +CONFIG_BSD_PROCESS_ACCT=y
303 +CONFIG_SYSCTL=y
304 +CONFIG_BINFMT_AOUT=y
305 +CONFIG_BINFMT_ELF=y
306 +CONFIG_BINFMT_MISC=y
307 +CONFIG_HOSTFS=y
308 +# CONFIG_HPPFS is not set
309 +CONFIG_MCONSOLE=y
310 +CONFIG_MAGIC_SYSRQ=y
311 +# CONFIG_HOST_2G_2G is not set
312 +# CONFIG_UML_SMP is not set
313 +# CONFIG_SMP is not set
314 +CONFIG_NEST_LEVEL=0
315 +CONFIG_KERNEL_HALF_GIGS=1
316 +
317 +#
318 +# Loadable module support
319 +#
320 +CONFIG_MODULES=y
321 +CONFIG_KMOD=y
322 +
323 +#
324 +# Character Devices
325 +#
326 +CONFIG_STDIO_CONSOLE=y
327 +CONFIG_SSL=y
328 +CONFIG_FD_CHAN=y
329 +# CONFIG_NULL_CHAN is not set
330 +CONFIG_PORT_CHAN=y
331 +CONFIG_PTY_CHAN=y
332 +CONFIG_TTY_CHAN=y
333 +CONFIG_XTERM_CHAN=y
334 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
335 +CONFIG_CON_CHAN="xterm"
336 +CONFIG_SSL_CHAN="pty"
337 +CONFIG_UNIX98_PTYS=y
338 +CONFIG_UNIX98_PTY_COUNT=256
339 +# CONFIG_WATCHDOG is not set
340 +CONFIG_UML_SOUND=y
341 +CONFIG_SOUND=y
342 +CONFIG_HOSTAUDIO=y
343 +# CONFIG_TTY_LOG is not set
344 +
345 +#
346 +# Block Devices
347 +#
348 +CONFIG_BLK_DEV_UBD=y
349 +# CONFIG_BLK_DEV_UBD_SYNC is not set
350 +CONFIG_BLK_DEV_LOOP=y
351 +CONFIG_BLK_DEV_NBD=y
352 +CONFIG_BLK_DEV_RAM=y
353 +CONFIG_BLK_DEV_RAM_SIZE=4096
354 +CONFIG_BLK_DEV_INITRD=y
355 +# CONFIG_MMAPPER is not set
356 +CONFIG_NETDEVICES=y
357 +
358 +#
359 +# Network Devices
360 +#
361 +CONFIG_UML_NET=y
362 +CONFIG_UML_NET_ETHERTAP=y
363 +CONFIG_UML_NET_TUNTAP=y
364 +CONFIG_UML_NET_SLIP=y
365 +CONFIG_UML_NET_DAEMON=y
366 +CONFIG_UML_NET_MCAST=y
367 +CONFIG_DUMMY=y
368 +CONFIG_BONDING=m
369 +CONFIG_EQUALIZER=m
370 +CONFIG_TUN=y
371 +CONFIG_PPP=m
372 +CONFIG_PPP_MULTILINK=y
373 +# CONFIG_PPP_ASYNC is not set
374 +CONFIG_PPP_SYNC_TTY=m
375 +CONFIG_PPP_DEFLATE=m
376 +CONFIG_PPP_BSDCOMP=m
377 +CONFIG_PPPOE=m
378 +CONFIG_SLIP=m
379 +
380 +#
381 +# Networking options
382 +#
383 +CONFIG_PACKET=y
384 +CONFIG_PACKET_MMAP=y
385 +# CONFIG_NETLINK_DEV is not set
386 +# CONFIG_NETFILTER is not set
387 +# CONFIG_FILTER is not set
388 +CONFIG_UNIX=y
389 +CONFIG_INET=y
390 +# CONFIG_IP_MULTICAST is not set
391 +# CONFIG_IP_ADVANCED_ROUTER is not set
392 +# CONFIG_IP_PNP is not set
393 +# CONFIG_NET_IPIP is not set
394 +# CONFIG_NET_IPGRE is not set
395 +# CONFIG_ARPD is not set
396 +# CONFIG_INET_ECN is not set
397 +# CONFIG_SYN_COOKIES is not set
398 +# CONFIG_IPV6 is not set
399 +# CONFIG_KHTTPD is not set
400 +# CONFIG_ATM is not set
401 +# CONFIG_VLAN_8021Q is not set
402 +
403 +#
404 +#  
405 +#
406 +# CONFIG_IPX is not set
407 +# CONFIG_ATALK is not set
408 +
409 +#
410 +# Appletalk devices
411 +#
412 +# CONFIG_DECNET is not set
413 +# CONFIG_BRIDGE is not set
414 +# CONFIG_X25 is not set
415 +# CONFIG_LAPB is not set
416 +# CONFIG_LLC is not set
417 +# CONFIG_NET_DIVERT is not set
418 +# CONFIG_ECONET is not set
419 +# CONFIG_WAN_ROUTER is not set
420 +# CONFIG_NET_FASTROUTE is not set
421 +# CONFIG_NET_HW_FLOWCONTROL is not set
422 +
423 +#
424 +# QoS and/or fair queueing
425 +#
426 +# CONFIG_NET_SCHED is not set
427 +
428 +#
429 +# Network testing
430 +#
431 +# CONFIG_NET_PKTGEN is not set
432 +
433 +#
434 +# File systems
435 +#
436 +CONFIG_QUOTA=y
437 +CONFIG_AUTOFS_FS=m
438 +CONFIG_AUTOFS4_FS=m
439 +CONFIG_REISERFS_FS=m
440 +# CONFIG_REISERFS_CHECK is not set
441 +# CONFIG_REISERFS_PROC_INFO is not set
442 +CONFIG_ADFS_FS=m
443 +# CONFIG_ADFS_FS_RW is not set
444 +CONFIG_AFFS_FS=m
445 +CONFIG_HFS_FS=m
446 +CONFIG_BFS_FS=m
447 +CONFIG_EXT3_FS=y
448 +CONFIG_JBD=y
449 +# CONFIG_JBD_DEBUG is not set
450 +CONFIG_FAT_FS=y
451 +CONFIG_MSDOS_FS=y
452 +CONFIG_UMSDOS_FS=y
453 +CONFIG_VFAT_FS=y
454 +CONFIG_EFS_FS=m
455 +CONFIG_CRAMFS=m
456 +CONFIG_TMPFS=y
457 +CONFIG_RAMFS=y
458 +CONFIG_ISO9660_FS=y
459 +# CONFIG_JOLIET is not set
460 +# CONFIG_ZISOFS is not set
461 +CONFIG_MINIX_FS=m
462 +CONFIG_VXFS_FS=m
463 +# CONFIG_NTFS_FS is not set
464 +CONFIG_HPFS_FS=m
465 +CONFIG_PROC_FS=y
466 +CONFIG_DEVFS_FS=y
467 +CONFIG_DEVFS_MOUNT=y
468 +# CONFIG_DEVFS_DEBUG is not set
469 +CONFIG_DEVPTS_FS=y
470 +CONFIG_QNX4FS_FS=m
471 +# CONFIG_QNX4FS_RW is not set
472 +CONFIG_ROMFS_FS=m
473 +CONFIG_EXT2_FS=y
474 +CONFIG_SYSV_FS=m
475 +CONFIG_UDF_FS=m
476 +# CONFIG_UDF_RW is not set
477 +CONFIG_UFS_FS=m
478 +# CONFIG_UFS_FS_WRITE is not set
479 +
480 +#
481 +# Network File Systems
482 +#
483 +# CONFIG_CODA_FS is not set
484 +# CONFIG_INTERMEZZO_FS is not set
485 +CONFIG_NFS_FS=y
486 +CONFIG_NFS_V3=y
487 +CONFIG_NFSD=y
488 +CONFIG_NFSD_V3=y
489 +CONFIG_SUNRPC=y
490 +CONFIG_LOCKD=y
491 +CONFIG_LOCKD_V4=y
492 +# CONFIG_SMB_FS is not set
493 +# CONFIG_NCP_FS is not set
494 +# CONFIG_ZISOFS_FS is not set
495 +CONFIG_ZLIB_FS_INFLATE=m
496 +
497 +#
498 +# Partition Types
499 +#
500 +# CONFIG_PARTITION_ADVANCED is not set
501 +CONFIG_MSDOS_PARTITION=y
502 +# CONFIG_SMB_NLS is not set
503 +CONFIG_NLS=y
504 +
505 +#
506 +# Native Language Support
507 +#
508 +CONFIG_NLS_DEFAULT="iso8859-1"
509 +# CONFIG_NLS_CODEPAGE_437 is not set
510 +# CONFIG_NLS_CODEPAGE_737 is not set
511 +# CONFIG_NLS_CODEPAGE_775 is not set
512 +# CONFIG_NLS_CODEPAGE_850 is not set
513 +# CONFIG_NLS_CODEPAGE_852 is not set
514 +# CONFIG_NLS_CODEPAGE_855 is not set
515 +# CONFIG_NLS_CODEPAGE_857 is not set
516 +# CONFIG_NLS_CODEPAGE_860 is not set
517 +# CONFIG_NLS_CODEPAGE_861 is not set
518 +# CONFIG_NLS_CODEPAGE_862 is not set
519 +# CONFIG_NLS_CODEPAGE_863 is not set
520 +# CONFIG_NLS_CODEPAGE_864 is not set
521 +# CONFIG_NLS_CODEPAGE_865 is not set
522 +# CONFIG_NLS_CODEPAGE_866 is not set
523 +# CONFIG_NLS_CODEPAGE_869 is not set
524 +# CONFIG_NLS_CODEPAGE_936 is not set
525 +# CONFIG_NLS_CODEPAGE_950 is not set
526 +# CONFIG_NLS_CODEPAGE_932 is not set
527 +# CONFIG_NLS_CODEPAGE_949 is not set
528 +# CONFIG_NLS_CODEPAGE_874 is not set
529 +# CONFIG_NLS_ISO8859_8 is not set
530 +# CONFIG_NLS_CODEPAGE_1250 is not set
531 +# CONFIG_NLS_CODEPAGE_1251 is not set
532 +# CONFIG_NLS_ISO8859_1 is not set
533 +# CONFIG_NLS_ISO8859_2 is not set
534 +# CONFIG_NLS_ISO8859_3 is not set
535 +# CONFIG_NLS_ISO8859_4 is not set
536 +# CONFIG_NLS_ISO8859_5 is not set
537 +# CONFIG_NLS_ISO8859_6 is not set
538 +# CONFIG_NLS_ISO8859_7 is not set
539 +# CONFIG_NLS_ISO8859_9 is not set
540 +# CONFIG_NLS_ISO8859_13 is not set
541 +# CONFIG_NLS_ISO8859_14 is not set
542 +# CONFIG_NLS_ISO8859_15 is not set
543 +# CONFIG_NLS_KOI8_R is not set
544 +# CONFIG_NLS_KOI8_U is not set
545 +# CONFIG_NLS_UTF8 is not set
546 +
547 +#
548 +# SCSI support
549 +#
550 +CONFIG_SCSI=y
551 +
552 +#
553 +# SCSI support type (disk, tape, CD-ROM)
554 +#
555 +# CONFIG_BLK_DEV_SD is not set
556 +# CONFIG_CHR_DEV_ST is not set
557 +# CONFIG_BLK_DEV_SR is not set
558 +# CONFIG_CHR_DEV_SG is not set
559 +
560 +#
561 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
562 +#
563 +# CONFIG_SCSI_DEBUG_QUEUES is not set
564 +# CONFIG_SCSI_MULTI_LUN is not set
565 +# CONFIG_SCSI_CONSTANTS is not set
566 +# CONFIG_SCSI_LOGGING is not set
567 +CONFIG_SCSI_DEBUG=m
568 +
569 +#
570 +# Multi-device support (RAID and LVM)
571 +#
572 +# CONFIG_MD is not set
573 +
574 +#
575 +# Memory Technology Devices (MTD)
576 +#
577 +# CONFIG_MTD is not set
578 +
579 +#
580 +# Kernel hacking
581 +#
582 +# CONFIG_DEBUG_SLAB is not set
583 +# CONFIG_DEBUGSYM is not set
584 diff -Naur -X ../exclude-files orig/arch/um/config_scsi.in um/arch/um/config_scsi.in
585 --- orig/arch/um/config_scsi.in 1969-12-31 19:00:00.000000000 -0500
586 +++ um/arch/um/config_scsi.in   2002-10-23 21:08:04.000000000 -0400
587 @@ -0,0 +1,30 @@
588 +comment 'SCSI support type (disk, tape, CD-ROM)'
589 +
590 +dep_tristate '  SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
591 +
592 +if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
593 +   int  'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
594 +fi
595 +
596 +dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
597 +
598 +dep_tristate '  SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
599 +
600 +if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
601 +   bool '    Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
602 +   int  'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2
603 +fi
604 +dep_tristate '  SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
605 +
606 +comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
607 +
608 +#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
609 +   bool '  Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES
610 +#fi
611 +
612 +bool '  Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
613 +  
614 +bool '  Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
615 +bool '  SCSI logging facility' CONFIG_SCSI_LOGGING
616 +
617 +dep_tristate 'SCSI debugging host simulator (EXPERIMENTAL)' CONFIG_SCSI_DEBUG $CONFIG_SCSI
618 diff -Naur -X ../exclude-files orig/arch/um/defconfig um/arch/um/defconfig
619 --- orig/arch/um/defconfig      1969-12-31 19:00:00.000000000 -0500
620 +++ um/arch/um/defconfig        2003-01-20 11:26:54.000000000 -0500
621 @@ -0,0 +1,396 @@
622 +#
623 +# Automatically generated make config: don't edit
624 +#
625 +CONFIG_USERMODE=y
626 +# CONFIG_ISA is not set
627 +# CONFIG_SBUS is not set
628 +# CONFIG_PCI is not set
629 +CONFIG_UID16=y
630 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
631 +
632 +#
633 +# Code maturity level options
634 +#
635 +CONFIG_EXPERIMENTAL=y
636 +
637 +#
638 +# General Setup
639 +#
640 +CONFIG_MODE_TT=y
641 +CONFIG_MODE_SKAS=y
642 +CONFIG_NET=y
643 +CONFIG_SYSVIPC=y
644 +CONFIG_BSD_PROCESS_ACCT=y
645 +CONFIG_SYSCTL=y
646 +CONFIG_BINFMT_AOUT=y
647 +CONFIG_BINFMT_ELF=y
648 +CONFIG_BINFMT_MISC=y
649 +CONFIG_HOSTFS=y
650 +CONFIG_HPPFS=y
651 +CONFIG_MCONSOLE=y
652 +CONFIG_MAGIC_SYSRQ=y
653 +# CONFIG_HOST_2G_2G is not set
654 +# CONFIG_UML_SMP is not set
655 +# CONFIG_SMP is not set
656 +CONFIG_NEST_LEVEL=0
657 +CONFIG_KERNEL_HALF_GIGS=1
658 +# CONFIG_HIGHMEM is not set
659 +CONFIG_PROC_MM=y
660 +CONFIG_KERNEL_STACK_ORDER=2
661 +
662 +#
663 +# Loadable module support
664 +#
665 +CONFIG_MODULES=y
666 +# CONFIG_KMOD is not set
667 +
668 +#
669 +# Character Devices
670 +#
671 +CONFIG_STDIO_CONSOLE=y
672 +CONFIG_SSL=y
673 +CONFIG_FD_CHAN=y
674 +CONFIG_NULL_CHAN=y
675 +CONFIG_PORT_CHAN=y
676 +CONFIG_PTY_CHAN=y
677 +CONFIG_TTY_CHAN=y
678 +CONFIG_XTERM_CHAN=y
679 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
680 +CONFIG_CON_CHAN="xterm"
681 +CONFIG_SSL_CHAN="pty"
682 +CONFIG_UNIX98_PTYS=y
683 +CONFIG_UNIX98_PTY_COUNT=256
684 +# CONFIG_WATCHDOG is not set
685 +# CONFIG_WATCHDOG_NOWAYOUT is not set
686 +# CONFIG_SOFT_WATCHDOG is not set
687 +# CONFIG_UML_WATCHDOG is not set
688 +CONFIG_UML_SOUND=y
689 +CONFIG_SOUND=y
690 +CONFIG_HOSTAUDIO=y
691 +# CONFIG_TTY_LOG is not set
692 +
693 +#
694 +# Block Devices
695 +#
696 +CONFIG_BLK_DEV_UBD=y
697 +# CONFIG_BLK_DEV_UBD_SYNC is not set
698 +CONFIG_BLK_DEV_LOOP=y
699 +CONFIG_BLK_DEV_NBD=y
700 +CONFIG_BLK_DEV_RAM=y
701 +CONFIG_BLK_DEV_RAM_SIZE=4096
702 +CONFIG_BLK_DEV_INITRD=y
703 +# CONFIG_MMAPPER is not set
704 +CONFIG_NETDEVICES=y
705 +
706 +#
707 +# Network Devices
708 +#
709 +CONFIG_UML_NET=y
710 +CONFIG_UML_NET_ETHERTAP=y
711 +CONFIG_UML_NET_TUNTAP=y
712 +CONFIG_UML_NET_SLIP=y
713 +CONFIG_UML_NET_SLIRP=y
714 +CONFIG_UML_NET_DAEMON=y
715 +CONFIG_UML_NET_MCAST=y
716 +# CONFIG_UML_NET_PCAP is not set
717 +CONFIG_DUMMY=y
718 +# CONFIG_BONDING is not set
719 +# CONFIG_EQUALIZER is not set
720 +CONFIG_TUN=y
721 +CONFIG_PPP=y
722 +# CONFIG_PPP_MULTILINK is not set
723 +# CONFIG_PPP_FILTER is not set
724 +# CONFIG_PPP_ASYNC is not set
725 +# CONFIG_PPP_SYNC_TTY is not set
726 +# CONFIG_PPP_DEFLATE is not set
727 +# CONFIG_PPP_BSDCOMP is not set
728 +# CONFIG_PPPOE is not set
729 +CONFIG_SLIP=y
730 +# CONFIG_SLIP_COMPRESSED is not set
731 +# CONFIG_SLIP_SMART is not set
732 +# CONFIG_SLIP_MODE_SLIP6 is not set
733 +
734 +#
735 +# Networking options
736 +#
737 +CONFIG_PACKET=y
738 +CONFIG_PACKET_MMAP=y
739 +# CONFIG_NETLINK_DEV is not set
740 +# CONFIG_NETFILTER is not set
741 +# CONFIG_FILTER is not set
742 +CONFIG_UNIX=y
743 +CONFIG_INET=y
744 +# CONFIG_IP_MULTICAST is not set
745 +# CONFIG_IP_ADVANCED_ROUTER is not set
746 +# CONFIG_IP_PNP is not set
747 +# CONFIG_NET_IPIP is not set
748 +# CONFIG_NET_IPGRE is not set
749 +# CONFIG_ARPD is not set
750 +# CONFIG_INET_ECN is not set
751 +# CONFIG_SYN_COOKIES is not set
752 +# CONFIG_IPV6 is not set
753 +# CONFIG_KHTTPD is not set
754 +# CONFIG_ATM is not set
755 +# CONFIG_VLAN_8021Q is not set
756 +
757 +#
758 +#  
759 +#
760 +# CONFIG_IPX is not set
761 +# CONFIG_ATALK is not set
762 +
763 +#
764 +# Appletalk devices
765 +#
766 +# CONFIG_DEV_APPLETALK is not set
767 +# CONFIG_DECNET is not set
768 +# CONFIG_BRIDGE is not set
769 +# CONFIG_X25 is not set
770 +# CONFIG_LAPB is not set
771 +# CONFIG_LLC is not set
772 +# CONFIG_NET_DIVERT is not set
773 +# CONFIG_ECONET is not set
774 +# CONFIG_WAN_ROUTER is not set
775 +# CONFIG_NET_FASTROUTE is not set
776 +# CONFIG_NET_HW_FLOWCONTROL is not set
777 +
778 +#
779 +# QoS and/or fair queueing
780 +#
781 +# CONFIG_NET_SCHED is not set
782 +
783 +#
784 +# Network testing
785 +#
786 +# CONFIG_NET_PKTGEN is not set
787 +
788 +#
789 +# File systems
790 +#
791 +CONFIG_QUOTA=y
792 +CONFIG_AUTOFS_FS=y
793 +CONFIG_AUTOFS4_FS=y
794 +CONFIG_REISERFS_FS=y
795 +# CONFIG_REISERFS_CHECK is not set
796 +# CONFIG_REISERFS_PROC_INFO is not set
797 +# CONFIG_ADFS_FS is not set
798 +# CONFIG_ADFS_FS_RW is not set
799 +# CONFIG_AFFS_FS is not set
800 +# CONFIG_HFS_FS is not set
801 +# CONFIG_BFS_FS is not set
802 +# CONFIG_EXT3_FS is not set
803 +# CONFIG_JBD is not set
804 +# CONFIG_JBD_DEBUG is not set
805 +CONFIG_FAT_FS=y
806 +CONFIG_MSDOS_FS=y
807 +CONFIG_UMSDOS_FS=y
808 +CONFIG_VFAT_FS=y
809 +# CONFIG_EFS_FS is not set
810 +CONFIG_JFFS_FS=y
811 +CONFIG_JFFS_FS_VERBOSE=0
812 +CONFIG_JFFS_PROC_FS=y
813 +CONFIG_JFFS2_FS=y
814 +CONFIG_JFFS2_FS_DEBUG=0
815 +# CONFIG_CRAMFS is not set
816 +# CONFIG_TMPFS is not set
817 +CONFIG_RAMFS=y
818 +CONFIG_ISO9660_FS=y
819 +# CONFIG_JOLIET is not set
820 +# CONFIG_ZISOFS is not set
821 +CONFIG_MINIX_FS=y
822 +# CONFIG_VXFS_FS is not set
823 +# CONFIG_NTFS_FS is not set
824 +# CONFIG_NTFS_RW is not set
825 +# CONFIG_HPFS_FS is not set
826 +CONFIG_PROC_FS=y
827 +CONFIG_DEVFS_FS=y
828 +CONFIG_DEVFS_MOUNT=y
829 +# CONFIG_DEVFS_DEBUG is not set
830 +CONFIG_DEVPTS_FS=y
831 +# CONFIG_QNX4FS_FS is not set
832 +# CONFIG_QNX4FS_RW is not set
833 +# CONFIG_ROMFS_FS is not set
834 +CONFIG_EXT2_FS=y
835 +# CONFIG_SYSV_FS is not set
836 +# CONFIG_UDF_FS is not set
837 +# CONFIG_UDF_RW is not set
838 +# CONFIG_UFS_FS is not set
839 +# CONFIG_UFS_FS_WRITE is not set
840 +
841 +#
842 +# Network File Systems
843 +#
844 +# CONFIG_CODA_FS is not set
845 +# CONFIG_INTERMEZZO_FS is not set
846 +# CONFIG_NFS_FS is not set
847 +# CONFIG_NFS_V3 is not set
848 +# CONFIG_ROOT_NFS is not set
849 +# CONFIG_NFSD is not set
850 +# CONFIG_NFSD_V3 is not set
851 +# CONFIG_SUNRPC is not set
852 +# CONFIG_LOCKD is not set
853 +# CONFIG_SMB_FS is not set
854 +# CONFIG_NCP_FS is not set
855 +# CONFIG_NCPFS_PACKET_SIGNING is not set
856 +# CONFIG_NCPFS_IOCTL_LOCKING is not set
857 +# CONFIG_NCPFS_STRONG is not set
858 +# CONFIG_NCPFS_NFS_NS is not set
859 +# CONFIG_NCPFS_OS2_NS is not set
860 +# CONFIG_NCPFS_SMALLDOS is not set
861 +# CONFIG_NCPFS_NLS is not set
862 +# CONFIG_NCPFS_EXTRAS is not set
863 +# CONFIG_ZISOFS_FS is not set
864 +# CONFIG_ZLIB_FS_INFLATE is not set
865 +
866 +#
867 +# Partition Types
868 +#
869 +# CONFIG_PARTITION_ADVANCED is not set
870 +CONFIG_MSDOS_PARTITION=y
871 +# CONFIG_SMB_NLS is not set
872 +CONFIG_NLS=y
873 +
874 +#
875 +# Native Language Support
876 +#
877 +CONFIG_NLS_DEFAULT="iso8859-1"
878 +# CONFIG_NLS_CODEPAGE_437 is not set
879 +# CONFIG_NLS_CODEPAGE_737 is not set
880 +# CONFIG_NLS_CODEPAGE_775 is not set
881 +# CONFIG_NLS_CODEPAGE_850 is not set
882 +# CONFIG_NLS_CODEPAGE_852 is not set
883 +# CONFIG_NLS_CODEPAGE_855 is not set
884 +# CONFIG_NLS_CODEPAGE_857 is not set
885 +# CONFIG_NLS_CODEPAGE_860 is not set
886 +# CONFIG_NLS_CODEPAGE_861 is not set
887 +# CONFIG_NLS_CODEPAGE_862 is not set
888 +# CONFIG_NLS_CODEPAGE_863 is not set
889 +# CONFIG_NLS_CODEPAGE_864 is not set
890 +# CONFIG_NLS_CODEPAGE_865 is not set
891 +# CONFIG_NLS_CODEPAGE_866 is not set
892 +# CONFIG_NLS_CODEPAGE_869 is not set
893 +# CONFIG_NLS_CODEPAGE_936 is not set
894 +# CONFIG_NLS_CODEPAGE_950 is not set
895 +# CONFIG_NLS_CODEPAGE_932 is not set
896 +# CONFIG_NLS_CODEPAGE_949 is not set
897 +# CONFIG_NLS_CODEPAGE_874 is not set
898 +# CONFIG_NLS_ISO8859_8 is not set
899 +# CONFIG_NLS_CODEPAGE_1250 is not set
900 +# CONFIG_NLS_CODEPAGE_1251 is not set
901 +# CONFIG_NLS_ISO8859_1 is not set
902 +# CONFIG_NLS_ISO8859_2 is not set
903 +# CONFIG_NLS_ISO8859_3 is not set
904 +# CONFIG_NLS_ISO8859_4 is not set
905 +# CONFIG_NLS_ISO8859_5 is not set
906 +# CONFIG_NLS_ISO8859_6 is not set
907 +# CONFIG_NLS_ISO8859_7 is not set
908 +# CONFIG_NLS_ISO8859_9 is not set
909 +# CONFIG_NLS_ISO8859_13 is not set
910 +# CONFIG_NLS_ISO8859_14 is not set
911 +# CONFIG_NLS_ISO8859_15 is not set
912 +# CONFIG_NLS_KOI8_R is not set
913 +# CONFIG_NLS_KOI8_U is not set
914 +# CONFIG_NLS_UTF8 is not set
915 +
916 +#
917 +# SCSI support
918 +#
919 +CONFIG_SCSI=y
920 +
921 +#
922 +# SCSI support type (disk, tape, CD-ROM)
923 +#
924 +# CONFIG_BLK_DEV_SD is not set
925 +# CONFIG_CHR_DEV_ST is not set
926 +# CONFIG_BLK_DEV_SR is not set
927 +# CONFIG_CHR_DEV_SG is not set
928 +
929 +#
930 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
931 +#
932 +# CONFIG_SCSI_DEBUG_QUEUES is not set
933 +# CONFIG_SCSI_MULTI_LUN is not set
934 +# CONFIG_SCSI_CONSTANTS is not set
935 +# CONFIG_SCSI_LOGGING is not set
936 +CONFIG_SCSI_DEBUG=y
937 +
938 +#
939 +# Multi-device support (RAID and LVM)
940 +#
941 +# CONFIG_MD is not set
942 +# CONFIG_BLK_DEV_MD is not set
943 +# CONFIG_MD_LINEAR is not set
944 +# CONFIG_MD_RAID0 is not set
945 +# CONFIG_MD_RAID1 is not set
946 +# CONFIG_MD_RAID5 is not set
947 +# CONFIG_MD_MULTIPATH is not set
948 +# CONFIG_BLK_DEV_LVM is not set
949 +
950 +#
951 +# Memory Technology Devices (MTD)
952 +#
953 +CONFIG_MTD=y
954 +# CONFIG_MTD_DEBUG is not set
955 +# CONFIG_MTD_PARTITIONS is not set
956 +# CONFIG_MTD_CONCAT is not set
957 +# CONFIG_MTD_REDBOOT_PARTS is not set
958 +
959 +#
960 +# User Modules And Translation Layers
961 +#
962 +CONFIG_MTD_CHAR=y
963 +CONFIG_MTD_BLOCK=y
964 +# CONFIG_FTL is not set
965 +# CONFIG_NFTL is not set
966 +
967 +#
968 +# RAM/ROM/Flash chip drivers
969 +#
970 +# CONFIG_MTD_CFI is not set
971 +# CONFIG_MTD_JEDECPROBE is not set
972 +# CONFIG_MTD_GEN_PROBE is not set
973 +# CONFIG_MTD_CFI_INTELEXT is not set
974 +# CONFIG_MTD_CFI_AMDSTD is not set
975 +# CONFIG_MTD_RAM is not set
976 +# CONFIG_MTD_ROM is not set
977 +# CONFIG_MTD_ABSENT is not set
978 +# CONFIG_MTD_OBSOLETE_CHIPS is not set
979 +# CONFIG_MTD_AMDSTD is not set
980 +# CONFIG_MTD_SHARP is not set
981 +# CONFIG_MTD_JEDEC is not set
982 +
983 +#
984 +# Mapping drivers for chip access
985 +#
986 +# CONFIG_MTD_PHYSMAP is not set
987 +# CONFIG_MTD_PCI is not set
988 +
989 +#
990 +# Self-contained MTD device drivers
991 +#
992 +# CONFIG_MTD_PMC551 is not set
993 +# CONFIG_MTD_SLRAM is not set
994 +# CONFIG_MTD_MTDRAM is not set
995 +CONFIG_MTD_BLKMTD=y
996 +
997 +#
998 +# Disk-On-Chip Device Drivers
999 +#
1000 +# CONFIG_MTD_DOC1000 is not set
1001 +# CONFIG_MTD_DOC2000 is not set
1002 +# CONFIG_MTD_DOC2001 is not set
1003 +# CONFIG_MTD_DOCPROBE is not set
1004 +
1005 +#
1006 +# NAND Flash Device Drivers
1007 +#
1008 +# CONFIG_MTD_NAND is not set
1009 +
1010 +#
1011 +# Kernel hacking
1012 +#
1013 +# CONFIG_DEBUG_SLAB is not set
1014 +CONFIG_DEBUGSYM=y
1015 +CONFIG_PT_PROXY=y
1016 +# CONFIG_GPROF is not set
1017 +# CONFIG_GCOV is not set
1018 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_kern.c um/arch/um/drivers/chan_kern.c
1019 --- orig/arch/um/drivers/chan_kern.c    1969-12-31 19:00:00.000000000 -0500
1020 +++ um/arch/um/drivers/chan_kern.c      2003-03-06 19:25:16.000000000 -0500
1021 @@ -0,0 +1,510 @@
1022 +/* 
1023 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
1024 + * Licensed under the GPL
1025 + */
1026 +
1027 +#include <linux/stddef.h>
1028 +#include <linux/kernel.h>
1029 +#include <linux/list.h>
1030 +#include <linux/slab.h>
1031 +#include <linux/tty.h>
1032 +#include <linux/string.h>
1033 +#include <linux/tty_flip.h>
1034 +#include <asm/irq.h>
1035 +#include "chan_kern.h"
1036 +#include "user_util.h"
1037 +#include "kern.h"
1038 +#include "irq_user.h"
1039 +#include "sigio.h"
1040 +#include "line.h"
1041 +
1042 +static void *not_configged_init(char *str, int device, struct chan_opts *opts)
1043 +{
1044 +       printk(KERN_ERR "Using a channel type which is configured out of "
1045 +              "UML\n");
1046 +       return(NULL);
1047 +}
1048 +
1049 +static int not_configged_open(int input, int output, int primary, void *data,
1050 +                             char **dev_out)
1051 +{
1052 +       printk(KERN_ERR "Using a channel type which is configured out of "
1053 +              "UML\n");
1054 +       return(-ENODEV);
1055 +}
1056 +
1057 +static void not_configged_close(int fd, void *data)
1058 +{
1059 +       printk(KERN_ERR "Using a channel type which is configured out of "
1060 +              "UML\n");
1061 +}
1062 +
1063 +static int not_configged_read(int fd, char *c_out, void *data)
1064 +{
1065 +       printk(KERN_ERR "Using a channel type which is configured out of "
1066 +              "UML\n");
1067 +       return(-EIO);
1068 +}
1069 +
1070 +static int not_configged_write(int fd, const char *buf, int len, void *data)
1071 +{
1072 +       printk(KERN_ERR "Using a channel type which is configured out of "
1073 +              "UML\n");
1074 +       return(-EIO);
1075 +}
1076 +
1077 +static int not_configged_console_write(int fd, const char *buf, int len,
1078 +                                      void *data)
1079 +{
1080 +       printk(KERN_ERR "Using a channel type which is configured out of "
1081 +              "UML\n");
1082 +       return(-EIO);
1083 +}
1084 +
1085 +static int not_configged_window_size(int fd, void *data, unsigned short *rows,
1086 +                                    unsigned short *cols)
1087 +{
1088 +       printk(KERN_ERR "Using a channel type which is configured out of "
1089 +              "UML\n");
1090 +       return(-ENODEV);
1091 +}
1092 +
1093 +static void not_configged_free(void *data)
1094 +{
1095 +       printk(KERN_ERR "Using a channel type which is configured out of "
1096 +              "UML\n");
1097 +}
1098 +
1099 +static struct chan_ops not_configged_ops = {
1100 +       .init           = not_configged_init,
1101 +       .open           = not_configged_open,
1102 +       .close          = not_configged_close,
1103 +       .read           = not_configged_read,
1104 +       .write          = not_configged_write,
1105 +       .console_write  = not_configged_console_write,
1106 +       .window_size    = not_configged_window_size,
1107 +       .free           = not_configged_free,
1108 +       .winch          = 0,
1109 +};
1110 +
1111 +static void tty_receive_char(struct tty_struct *tty, char ch)
1112 +{
1113 +       if(tty == NULL) return;
1114 +
1115 +       if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
1116 +               if(ch == STOP_CHAR(tty)){
1117 +                       stop_tty(tty);
1118 +                       return;
1119 +               }
1120 +               else if(ch == START_CHAR(tty)){
1121 +                       start_tty(tty);
1122 +                       return;
1123 +               }
1124 +       }
1125 +
1126 +       if((tty->flip.flag_buf_ptr == NULL) || 
1127 +          (tty->flip.char_buf_ptr == NULL))
1128 +               return;
1129 +       tty_insert_flip_char(tty, ch, TTY_NORMAL);
1130 +}
1131 +
1132 +static int open_one_chan(struct chan *chan, int input, int output, int primary)
1133 +{
1134 +       int fd;
1135 +
1136 +       if(chan->opened) return(0);
1137 +       if(chan->ops->open == NULL) fd = 0;
1138 +       else fd = (*chan->ops->open)(input, output, primary, chan->data,
1139 +                                    &chan->dev);
1140 +       if(fd < 0) return(fd);
1141 +       chan->fd = fd;
1142 +
1143 +       chan->opened = 1;
1144 +       return(0);
1145 +}
1146 +
1147 +int open_chan(struct list_head *chans)
1148 +{
1149 +       struct list_head *ele;
1150 +       struct chan *chan;
1151 +       int ret, err = 0;
1152 +
1153 +       list_for_each(ele, chans){
1154 +               chan = list_entry(ele, struct chan, list);
1155 +               ret = open_one_chan(chan, chan->input, chan->output,
1156 +                                   chan->primary);
1157 +               if(chan->primary) err = ret;
1158 +       }
1159 +       return(err);
1160 +}
1161 +
1162 +void chan_enable_winch(struct list_head *chans, void *line)
1163 +{
1164 +       struct list_head *ele;
1165 +       struct chan *chan;
1166 +
1167 +       list_for_each(ele, chans){
1168 +               chan = list_entry(ele, struct chan, list);
1169 +               if(chan->primary && chan->output && chan->ops->winch){
1170 +                       register_winch(chan->fd, line);
1171 +                       return;
1172 +               }
1173 +       }
1174 +}
1175 +
1176 +void enable_chan(struct list_head *chans, void *data)
1177 +{
1178 +       struct list_head *ele;
1179 +       struct chan *chan;
1180 +
1181 +       list_for_each(ele, chans){
1182 +               chan = list_entry(ele, struct chan, list);
1183 +               if(!chan->opened) continue;
1184 +
1185 +               line_setup_irq(chan->fd, chan->input, chan->output, data);
1186 +       }
1187 +}
1188 +
1189 +void close_chan(struct list_head *chans)
1190 +{
1191 +       struct list_head *ele;
1192 +       struct chan *chan;
1193 +
1194 +       /* Close in reverse order as open in case more than one of them
1195 +        * refers to the same device and they save and restore that device's
1196 +        * state.  Then, the first one opened will have the original state,
1197 +        * so it must be the last closed.
1198 +        */
1199 +        for(ele = chans->prev; ele != chans; ele = ele->prev){
1200 +                chan = list_entry(ele, struct chan, list);
1201 +               if(!chan->opened) continue;
1202 +               if(chan->ops->close != NULL)
1203 +                       (*chan->ops->close)(chan->fd, chan->data);
1204 +               chan->opened = 0;
1205 +               chan->fd = -1;
1206 +       }
1207 +}
1208 +
1209 +int write_chan(struct list_head *chans, const char *buf, int len, 
1210 +              int write_irq)
1211 +{
1212 +       struct list_head *ele;
1213 +       struct chan *chan;
1214 +       int n, ret = 0;
1215 +
1216 +       list_for_each(ele, chans){
1217 +               chan = list_entry(ele, struct chan, list);
1218 +               if(!chan->output || (chan->ops->write == NULL)) continue;
1219 +               n = chan->ops->write(chan->fd, buf, len, chan->data);
1220 +               if(chan->primary){
1221 +                       ret = n;
1222 +                       if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
1223 +                               reactivate_fd(chan->fd, write_irq);
1224 +                               if(ret == -EAGAIN) ret = 0;
1225 +                       }
1226 +               }
1227 +       }
1228 +       return(ret);
1229 +}
1230 +
1231 +int console_write_chan(struct list_head *chans, const char *buf, int len)
1232 +{
1233 +       struct list_head *ele;
1234 +       struct chan *chan;
1235 +       int n, ret = 0;
1236 +
1237 +       list_for_each(ele, chans){
1238 +               chan = list_entry(ele, struct chan, list);
1239 +               if(!chan->output || (chan->ops->console_write == NULL))
1240 +                       continue;
1241 +               n = chan->ops->console_write(chan->fd, buf, len, chan->data);
1242 +               if(chan->primary) ret = n;
1243 +       }
1244 +       return(ret);
1245 +}
1246 +
1247 +int chan_window_size(struct list_head *chans, unsigned short *rows_out,
1248 +                     unsigned short *cols_out)
1249 +{
1250 +       struct list_head *ele;
1251 +       struct chan *chan;
1252 +
1253 +       list_for_each(ele, chans){
1254 +               chan = list_entry(ele, struct chan, list);
1255 +               if(chan->primary){
1256 +                       if(chan->ops->window_size == NULL) return(0);
1257 +                       return(chan->ops->window_size(chan->fd, chan->data,
1258 +                                                     rows_out, cols_out));
1259 +               }
1260 +       }
1261 +       return(0);
1262 +}
1263 +
1264 +void free_one_chan(struct chan *chan)
1265 +{
1266 +       list_del(&chan->list);
1267 +       if(chan->ops->free != NULL)
1268 +               (*chan->ops->free)(chan->data);
1269 +       free_irq_by_fd(chan->fd);
1270 +       if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
1271 +       kfree(chan);
1272 +}
1273 +
1274 +void free_chan(struct list_head *chans)
1275 +{
1276 +       struct list_head *ele, *next;
1277 +       struct chan *chan;
1278 +
1279 +       list_for_each_safe(ele, next, chans){
1280 +               chan = list_entry(ele, struct chan, list);
1281 +               free_one_chan(chan);
1282 +       }
1283 +}
1284 +
1285 +static int one_chan_config_string(struct chan *chan, char *str, int size,
1286 +                                 char **error_out)
1287 +{
1288 +       int n = 0;
1289 +
1290 +       CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
1291 +
1292 +       if(chan->dev == NULL){
1293 +               CONFIG_CHUNK(str, size, n, "", 1);
1294 +               return(n);
1295 +       }
1296 +
1297 +       CONFIG_CHUNK(str, size, n, ":", 0);
1298 +       CONFIG_CHUNK(str, size, n, chan->dev, 0);
1299 +
1300 +       return(n);
1301 +}
1302 +
1303 +static int chan_pair_config_string(struct chan *in, struct chan *out, 
1304 +                                  char *str, int size, char **error_out)
1305 +{
1306 +       int n;
1307 +
1308 +       n = one_chan_config_string(in, str, size, error_out);
1309 +       str += n;
1310 +       size -= n;
1311 +
1312 +       if(in == out){
1313 +               CONFIG_CHUNK(str, size, n, "", 1);
1314 +               return(n);
1315 +       }
1316 +
1317 +       CONFIG_CHUNK(str, size, n, ",", 1);
1318 +       n = one_chan_config_string(out, str, size, error_out);
1319 +       str += n;
1320 +       size -= n;
1321 +       CONFIG_CHUNK(str, size, n, "", 1);
1322 +
1323 +       return(n);
1324 +}
1325 +
1326 +int chan_config_string(struct list_head *chans, char *str, int size, 
1327 +                      char **error_out)
1328 +{
1329 +       struct list_head *ele;
1330 +       struct chan *chan, *in = NULL, *out = NULL;
1331 +
1332 +       list_for_each(ele, chans){
1333 +               chan = list_entry(ele, struct chan, list);
1334 +               if(!chan->primary)
1335 +                       continue;
1336 +               if(chan->input)
1337 +                       in = chan;
1338 +               if(chan->output)
1339 +                       out = chan;
1340 +       }
1341 +
1342 +       return(chan_pair_config_string(in, out, str, size, error_out));
1343 +}
1344 +
1345 +struct chan_type {
1346 +       char *key;
1347 +       struct chan_ops *ops;
1348 +};
1349 +
1350 +struct chan_type chan_table[] = {
1351 +#ifdef CONFIG_FD_CHAN
1352 +       { "fd", &fd_ops },
1353 +#else
1354 +       { "fd", &not_configged_ops },
1355 +#endif
1356 +
1357 +#ifdef CONFIG_NULL_CHAN
1358 +       { "null", &null_ops },
1359 +#else
1360 +       { "null", &not_configged_ops },
1361 +#endif
1362 +
1363 +#ifdef CONFIG_PORT_CHAN
1364 +       { "port", &port_ops },
1365 +#else
1366 +       { "port", &not_configged_ops },
1367 +#endif
1368 +
1369 +#ifdef CONFIG_PTY_CHAN
1370 +       { "pty", &pty_ops },
1371 +       { "pts", &pts_ops },
1372 +#else
1373 +       { "pty", &not_configged_ops },
1374 +       { "pts", &not_configged_ops },
1375 +#endif
1376 +
1377 +#ifdef CONFIG_TTY_CHAN
1378 +       { "tty", &tty_ops },
1379 +#else
1380 +       { "tty", &not_configged_ops },
1381 +#endif
1382 +
1383 +#ifdef CONFIG_XTERM_CHAN
1384 +       { "xterm", &xterm_ops },
1385 +#else
1386 +       { "xterm", &not_configged_ops },
1387 +#endif
1388 +};
1389 +
1390 +static struct chan *parse_chan(char *str, int pri, int device, 
1391 +                              struct chan_opts *opts)
1392 +{
1393 +       struct chan_type *entry;
1394 +       struct chan_ops *ops;
1395 +       struct chan *chan;
1396 +       void *data;
1397 +       int i;
1398 +
1399 +       ops = NULL;
1400 +       data = NULL;
1401 +       for(i = 0; i < sizeof(chan_table)/sizeof(chan_table[0]); i++){
1402 +               entry = &chan_table[i];
1403 +               if(!strncmp(str, entry->key, strlen(entry->key))){
1404 +                       ops = entry->ops;
1405 +                       str += strlen(entry->key);
1406 +                       break;
1407 +               }
1408 +       }
1409 +       if(ops == NULL){
1410 +               printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n", 
1411 +                      str);
1412 +               return(NULL);
1413 +       }
1414 +       if(ops->init == NULL) return(NULL); 
1415 +       data = (*ops->init)(str, device, opts);
1416 +       if(data == NULL) return(NULL);
1417 +
1418 +       chan = kmalloc(sizeof(*chan), GFP_KERNEL);
1419 +       if(chan == NULL) return(NULL);
1420 +       *chan = ((struct chan) { .list          = LIST_HEAD_INIT(chan->list),
1421 +                                .primary       = 1,
1422 +                                .input         = 0,
1423 +                                .output        = 0,
1424 +                                .opened        = 0,
1425 +                                .fd            = -1,
1426 +                                .pri           = pri,
1427 +                                .ops           = ops,
1428 +                                .data          = data });
1429 +       return(chan);
1430 +}
1431 +
1432 +int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
1433 +                   struct chan_opts *opts)
1434 +{
1435 +       struct chan *new, *chan;
1436 +       char *in, *out;
1437 +
1438 +       if(!list_empty(chans)){
1439 +               chan = list_entry(chans->next, struct chan, list);
1440 +               if(chan->pri >= pri) return(0);
1441 +               free_chan(chans);
1442 +               INIT_LIST_HEAD(chans);
1443 +       }
1444 +
1445 +       if((out = strchr(str, ',')) != NULL){
1446 +               in = str;
1447 +               *out = '\0';
1448 +               out++;
1449 +               new = parse_chan(in, pri, device, opts);
1450 +               if(new == NULL) return(-1);
1451 +               new->input = 1;
1452 +               list_add(&new->list, chans);
1453 +
1454 +               new = parse_chan(out, pri, device, opts);
1455 +               if(new == NULL) return(-1);
1456 +               list_add(&new->list, chans);
1457 +               new->output = 1;
1458 +       }
1459 +       else {
1460 +               new = parse_chan(str, pri, device, opts);
1461 +               if(new == NULL) return(-1);
1462 +               list_add(&new->list, chans);
1463 +               new->input = 1;
1464 +               new->output = 1;
1465 +       }
1466 +       return(0);
1467 +}
1468 +
1469 +int chan_out_fd(struct list_head *chans)
1470 +{
1471 +       struct list_head *ele;
1472 +       struct chan *chan;
1473 +
1474 +       list_for_each(ele, chans){
1475 +               chan = list_entry(ele, struct chan, list);
1476 +               if(chan->primary && chan->output)
1477 +                       return(chan->fd);
1478 +       }
1479 +       return(-1);
1480 +}
1481 +
1482 +void chan_interrupt(struct list_head *chans, struct tq_struct *task,
1483 +                   struct tty_struct *tty, int irq, void *dev)
1484 +{
1485 +       struct list_head *ele, *next;
1486 +       struct chan *chan;
1487 +       int err;
1488 +       char c;
1489 +
1490 +       list_for_each_safe(ele, next, chans){
1491 +               chan = list_entry(ele, struct chan, list);
1492 +               if(!chan->input || (chan->ops->read == NULL)) continue;
1493 +               do {
1494 +                       if((tty != NULL) && 
1495 +                          (tty->flip.count >= TTY_FLIPBUF_SIZE)){
1496 +                               queue_task(task, &tq_timer);
1497 +                               goto out;
1498 +                       }
1499 +                       err = chan->ops->read(chan->fd, &c, chan->data);
1500 +                       if(err > 0) tty_receive_char(tty, c);
1501 +               } while(err > 0);
1502 +               if(err == 0) reactivate_fd(chan->fd, irq);
1503 +               if(err == -EIO){
1504 +                       if(chan->primary){
1505 +                               if(tty != NULL) tty_hangup(tty);
1506 +                               line_disable(dev, irq);
1507 +                               close_chan(chans);
1508 +                               free_chan(chans);
1509 +                               return;
1510 +                       }
1511 +                       else {
1512 +                               if(chan->ops->close != NULL)
1513 +                                       chan->ops->close(chan->fd, chan->data);
1514 +                               free_one_chan(chan);
1515 +                       }
1516 +               }
1517 +       }
1518 + out:
1519 +       if(tty) tty_flip_buffer_push(tty);
1520 +}
1521 +
1522 +/*
1523 + * Overrides for Emacs so that we follow Linus's tabbing style.
1524 + * Emacs will notice this stuff at the end of the file and automatically
1525 + * adjust the settings for this buffer only.  This must remain at the end
1526 + * of the file.
1527 + * ---------------------------------------------------------------------------
1528 + * Local variables:
1529 + * c-file-style: "linux"
1530 + * End:
1531 + */
1532 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_user.c um/arch/um/drivers/chan_user.c
1533 --- orig/arch/um/drivers/chan_user.c    1969-12-31 19:00:00.000000000 -0500
1534 +++ um/arch/um/drivers/chan_user.c      2003-03-26 13:23:48.000000000 -0500
1535 @@ -0,0 +1,213 @@
1536 +/* 
1537 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
1538 + * Licensed under the GPL
1539 + */
1540 +
1541 +#include <unistd.h>
1542 +#include <stdlib.h>
1543 +#include <errno.h>
1544 +#include <termios.h>
1545 +#include <fcntl.h>
1546 +#include <string.h>
1547 +#include <signal.h>
1548 +#include <sys/stat.h>
1549 +#include <sys/ioctl.h>
1550 +#include <sys/socket.h>
1551 +#include "kern_util.h"
1552 +#include "user_util.h"
1553 +#include "chan_user.h"
1554 +#include "user.h"
1555 +#include "helper.h"
1556 +#include "os.h"
1557 +#include "choose-mode.h"
1558 +#include "mode.h"
1559 +
1560 +void generic_close(int fd, void *unused)
1561 +{
1562 +       close(fd);
1563 +}
1564 +
1565 +int generic_read(int fd, char *c_out, void *unused)
1566 +{
1567 +       int n;
1568 +
1569 +       n = read(fd, c_out, sizeof(*c_out));
1570 +       if(n < 0){
1571 +               if(errno == EAGAIN) return(0);
1572 +               return(-errno);
1573 +       }
1574 +       else if(n == 0) return(-EIO);
1575 +       return(1);
1576 +}
1577 +
1578 +int generic_write(int fd, const char *buf, int n, void *unused)
1579 +{
1580 +       int count;
1581 +
1582 +       count = write(fd, buf, n);
1583 +       if(count < 0) return(-errno);
1584 +       return(count);
1585 +}
1586 +
1587 +int generic_console_write(int fd, const char *buf, int n, void *unused)
1588 +{
1589 +       struct termios save, new;
1590 +       int err;
1591 +
1592 +       if(isatty(fd)){
1593 +               tcgetattr(fd, &save);
1594 +               new = save;
1595 +               new.c_oflag |= OPOST;
1596 +               tcsetattr(fd, TCSAFLUSH, &new);
1597 +       }
1598 +       err = generic_write(fd, buf, n, NULL);
1599 +       if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
1600 +       return(err);
1601 +}
1602 +
1603 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
1604 +                       unsigned short *cols_out)
1605 +{
1606 +       struct winsize size;
1607 +       int ret = 0;
1608 +
1609 +       if(ioctl(fd, TIOCGWINSZ, &size) == 0){
1610 +               ret = ((*rows_out != size.ws_row) || 
1611 +                      (*cols_out != size.ws_col));
1612 +               *rows_out = size.ws_row;
1613 +               *cols_out = size.ws_col;
1614 +       }
1615 +       return(ret);
1616 +}
1617 +
1618 +void generic_free(void *data)
1619 +{
1620 +       kfree(data);
1621 +}
1622 +
1623 +static void winch_handler(int sig)
1624 +{
1625 +}
1626 +
1627 +struct winch_data {
1628 +       int pty_fd;
1629 +       int pipe_fd;
1630 +       int close_me;
1631 +};
1632 +
1633 +static int winch_thread(void *arg)
1634 +{
1635 +       struct winch_data *data = arg;
1636 +       sigset_t sigs;
1637 +       int pty_fd, pipe_fd;
1638 +       char c = 1;
1639 +
1640 +       close(data->close_me);
1641 +       pty_fd = data->pty_fd;
1642 +       pipe_fd = data->pipe_fd;
1643 +       if(write(pipe_fd, &c, sizeof(c)) != sizeof(c))
1644 +               printk("winch_thread : failed to write synchronization "
1645 +                      "byte, errno = %d\n", errno);
1646 +
1647 +       signal(SIGWINCH, winch_handler);
1648 +       sigfillset(&sigs);
1649 +       sigdelset(&sigs, SIGWINCH);
1650 +       if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
1651 +               printk("winch_thread : sigprocmask failed, errno = %d\n", 
1652 +                      errno);
1653 +               exit(1);
1654 +       }
1655 +
1656 +       if(setsid() < 0){
1657 +               printk("winch_thread : setsid failed, errno = %d\n", errno);
1658 +               exit(1);
1659 +       }
1660 +
1661 +       if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
1662 +               printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
1663 +               exit(1);
1664 +       }
1665 +       if(tcsetpgrp(pty_fd, os_getpid()) < 0){
1666 +               printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno);
1667 +               exit(1);
1668 +       }
1669 +
1670 +       if(read(pipe_fd, &c, sizeof(c)) != sizeof(c))
1671 +               printk("winch_thread : failed to read synchronization byte, "
1672 +                      "errno = %d\n", errno);
1673 +
1674 +       while(1){
1675 +               pause();
1676 +
1677 +               if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
1678 +                       printk("winch_thread : write failed, errno = %d\n",
1679 +                              errno);
1680 +               }
1681 +       }
1682 +}
1683 +
1684 +static int winch_tramp(int fd, void *device_data, int *fd_out)
1685 +{
1686 +       struct winch_data data;
1687 +       unsigned long stack;
1688 +       int fds[2], pid, n, err;
1689 +       char c;
1690 +
1691 +       err = os_pipe(fds, 1, 1);
1692 +       if(err){
1693 +               printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
1694 +               return(err);
1695 +       }
1696 +
1697 +       data = ((struct winch_data) { .pty_fd           = fd,
1698 +                                     .pipe_fd          = fds[1],
1699 +                                     .close_me         = fds[0] } );
1700 +       pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
1701 +       if(pid < 0){
1702 +               printk("fork of winch_thread failed - errno = %d\n", errno);
1703 +               return(pid);
1704 +       }
1705 +
1706 +       close(fds[1]);
1707 +       *fd_out = fds[0];
1708 +       n = read(fds[0], &c, sizeof(c));
1709 +       if(n != sizeof(c)){
1710 +               printk("winch_tramp : failed to read synchronization byte\n");
1711 +               printk("read returned %d, errno = %d\n", n, errno);
1712 +               printk("fd %d will not support SIGWINCH\n", fd);
1713 +               *fd_out = -1;
1714 +       }
1715 +       return(pid);
1716 +}
1717 +
1718 +void register_winch(int fd, void *device_data)
1719 +{
1720 +       int pid, thread, thread_fd;
1721 +       char c = 1;
1722 +
1723 +       if(!isatty(fd)) return;
1724 +
1725 +       pid = tcgetpgrp(fd);
1726 +       if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
1727 +                            device_data) && (pid == -1)){
1728 +               thread = winch_tramp(fd, device_data, &thread_fd);
1729 +               if(fd != -1){
1730 +                       register_winch_irq(thread_fd, fd, thread, device_data);
1731 +
1732 +                       if(write(thread_fd, &c, sizeof(c)) != sizeof(c))
1733 +                               printk("register_winch : failed to write "
1734 +                                      "synchronization byte\n");
1735 +               }
1736 +       }
1737 +}
1738 +
1739 +/*
1740 + * Overrides for Emacs so that we follow Linus's tabbing style.
1741 + * Emacs will notice this stuff at the end of the file and automatically
1742 + * adjust the settings for this buffer only.  This must remain at the end
1743 + * of the file.
1744 + * ---------------------------------------------------------------------------
1745 + * Local variables:
1746 + * c-file-style: "linux"
1747 + * End:
1748 + */
1749 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow.h um/arch/um/drivers/cow.h
1750 --- orig/arch/um/drivers/cow.h  1969-12-31 19:00:00.000000000 -0500
1751 +++ um/arch/um/drivers/cow.h    2003-06-05 14:28:44.000000000 -0400
1752 @@ -0,0 +1,34 @@
1753 +#ifndef __COW_H__
1754 +#define __COW_H__
1755 +
1756 +#include <asm/types.h>
1757 +
1758 +#if __BYTE_ORDER == __BIG_ENDIAN
1759 +# define ntohll(x) (x)
1760 +# define htonll(x) (x)
1761 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
1762 +# define ntohll(x)  bswap_64(x)
1763 +# define htonll(x)  bswap_64(x)
1764 +#else
1765 +#error "__BYTE_ORDER not defined"
1766 +#endif
1767 +
1768 +extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
1769 +                        int sectorsize, int *bitmap_offset_out, 
1770 +                        unsigned long *bitmap_len_out, int *data_offset_out);
1771 +extern int read_cow_header(int fd, __u32 *magic_out, char **backing_file_out, 
1772 +                          time_t *mtime_out, __u64 *size_out, 
1773 +                          int *sectorsize_out, int *bitmap_offset_out);
1774 +extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
1775 +                           int sectorsize, long long *size);
1776 +extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
1777 +                     unsigned long *bitmap_len_out, int *data_offset_out);
1778 +
1779 +#endif
1780 +
1781 +/*
1782 + * ---------------------------------------------------------------------------
1783 + * Local variables:
1784 + * c-file-style: "linux"
1785 + * End:
1786 + */
1787 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_sys.h um/arch/um/drivers/cow_sys.h
1788 --- orig/arch/um/drivers/cow_sys.h      1969-12-31 19:00:00.000000000 -0500
1789 +++ um/arch/um/drivers/cow_sys.h        2003-06-05 14:29:25.000000000 -0400
1790 @@ -0,0 +1,48 @@
1791 +#ifndef __COW_SYS_H__
1792 +#define __COW_SYS_H__
1793 +
1794 +#include "kern_util.h"
1795 +#include "user_util.h"
1796 +#include "os.h"
1797 +#include "user.h"
1798 +
1799 +static inline void *cow_malloc(int size)
1800 +{
1801 +       return(um_kmalloc(size));
1802 +}
1803 +
1804 +static inline void cow_free(void *ptr)
1805 +{
1806 +       kfree(ptr);
1807 +}
1808 +
1809 +#define cow_printf printk
1810 +
1811 +static inline char *cow_strdup(char *str)
1812 +{
1813 +       return(uml_strdup(str));
1814 +}
1815 +
1816 +static inline int cow_seek_file(int fd, __u64 offset)
1817 +{
1818 +       return(os_seek_file(fd, offset));
1819 +}
1820 +
1821 +static inline int cow_file_size(char *file, __u64 *size_out)
1822 +{
1823 +       return(os_file_size(file, size_out));
1824 +}
1825 +
1826 +static inline int cow_write_file(int fd, char *buf, int size)
1827 +{
1828 +       return(os_write_file(fd, buf, size));
1829 +}
1830 +
1831 +#endif
1832 +
1833 +/*
1834 + * ---------------------------------------------------------------------------
1835 + * Local variables:
1836 + * c-file-style: "linux"
1837 + * End:
1838 + */
1839 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_user.c um/arch/um/drivers/cow_user.c
1840 --- orig/arch/um/drivers/cow_user.c     1969-12-31 19:00:00.000000000 -0500
1841 +++ um/arch/um/drivers/cow_user.c       2003-06-05 14:39:18.000000000 -0400
1842 @@ -0,0 +1,287 @@
1843 +#include <stddef.h>
1844 +#include <string.h>
1845 +#include <errno.h>
1846 +#include <unistd.h>
1847 +#include <byteswap.h>
1848 +#include <sys/stat.h>
1849 +#include <sys/time.h>
1850 +#include <sys/param.h>
1851 +#include <netinet/in.h>
1852 +
1853 +#include "cow.h"
1854 +#include "cow_sys.h"
1855 +
1856 +#define PATH_LEN_V1 256
1857 +
1858 +struct cow_header_v1 {
1859 +       int magic;
1860 +       int version;
1861 +       char backing_file[PATH_LEN_V1];
1862 +       time_t mtime;
1863 +       __u64 size;
1864 +       int sectorsize;
1865 +};
1866 +
1867 +#define PATH_LEN_V2 MAXPATHLEN
1868 +
1869 +struct cow_header_v2 {
1870 +       unsigned long magic;
1871 +       unsigned long version;
1872 +       char backing_file[PATH_LEN_V2];
1873 +       time_t mtime;
1874 +       __u64 size;
1875 +       int sectorsize;
1876 +};
1877 +
1878 +union cow_header {
1879 +       struct cow_header_v1 v1;
1880 +       struct cow_header_v2 v2;
1881 +};
1882 +
1883 +#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
1884 +#define COW_VERSION 2
1885 +
1886 +void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
1887 +              unsigned long *bitmap_len_out, int *data_offset_out)
1888 +{
1889 +       *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
1890 +
1891 +       *data_offset_out = bitmap_offset + *bitmap_len_out;
1892 +       *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
1893 +       *data_offset_out *= sectorsize;
1894 +}
1895 +
1896 +static int absolutize(char *to, int size, char *from)
1897 +{
1898 +       char save_cwd[256], *slash;
1899 +       int remaining;
1900 +
1901 +       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
1902 +               cow_printf("absolutize : unable to get cwd - errno = %d\n", 
1903 +                          errno);
1904 +               return(-1);
1905 +       }
1906 +       slash = strrchr(from, '/');
1907 +       if(slash != NULL){
1908 +               *slash = '\0';
1909 +               if(chdir(from)){
1910 +                       *slash = '/';
1911 +                       cow_printf("absolutize : Can't cd to '%s' - " 
1912 +                                  "errno = %d\n", from, errno);
1913 +                       return(-1);
1914 +               }
1915 +               *slash = '/';
1916 +               if(getcwd(to, size) == NULL){
1917 +                       cow_printf("absolutize : unable to get cwd of '%s' - "
1918 +                              "errno = %d\n", from, errno);
1919 +                       return(-1);
1920 +               }
1921 +               remaining = size - strlen(to);
1922 +               if(strlen(slash) + 1 > remaining){
1923 +                       cow_printf("absolutize : unable to fit '%s' into %d "
1924 +                              "chars\n", from, size);
1925 +                       return(-1);
1926 +               }
1927 +               strcat(to, slash);
1928 +       }
1929 +       else {
1930 +               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
1931 +                       cow_printf("absolutize : unable to fit '%s' into %d "
1932 +                              "chars\n", from, size);
1933 +                       return(-1);
1934 +               }
1935 +               strcpy(to, save_cwd);
1936 +               strcat(to, "/");
1937 +               strcat(to, from);
1938 +       }
1939 +       chdir(save_cwd);
1940 +       return(0);
1941 +}
1942 +
1943 +int write_cow_header(char *cow_file, int fd, char *backing_file, 
1944 +                    int sectorsize, long long *size)
1945 +{
1946 +        struct cow_header_v2 *header;
1947 +       struct stat64 buf;
1948 +       int err;
1949 +
1950 +       err = cow_seek_file(fd, 0);
1951 +       if(err != 0){
1952 +               cow_printf("write_cow_header - lseek failed, errno = %d\n", 
1953 +                          errno);
1954 +               return(-errno);
1955 +       }
1956 +
1957 +       err = -ENOMEM;
1958 +       header = cow_malloc(sizeof(*header));
1959 +       if(header == NULL){
1960 +               cow_printf("Failed to allocate COW V2 header\n");
1961 +               goto out;
1962 +       }
1963 +       header->magic = htonl(COW_MAGIC);
1964 +       header->version = htonl(COW_VERSION);
1965 +
1966 +       err = -EINVAL;
1967 +       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
1968 +               cow_printf("Backing file name \"%s\" is too long - names are "
1969 +                          "limited to %d characters\n", backing_file, 
1970 +                          sizeof(header->backing_file) - 1);
1971 +               goto out_free;
1972 +       }
1973 +
1974 +       if(absolutize(header->backing_file, sizeof(header->backing_file), 
1975 +                     backing_file))
1976 +               goto out_free;
1977 +
1978 +       err = stat64(header->backing_file, &buf);
1979 +       if(err < 0){
1980 +               cow_printf("Stat of backing file '%s' failed, errno = %d\n",
1981 +                          header->backing_file, errno);
1982 +               err = -errno;
1983 +               goto out_free;
1984 +       }
1985 +
1986 +       err = cow_file_size(header->backing_file, size);
1987 +       if(err){
1988 +               cow_printf("Couldn't get size of backing file '%s', "
1989 +                          "errno = %d\n", header->backing_file, -*size);
1990 +               goto out_free;
1991 +       }
1992 +
1993 +       header->mtime = htonl(buf.st_mtime);
1994 +       header->size = htonll(*size);
1995 +       header->sectorsize = htonl(sectorsize);
1996 +
1997 +       err = write(fd, header, sizeof(*header));
1998 +       if(err != sizeof(*header)){
1999 +               cow_printf("Write of header to new COW file '%s' failed, "
2000 +                          "errno = %d\n", cow_file, errno);
2001 +               goto out_free;
2002 +       }
2003 +       err = 0;
2004 + out_free:
2005 +       cow_free(header);
2006 + out:
2007 +       return(err);
2008 +}
2009 +
2010 +int read_cow_header(int fd, __u32 *magic_out, char **backing_file_out, 
2011 +                   time_t *mtime_out, __u64 *size_out, 
2012 +                   int *sectorsize_out, int *bitmap_offset_out)
2013 +{
2014 +       union cow_header *header;
2015 +       char *file;
2016 +       int err, n;
2017 +       unsigned long version, magic;
2018 +
2019 +       header = cow_malloc(sizeof(*header));
2020 +       if(header == NULL){
2021 +               cow_printf("read_cow_header - Failed to allocate header\n");
2022 +               return(-ENOMEM);
2023 +       }
2024 +       err = -EINVAL;
2025 +       n = read(fd, header, sizeof(*header));
2026 +       if(n < offsetof(typeof(header->v1), backing_file)){
2027 +               cow_printf("read_cow_header - short header\n");
2028 +               goto out;
2029 +       }
2030 +
2031 +       magic = header->v1.magic;
2032 +       if(magic == COW_MAGIC) {
2033 +               version = header->v1.version;
2034 +       }
2035 +       else if(magic == ntohl(COW_MAGIC)){
2036 +               version = ntohl(header->v1.version);
2037 +       }
2038 +       else goto out;
2039 +
2040 +       *magic_out = COW_MAGIC;
2041 +
2042 +       if(version == 1){
2043 +               if(n < sizeof(header->v1)){
2044 +                       cow_printf("read_cow_header - failed to read V1 "
2045 +                                  "header\n");
2046 +                       goto out;
2047 +               }
2048 +               *mtime_out = header->v1.mtime;
2049 +               *size_out = header->v1.size;
2050 +               *sectorsize_out = header->v1.sectorsize;
2051 +               *bitmap_offset_out = sizeof(header->v1);
2052 +               file = header->v1.backing_file;
2053 +       }
2054 +       else if(version == 2){
2055 +               if(n < sizeof(header->v2)){
2056 +                       cow_printf("read_cow_header - failed to read V2 "
2057 +                                  "header\n");
2058 +                       goto out;
2059 +               }
2060 +               *mtime_out = ntohl(header->v2.mtime);
2061 +               *size_out = ntohll(header->v2.size);
2062 +               *sectorsize_out = ntohl(header->v2.sectorsize);
2063 +               *bitmap_offset_out = sizeof(header->v2);
2064 +               file = header->v2.backing_file;
2065 +       }
2066 +       else {
2067 +               cow_printf("read_cow_header - invalid COW version\n");
2068 +               goto out;
2069 +       }
2070 +       err = -ENOMEM;
2071 +       *backing_file_out = cow_strdup(file);
2072 +       if(*backing_file_out == NULL){
2073 +               cow_printf("read_cow_header - failed to allocate backing "
2074 +                          "file\n");
2075 +               goto out;
2076 +       }
2077 +       err = 0;
2078 + out:
2079 +       cow_free(header);
2080 +       return(err);
2081 +}
2082 +
2083 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
2084 +                 int *bitmap_offset_out, unsigned long *bitmap_len_out, 
2085 +                 int *data_offset_out)
2086 +{
2087 +       __u64 size, offset;
2088 +       char zero = 0;
2089 +       int err;
2090 +
2091 +       err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
2092 +       if(err) 
2093 +               goto out;
2094 +       
2095 +       cow_sizes(size, sectorsize, sizeof(struct cow_header_v2), 
2096 +                 bitmap_len_out, data_offset_out);
2097 +       *bitmap_offset_out = sizeof(struct cow_header_v2);
2098 +
2099 +       offset = *data_offset_out + size - sizeof(zero);
2100 +       err = cow_seek_file(fd, offset);
2101 +       if(err != 0){
2102 +               cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
2103 +               goto out;
2104 +       }
2105 +
2106 +       /* does not really matter how much we write it is just to set EOF 
2107 +        * this also sets the entire COW bitmap
2108 +        * to zero without having to allocate it 
2109 +        */
2110 +       err = cow_write_file(fd, &zero, sizeof(zero));
2111 +       if(err != sizeof(zero)){
2112 +               err = -EINVAL;
2113 +               cow_printf("Write of bitmap to new COW file '%s' failed, "
2114 +                          "errno = %d\n", cow_file, errno);
2115 +               goto out;
2116 +       }
2117 +
2118 +       return(0);
2119 +
2120 + out:
2121 +       return(err);
2122 +}
2123 +
2124 +/*
2125 + * ---------------------------------------------------------------------------
2126 + * Local variables:
2127 + * c-file-style: "linux"
2128 + * End:
2129 + */
2130 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon.h um/arch/um/drivers/daemon.h
2131 --- orig/arch/um/drivers/daemon.h       1969-12-31 19:00:00.000000000 -0500
2132 +++ um/arch/um/drivers/daemon.h 2002-10-23 21:08:04.000000000 -0400
2133 @@ -0,0 +1,35 @@
2134 +/* 
2135 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2136 + * Licensed under the GPL
2137 + */
2138 +
2139 +#include "net_user.h"
2140 +
2141 +#define SWITCH_VERSION 3
2142 +
2143 +struct daemon_data {
2144 +       char *sock_type;
2145 +       char *ctl_sock;
2146 +       void *ctl_addr;
2147 +       void *data_addr;
2148 +       void *local_addr;
2149 +       int fd;
2150 +       int control;
2151 +       void *dev;
2152 +};
2153 +
2154 +extern struct net_user_info daemon_user_info;
2155 +
2156 +extern int daemon_user_write(int fd, void *buf, int len, 
2157 +                            struct daemon_data *pri);
2158 +
2159 +/*
2160 + * Overrides for Emacs so that we follow Linus's tabbing style.
2161 + * Emacs will notice this stuff at the end of the file and automatically
2162 + * adjust the settings for this buffer only.  This must remain at the end
2163 + * of the file.
2164 + * ---------------------------------------------------------------------------
2165 + * Local variables:
2166 + * c-file-style: "linux"
2167 + * End:
2168 + */
2169 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_kern.c um/arch/um/drivers/daemon_kern.c
2170 --- orig/arch/um/drivers/daemon_kern.c  1969-12-31 19:00:00.000000000 -0500
2171 +++ um/arch/um/drivers/daemon_kern.c    2002-12-15 21:19:17.000000000 -0500
2172 @@ -0,0 +1,113 @@
2173 +/*
2174 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
2175 + * James Leu (jleu@mindspring.net).
2176 + * Copyright (C) 2001 by various other people who didn't put their name here.
2177 + * Licensed under the GPL.
2178 + */
2179 +
2180 +#include "linux/kernel.h"
2181 +#include "linux/init.h"
2182 +#include "linux/netdevice.h"
2183 +#include "linux/etherdevice.h"
2184 +#include "net_kern.h"
2185 +#include "net_user.h"
2186 +#include "daemon.h"
2187 +
2188 +struct daemon_init {
2189 +       char *sock_type;
2190 +       char *ctl_sock;
2191 +};
2192 +
2193 +void daemon_init(struct net_device *dev, void *data)
2194 +{
2195 +       struct uml_net_private *pri;
2196 +       struct daemon_data *dpri;
2197 +       struct daemon_init *init = data;
2198 +
2199 +       init_etherdev(dev, 0);
2200 +       pri = dev->priv;
2201 +       dpri = (struct daemon_data *) pri->user;
2202 +       *dpri = ((struct daemon_data)
2203 +               { .sock_type            = init->sock_type,
2204 +                 .ctl_sock             = init->ctl_sock,
2205 +                 .ctl_addr             = NULL,
2206 +                 .data_addr            = NULL,
2207 +                 .local_addr           = NULL,
2208 +                 .fd                   = -1,
2209 +                 .control              = -1,
2210 +                 .dev                  = dev });
2211 +
2212 +       printk("daemon backend (uml_switch version %d) - %s:%s", 
2213 +              SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
2214 +       printk("\n");
2215 +}
2216 +
2217 +static int daemon_read(int fd, struct sk_buff **skb, 
2218 +                      struct uml_net_private *lp)
2219 +{
2220 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
2221 +       if(*skb == NULL) return(-ENOMEM);
2222 +       return(net_recvfrom(fd, (*skb)->mac.raw, 
2223 +                           (*skb)->dev->mtu + ETH_HEADER_OTHER));
2224 +}
2225 +
2226 +static int daemon_write(int fd, struct sk_buff **skb,
2227 +                       struct uml_net_private *lp)
2228 +{
2229 +       return(daemon_user_write(fd, (*skb)->data, (*skb)->len, 
2230 +                                (struct daemon_data *) &lp->user));
2231 +}
2232 +
2233 +static struct net_kern_info daemon_kern_info = {
2234 +       .init                   = daemon_init,
2235 +       .protocol               = eth_protocol,
2236 +       .read                   = daemon_read,
2237 +       .write                  = daemon_write,
2238 +};
2239 +
2240 +int daemon_setup(char *str, char **mac_out, void *data)
2241 +{
2242 +       struct daemon_init *init = data;
2243 +       char *remain;
2244 +
2245 +       *init = ((struct daemon_init)
2246 +               { .sock_type            = "unix",
2247 +                 .ctl_sock             = "/tmp/uml.ctl" });
2248 +       
2249 +       remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
2250 +                              NULL);
2251 +       if(remain != NULL)
2252 +               printk(KERN_WARNING "daemon_setup : Ignoring data socket "
2253 +                      "specification\n");
2254 +       
2255 +       return(1);
2256 +}
2257 +
2258 +static struct transport daemon_transport = {
2259 +       .list           = LIST_HEAD_INIT(daemon_transport.list),
2260 +       .name           = "daemon",
2261 +       .setup          = daemon_setup,
2262 +       .user           = &daemon_user_info,
2263 +       .kern           = &daemon_kern_info,
2264 +       .private_size   = sizeof(struct daemon_data),
2265 +       .setup_size     = sizeof(struct daemon_init),
2266 +};
2267 +
2268 +static int register_daemon(void)
2269 +{
2270 +       register_transport(&daemon_transport);
2271 +       return(1);
2272 +}
2273 +
2274 +__initcall(register_daemon);
2275 +
2276 +/*
2277 + * Overrides for Emacs so that we follow Linus's tabbing style.
2278 + * Emacs will notice this stuff at the end of the file and automatically
2279 + * adjust the settings for this buffer only.  This must remain at the end
2280 + * of the file.
2281 + * ---------------------------------------------------------------------------
2282 + * Local variables:
2283 + * c-file-style: "linux"
2284 + * End:
2285 + */
2286 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_user.c um/arch/um/drivers/daemon_user.c
2287 --- orig/arch/um/drivers/daemon_user.c  1969-12-31 19:00:00.000000000 -0500
2288 +++ um/arch/um/drivers/daemon_user.c    2003-01-17 13:48:59.000000000 -0500
2289 @@ -0,0 +1,195 @@
2290 +/*
2291 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
2292 + * James Leu (jleu@mindspring.net).
2293 + * Copyright (C) 2001 by various other people who didn't put their name here.
2294 + * Licensed under the GPL.
2295 + */
2296 +
2297 +#include <errno.h>
2298 +#include <unistd.h>
2299 +#include <stdint.h>
2300 +#include <sys/socket.h>
2301 +#include <sys/un.h>
2302 +#include <sys/time.h>
2303 +#include "net_user.h"
2304 +#include "daemon.h"
2305 +#include "kern_util.h"
2306 +#include "user_util.h"
2307 +#include "user.h"
2308 +#include "os.h"
2309 +
2310 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
2311 +
2312 +enum request_type { REQ_NEW_CONTROL };
2313 +
2314 +#define SWITCH_MAGIC 0xfeedface
2315 +
2316 +struct request_v3 {
2317 +       uint32_t magic;
2318 +       uint32_t version;
2319 +       enum request_type type;
2320 +       struct sockaddr_un sock;
2321 +};
2322 +
2323 +static struct sockaddr_un *new_addr(void *name, int len)
2324 +{
2325 +       struct sockaddr_un *sun;
2326 +
2327 +       sun = um_kmalloc(sizeof(struct sockaddr_un));
2328 +       if(sun == NULL){
2329 +               printk("new_addr: allocation of sockaddr_un failed\n");
2330 +               return(NULL);
2331 +       }
2332 +       sun->sun_family = AF_UNIX;
2333 +       memcpy(sun->sun_path, name, len);
2334 +       return(sun);
2335 +}
2336 +
2337 +static int connect_to_switch(struct daemon_data *pri)
2338 +{
2339 +       struct sockaddr_un *ctl_addr = pri->ctl_addr;
2340 +       struct sockaddr_un *local_addr = pri->local_addr;
2341 +       struct sockaddr_un *sun;
2342 +       struct request_v3 req;
2343 +       int fd, n, err;
2344 +
2345 +       if((pri->control = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
2346 +               printk("daemon_open : control socket failed, errno = %d\n", 
2347 +                      errno);          
2348 +               return(-errno);
2349 +       }
2350 +
2351 +       if(connect(pri->control, (struct sockaddr *) ctl_addr, 
2352 +                  sizeof(*ctl_addr)) < 0){
2353 +               printk("daemon_open : control connect failed, errno = %d\n",
2354 +                      errno);
2355 +               err = -errno;
2356 +               goto out;
2357 +       }
2358 +
2359 +       if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
2360 +               printk("daemon_open : data socket failed, errno = %d\n", 
2361 +                      errno);
2362 +               err = -errno;
2363 +               goto out;
2364 +       }
2365 +       if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
2366 +               printk("daemon_open : data bind failed, errno = %d\n", 
2367 +                      errno);
2368 +               err = -errno;
2369 +               goto out_close;
2370 +       }
2371 +
2372 +       sun = um_kmalloc(sizeof(struct sockaddr_un));
2373 +       if(sun == NULL){
2374 +               printk("new_addr: allocation of sockaddr_un failed\n");
2375 +               err = -ENOMEM;
2376 +               goto out_close;
2377 +       }
2378 +
2379 +       req.magic = SWITCH_MAGIC;
2380 +       req.version = SWITCH_VERSION;
2381 +       req.type = REQ_NEW_CONTROL;
2382 +       req.sock = *local_addr;
2383 +       n = write(pri->control, &req, sizeof(req));
2384 +       if(n != sizeof(req)){
2385 +               printk("daemon_open : control setup request returned %d, "
2386 +                      "errno = %d\n", n, errno);
2387 +               err = -ENOTCONN;
2388 +               goto out;               
2389 +       }
2390 +
2391 +       n = read(pri->control, sun, sizeof(*sun));
2392 +       if(n != sizeof(*sun)){
2393 +               printk("daemon_open : read of data socket returned %d, "
2394 +                      "errno = %d\n", n, errno);
2395 +               err = -ENOTCONN;
2396 +               goto out_close;         
2397 +       }
2398 +
2399 +       pri->data_addr = sun;
2400 +       return(fd);
2401 +
2402 + out_close:
2403 +       close(fd);
2404 + out:
2405 +       close(pri->control);
2406 +       return(err);
2407 +}
2408 +
2409 +static void daemon_user_init(void *data, void *dev)
2410 +{
2411 +       struct daemon_data *pri = data;
2412 +       struct timeval tv;
2413 +       struct {
2414 +               char zero;
2415 +               int pid;
2416 +               int usecs;
2417 +       } name;
2418 +
2419 +       if(!strcmp(pri->sock_type, "unix"))
2420 +               pri->ctl_addr = new_addr(pri->ctl_sock, 
2421 +                                        strlen(pri->ctl_sock) + 1);
2422 +       name.zero = 0;
2423 +       name.pid = os_getpid();
2424 +       gettimeofday(&tv, NULL);
2425 +       name.usecs = tv.tv_usec;
2426 +       pri->local_addr = new_addr(&name, sizeof(name));
2427 +       pri->dev = dev;
2428 +       pri->fd = connect_to_switch(pri);
2429 +       if(pri->fd < 0){
2430 +               kfree(pri->local_addr);
2431 +               pri->local_addr = NULL;
2432 +       }
2433 +}
2434 +
2435 +static int daemon_open(void *data)
2436 +{
2437 +       struct daemon_data *pri = data;
2438 +       return(pri->fd);
2439 +}
2440 +
2441 +static void daemon_remove(void *data)
2442 +{
2443 +       struct daemon_data *pri = data;
2444 +
2445 +       close(pri->fd);
2446 +       close(pri->control);
2447 +       if(pri->data_addr != NULL) kfree(pri->data_addr);
2448 +       if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
2449 +       if(pri->local_addr != NULL) kfree(pri->local_addr);
2450 +}
2451 +
2452 +int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
2453 +{
2454 +       struct sockaddr_un *data_addr = pri->data_addr;
2455 +
2456 +       return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
2457 +}
2458 +
2459 +static int daemon_set_mtu(int mtu, void *data)
2460 +{
2461 +       return(mtu);
2462 +}
2463 +
2464 +struct net_user_info daemon_user_info = {
2465 +       .init           = daemon_user_init,
2466 +       .open           = daemon_open,
2467 +       .close          = NULL,
2468 +       .remove         = daemon_remove,
2469 +       .set_mtu        = daemon_set_mtu,
2470 +       .add_address    = NULL,
2471 +       .delete_address = NULL,
2472 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
2473 +};
2474 +
2475 +/*
2476 + * Overrides for Emacs so that we follow Linus's tabbing style.
2477 + * Emacs will notice this stuff at the end of the file and automatically
2478 + * adjust the settings for this buffer only.  This must remain at the end
2479 + * of the file.
2480 + * ---------------------------------------------------------------------------
2481 + * Local variables:
2482 + * c-file-style: "linux"
2483 + * End:
2484 + */
2485 diff -Naur -X ../exclude-files orig/arch/um/drivers/fd.c um/arch/um/drivers/fd.c
2486 --- orig/arch/um/drivers/fd.c   1969-12-31 19:00:00.000000000 -0500
2487 +++ um/arch/um/drivers/fd.c     2002-12-15 20:57:25.000000000 -0500
2488 @@ -0,0 +1,96 @@
2489 +/* 
2490 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2491 + * Licensed under the GPL
2492 + */
2493 +
2494 +#include <stdio.h>
2495 +#include <stdlib.h>
2496 +#include <unistd.h>
2497 +#include <termios.h>
2498 +#include "user.h"
2499 +#include "user_util.h"
2500 +#include "chan_user.h"
2501 +
2502 +struct fd_chan {
2503 +       int fd;
2504 +       int raw;
2505 +       struct termios tt;
2506 +       char str[sizeof("1234567890\0")];
2507 +};
2508 +
2509 +void *fd_init(char *str, int device, struct chan_opts *opts)
2510 +{
2511 +       struct fd_chan *data;
2512 +       char *end;
2513 +       int n;
2514 +
2515 +       if(*str != ':'){
2516 +               printk("fd_init : channel type 'fd' must specify a file "
2517 +                      "descriptor\n");
2518 +               return(NULL);
2519 +       }
2520 +       str++;
2521 +       n = strtoul(str, &end, 0);
2522 +       if((*end != '\0') || (end == str)){
2523 +               printk("fd_init : couldn't parse file descriptor '%s'\n", str);
2524 +               return(NULL);
2525 +       }
2526 +       if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
2527 +       *data = ((struct fd_chan) { .fd         = n,
2528 +                                   .raw        = opts->raw });
2529 +       return(data);
2530 +}
2531 +
2532 +int fd_open(int input, int output, int primary, void *d, char **dev_out)
2533 +{
2534 +       struct fd_chan *data = d;
2535 +
2536 +       if(data->raw && isatty(data->fd)){
2537 +               tcgetattr(data->fd, &data->tt);
2538 +               raw(data->fd, 0);
2539 +       }
2540 +       sprintf(data->str, "%d", data->fd);
2541 +       *dev_out = data->str;
2542 +       return(data->fd);
2543 +}
2544 +
2545 +void fd_close(int fd, void *d)
2546 +{
2547 +       struct fd_chan *data = d;
2548 +
2549 +       if(data->raw && isatty(fd)){
2550 +               tcsetattr(fd, TCSAFLUSH, &data->tt);
2551 +               data->raw = 0;
2552 +       }
2553 +}
2554 +
2555 +int fd_console_write(int fd, const char *buf, int n, void *d)
2556 +{
2557 +       struct fd_chan *data = d;
2558 +
2559 +       return(generic_console_write(fd, buf, n, &data->tt));
2560 +}
2561 +
2562 +struct chan_ops fd_ops = {
2563 +       .type           = "fd",
2564 +       .init           = fd_init,
2565 +       .open           = fd_open,
2566 +       .close          = fd_close,
2567 +       .read           = generic_read,
2568 +       .write          = generic_write,
2569 +       .console_write  = fd_console_write,
2570 +       .window_size    = generic_window_size,
2571 +       .free           = generic_free,
2572 +       .winch          = 1,
2573 +};
2574 +
2575 +/*
2576 + * Overrides for Emacs so that we follow Linus's tabbing style.
2577 + * Emacs will notice this stuff at the end of the file and automatically
2578 + * adjust the settings for this buffer only.  This must remain at the end
2579 + * of the file.
2580 + * ---------------------------------------------------------------------------
2581 + * Local variables:
2582 + * c-file-style: "linux"
2583 + * End:
2584 + */
2585 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_kern.c um/arch/um/drivers/harddog_kern.c
2586 --- orig/arch/um/drivers/harddog_kern.c 1969-12-31 19:00:00.000000000 -0500
2587 +++ um/arch/um/drivers/harddog_kern.c   2002-12-15 20:57:42.000000000 -0500
2588 @@ -0,0 +1,194 @@
2589 +/* UML hardware watchdog, shamelessly stolen from:
2590 + *
2591 + *     SoftDog 0.05:   A Software Watchdog Device
2592 + *
2593 + *     (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
2594 + *                             http://www.redhat.com
2595 + *
2596 + *     This program is free software; you can redistribute it and/or
2597 + *     modify it under the terms of the GNU General Public License
2598 + *     as published by the Free Software Foundation; either version
2599 + *     2 of the License, or (at your option) any later version.
2600 + *     
2601 + *     Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
2602 + *     warranty for any of this software. This material is provided 
2603 + *     "AS-IS" and at no charge.       
2604 + *
2605 + *     (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
2606 + *
2607 + *     Software only watchdog driver. Unlike its big brother the WDT501P
2608 + *     driver this won't always recover a failed machine.
2609 + *
2610 + *  03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
2611 + *     Modularised.
2612 + *     Added soft_margin; use upon insmod to change the timer delay.
2613 + *     NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate
2614 + *         minors.
2615 + *
2616 + *  19980911 Alan Cox
2617 + *     Made SMP safe for 2.3.x
2618 + *
2619 + *  20011127 Joel Becker (jlbec@evilplan.org>
2620 + *     Added soft_noboot; Allows testing the softdog trigger without 
2621 + *     requiring a recompile.
2622 + *     Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
2623 + */
2624
2625 +#include <linux/module.h>
2626 +#include <linux/config.h>
2627 +#include <linux/types.h>
2628 +#include <linux/kernel.h>
2629 +#include <linux/fs.h>
2630 +#include <linux/mm.h>
2631 +#include <linux/miscdevice.h>
2632 +#include <linux/watchdog.h>
2633 +#include <linux/reboot.h>
2634 +#include <linux/smp_lock.h>
2635 +#include <linux/init.h>
2636 +#include <asm/uaccess.h>
2637 +#include "helper.h"
2638 +#include "mconsole.h"
2639 +
2640 +MODULE_LICENSE("GPL");
2641 +
2642 +/* Locked by the BKL in harddog_open and harddog_release */
2643 +static int timer_alive;
2644 +static int harddog_in_fd = -1;
2645 +static int harddog_out_fd = -1;
2646 +
2647 +/*
2648 + *     Allow only one person to hold it open
2649 + */
2650
2651 +extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock);
2652 +
2653 +static int harddog_open(struct inode *inode, struct file *file)
2654 +{
2655 +       int err;
2656 +       char *sock = NULL;
2657 +
2658 +       lock_kernel();
2659 +       if(timer_alive)
2660 +               return -EBUSY;
2661 +#ifdef CONFIG_HARDDOG_NOWAYOUT  
2662 +       MOD_INC_USE_COUNT;
2663 +#endif
2664 +
2665 +#ifdef CONFIG_MCONSOLE
2666 +       sock = mconsole_notify_socket();
2667 +#endif
2668 +       err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock);
2669 +       if(err) return(err);
2670 +
2671 +       timer_alive = 1;
2672 +       unlock_kernel();
2673 +       return 0;
2674 +}
2675 +
2676 +extern void stop_watchdog(int in_fd, int out_fd);
2677 +
2678 +static int harddog_release(struct inode *inode, struct file *file)
2679 +{
2680 +       /*
2681 +        *      Shut off the timer.
2682 +        */
2683 +       lock_kernel();
2684 +
2685 +       stop_watchdog(harddog_in_fd, harddog_out_fd);
2686 +       harddog_in_fd = -1;
2687 +       harddog_out_fd = -1;
2688 +
2689 +       timer_alive=0;
2690 +       unlock_kernel();
2691 +       return 0;
2692 +}
2693 +
2694 +extern int ping_watchdog(int fd);
2695 +
2696 +static ssize_t harddog_write(struct file *file, const char *data, size_t len,
2697 +                            loff_t *ppos)
2698 +{
2699 +       /*  Can't seek (pwrite) on this device  */
2700 +       if (ppos != &file->f_pos)
2701 +               return -ESPIPE;
2702 +
2703 +       /*
2704 +        *      Refresh the timer.
2705 +        */
2706 +       if(len)
2707 +               return(ping_watchdog(harddog_out_fd));
2708 +       return 0;
2709 +}
2710 +
2711 +static int harddog_ioctl(struct inode *inode, struct file *file,
2712 +                        unsigned int cmd, unsigned long arg)
2713 +{
2714 +       static struct watchdog_info ident = {
2715 +               WDIOF_SETTIMEOUT,
2716 +               0,
2717 +               "UML Hardware Watchdog"
2718 +       };
2719 +       switch (cmd) {
2720 +               default:
2721 +                       return -ENOTTY;
2722 +               case WDIOC_GETSUPPORT:
2723 +                       if(copy_to_user((struct harddog_info *)arg, &ident,
2724 +                                       sizeof(ident)))
2725 +                               return -EFAULT;
2726 +                       return 0;
2727 +               case WDIOC_GETSTATUS:
2728 +               case WDIOC_GETBOOTSTATUS:
2729 +                       return put_user(0,(int *)arg);
2730 +               case WDIOC_KEEPALIVE:
2731 +                       return(ping_watchdog(harddog_out_fd));
2732 +       }
2733 +}
2734 +
2735 +static struct file_operations harddog_fops = {
2736 +       .owner          = THIS_MODULE,
2737 +       .write          = harddog_write,
2738 +       .ioctl          = harddog_ioctl,
2739 +       .open           = harddog_open,
2740 +       .release        = harddog_release,
2741 +};
2742 +
2743 +static struct miscdevice harddog_miscdev = {
2744 +       .minor          = WATCHDOG_MINOR,
2745 +       .name           = "watchdog",
2746 +       .fops           = &harddog_fops,
2747 +};
2748 +
2749 +static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n";
2750 +
2751 +static int __init harddog_init(void)
2752 +{
2753 +       int ret;
2754 +
2755 +       ret = misc_register(&harddog_miscdev);
2756 +
2757 +       if (ret)
2758 +               return ret;
2759 +
2760 +       printk(banner);
2761 +
2762 +       return(0);
2763 +}
2764 +
2765 +static void __exit harddog_exit(void)
2766 +{
2767 +       misc_deregister(&harddog_miscdev);
2768 +}
2769 +
2770 +module_init(harddog_init);
2771 +module_exit(harddog_exit);
2772 +
2773 +/*
2774 + * Overrides for Emacs so that we follow Linus's tabbing style.
2775 + * Emacs will notice this stuff at the end of the file and automatically
2776 + * adjust the settings for this buffer only.  This must remain at the end
2777 + * of the file.
2778 + * ---------------------------------------------------------------------------
2779 + * Local variables:
2780 + * c-file-style: "linux"
2781 + * End:
2782 + */
2783 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_user.c um/arch/um/drivers/harddog_user.c
2784 --- orig/arch/um/drivers/harddog_user.c 1969-12-31 19:00:00.000000000 -0500
2785 +++ um/arch/um/drivers/harddog_user.c   2002-12-04 16:38:05.000000000 -0500
2786 @@ -0,0 +1,137 @@
2787 +/* 
2788 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
2789 + * Licensed under the GPL
2790 + */
2791 +
2792 +#include <stdio.h>
2793 +#include <unistd.h>
2794 +#include <errno.h>
2795 +#include "user_util.h"
2796 +#include "user.h"
2797 +#include "helper.h"
2798 +#include "mconsole.h"
2799 +#include "os.h"
2800 +#include "choose-mode.h"
2801 +#include "mode.h"
2802 +
2803 +struct dog_data {
2804 +       int stdin;
2805 +       int stdout;
2806 +       int close_me[2];
2807 +};
2808 +
2809 +static void pre_exec(void *d)
2810 +{
2811 +       struct dog_data *data = d;
2812 +
2813 +       dup2(data->stdin, 0);
2814 +       dup2(data->stdout, 1);
2815 +       dup2(data->stdout, 2);
2816 +       close(data->stdin);
2817 +       close(data->stdout);
2818 +       close(data->close_me[0]);
2819 +       close(data->close_me[1]);
2820 +}
2821 +
2822 +int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
2823 +{
2824 +       struct dog_data data;
2825 +       int in_fds[2], out_fds[2], pid, n, err;
2826 +       char pid_buf[sizeof("nnnnn\0")], c;
2827 +       char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
2828 +       char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, 
2829 +                                 NULL };
2830 +       char **args = NULL;
2831 +
2832 +       err = os_pipe(in_fds, 1, 0);
2833 +       if(err){
2834 +               printk("harddog_open - os_pipe failed, errno = %d\n", -err);
2835 +               return(err);
2836 +       }
2837 +
2838 +       err = os_pipe(out_fds, 1, 0);
2839 +       if(err){
2840 +               printk("harddog_open - os_pipe failed, errno = %d\n", -err);
2841 +               return(err);
2842 +       }
2843 +
2844 +       data.stdin = out_fds[0];
2845 +       data.stdout = in_fds[1];
2846 +       data.close_me[0] = out_fds[1];
2847 +       data.close_me[1] = in_fds[0];
2848 +
2849 +       if(sock != NULL){
2850 +               mconsole_args[2] = sock;
2851 +               args = mconsole_args;
2852 +       }
2853 +       else {
2854 +               /* XXX The os_getpid() is not SMP correct */
2855 +               sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
2856 +               args = pid_args;
2857 +       }
2858 +
2859 +       pid = run_helper(pre_exec, &data, args, NULL);
2860 +
2861 +       close(out_fds[0]);
2862 +       close(in_fds[1]);
2863 +
2864 +       if(pid < 0){
2865 +               err = -pid;
2866 +               printk("harddog_open - run_helper failed, errno = %d\n", err);
2867 +               goto out;
2868 +       }
2869 +
2870 +       n = read(in_fds[0], &c, sizeof(c));
2871 +       if(n == 0){
2872 +               printk("harddog_open - EOF on watchdog pipe\n");
2873 +               helper_wait(pid);
2874 +               err = -EIO;
2875 +               goto out;
2876 +       }
2877 +       else if(n < 0){
2878 +               printk("harddog_open - read of watchdog pipe failed, "
2879 +                      "errno = %d\n", errno);
2880 +               helper_wait(pid);
2881 +               err = -errno;
2882 +               goto out;
2883 +       }
2884 +       *in_fd_ret = in_fds[0];
2885 +       *out_fd_ret = out_fds[1];
2886 +       return(0);
2887 + out:
2888 +       close(out_fds[1]);
2889 +       close(in_fds[0]);
2890 +       return(err);
2891 +}
2892 +
2893 +void stop_watchdog(int in_fd, int out_fd)
2894 +{
2895 +       close(in_fd);
2896 +       close(out_fd);
2897 +}
2898 +
2899 +int ping_watchdog(int fd)
2900 +{
2901 +       int n;
2902 +       char c = '\n';
2903 +
2904 +       n = write(fd, &c, sizeof(c));
2905 +       if(n < sizeof(c)){
2906 +               printk("ping_watchdog - write failed, errno = %d\n",
2907 +                      errno);
2908 +               return(-errno);
2909 +       }
2910 +       return 1;
2911 +
2912 +}
2913 +
2914 +/*
2915 + * Overrides for Emacs so that we follow Linus's tabbing style.
2916 + * Emacs will notice this stuff at the end of the file and automatically
2917 + * adjust the settings for this buffer only.  This must remain at the end
2918 + * of the file.
2919 + * ---------------------------------------------------------------------------
2920 + * Local variables:
2921 + * c-file-style: "linux"
2922 + * End:
2923 + */
2924 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_kern.c um/arch/um/drivers/hostaudio_kern.c
2925 --- orig/arch/um/drivers/hostaudio_kern.c       1969-12-31 19:00:00.000000000 -0500
2926 +++ um/arch/um/drivers/hostaudio_kern.c 2003-03-28 21:57:16.000000000 -0500
2927 @@ -0,0 +1,330 @@
2928 +/* 
2929 + * Copyright (C) 2002 Steve Schmidtke 
2930 + * Licensed under the GPL
2931 + */
2932 +
2933 +#include "linux/config.h"
2934 +#include "linux/module.h"
2935 +#include "linux/version.h"
2936 +#include "linux/init.h"
2937 +#include "linux/slab.h"
2938 +#include "linux/fs.h"
2939 +#include "linux/sound.h"
2940 +#include "linux/soundcard.h"
2941 +#include "asm/uaccess.h"
2942 +#include "kern_util.h"
2943 +#include "init.h"
2944 +#include "hostaudio.h"
2945 +
2946 +/* Only changed from linux_main at boot time */
2947 +char *dsp = HOSTAUDIO_DEV_DSP;
2948 +char *mixer = HOSTAUDIO_DEV_MIXER;
2949 +
2950 +#ifndef MODULE
2951 +static int set_dsp(char *name, int *add)
2952 +{
2953 +       dsp = name;
2954 +       return(0);
2955 +}
2956 +
2957 +__uml_setup("dsp=", set_dsp,
2958 +"dsp=<dsp device>\n"
2959 +"    This is used to specify the host dsp device to the hostaudio driver.\n"
2960 +"    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
2961 +);
2962 +
2963 +static int set_mixer(char *name, int *add)
2964 +{
2965 +       mixer = name;
2966 +       return(0);
2967 +}
2968 +
2969 +__uml_setup("mixer=", set_mixer,
2970 +"mixer=<mixer device>\n"
2971 +"    This is used to specify the host mixer device to the hostaudio driver.\n"
2972 +"    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
2973 +);
2974 +#endif
2975 +
2976 +/* /dev/dsp file operations */
2977 +
2978 +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count, 
2979 +                             loff_t *ppos)
2980 +{
2981 +        struct hostaudio_state *state = file->private_data;
2982 +       void *kbuf;
2983 +       int err;
2984 +
2985 +#ifdef DEBUG
2986 +        printk("hostaudio: read called, count = %d\n", count);
2987 +#endif
2988 +
2989 +       kbuf = kmalloc(count, GFP_KERNEL);
2990 +       if(kbuf == NULL)
2991 +               return(-ENOMEM);
2992 +
2993 +        err = hostaudio_read_user(state, kbuf, count, ppos);
2994 +       if(err < 0)
2995 +               goto out;
2996 +
2997 +       if(copy_to_user(buffer, kbuf, err))
2998 +               err = -EFAULT;
2999 +
3000 + out:
3001 +       kfree(kbuf);
3002 +       return(err);
3003 +}
3004 +
3005 +static ssize_t hostaudio_write(struct file *file, const char *buffer, 
3006 +                              size_t count, loff_t *ppos)
3007 +{
3008 +        struct hostaudio_state *state = file->private_data;
3009 +       void *kbuf;
3010 +       int err;
3011 +
3012 +#ifdef DEBUG
3013 +        printk("hostaudio: write called, count = %d\n", count);
3014 +#endif
3015 +
3016 +       kbuf = kmalloc(count, GFP_KERNEL);
3017 +       if(kbuf == NULL)
3018 +               return(-ENOMEM);
3019 +
3020 +       err = -EFAULT;
3021 +       if(copy_from_user(kbuf, buffer, count))
3022 +               goto out;
3023 +
3024 +        err = hostaudio_write_user(state, kbuf, count, ppos);
3025 +       if(err < 0)
3026 +               goto out;
3027 +
3028 + out:
3029 +       kfree(kbuf);
3030 +       return(err);
3031 +}
3032 +
3033 +static unsigned int hostaudio_poll(struct file *file, 
3034 +                                  struct poll_table_struct *wait)
3035 +{
3036 +        unsigned int mask = 0;
3037 +
3038 +#ifdef DEBUG
3039 +        printk("hostaudio: poll called (unimplemented)\n");
3040 +#endif
3041 +
3042 +        return(mask);
3043 +}
3044 +
3045 +static int hostaudio_ioctl(struct inode *inode, struct file *file, 
3046 +                          unsigned int cmd, unsigned long arg)
3047 +{
3048 +        struct hostaudio_state *state = file->private_data;
3049 +       unsigned long data = 0;
3050 +       int err;
3051 +
3052 +#ifdef DEBUG
3053 +        printk("hostaudio: ioctl called, cmd = %u\n", cmd);
3054 +#endif
3055 +       switch(cmd){
3056 +       case SNDCTL_DSP_SPEED:
3057 +       case SNDCTL_DSP_STEREO:
3058 +       case SNDCTL_DSP_GETBLKSIZE:
3059 +       case SNDCTL_DSP_CHANNELS:
3060 +       case SNDCTL_DSP_SUBDIVIDE:
3061 +       case SNDCTL_DSP_SETFRAGMENT:
3062 +               if(get_user(data, (int *) arg))
3063 +                       return(-EFAULT);
3064 +               break;
3065 +       default:
3066 +               break;
3067 +       }
3068 +
3069 +        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
3070 +
3071 +       switch(cmd){
3072 +       case SNDCTL_DSP_SPEED:
3073 +       case SNDCTL_DSP_STEREO:
3074 +       case SNDCTL_DSP_GETBLKSIZE:
3075 +       case SNDCTL_DSP_CHANNELS:
3076 +       case SNDCTL_DSP_SUBDIVIDE:
3077 +       case SNDCTL_DSP_SETFRAGMENT:
3078 +               if(put_user(data, (int *) arg))
3079 +                       return(-EFAULT);
3080 +               break;
3081 +       default:
3082 +               break;
3083 +       }
3084 +
3085 +       return(err);
3086 +}
3087 +
3088 +static int hostaudio_open(struct inode *inode, struct file *file)
3089 +{
3090 +        struct hostaudio_state *state;
3091 +        int r = 0, w = 0;
3092 +        int ret;
3093 +
3094 +#ifdef DEBUG
3095 +        printk("hostaudio: open called (host: %s)\n", dsp);
3096 +#endif
3097 +
3098 +        state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
3099 +        if(state == NULL) return(-ENOMEM);
3100 +
3101 +        if(file->f_mode & FMODE_READ) r = 1;
3102 +        if(file->f_mode & FMODE_WRITE) w = 1;
3103 +
3104 +        ret = hostaudio_open_user(state, r, w, dsp);
3105 +        if(ret < 0){
3106 +               kfree(state);
3107 +               return(ret);
3108 +        }
3109 +
3110 +        file->private_data = state;
3111 +        return(0);
3112 +}
3113 +
3114 +static int hostaudio_release(struct inode *inode, struct file *file)
3115 +{
3116 +        struct hostaudio_state *state = file->private_data;
3117 +        int ret;
3118 +
3119 +#ifdef DEBUG
3120 +        printk("hostaudio: release called\n");
3121 +#endif
3122 +
3123 +        ret = hostaudio_release_user(state);
3124 +        kfree(state);
3125 +
3126 +        return(ret);
3127 +}
3128 +
3129 +/* /dev/mixer file operations */
3130 +
3131 +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, 
3132 +                                 unsigned int cmd, unsigned long arg)
3133 +{
3134 +        struct hostmixer_state *state = file->private_data;
3135 +
3136 +#ifdef DEBUG
3137 +        printk("hostmixer: ioctl called\n");
3138 +#endif
3139 +
3140 +        return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
3141 +}
3142 +
3143 +static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
3144 +{
3145 +        struct hostmixer_state *state;
3146 +        int r = 0, w = 0;
3147 +        int ret;
3148 +
3149 +#ifdef DEBUG
3150 +        printk("hostmixer: open called (host: %s)\n", mixer);
3151 +#endif
3152 +
3153 +        state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
3154 +        if(state == NULL) return(-ENOMEM);
3155 +
3156 +        if(file->f_mode & FMODE_READ) r = 1;
3157 +        if(file->f_mode & FMODE_WRITE) w = 1;
3158 +
3159 +        ret = hostmixer_open_mixdev_user(state, r, w, mixer);
3160 +        
3161 +        if(ret < 0){
3162 +               kfree(state);
3163 +               return(ret);
3164 +        }
3165 +
3166 +        file->private_data = state;
3167 +        return(0);
3168 +}
3169 +
3170 +static int hostmixer_release(struct inode *inode, struct file *file)
3171 +{
3172 +        struct hostmixer_state *state = file->private_data;
3173 +       int ret;
3174 +
3175 +#ifdef DEBUG
3176 +        printk("hostmixer: release called\n");
3177 +#endif
3178 +
3179 +        ret = hostmixer_release_mixdev_user(state);
3180 +        kfree(state);
3181 +
3182 +        return(ret);
3183 +}
3184 +
3185 +
3186 +/* kernel module operations */
3187 +
3188 +static struct file_operations hostaudio_fops = {
3189 +        .owner          = THIS_MODULE,
3190 +        .llseek         = no_llseek,
3191 +        .read           = hostaudio_read,
3192 +        .write          = hostaudio_write,
3193 +        .poll           = hostaudio_poll,
3194 +        .ioctl          = hostaudio_ioctl,
3195 +        .mmap           = NULL,
3196 +        .open           = hostaudio_open,
3197 +        .release        = hostaudio_release,
3198 +};
3199 +
3200 +static struct file_operations hostmixer_fops = {
3201 +        .owner          = THIS_MODULE,
3202 +        .llseek         = no_llseek,
3203 +        .ioctl          = hostmixer_ioctl_mixdev,
3204 +        .open           = hostmixer_open_mixdev,
3205 +        .release        = hostmixer_release,
3206 +};
3207 +
3208 +struct {
3209 +       int dev_audio;
3210 +       int dev_mixer;
3211 +} module_data;
3212 +
3213 +MODULE_AUTHOR("Steve Schmidtke");
3214 +MODULE_DESCRIPTION("UML Audio Relay");
3215 +MODULE_LICENSE("GPL");
3216 +
3217 +static int __init hostaudio_init_module(void)
3218 +{
3219 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
3220 +              dsp, mixer);
3221 +
3222 +       module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
3223 +        if(module_data.dev_audio < 0){
3224 +                printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
3225 +                return -ENODEV;
3226 +        }
3227 +
3228 +       module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
3229 +        if(module_data.dev_mixer < 0){
3230 +                printk(KERN_ERR "hostmixer: couldn't register mixer "
3231 +                      "device!\n");
3232 +                unregister_sound_dsp(module_data.dev_audio);
3233 +                return -ENODEV;
3234 +        }
3235 +
3236 +        return 0;
3237 +}
3238 +
3239 +static void __exit hostaudio_cleanup_module (void)
3240 +{
3241 +       unregister_sound_mixer(module_data.dev_mixer);
3242 +       unregister_sound_dsp(module_data.dev_audio);
3243 +}
3244 +
3245 +module_init(hostaudio_init_module);
3246 +module_exit(hostaudio_cleanup_module);
3247 +
3248 +/*
3249 + * Overrides for Emacs so that we follow Linus's tabbing style.
3250 + * Emacs will notice this stuff at the end of the file and automatically
3251 + * adjust the settings for this buffer only.  This must remain at the end
3252 + * of the file.
3253 + * ---------------------------------------------------------------------------
3254 + * Local variables:
3255 + * c-file-style: "linux"
3256 + * End:
3257 + */
3258 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_user.c um/arch/um/drivers/hostaudio_user.c
3259 --- orig/arch/um/drivers/hostaudio_user.c       1969-12-31 19:00:00.000000000 -0500
3260 +++ um/arch/um/drivers/hostaudio_user.c 2002-10-23 21:08:04.000000000 -0400
3261 @@ -0,0 +1,149 @@
3262 +/* 
3263 + * Copyright (C) 2002 Steve Schmidtke 
3264 + * Licensed under the GPL
3265 + */
3266 +
3267 +#include <sys/types.h>
3268 +#include <sys/stat.h>
3269 +#include <sys/ioctl.h>
3270 +#include <fcntl.h>
3271 +#include <unistd.h>
3272 +#include <errno.h>
3273 +#include "hostaudio.h"
3274 +#include "user_util.h"
3275 +#include "kern_util.h"
3276 +#include "user.h"
3277 +#include "os.h"
3278 +
3279 +/* /dev/dsp file operations */
3280 +
3281 +ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, 
3282 +                           size_t count, loff_t *ppos)
3283 +{
3284 +       ssize_t ret;
3285 +
3286 +#ifdef DEBUG
3287 +        printk("hostaudio: read_user called, count = %d\n", count);
3288 +#endif
3289 +
3290 +        ret = read(state->fd, buffer, count);
3291 +
3292 +        if(ret < 0) return(-errno);
3293 +        return(ret);
3294 +}
3295 +
3296 +ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
3297 +                            size_t count, loff_t *ppos)
3298 +{
3299 +       ssize_t ret;
3300 +
3301 +#ifdef DEBUG
3302 +        printk("hostaudio: write_user called, count = %d\n", count);
3303 +#endif
3304 +
3305 +        ret = write(state->fd, buffer, count);
3306 +
3307 +        if(ret < 0) return(-errno);
3308 +        return(ret);
3309 +}
3310 +
3311 +int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, 
3312 +                        unsigned long arg)
3313 +{
3314 +       int ret;
3315 +#ifdef DEBUG
3316 +        printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
3317 +#endif
3318 +
3319 +        ret = ioctl(state->fd, cmd, arg);
3320 +       
3321 +        if(ret < 0) return(-errno);
3322 +        return(ret);
3323 +}
3324 +
3325 +int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
3326 +{
3327 +#ifdef DEBUG
3328 +        printk("hostaudio: open_user called\n");
3329 +#endif
3330 +
3331 +        state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
3332 +
3333 +        if(state->fd >= 0) return(0);
3334 +
3335 +        printk("hostaudio_open_user failed to open '%s', errno = %d\n",
3336 +              dsp, errno);
3337 +        
3338 +        return(-errno); 
3339 +}
3340 +
3341 +int hostaudio_release_user(struct hostaudio_state *state)
3342 +{
3343 +#ifdef DEBUG
3344 +        printk("hostaudio: release called\n");
3345 +#endif
3346 +        if(state->fd >= 0){
3347 +               close(state->fd);
3348 +               state->fd=-1;
3349 +        }
3350 +
3351 +        return(0);
3352 +}
3353 +
3354 +/* /dev/mixer file operations */
3355 +
3356 +int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
3357 +                               unsigned int cmd, unsigned long arg)
3358 +{
3359 +       int ret;
3360 +#ifdef DEBUG
3361 +        printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
3362 +#endif
3363 +
3364 +        ret = ioctl(state->fd, cmd, arg);
3365 +       if(ret < 0) 
3366 +               return(-errno);
3367 +       return(ret);
3368 +}
3369 +
3370 +int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
3371 +                              char *mixer)
3372 +{
3373 +#ifdef DEBUG
3374 +        printk("hostmixer: open_user called\n");
3375 +#endif
3376 +
3377 +        state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
3378 +
3379 +        if(state->fd >= 0) return(0);
3380 +
3381 +        printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
3382 +              mixer, errno);
3383 +        
3384 +        return(-errno); 
3385 +}
3386 +
3387 +int hostmixer_release_mixdev_user(struct hostmixer_state *state)
3388 +{
3389 +#ifdef DEBUG
3390 +        printk("hostmixer: release_user called\n");
3391 +#endif
3392 +
3393 +        if(state->fd >= 0){
3394 +               close(state->fd);
3395 +               state->fd = -1;
3396 +        }
3397 +
3398 +        return 0;
3399 +}
3400 +
3401 +/*
3402 + * Overrides for Emacs so that we follow Linus's tabbing style.
3403 + * Emacs will notice this stuff at the end of the file and automatically
3404 + * adjust the settings for this buffer only.  This must remain at the end
3405 + * of the file.
3406 + * ---------------------------------------------------------------------------
3407 + * Local variables:
3408 + * c-file-style: "linux"
3409 + * End:
3410 + */
3411 diff -Naur -X ../exclude-files orig/arch/um/drivers/line.c um/arch/um/drivers/line.c
3412 --- orig/arch/um/drivers/line.c 1969-12-31 19:00:00.000000000 -0500
3413 +++ um/arch/um/drivers/line.c   2003-03-26 15:09:44.000000000 -0500
3414 @@ -0,0 +1,589 @@
3415 +/* 
3416 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3417 + * Licensed under the GPL
3418 + */
3419 +
3420 +#include "linux/sched.h"
3421 +#include "linux/slab.h"
3422 +#include "linux/list.h"
3423 +#include "linux/devfs_fs_kernel.h"
3424 +#include "asm/irq.h"
3425 +#include "asm/uaccess.h"
3426 +#include "chan_kern.h"
3427 +#include "irq_user.h"
3428 +#include "line.h"
3429 +#include "kern.h"
3430 +#include "user_util.h"
3431 +#include "kern_util.h"
3432 +#include "os.h"
3433 +
3434 +#define LINE_BUFSIZE 4096
3435 +
3436 +void line_interrupt(int irq, void *data, struct pt_regs *unused)
3437 +{
3438 +       struct line *dev = data;
3439 +
3440 +       if(dev->count > 0) 
3441 +               chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
3442 +                              dev);
3443 +}
3444 +
3445 +void line_timer_cb(void *arg)
3446 +{
3447 +       struct line *dev = arg;
3448 +
3449 +       line_interrupt(dev->driver->read_irq, dev, NULL);
3450 +}
3451 +
3452 +static void buffer_data(struct line *line, const char *buf, int len)
3453 +{
3454 +       int end;
3455 +
3456 +       if(line->buffer == NULL){
3457 +               line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
3458 +               if(line->buffer == NULL){
3459 +                       printk("buffer_data - atomic allocation failed\n");
3460 +                       return;
3461 +               }
3462 +               line->head = line->buffer;
3463 +               line->tail = line->buffer;
3464 +       }
3465 +       end = line->buffer + LINE_BUFSIZE - line->tail;
3466 +       if(len < end){
3467 +               memcpy(line->tail, buf, len);
3468 +               line->tail += len;
3469 +       }
3470 +       else {
3471 +               memcpy(line->tail, buf, end);
3472 +               buf += end;
3473 +               len -= end;
3474 +               memcpy(line->buffer, buf, len);
3475 +               line->tail = line->buffer + len;
3476 +       }
3477 +}
3478 +
3479 +static int flush_buffer(struct line *line)
3480 +{
3481 +       int n, count;
3482 +
3483 +       if((line->buffer == NULL) || (line->head == line->tail)) return(1);
3484 +
3485 +       if(line->tail < line->head){
3486 +               count = line->buffer + LINE_BUFSIZE - line->head;
3487 +               n = write_chan(&line->chan_list, line->head, count,
3488 +                              line->driver->write_irq);
3489 +               if(n < 0) return(n);
3490 +               if(n == count) line->head = line->buffer;
3491 +               else {
3492 +                       line->head += n;
3493 +                       return(0);
3494 +               }
3495 +       }
3496 +
3497 +       count = line->tail - line->head;
3498 +       n = write_chan(&line->chan_list, line->head, count, 
3499 +                      line->driver->write_irq);
3500 +       if(n < 0) return(n);
3501 +
3502 +       line->head += n;
3503 +       return(line->head == line->tail);
3504 +}
3505 +
3506 +int line_write(struct line *lines, struct tty_struct *tty, int from_user,
3507 +              const char *buf, int len)
3508 +{
3509 +       struct line *line;
3510 +       char *new;
3511 +       unsigned long flags;
3512 +       int n, err, i;
3513 +
3514 +       if(tty->stopped) return 0;
3515 +
3516 +       if(from_user){
3517 +               new = kmalloc(len, GFP_KERNEL);
3518 +               if(new == NULL)
3519 +                       return(0);
3520 +               n = copy_from_user(new, buf, len);
3521 +               if(n == len)
3522 +                       return(-EFAULT);
3523 +               buf = new;
3524 +       }
3525 +
3526 +       i = minor(tty->device) - tty->driver.minor_start;
3527 +       line = &lines[i];
3528 +
3529 +       down(&line->sem);
3530 +       if(line->head != line->tail){
3531 +               local_irq_save(flags);
3532 +               buffer_data(line, buf, len);
3533 +               err = flush_buffer(line);
3534 +               local_irq_restore(flags);
3535 +               if(err <= 0)
3536 +                       goto out;
3537 +       }
3538 +       else {
3539 +               n = write_chan(&line->chan_list, buf, len, 
3540 +                              line->driver->write_irq);
3541 +               if(n < 0){
3542 +                       len = n;
3543 +                       goto out;
3544 +               }
3545 +               if(n < len)
3546 +                       buffer_data(line, buf + n, len - n);
3547 +       }
3548 + out:
3549 +       up(&line->sem);
3550 +
3551 +       if(from_user)
3552 +               kfree(buf);
3553 +       return(len);
3554 +}
3555 +
3556 +void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
3557 +{
3558 +       struct line *dev = data;
3559 +       struct tty_struct *tty = dev->tty;
3560 +       int err;
3561 +
3562 +       err = flush_buffer(dev);
3563 +       if(err == 0) return;
3564 +       else if(err < 0){
3565 +               dev->head = dev->buffer;
3566 +               dev->tail = dev->buffer;
3567 +       }
3568 +
3569 +       if(tty == NULL) return;
3570 +
3571 +       if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
3572 +          (tty->ldisc.write_wakeup != NULL))
3573 +               (tty->ldisc.write_wakeup)(tty);
3574 +       
3575 +       /* BLOCKING mode
3576 +        * In blocking mode, everything sleeps on tty->write_wait.
3577 +        * Sleeping in the console driver would break non-blocking
3578 +        * writes.
3579 +        */
3580 +
3581 +       if (waitqueue_active(&tty->write_wait))
3582 +               wake_up_interruptible(&tty->write_wait);
3583 +
3584 +}
3585 +
3586 +int line_write_room(struct tty_struct *tty)
3587 +{
3588 +       struct line *dev = tty->driver_data;
3589 +       int n;
3590 +
3591 +       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
3592 +
3593 +       n = dev->head - dev->tail;
3594 +       if(n <= 0) n = LINE_BUFSIZE + n;
3595 +       return(n - 1);
3596 +}
3597 +
3598 +int line_setup_irq(int fd, int input, int output, void *data)
3599 +{
3600 +       struct line *line = data;
3601 +       struct line_driver *driver = line->driver;
3602 +       int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
3603 +
3604 +       if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, 
3605 +                                      line_interrupt, flags, 
3606 +                                      driver->read_irq_name, line);
3607 +       if(err) return(err);
3608 +       if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 
3609 +                                       line_write_interrupt, flags, 
3610 +                                       driver->write_irq_name, line);
3611 +       line->have_irq = 1;
3612 +       return(err);
3613 +}
3614 +
3615 +void line_disable(struct line *line, int current_irq)
3616 +{
3617 +       if(!line->have_irq) return;
3618 +
3619 +       if(line->driver->read_irq == current_irq)
3620 +               free_irq_later(line->driver->read_irq, line);
3621 +       else
3622 +               free_irq(line->driver->read_irq, line);
3623 +
3624 +       if(line->driver->write_irq == current_irq)
3625 +               free_irq_later(line->driver->write_irq, line);
3626 +       else
3627 +               free_irq(line->driver->write_irq, line);
3628 +
3629 +       line->have_irq = 0;
3630 +}
3631 +
3632 +int line_open(struct line *lines, struct tty_struct *tty,
3633 +             struct chan_opts *opts)
3634 +{
3635 +       struct line *line;
3636 +       int n, err = 0;
3637 +
3638 +       if(tty == NULL) n = 0;
3639 +       else n = minor(tty->device) - tty->driver.minor_start;
3640 +       line = &lines[n];
3641 +
3642 +       down(&line->sem);
3643 +       if(line->count == 0){
3644 +               if(!line->valid){
3645 +                       err = -ENODEV;
3646 +                       goto out;
3647 +               }
3648 +               if(list_empty(&line->chan_list)){
3649 +                       err = parse_chan_pair(line->init_str, &line->chan_list,
3650 +                                             line->init_pri, n, opts);
3651 +                       if(err) goto out;
3652 +                       err = open_chan(&line->chan_list);
3653 +                       if(err) goto out;
3654 +               }
3655 +               enable_chan(&line->chan_list, line);
3656 +               INIT_TQUEUE(&line->task, line_timer_cb, line);
3657 +       }
3658 +
3659 +       if(!line->sigio){
3660 +               chan_enable_winch(&line->chan_list, line);
3661 +               line->sigio = 1;
3662 +       }
3663 +
3664 +       /* This is outside the if because the initial console is opened
3665 +        * with tty == NULL
3666 +        */
3667 +       line->tty = tty;
3668 +
3669 +       if(tty != NULL){
3670 +               tty->driver_data = line;
3671 +               chan_window_size(&line->chan_list, &tty->winsize.ws_row, 
3672 +                                &tty->winsize.ws_col);
3673 +       }
3674 +
3675 +       line->count++;
3676 + out:
3677 +       up(&line->sem);
3678 +       return(err);
3679 +}
3680 +
3681 +void line_close(struct line *lines, struct tty_struct *tty)
3682 +{
3683 +       struct line *line;
3684 +       int n;
3685 +
3686 +       if(tty == NULL) n = 0;
3687 +       else n = minor(tty->device) - tty->driver.minor_start;
3688 +       line = &lines[n];
3689 +
3690 +       down(&line->sem);
3691 +       line->count--;
3692 +
3693 +       /* I don't like this, but I can't think of anything better.  What's
3694 +        * going on is that the tty is in the process of being closed for
3695 +        * the last time.  Its count hasn't been dropped yet, so it's still
3696 +        * at 1.  This may happen when line->count != 0 because of the initial
3697 +        * console open (without a tty) bumping it up to 1.
3698 +        */
3699 +       if((line->tty != NULL) && (line->tty->count == 1))
3700 +               line->tty = NULL;
3701 +       if(line->count == 0)
3702 +               line_disable(line, -1);
3703 +       up(&line->sem);
3704 +}
3705 +
3706 +void close_lines(struct line *lines, int nlines)
3707 +{
3708 +       int i;
3709 +
3710 +       for(i = 0; i < nlines; i++)
3711 +               close_chan(&lines[i].chan_list);
3712 +}
3713 +
3714 +int line_setup(struct line *lines, int num, char *init, int all_allowed)
3715 +{
3716 +       int i, n;
3717 +       char *end;
3718 +
3719 +       if(*init == '=') n = -1;
3720 +       else {
3721 +               n = simple_strtoul(init, &end, 0);
3722 +               if(*end != '='){
3723 +                       printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 
3724 +                              init);
3725 +                       return(1);
3726 +               }
3727 +               init = end;
3728 +       }
3729 +       init++;
3730 +       if((n >= 0) && (n >= num)){
3731 +               printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
3732 +                      n, num);
3733 +               return(1);
3734 +       }
3735 +       else if(n >= 0){
3736 +               if(lines[n].count > 0){
3737 +                       printk("line_setup - device %d is open\n", n);
3738 +                       return(1);
3739 +               }
3740 +               if(lines[n].init_pri <= INIT_ONE){
3741 +                       lines[n].init_pri = INIT_ONE;
3742 +                       if(!strcmp(init, "none")) lines[n].valid = 0;
3743 +                       else {
3744 +                               lines[n].init_str = init;
3745 +                               lines[n].valid = 1;
3746 +                       }       
3747 +               }
3748 +       }
3749 +       else if(!all_allowed){
3750 +               printk("line_setup - can't configure all devices from "
3751 +                      "mconsole\n");
3752 +               return(1);
3753 +       }
3754 +       else {
3755 +               for(i = 0; i < num; i++){
3756 +                       if(lines[i].init_pri <= INIT_ALL){
3757 +                               lines[i].init_pri = INIT_ALL;
3758 +                               if(!strcmp(init, "none")) lines[i].valid = 0;
3759 +                               else {
3760 +                                       lines[i].init_str = init;
3761 +                                       lines[i].valid = 1;
3762 +                               }
3763 +                       }
3764 +               }
3765 +       }
3766 +       return(0);
3767 +}
3768 +
3769 +int line_config(struct line *lines, int num, char *str)
3770 +{
3771 +       char *new = uml_strdup(str);
3772 +
3773 +       if(new == NULL){
3774 +               printk("line_config - uml_strdup failed\n");
3775 +               return(-ENOMEM);
3776 +       }
3777 +       return(line_setup(lines, num, new, 0));
3778 +}
3779 +
3780 +int line_get_config(char *name, struct line *lines, int num, char *str, 
3781 +                   int size, char **error_out)
3782 +{
3783 +       struct line *line;
3784 +       char *end;
3785 +       int dev, n = 0;
3786 +
3787 +       dev = simple_strtoul(name, &end, 0);
3788 +       if((*end != '\0') || (end == name)){
3789 +               *error_out = "line_get_config failed to parse device number";
3790 +               return(0);
3791 +       }
3792 +
3793 +       if((dev < 0) || (dev >= num)){
3794 +               *error_out = "device number of of range";
3795 +               return(0);
3796 +       }
3797 +
3798 +       line = &lines[dev];
3799 +
3800 +       down(&line->sem);
3801 +       if(!line->valid)
3802 +               CONFIG_CHUNK(str, size, n, "none", 1);
3803 +       else if(line->count == 0)
3804 +               CONFIG_CHUNK(str, size, n, line->init_str, 1);
3805 +       else n = chan_config_string(&line->chan_list, str, size, error_out);
3806 +       up(&line->sem);
3807 +
3808 +       return(n);
3809 +}
3810 +
3811 +int line_remove(struct line *lines, int num, char *str)
3812 +{
3813 +       char config[sizeof("conxxxx=none\0")];
3814 +
3815 +       sprintf(config, "%s=none", str);
3816 +       return(line_setup(lines, num, config, 0));
3817 +}
3818 +
3819 +void line_register_devfs(struct lines *set, struct line_driver *line_driver, 
3820 +                        struct tty_driver *driver, struct line *lines,
3821 +                        int nlines)
3822 +{
3823 +       int err, i, n;
3824 +       char *from, *to;
3825 +
3826 +       driver->driver_name = line_driver->name;
3827 +       driver->name = line_driver->devfs_name;
3828 +       driver->major = line_driver->major;
3829 +       driver->minor_start = line_driver->minor_start;
3830 +       driver->type = line_driver->type;
3831 +       driver->subtype = line_driver->subtype;
3832 +       driver->magic = TTY_DRIVER_MAGIC;
3833 +       driver->flags = TTY_DRIVER_REAL_RAW;
3834 +
3835 +       n = set->num;
3836 +       driver->num = n;
3837 +       driver->table = kmalloc(n * sizeof(driver->table[0]), GFP_KERNEL);
3838 +       driver->termios = kmalloc(n * sizeof(driver->termios[0]), GFP_KERNEL);
3839 +       driver->termios_locked = kmalloc(n * sizeof(driver->termios_locked[0]),
3840 +                                        GFP_KERNEL);
3841 +       if((driver->table == NULL) || (driver->termios == NULL) ||
3842 +          (driver->termios_locked == NULL))
3843 +               panic("Failed to allocate driver table");
3844 +
3845 +       memset(driver->table, 0, n * sizeof(driver->table[0]));
3846 +       memset(driver->termios, 0, n * sizeof(driver->termios[0]));
3847 +       memset(driver->termios_locked, 0, 
3848 +              n * sizeof(driver->termios_locked[0]));
3849 +
3850 +       driver->write_room = line_write_room;
3851 +       driver->init_termios = tty_std_termios;
3852 +
3853 +       if (tty_register_driver(driver))
3854 +               panic("line_register_devfs : Couldn't register driver\n");
3855 +
3856 +       from = line_driver->symlink_from;
3857 +       to = line_driver->symlink_to;
3858 +       err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL);
3859 +       if(err) printk("Symlink creation from /dev/%s to /dev/%s "
3860 +                      "returned %d\n", from, to, err);
3861 +
3862 +       for(i = 0; i < nlines; i++){
3863 +               if(!lines[i].valid) 
3864 +                       tty_unregister_devfs(driver, driver->minor_start + i);
3865 +       }
3866 +
3867 +       mconsole_register_dev(&line_driver->mc);
3868 +}
3869 +
3870 +void lines_init(struct line *lines, int nlines)
3871 +{
3872 +       struct line *line;
3873 +       int i;
3874 +
3875 +       for(i = 0; i < nlines; i++){
3876 +               line = &lines[i];
3877 +               INIT_LIST_HEAD(&line->chan_list);
3878 +               sema_init(&line->sem, 1);
3879 +               if(line->init_str != NULL){
3880 +                       line->init_str = uml_strdup(line->init_str);
3881 +                       if(line->init_str == NULL)
3882 +                               printk("lines_init - uml_strdup returned "
3883 +                                      "NULL\n");
3884 +               }
3885 +       }
3886 +}
3887 +
3888 +struct winch {
3889 +       struct list_head list;
3890 +       int fd;
3891 +       int tty_fd;
3892 +       int pid;
3893 +       struct line *line;
3894 +};
3895 +
3896 +void winch_interrupt(int irq, void *data, struct pt_regs *unused)
3897 +{
3898 +       struct winch *winch = data;
3899 +       struct tty_struct *tty;
3900 +       int err;
3901 +       char c;
3902 +
3903 +       if(winch->fd != -1){
3904 +               err = generic_read(winch->fd, &c, NULL);
3905 +               if(err < 0){
3906 +                       if(err != -EAGAIN){
3907 +                               printk("winch_interrupt : read failed, "
3908 +                                      "errno = %d\n", -err);
3909 +                               printk("fd %d is losing SIGWINCH support\n", 
3910 +                                      winch->tty_fd);
3911 +                               return;
3912 +                       }
3913 +                       goto out;
3914 +               }
3915 +       }
3916 +       tty = winch->line->tty;
3917 +       if(tty != NULL){
3918 +               chan_window_size(&winch->line->chan_list, 
3919 +                                &tty->winsize.ws_row, 
3920 +                                &tty->winsize.ws_col);
3921 +               kill_pg(tty->pgrp, SIGWINCH, 1);
3922 +       }
3923 + out:
3924 +       if(winch->fd != -1)
3925 +               reactivate_fd(winch->fd, WINCH_IRQ);
3926 +}
3927 +
3928 +DECLARE_MUTEX(winch_handler_sem);
3929 +LIST_HEAD(winch_handlers);
3930 +
3931 +void register_winch_irq(int fd, int tty_fd, int pid, void *line)
3932 +{
3933 +       struct winch *winch;
3934 +
3935 +       down(&winch_handler_sem);
3936 +       winch = kmalloc(sizeof(*winch), GFP_KERNEL);
3937 +       if(winch == NULL){
3938 +               printk("register_winch_irq - kmalloc failed\n");
3939 +               goto out;
3940 +       }
3941 +       *winch = ((struct winch) { .list        = LIST_HEAD_INIT(winch->list),
3942 +                                  .fd          = fd,
3943 +                                  .tty_fd      = tty_fd,
3944 +                                  .pid         = pid,
3945 +                                  .line        = line });
3946 +       list_add(&winch->list, &winch_handlers);
3947 +       if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 
3948 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
3949 +                         "winch", winch) < 0)
3950 +               printk("register_winch_irq - failed to register IRQ\n");
3951 + out:
3952 +       up(&winch_handler_sem);
3953 +}
3954 +
3955 +static void winch_cleanup(void)
3956 +{
3957 +       struct list_head *ele;
3958 +       struct winch *winch;
3959 +
3960 +       list_for_each(ele, &winch_handlers){
3961 +               winch = list_entry(ele, struct winch, list);
3962 +               if(winch->fd != -1){
3963 +                       deactivate_fd(winch->fd, WINCH_IRQ);
3964 +                       close(winch->fd);
3965 +               }
3966 +               if(winch->pid != -1) 
3967 +                       os_kill_process(winch->pid, 1);
3968 +       }
3969 +}
3970 +
3971 +__uml_exitcall(winch_cleanup);
3972 +
3973 +char *add_xterm_umid(char *base)
3974 +{
3975 +       char *umid, *title;
3976 +       int len;
3977 +
3978 +       umid = get_umid(1);
3979 +       if(umid == NULL) return(base);
3980 +       
3981 +       len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
3982 +       title = kmalloc(len, GFP_KERNEL);
3983 +       if(title == NULL){
3984 +               printk("Failed to allocate buffer for xterm title\n");
3985 +               return(base);
3986 +       }
3987 +
3988 +       strncpy(title, base, len);
3989 +       len -= strlen(title);
3990 +       snprintf(&title[strlen(title)], len, " (%s)", umid);
3991 +       return(title);
3992 +}
3993 +
3994 +/*
3995 + * Overrides for Emacs so that we follow Linus's tabbing style.
3996 + * Emacs will notice this stuff at the end of the file and automatically
3997 + * adjust the settings for this buffer only.  This must remain at the end
3998 + * of the file.
3999 + * ---------------------------------------------------------------------------
4000 + * Local variables:
4001 + * c-file-style: "linux"
4002 + * End:
4003 + */
4004 diff -Naur -X ../exclude-files orig/arch/um/drivers/Makefile um/arch/um/drivers/Makefile
4005 --- orig/arch/um/drivers/Makefile       1969-12-31 19:00:00.000000000 -0500
4006 +++ um/arch/um/drivers/Makefile 2003-06-05 13:48:51.000000000 -0400
4007 @@ -0,0 +1,94 @@
4008 +# 
4009 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
4010 +# Licensed under the GPL
4011 +#
4012 +
4013 +O_TARGET := built-in.o 
4014 +
4015 +CHAN_OBJS := chan_kern.o chan_user.o line.o 
4016 +
4017 +list-multi := slip.o slirp.o daemon.o mcast.o mconsole.o net.o ubd.o \
4018 +       hostaudio.o pcap.o port.o harddog.o
4019 +
4020 +slip-objs := slip_kern.o slip_user.o
4021 +slirp-objs := slirp_kern.o slirp_user.o
4022 +daemon-objs := daemon_kern.o daemon_user.o
4023 +mcast-objs := mcast_kern.o mcast_user.o
4024 +pcap-objs := pcap_kern.o pcap_user.o -lpcap -L/usr/lib
4025 +net-objs := net_kern.o net_user.o
4026 +mconsole-objs := mconsole_kern.o mconsole_user.o
4027 +hostaudio-objs := hostaudio_kern.o hostaudio_user.o
4028 +ubd-objs := ubd_kern.o ubd_user.o cow_user.o
4029 +port-objs := port_kern.o port_user.o
4030 +harddog-objs := harddog_kern.o harddog_user.o
4031 +
4032 +export-objs := mconsole_kern.o
4033 +
4034 +obj-y = 
4035 +obj-$(CONFIG_SSL) += ssl.o 
4036 +obj-$(CONFIG_UML_NET_SLIP) += slip.o
4037 +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
4038 +obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
4039 +obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
4040 +obj-$(CONFIG_UML_NET_PCAP) += pcap.o 
4041 +obj-$(CONFIG_UML_NET) += net.o 
4042 +obj-$(CONFIG_MCONSOLE) += mconsole.o
4043 +obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
4044 +obj-$(CONFIG_BLK_DEV_UBD) += ubd.o 
4045 +obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
4046 +obj-$(CONFIG_FD_CHAN) += fd.o 
4047 +obj-$(CONFIG_NULL_CHAN) += null.o 
4048 +obj-$(CONFIG_PORT_CHAN) += port.o
4049 +obj-$(CONFIG_PTY_CHAN) += pty.o
4050 +obj-$(CONFIG_TTY_CHAN) += tty.o 
4051 +obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
4052 +obj-$(CONFIG_UML_WATCHDOG) += harddog.o
4053 +
4054 +CFLAGS_pcap_user.o = -I/usr/include/pcap
4055 +
4056 +obj-y += stdio_console.o $(CHAN_OBJS)
4057 +
4058 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
4059 +
4060 +USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
4061 +       null.o pty.o tty.o xterm.o
4062 +
4063 +include $(TOPDIR)/Rules.make
4064 +
4065 +$(USER_OBJS) : %.o: %.c
4066 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
4067 +
4068 +clean:
4069 +
4070 +modules:
4071 +
4072 +fastdep:
4073 +
4074 +dep:
4075 +
4076 +archmrproper:
4077 +
4078 +daemon.o : $(daemon-objs)
4079 +
4080 +slip.o : $(slip-objs)
4081 +
4082 +slirp.o : $(slirp-objs)
4083 +
4084 +mcast.o : $(mcast-objs)
4085 +
4086 +pcap.o : $(pcap-objs)
4087 +
4088 +mconsole.o : $(mconsole-objs)
4089 +
4090 +net.o : $(net-objs)
4091 +
4092 +hostaudio.o : $(hostaudio-objs)
4093 +
4094 +ubd.o : $(ubd-objs)
4095 +
4096 +port.o : $(port-objs)
4097 +
4098 +harddog.o : $(harddog-objs)
4099 +
4100 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
4101 +       $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
4102 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast.h um/arch/um/drivers/mcast.h
4103 --- orig/arch/um/drivers/mcast.h        1969-12-31 19:00:00.000000000 -0500
4104 +++ um/arch/um/drivers/mcast.h  2002-10-23 21:08:04.000000000 -0400
4105 @@ -0,0 +1,30 @@
4106 +/* 
4107 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4108 + * Licensed under the GPL
4109 + */
4110 +
4111 +#include "net_user.h"
4112 +
4113 +struct mcast_data {
4114 +       char *addr;
4115 +       unsigned short port;
4116 +       void *mcast_addr;
4117 +       int ttl;
4118 +       void *dev;
4119 +};
4120 +
4121 +extern struct net_user_info mcast_user_info;
4122 +
4123 +extern int mcast_user_write(int fd, void *buf, int len, 
4124 +                           struct mcast_data *pri);
4125 +
4126 +/*
4127 + * Overrides for Emacs so that we follow Linus's tabbing style.
4128 + * Emacs will notice this stuff at the end of the file and automatically
4129 + * adjust the settings for this buffer only.  This must remain at the end
4130 + * of the file.
4131 + * ---------------------------------------------------------------------------
4132 + * Local variables:
4133 + * c-file-style: "linux"
4134 + * End:
4135 + */
4136 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_kern.c um/arch/um/drivers/mcast_kern.c
4137 --- orig/arch/um/drivers/mcast_kern.c   1969-12-31 19:00:00.000000000 -0500
4138 +++ um/arch/um/drivers/mcast_kern.c     2002-12-15 20:58:55.000000000 -0500
4139 @@ -0,0 +1,145 @@
4140 +/*
4141 + * user-mode-linux networking multicast transport
4142 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4143 + *
4144 + * based on the existing uml-networking code, which is
4145 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
4146 + * James Leu (jleu@mindspring.net).
4147 + * Copyright (C) 2001 by various other people who didn't put their name here.
4148 + *
4149 + * Licensed under the GPL.
4150 + */
4151 +
4152 +#include "linux/kernel.h"
4153 +#include "linux/init.h"
4154 +#include "linux/netdevice.h"
4155 +#include "linux/etherdevice.h"
4156 +#include "linux/in.h"
4157 +#include "linux/inet.h"
4158 +#include "net_kern.h"
4159 +#include "net_user.h"
4160 +#include "mcast.h"
4161 +
4162 +struct mcast_init {
4163 +       char *addr;
4164 +       int port;
4165 +       int ttl;
4166 +};
4167 +
4168 +void mcast_init(struct net_device *dev, void *data)
4169 +{
4170 +       struct uml_net_private *pri;
4171 +       struct mcast_data *dpri;
4172 +       struct mcast_init *init = data;
4173 +
4174 +       init_etherdev(dev, 0);
4175 +       pri = dev->priv;
4176 +       dpri = (struct mcast_data *) pri->user;
4177 +       *dpri = ((struct mcast_data)
4178 +               { .addr         = init->addr,
4179 +                 .port         = init->port,
4180 +                 .ttl          = init->ttl,
4181 +                 .mcast_addr   = NULL,
4182 +                 .dev          = dev });
4183 +       printk("mcast backend ");
4184 +       printk("multicast adddress: %s:%u, TTL:%u ",
4185 +              dpri->addr, dpri->port, dpri->ttl);
4186 +
4187 +       printk("\n");
4188 +}
4189 +
4190 +static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
4191 +{
4192 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
4193 +       if(*skb == NULL) return(-ENOMEM);
4194 +       return(net_recvfrom(fd, (*skb)->mac.raw, 
4195 +                           (*skb)->dev->mtu + ETH_HEADER_OTHER));
4196 +}
4197 +
4198 +static int mcast_write(int fd, struct sk_buff **skb,
4199 +                       struct uml_net_private *lp)
4200 +{
4201 +       return mcast_user_write(fd, (*skb)->data, (*skb)->len, 
4202 +                                (struct mcast_data *) &lp->user);
4203 +}
4204 +
4205 +static struct net_kern_info mcast_kern_info = {
4206 +       .init                   = mcast_init,
4207 +       .protocol               = eth_protocol,
4208 +       .read                   = mcast_read,
4209 +       .write                  = mcast_write,
4210 +};
4211 +
4212 +int mcast_setup(char *str, char **mac_out, void *data)
4213 +{
4214 +       struct mcast_init *init = data;
4215 +       char *port_str = NULL, *ttl_str = NULL, *remain;
4216 +       char *last;
4217 +       int n;
4218 +
4219 +       *init = ((struct mcast_init)
4220 +               { .addr         = "239.192.168.1",
4221 +                 .port         = 1102,
4222 +                 .ttl          = 1 });
4223 +
4224 +       remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
4225 +                              NULL);
4226 +       if(remain != NULL){
4227 +               printk(KERN_ERR "mcast_setup - Extra garbage on "
4228 +                      "specification : '%s'\n", remain);
4229 +               return(0);
4230 +       }
4231 +       
4232 +       if(port_str != NULL){
4233 +               n = simple_strtoul(port_str, &last, 10);
4234 +               if((*last != '\0') || (last == port_str)){
4235 +                       printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 
4236 +                              port_str);
4237 +                       return(0);
4238 +               }
4239 +               init->port = htons(n);
4240 +       }
4241 +
4242 +       if(ttl_str != NULL){
4243 +               init->ttl = simple_strtoul(ttl_str, &last, 10);
4244 +               if((*last != '\0') || (last == ttl_str)){
4245 +                       printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", 
4246 +                              ttl_str);
4247 +                       return(0);
4248 +               }
4249 +       }
4250 +
4251 +       printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
4252 +              init->port, init->ttl);
4253 +
4254 +       return(1);
4255 +}
4256 +
4257 +static struct transport mcast_transport = {
4258 +       .list           = LIST_HEAD_INIT(mcast_transport.list),
4259 +       .name           = "mcast",
4260 +       .setup          = mcast_setup,
4261 +       .user           = &mcast_user_info,
4262 +       .kern           = &mcast_kern_info,
4263 +       .private_size   = sizeof(struct mcast_data),
4264 +       .setup_size     = sizeof(struct mcast_init),
4265 +};
4266 +
4267 +static int register_mcast(void)
4268 +{
4269 +       register_transport(&mcast_transport);
4270 +       return(1);
4271 +}
4272 +
4273 +__initcall(register_mcast);
4274 +
4275 +/*
4276 + * Overrides for Emacs so that we follow Linus's tabbing style.
4277 + * Emacs will notice this stuff at the end of the file and automatically
4278 + * adjust the settings for this buffer only.  This must remain at the end
4279 + * of the file.
4280 + * ---------------------------------------------------------------------------
4281 + * Local variables:
4282 + * c-file-style: "linux"
4283 + * End:
4284 + */
4285 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_user.c um/arch/um/drivers/mcast_user.c
4286 --- orig/arch/um/drivers/mcast_user.c   1969-12-31 19:00:00.000000000 -0500
4287 +++ um/arch/um/drivers/mcast_user.c     2002-12-15 21:19:16.000000000 -0500
4288 @@ -0,0 +1,175 @@
4289 +/*
4290 + * user-mode-linux networking multicast transport
4291 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4292 + *
4293 + * based on the existing uml-networking code, which is
4294 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
4295 + * James Leu (jleu@mindspring.net).
4296 + * Copyright (C) 2001 by various other people who didn't put their name here.
4297 + *
4298 + * Licensed under the GPL.
4299 + *
4300 + */
4301 +
4302 +#include <errno.h>
4303 +#include <unistd.h>
4304 +#include <linux/inet.h>
4305 +#include <sys/socket.h>
4306 +#include <sys/un.h>
4307 +#include <sys/time.h>
4308 +#include <netinet/in.h>
4309 +#include "net_user.h"
4310 +#include "mcast.h"
4311 +#include "kern_util.h"
4312 +#include "user_util.h"
4313 +#include "user.h"
4314 +
4315 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
4316 +
4317 +static struct sockaddr_in *new_addr(char *addr, unsigned short port)
4318 +{
4319 +       struct sockaddr_in *sin;
4320 +
4321 +       sin = um_kmalloc(sizeof(struct sockaddr_in));
4322 +       if(sin == NULL){
4323 +               printk("new_addr: allocation of sockaddr_in failed\n");
4324 +               return(NULL);
4325 +       }
4326 +       sin->sin_family = AF_INET;
4327 +       sin->sin_addr.s_addr = in_aton(addr);
4328 +       sin->sin_port = port;
4329 +       return(sin);
4330 +}
4331 +
4332 +static void mcast_user_init(void *data, void *dev)
4333 +{
4334 +       struct mcast_data *pri = data;
4335 +
4336 +       pri->mcast_addr = new_addr(pri->addr, pri->port);
4337 +       pri->dev = dev;
4338 +}
4339 +
4340 +static int mcast_open(void *data)
4341 +{
4342 +       struct mcast_data *pri = data;
4343 +       struct sockaddr_in *sin = pri->mcast_addr;
4344 +       struct ip_mreq mreq;
4345 +       int fd, yes = 1;
4346 +
4347 +
4348 +       if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
4349 +               fd = -EINVAL;
4350 +               goto out;
4351 +       }
4352 +
4353 +       if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
4354 +               printk("mcast_open : data socket failed, errno = %d\n", 
4355 +                      errno);
4356 +               fd = -ENOMEM;
4357 +               goto out;
4358 +       }
4359 +
4360 +       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
4361 +               printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
4362 +                       errno);
4363 +               close(fd);
4364 +               fd = -EINVAL;
4365 +               goto out;
4366 +       }
4367 +
4368 +       /* set ttl according to config */
4369 +       if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
4370 +                      sizeof(pri->ttl)) < 0) {
4371 +               printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
4372 +                       errno);
4373 +               close(fd);
4374 +               fd = -EINVAL;
4375 +               goto out;
4376 +       }
4377 +
4378 +       /* set LOOP, so data does get fed back to local sockets */
4379 +       if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
4380 +               printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
4381 +                       errno);
4382 +               close(fd);
4383 +               fd = -EINVAL;
4384 +               goto out;
4385 +       }
4386 +
4387 +       /* bind socket to mcast address */
4388 +       if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
4389 +               printk("mcast_open : data bind failed, errno = %d\n", errno);
4390 +               close(fd);
4391 +               fd = -EINVAL;
4392 +               goto out;
4393 +       }               
4394 +       
4395 +       /* subscribe to the multicast group */
4396 +       mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
4397 +       mreq.imr_interface.s_addr = 0;
4398 +       if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, 
4399 +                      &mreq, sizeof(mreq)) < 0) {
4400 +               printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
4401 +                       errno);
4402 +               printk("There appears not to be a multicast-capable network "
4403 +                      "interface on the host.\n");
4404 +               printk("eth0 should be configured in order to use the "
4405 +                      "multicast transport.\n");
4406 +               close(fd);
4407 +               fd = -EINVAL;
4408 +       }
4409 +
4410 + out:
4411 +       return(fd);
4412 +}
4413 +
4414 +static void mcast_close(int fd, void *data)
4415 +{
4416 +       struct ip_mreq mreq;
4417 +       struct mcast_data *pri = data;
4418 +       struct sockaddr_in *sin = pri->mcast_addr;
4419 +
4420 +       mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
4421 +       mreq.imr_interface.s_addr = 0;
4422 +       if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
4423 +                      &mreq, sizeof(mreq)) < 0) {
4424 +               printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
4425 +                       errno);
4426 +       }
4427 +
4428 +       close(fd);
4429 +}
4430 +
4431 +int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
4432 +{
4433 +       struct sockaddr_in *data_addr = pri->mcast_addr;
4434 +
4435 +       return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
4436 +}
4437 +
4438 +static int mcast_set_mtu(int mtu, void *data)
4439 +{
4440 +       return(mtu);
4441 +}
4442 +
4443 +struct net_user_info mcast_user_info = {
4444 +       .init           = mcast_user_init,
4445 +       .open           = mcast_open,
4446 +       .close          = mcast_close,
4447 +       .remove         = NULL,
4448 +       .set_mtu        = mcast_set_mtu,
4449 +       .add_address    = NULL,
4450 +       .delete_address = NULL,
4451 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
4452 +};
4453 +
4454 +/*
4455 + * Overrides for Emacs so that we follow Linus's tabbing style.
4456 + * Emacs will notice this stuff at the end of the file and automatically
4457 + * adjust the settings for this buffer only.  This must remain at the end
4458 + * of the file.
4459 + * ---------------------------------------------------------------------------
4460 + * Local variables:
4461 + * c-file-style: "linux"
4462 + * End:
4463 + */
4464 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_kern.c um/arch/um/drivers/mconsole_kern.c
4465 --- orig/arch/um/drivers/mconsole_kern.c        1969-12-31 19:00:00.000000000 -0500
4466 +++ um/arch/um/drivers/mconsole_kern.c  2003-03-28 21:58:11.000000000 -0500
4467 @@ -0,0 +1,453 @@
4468 +/*
4469 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
4470 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4471 + * Licensed under the GPL
4472 + */
4473 +
4474 +#include "linux/kernel.h"
4475 +#include "linux/slab.h"
4476 +#include "linux/init.h"
4477 +#include "linux/notifier.h"
4478 +#include "linux/reboot.h"
4479 +#include "linux/utsname.h"
4480 +#include "linux/ctype.h"
4481 +#include "linux/interrupt.h"
4482 +#include "linux/sysrq.h"
4483 +#include "linux/tqueue.h"
4484 +#include "linux/module.h"
4485 +#include "linux/proc_fs.h"
4486 +#include "asm/irq.h"
4487 +#include "asm/uaccess.h"
4488 +#include "user_util.h"
4489 +#include "kern_util.h"
4490 +#include "kern.h"
4491 +#include "mconsole.h"
4492 +#include "mconsole_kern.h"
4493 +#include "irq_user.h"
4494 +#include "init.h"
4495 +#include "os.h"
4496 +#include "umid.h"
4497 +
4498 +static int do_unlink_socket(struct notifier_block *notifier, 
4499 +                           unsigned long what, void *data)
4500 +{
4501 +       return(mconsole_unlink_socket());
4502 +}
4503 +
4504 +
4505 +static struct notifier_block reboot_notifier = {
4506 +       .notifier_call          = do_unlink_socket,
4507 +       .priority               = 0,
4508 +};
4509 +
4510 +/* Safe without explicit locking for now.  Tasklets provide their own 
4511 + * locking, and the interrupt handler is safe because it can't interrupt
4512 + * itself and it can only happen on CPU 0.
4513 + */
4514 +
4515 +LIST_HEAD(mc_requests);
4516 +
4517 +void mc_task_proc(void *unused)
4518 +{
4519 +       struct mconsole_entry *req;
4520 +       unsigned long flags;
4521 +       int done;
4522 +
4523 +       do {
4524 +               save_flags(flags);
4525 +               req = list_entry(mc_requests.next, struct mconsole_entry, 
4526 +                                list);
4527 +               list_del(&req->list);
4528 +               done = list_empty(&mc_requests);
4529 +               restore_flags(flags);
4530 +               req->request.cmd->handler(&req->request);
4531 +               kfree(req);
4532 +       } while(!done);
4533 +}
4534 +
4535 +struct tq_struct mconsole_task = {
4536 +       .routine        = mc_task_proc,
4537 +       .data           = NULL
4538 +};
4539 +
4540 +void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
4541 +{
4542 +       int fd;
4543 +       struct mconsole_entry *new;
4544 +       struct mc_request req;
4545 +
4546 +       fd = (int) dev_id;
4547 +       while (mconsole_get_request(fd, &req)){
4548 +               if(req.cmd->as_interrupt) (*req.cmd->handler)(&req);
4549 +               else {
4550 +                       new = kmalloc(sizeof(req), GFP_ATOMIC);
4551 +                       if(new == NULL)
4552 +                               mconsole_reply(&req, "Out of memory", 1, 0);
4553 +                       else {
4554 +                               new->request = req;
4555 +                               list_add(&new->list, &mc_requests);
4556 +                       }
4557 +               }
4558 +       }
4559 +       if(!list_empty(&mc_requests)) schedule_task(&mconsole_task);
4560 +       reactivate_fd(fd, MCONSOLE_IRQ);
4561 +}
4562 +
4563 +void mconsole_version(struct mc_request *req)
4564 +{
4565 +       char version[256];
4566 +
4567 +       sprintf(version, "%s %s %s %s %s", system_utsname.sysname, 
4568 +               system_utsname.nodename, system_utsname.release, 
4569 +               system_utsname.version, system_utsname.machine);
4570 +       mconsole_reply(req, version, 0, 0);
4571 +}
4572 +
4573 +#define UML_MCONSOLE_HELPTEXT \
4574 +"Commands: \n\
4575 +    version - Get kernel version \n\
4576 +    help - Print this message \n\
4577 +    halt - Halt UML \n\
4578 +    reboot - Reboot UML \n\
4579 +    config <dev>=<config> - Add a new device to UML;  \n\
4580 +       same syntax as command line \n\
4581 +    config <dev> - Query the configuration of a device \n\
4582 +    remove <dev> - Remove a device from UML \n\
4583 +    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
4584 +    cad - invoke the Ctl-Alt-Del handler \n\
4585 +    stop - pause the UML; it will do nothing until it receives a 'go' \n\
4586 +    go - continue the UML after a 'stop' \n\
4587 +"
4588 +
4589 +void mconsole_help(struct mc_request *req)
4590 +{
4591 +       mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0);
4592 +}
4593 +
4594 +void mconsole_halt(struct mc_request *req)
4595 +{
4596 +       mconsole_reply(req, "", 0, 0);
4597 +       machine_halt();
4598 +}
4599 +
4600 +void mconsole_reboot(struct mc_request *req)
4601 +{
4602 +       mconsole_reply(req, "", 0, 0);
4603 +       machine_restart(NULL);
4604 +}
4605 +
4606 +extern void ctrl_alt_del(void);
4607 +
4608 +void mconsole_cad(struct mc_request *req)
4609 +{
4610 +       mconsole_reply(req, "", 0, 0);
4611 +       ctrl_alt_del();
4612 +}
4613 +
4614 +void mconsole_go(struct mc_request *req)
4615 +{
4616 +       mconsole_reply(req, "Not stopped", 1, 0);
4617 +}
4618 +
4619 +void mconsole_stop(struct mc_request *req)
4620 +{
4621 +       deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
4622 +       os_set_fd_block(req->originating_fd, 1);
4623 +       mconsole_reply(req, "", 0, 0);
4624 +       while(mconsole_get_request(req->originating_fd, req)){
4625 +               if(req->cmd->handler == mconsole_go) break;
4626 +               (*req->cmd->handler)(req);
4627 +       }
4628 +       os_set_fd_block(req->originating_fd, 0);
4629 +       reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
4630 +       mconsole_reply(req, "", 0, 0);
4631 +}
4632 +
4633 +/* This list is populated by __initcall routines. */
4634 +
4635 +LIST_HEAD(mconsole_devices);
4636 +
4637 +void mconsole_register_dev(struct mc_device *new)
4638 +{
4639 +       list_add(&new->list, &mconsole_devices);
4640 +}
4641 +
4642 +static struct mc_device *mconsole_find_dev(char *name)
4643 +{
4644 +       struct list_head *ele;
4645 +       struct mc_device *dev;
4646 +
4647 +       list_for_each(ele, &mconsole_devices){
4648 +               dev = list_entry(ele, struct mc_device, list);
4649 +               if(!strncmp(name, dev->name, strlen(dev->name)))
4650 +                       return(dev);
4651 +       }
4652 +       return(NULL);
4653 +}
4654 +
4655 +#define CONFIG_BUF_SIZE 64
4656 +
4657 +static void mconsole_get_config(int (*get_config)(char *, char *, int, 
4658 +                                                 char **),
4659 +                               struct mc_request *req, char *name)
4660 +{
4661 +       char default_buf[CONFIG_BUF_SIZE], *error, *buf;
4662 +       int n, size;
4663 +
4664 +       if(get_config == NULL){
4665 +               mconsole_reply(req, "No get_config routine defined", 1, 0);
4666 +               return;
4667 +       }
4668 +
4669 +       error = NULL;
4670 +       size = sizeof(default_buf)/sizeof(default_buf[0]);
4671 +       buf = default_buf;
4672 +
4673 +       while(1){
4674 +               n = (*get_config)(name, buf, size, &error);
4675 +               if(error != NULL){
4676 +                       mconsole_reply(req, error, 1, 0);
4677 +                       goto out;
4678 +               }
4679 +
4680 +               if(n <= size){
4681 +                       mconsole_reply(req, buf, 0, 0);
4682 +                       goto out;
4683 +               }
4684 +
4685 +               if(buf != default_buf)
4686 +                       kfree(buf);
4687 +
4688 +               size = n;
4689 +               buf = kmalloc(size, GFP_KERNEL);
4690 +               if(buf == NULL){
4691 +                       mconsole_reply(req, "Failed to allocate buffer", 1, 0);
4692 +                       return;
4693 +               }
4694 +       }
4695 + out:
4696 +       if(buf != default_buf)
4697 +               kfree(buf);
4698 +       
4699 +}
4700 +
4701 +void mconsole_config(struct mc_request *req)
4702 +{
4703 +       struct mc_device *dev;
4704 +       char *ptr = req->request.data, *name;
4705 +       int err;
4706 +
4707 +       ptr += strlen("config");
4708 +       while(isspace(*ptr)) ptr++;
4709 +       dev = mconsole_find_dev(ptr);
4710 +       if(dev == NULL){
4711 +               mconsole_reply(req, "Bad configuration option", 1, 0);
4712 +               return;
4713 +       }
4714 +
4715 +       name = &ptr[strlen(dev->name)];
4716 +       ptr = name;
4717 +       while((*ptr != '=') && (*ptr != '\0'))
4718 +               ptr++;
4719 +
4720 +       if(*ptr == '='){
4721 +               err = (*dev->config)(name);
4722 +               mconsole_reply(req, "", err, 0);
4723 +       }
4724 +       else mconsole_get_config(dev->get_config, req, name);
4725 +}
4726 +
4727 +void mconsole_remove(struct mc_request *req)
4728 +{
4729 +       struct mc_device *dev;  
4730 +       char *ptr = req->request.data;
4731 +       int err;
4732 +
4733 +       ptr += strlen("remove");
4734 +       while(isspace(*ptr)) ptr++;
4735 +       dev = mconsole_find_dev(ptr);
4736 +       if(dev == NULL){
4737 +               mconsole_reply(req, "Bad remove option", 1, 0);
4738 +               return;
4739 +       }
4740 +       err = (*dev->remove)(&ptr[strlen(dev->name)]);
4741 +       mconsole_reply(req, "", err, 0);
4742 +}
4743 +
4744 +#ifdef CONFIG_MAGIC_SYSRQ
4745 +void mconsole_sysrq(struct mc_request *req)
4746 +{
4747 +       char *ptr = req->request.data;
4748 +
4749 +       ptr += strlen("sysrq");
4750 +       while(isspace(*ptr)) ptr++;
4751 +
4752 +       handle_sysrq(*ptr, &current->thread.regs, NULL, NULL);
4753 +       mconsole_reply(req, "", 0, 0);
4754 +}
4755 +#else
4756 +void mconsole_sysrq(struct mc_request *req)
4757 +{
4758 +       mconsole_reply(req, "Sysrq not compiled in", 1, 0);
4759 +}
4760 +#endif
4761 +
4762 +/* Changed by mconsole_setup, which is __setup, and called before SMP is
4763 + * active.
4764 + */
4765 +static char *notify_socket = NULL; 
4766 +
4767 +int mconsole_init(void)
4768 +{
4769 +       int err, sock;
4770 +       char file[256];
4771 +
4772 +       if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
4773 +       snprintf(mconsole_socket_name, sizeof(file), "%s", file);
4774 +
4775 +       sock = create_unix_socket(file, sizeof(file));
4776 +       if (sock < 0){
4777 +               printk("Failed to initialize management console\n");
4778 +               return(1);
4779 +       }
4780 +
4781 +       register_reboot_notifier(&reboot_notifier);
4782 +
4783 +       err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
4784 +                            SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
4785 +                            "mconsole", (void *)sock);
4786 +       if (err){
4787 +               printk("Failed to get IRQ for management console\n");
4788 +               return(1);
4789 +       }
4790 +
4791 +       if(notify_socket != NULL){
4792 +               notify_socket = uml_strdup(notify_socket);
4793 +               if(notify_socket != NULL)
4794 +                       mconsole_notify(notify_socket, MCONSOLE_SOCKET,
4795 +                                       mconsole_socket_name, 
4796 +                                       strlen(mconsole_socket_name) + 1);
4797 +               else printk(KERN_ERR "mconsole_setup failed to strdup "
4798 +                           "string\n");
4799 +       }
4800 +
4801 +       printk("mconsole (version %d) initialized on %s\n", 
4802 +              MCONSOLE_VERSION, mconsole_socket_name);
4803 +       return(0);
4804 +}
4805 +
4806 +__initcall(mconsole_init);
4807 +
4808 +static int write_proc_mconsole(struct file *file, const char *buffer,
4809 +                              unsigned long count, void *data)
4810 +{
4811 +       char *buf;
4812 +
4813 +       buf = kmalloc(count + 1, GFP_KERNEL);
4814 +       if(buf == NULL) 
4815 +               return(-ENOMEM);
4816 +
4817 +       if(copy_from_user(buf, buffer, count))
4818 +               return(-EFAULT);
4819 +       buf[count] = '\0';
4820 +
4821 +       mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
4822 +       return(count);
4823 +}
4824 +
4825 +static int create_proc_mconsole(void)
4826 +{
4827 +       struct proc_dir_entry *ent;
4828 +
4829 +       if(notify_socket == NULL) return(0);
4830 +
4831 +       ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
4832 +       if(ent == NULL){
4833 +               printk("create_proc_mconsole : create_proc_entry failed\n");
4834 +               return(0);
4835 +       }
4836 +
4837 +       ent->read_proc = NULL;
4838 +       ent->write_proc = write_proc_mconsole;
4839 +       return(0);
4840 +}
4841 +
4842 +static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
4843 +
4844 +void lock_notify(void)
4845 +{
4846 +       spin_lock(&notify_spinlock);
4847 +}
4848 +
4849 +void unlock_notify(void)
4850 +{
4851 +       spin_unlock(&notify_spinlock);
4852 +}
4853 +
4854 +__initcall(create_proc_mconsole);
4855 +
4856 +#define NOTIFY "=notify:"
4857 +
4858 +static int mconsole_setup(char *str)
4859 +{
4860 +       if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
4861 +               str += strlen(NOTIFY);
4862 +               notify_socket = str;
4863 +       }
4864 +       else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
4865 +       return(1);
4866 +}
4867 +
4868 +__setup("mconsole", mconsole_setup);
4869 +
4870 +__uml_help(mconsole_setup,
4871 +"mconsole=notify:<socket>\n"
4872 +"    Requests that the mconsole driver send a message to the named Unix\n"
4873 +"    socket containing the name of the mconsole socket.  This also serves\n"
4874 +"    to notify outside processes when UML has booted far enough to respond\n"
4875 +"    to mconsole requests.\n\n"
4876 +);
4877 +
4878 +static int notify_panic(struct notifier_block *self, unsigned long unused1,
4879 +                       void *ptr)
4880 +{
4881 +       char *message = ptr;
4882 +
4883 +       if(notify_socket == NULL) return(0);
4884 +
4885 +       mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 
4886 +                       strlen(message) + 1);
4887 +       return(0);
4888 +}
4889 +
4890 +static struct notifier_block panic_exit_notifier = {
4891 +       .notifier_call          = notify_panic,
4892 +       .next                   = NULL,
4893 +       .priority               = 1
4894 +};
4895 +
4896 +static int add_notifier(void)
4897 +{
4898 +       notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
4899 +       return(0);
4900 +}
4901 +
4902 +__initcall(add_notifier);
4903 +
4904 +char *mconsole_notify_socket(void)
4905 +{
4906 +       return(notify_socket);
4907 +}
4908 +
4909 +EXPORT_SYMBOL(mconsole_notify_socket);
4910 +
4911 +/*
4912 + * Overrides for Emacs so that we follow Linus's tabbing style.
4913 + * Emacs will notice this stuff at the end of the file and automatically
4914 + * adjust the settings for this buffer only.  This must remain at the end
4915 + * of the file.
4916 + * ---------------------------------------------------------------------------
4917 + * Local variables:
4918 + * c-file-style: "linux"
4919 + * End:
4920 + */
4921 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_user.c um/arch/um/drivers/mconsole_user.c
4922 --- orig/arch/um/drivers/mconsole_user.c        1969-12-31 19:00:00.000000000 -0500
4923 +++ um/arch/um/drivers/mconsole_user.c  2002-10-23 21:08:04.000000000 -0400
4924 @@ -0,0 +1,212 @@
4925 +/*
4926 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
4927 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4928 + * Licensed under the GPL
4929 + */
4930 +
4931 +#include <stdio.h>
4932 +#include <stdlib.h>
4933 +#include <errno.h>
4934 +#include <signal.h>
4935 +#include <sys/socket.h>
4936 +#include <sys/types.h>
4937 +#include <sys/uio.h>
4938 +#include <sys/un.h>
4939 +#include <unistd.h>
4940 +#include "user.h"
4941 +#include "mconsole.h"
4942 +#include "umid.h"
4943 +
4944 +static struct mconsole_command commands[] = {
4945 +       { "version", mconsole_version, 1 },
4946 +       { "halt", mconsole_halt, 0 },
4947 +       { "reboot", mconsole_reboot, 0 },
4948 +       { "config", mconsole_config, 0 },
4949 +       { "remove", mconsole_remove, 0 },
4950 +       { "sysrq", mconsole_sysrq, 1 },
4951 +       { "help", mconsole_help, 1 },
4952 +       { "cad", mconsole_cad, 1 },
4953 +       { "stop", mconsole_stop, 0 },
4954 +       { "go", mconsole_go, 1 },
4955 +};
4956 +
4957 +/* Initialized in mconsole_init, which is an initcall */
4958 +char mconsole_socket_name[256];
4959 +
4960 +int mconsole_reply_v0(struct mc_request *req, char *reply)
4961 +{
4962 +        struct iovec iov;
4963 +        struct msghdr msg;
4964 +
4965 +        iov.iov_base = reply;
4966 +        iov.iov_len = strlen(reply);
4967 +
4968 +        msg.msg_name = &(req->origin);
4969 +        msg.msg_namelen = req->originlen;
4970 +        msg.msg_iov = &iov;
4971 +        msg.msg_iovlen = 1;
4972 +        msg.msg_control = NULL;
4973 +        msg.msg_controllen = 0;
4974 +        msg.msg_flags = 0;
4975 +
4976 +        return sendmsg(req->originating_fd, &msg, 0);
4977 +}
4978 +
4979 +static struct mconsole_command *mconsole_parse(struct mc_request *req)
4980 +{
4981 +       struct mconsole_command *cmd;
4982 +       int i;
4983 +
4984 +       for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){
4985 +               cmd = &commands[i];
4986 +               if(!strncmp(req->request.data, cmd->command, 
4987 +                           strlen(cmd->command))){
4988 +                       return(cmd);
4989 +               }
4990 +       }
4991 +       return(NULL);
4992 +}
4993 +
4994 +#define MIN(a,b) ((a)<(b) ? (a):(b))
4995 +
4996 +#define STRINGX(x) #x
4997 +#define STRING(x) STRINGX(x)
4998 +
4999 +int mconsole_get_request(int fd, struct mc_request *req)
5000 +{
5001 +       int len;
5002 +
5003 +       req->originlen = sizeof(req->origin);
5004 +       req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
5005 +                           (struct sockaddr *) req->origin, &req->originlen);
5006 +       if (req->len < 0)
5007 +               return 0;
5008 +
5009 +       req->originating_fd = fd;
5010 +
5011 +       if(req->request.magic != MCONSOLE_MAGIC){
5012 +               /* Unversioned request */
5013 +               len = MIN(sizeof(req->request.data) - 1, 
5014 +                         strlen((char *) &req->request));
5015 +               memmove(req->request.data, &req->request, len);
5016 +               req->request.data[len] = '\0';
5017 +
5018 +               req->request.magic = MCONSOLE_MAGIC;
5019 +               req->request.version = 0;
5020 +               req->request.len = len;
5021 +
5022 +               mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
5023 +                                 "not supported by this driver");
5024 +               return(0);
5025 +       }
5026 +
5027 +       if(req->request.len >= MCONSOLE_MAX_DATA){
5028 +               mconsole_reply(req, "Request too large", 1, 0);
5029 +               return(0);
5030 +       }
5031 +       if(req->request.version != MCONSOLE_VERSION){
5032 +               mconsole_reply(req, "This driver only supports version " 
5033 +                               STRING(MCONSOLE_VERSION) " clients", 1, 0);
5034 +       }
5035 +       
5036 +       req->request.data[req->request.len] = '\0';
5037 +       req->cmd = mconsole_parse(req);
5038 +       if(req->cmd == NULL){
5039 +               mconsole_reply(req, "Unknown command", 1, 0);
5040 +               return(0);
5041 +       }
5042 +
5043 +       return(1);
5044 +}
5045 +
5046 +int mconsole_reply(struct mc_request *req, char *str, int err, int more)
5047 +{
5048 +       struct mconsole_reply reply;
5049 +       int total, len, n;
5050 +
5051 +       total = strlen(str);
5052 +       do {
5053 +               reply.err = err;
5054 +
5055 +               /* err can only be true on the first packet */
5056 +               err = 0;
5057 +
5058 +               len = MIN(total, MCONSOLE_MAX_DATA - 1);
5059 +
5060 +               if(len == total) reply.more = more;
5061 +               else reply.more = 1;
5062 +
5063 +               memcpy(reply.data, str, len);
5064 +               reply.data[len] = '\0';
5065 +               total -= len;
5066 +               reply.len = len + 1;
5067 +
5068 +               len = sizeof(reply) + reply.len - sizeof(reply.data);
5069 +
5070 +               n = sendto(req->originating_fd, &reply, len, 0,
5071 +                          (struct sockaddr *) req->origin, req->originlen);
5072 +
5073 +               if(n < 0) return(-errno);
5074 +       } while(total > 0);
5075 +       return(0);
5076 +}
5077 +
5078 +int mconsole_unlink_socket(void)
5079 +{
5080 +       unlink(mconsole_socket_name);
5081 +       return 0;
5082 +}
5083 +
5084 +static int notify_sock = -1;
5085 +
5086 +int mconsole_notify(char *sock_name, int type, const void *data, int len)
5087 +{
5088 +       struct sockaddr_un target;
5089 +       struct mconsole_notify packet;
5090 +       int n, err = 0;
5091 +
5092 +       lock_notify();
5093 +       if(notify_sock < 0){
5094 +               notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
5095 +               if(notify_sock < 0){
5096 +                       printk("mconsole_notify - socket failed, errno = %d\n",
5097 +                              errno);
5098 +                       err = -errno;
5099 +               }
5100 +       }
5101 +       unlock_notify();
5102 +       
5103 +       if(err)
5104 +               return(err);
5105 +
5106 +       target.sun_family = AF_UNIX;
5107 +       strcpy(target.sun_path, sock_name);
5108 +
5109 +       packet.magic = MCONSOLE_MAGIC;
5110 +       packet.version = MCONSOLE_VERSION;
5111 +       packet.type = type;
5112 +       len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
5113 +       packet.len = len;
5114 +       memcpy(packet.data, data, len);
5115 +
5116 +       err = 0;
5117 +       len = sizeof(packet) + packet.len - sizeof(packet.data);
5118 +       n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, 
5119 +                  sizeof(target));
5120 +       if(n < 0){
5121 +               printk("mconsole_notify - sendto failed, errno = %d\n", errno);
5122 +               err = -errno;
5123 +       }
5124 +       return(err);
5125 +}
5126 +
5127 +/*
5128 + * Overrides for Emacs so that we follow Linus's tabbing style.
5129 + * Emacs will notice this stuff at the end of the file and automatically
5130 + * adjust the settings for this buffer only.  This must remain at the end
5131 + * of the file.
5132 + * ---------------------------------------------------------------------------
5133 + * Local variables:
5134 + * c-file-style: "linux"
5135 + * End:
5136 + */
5137 diff -Naur -X ../exclude-files orig/arch/um/drivers/mmapper_kern.c um/arch/um/drivers/mmapper_kern.c
5138 --- orig/arch/um/drivers/mmapper_kern.c 1969-12-31 19:00:00.000000000 -0500
5139 +++ um/arch/um/drivers/mmapper_kern.c   2002-12-15 21:03:08.000000000 -0500
5140 @@ -0,0 +1,148 @@
5141 +/*
5142 + * arch/um/drivers/mmapper_kern.c
5143 + *
5144 + * BRIEF MODULE DESCRIPTION
5145 + *
5146 + * Copyright (C) 2000 RidgeRun, Inc.
5147 + * Author: RidgeRun, Inc.
5148 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
5149 + *
5150 + */
5151 +#include <linux/kdev_t.h>
5152 +#include <linux/time.h>
5153 +#include <linux/devfs_fs_kernel.h>
5154 +#include <linux/module.h>
5155 +#include <linux/mm.h> 
5156 +#include <linux/slab.h>
5157 +#include <linux/init.h> 
5158 +#include <asm/uaccess.h>
5159 +#include <asm/irq.h>
5160 +#include <asm/smplock.h>
5161 +#include <asm/pgtable.h>
5162 +#include "mem_user.h"
5163 +#include "user_util.h"
5164
5165 +/* These are set in mmapper_init, which is called at boot time */
5166 +static unsigned long mmapper_size;
5167 +static unsigned long p_buf = 0;
5168 +static char *v_buf = NULL;
5169 +
5170 +static ssize_t
5171 +mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
5172 +{
5173 +       if(*ppos > mmapper_size)
5174 +               return -EINVAL;
5175 +
5176 +       if(count + *ppos > mmapper_size)
5177 +               count = count + *ppos - mmapper_size;
5178 +
5179 +       if(count < 0)
5180 +               return -EINVAL;
5181
5182 +       copy_to_user(buf,&v_buf[*ppos],count);
5183 +       
5184 +       return count;
5185 +}
5186 +
5187 +static ssize_t
5188 +mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
5189 +{
5190 +       if(*ppos > mmapper_size)
5191 +               return -EINVAL;
5192 +
5193 +       if(count + *ppos > mmapper_size)
5194 +               count = count + *ppos - mmapper_size;
5195 +
5196 +       if(count < 0)
5197 +               return -EINVAL;
5198 +
5199 +       copy_from_user(&v_buf[*ppos],buf,count);
5200 +       
5201 +       return count;
5202 +}
5203 +
5204 +static int 
5205 +mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
5206 +        unsigned long arg)
5207 +{
5208 +       return(-ENOIOCTLCMD);
5209 +}
5210 +
5211 +static int 
5212 +mmapper_mmap(struct file *file, struct vm_area_struct * vma)
5213 +{
5214 +       int ret = -EINVAL;
5215 +       int size;
5216 +
5217 +       lock_kernel();
5218 +       if (vma->vm_pgoff != 0)
5219 +               goto out;
5220 +       
5221 +       size = vma->vm_end - vma->vm_start;
5222 +       if(size > mmapper_size) return(-EFAULT);
5223 +
5224 +       /* XXX A comment above remap_page_range says it should only be
5225 +        * called when the mm semaphore is held
5226 +        */
5227 +       if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot))
5228 +               goto out;
5229 +       ret = 0;
5230 +out:
5231 +       unlock_kernel();
5232 +       return ret;
5233 +}
5234 +
5235 +static int
5236 +mmapper_open(struct inode *inode, struct file *file)
5237 +{
5238 +       return 0;
5239 +}
5240 +
5241 +static int 
5242 +mmapper_release(struct inode *inode, struct file *file)
5243 +{
5244 +       return 0;
5245 +}
5246 +
5247 +static struct file_operations mmapper_fops = {
5248 +       .owner          = THIS_MODULE,
5249 +       .read           = mmapper_read,
5250 +       .write          = mmapper_write,
5251 +       .ioctl          = mmapper_ioctl,
5252 +       .mmap           = mmapper_mmap,
5253 +       .open           = mmapper_open,
5254 +       .release        = mmapper_release,
5255 +};
5256 +
5257 +static int __init mmapper_init(void)
5258 +{
5259 +       printk(KERN_INFO "Mapper v0.1\n");
5260 +
5261 +       v_buf = (char *) find_iomem("mmapper", &mmapper_size);
5262 +       if(mmapper_size == 0) return(0);
5263 +
5264 +       p_buf = __pa(v_buf);
5265 +
5266 +       devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT, 
5267 +                       30, 0, S_IFCHR | S_IRUGO | S_IWUGO, 
5268 +                       &mmapper_fops, NULL); 
5269 +       devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper",
5270 +                        NULL, NULL);
5271 +       return(0);
5272 +}
5273 +
5274 +static void mmapper_exit(void)
5275 +{
5276 +}
5277 +
5278 +module_init(mmapper_init);
5279 +module_exit(mmapper_exit);
5280 +
5281 +MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
5282 +MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
5283 +/*
5284 + * ---------------------------------------------------------------------------
5285 + * Local variables:
5286 + * c-file-style: "linux"
5287 + * End:
5288 + */
5289 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_kern.c um/arch/um/drivers/net_kern.c
5290 --- orig/arch/um/drivers/net_kern.c     1969-12-31 19:00:00.000000000 -0500
5291 +++ um/arch/um/drivers/net_kern.c       2002-12-15 21:19:16.000000000 -0500
5292 @@ -0,0 +1,870 @@
5293 +/*
5294 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
5295 + * James Leu (jleu@mindspring.net).
5296 + * Copyright (C) 2001 by various other people who didn't put their name here.
5297 + * Licensed under the GPL.
5298 + */
5299 +
5300 +#include "linux/config.h"
5301 +#include "linux/kernel.h"
5302 +#include "linux/netdevice.h"
5303 +#include "linux/rtnetlink.h"
5304 +#include "linux/skbuff.h"
5305 +#include "linux/socket.h"
5306 +#include "linux/spinlock.h"
5307 +#include "linux/module.h"
5308 +#include "linux/init.h"
5309 +#include "linux/etherdevice.h"
5310 +#include "linux/list.h"
5311 +#include "linux/inetdevice.h"
5312 +#include "linux/ctype.h"
5313 +#include "linux/bootmem.h"
5314 +#include "user_util.h"
5315 +#include "kern_util.h"
5316 +#include "net_kern.h"
5317 +#include "net_user.h"
5318 +#include "mconsole_kern.h"
5319 +#include "init.h"
5320 +#include "irq_user.h"
5321 +
5322 +static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
5323 +LIST_HEAD(opened);
5324 +
5325 +static int uml_net_rx(struct net_device *dev)
5326 +{
5327 +       struct uml_net_private *lp = dev->priv;
5328 +       int pkt_len;
5329 +       struct sk_buff *skb;
5330 +
5331 +       /* If we can't allocate memory, try again next round. */
5332 +       if ((skb = dev_alloc_skb(dev->mtu)) == NULL) {
5333 +               lp->stats.rx_dropped++;
5334 +               return 0;
5335 +       }
5336 +
5337 +       skb->dev = dev;
5338 +       skb_put(skb, dev->mtu);
5339 +       skb->mac.raw = skb->data;
5340 +       pkt_len = (*lp->read)(lp->fd, &skb, lp);
5341 +
5342 +       if (pkt_len > 0) {
5343 +               skb_trim(skb, pkt_len);
5344 +               skb->protocol = (*lp->protocol)(skb);
5345 +               netif_rx(skb);
5346 +
5347 +               lp->stats.rx_bytes += skb->len;
5348 +               lp->stats.rx_packets++;
5349 +               return pkt_len;
5350 +       }
5351 +
5352 +       kfree_skb(skb);
5353 +       return pkt_len;
5354 +}
5355 +
5356 +void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5357 +{
5358 +       struct net_device *dev = dev_id;
5359 +       struct uml_net_private *lp = dev->priv;
5360 +       int err;
5361 +
5362 +       if(!netif_running(dev))
5363 +               return;
5364 +
5365 +       spin_lock(&lp->lock);
5366 +       while((err = uml_net_rx(dev)) > 0) ;
5367 +       if(err < 0) {
5368 +               printk(KERN_ERR 
5369 +                      "Device '%s' read returned %d, shutting it down\n", 
5370 +                      dev->name, err);
5371 +               dev_close(dev);
5372 +               goto out;
5373 +       }
5374 +       reactivate_fd(lp->fd, UM_ETH_IRQ);
5375 +
5376 + out:
5377 +       spin_unlock(&lp->lock);
5378 +}
5379 +
5380 +static int uml_net_open(struct net_device *dev)
5381 +{
5382 +       struct uml_net_private *lp = dev->priv;
5383 +       char addr[sizeof("255.255.255.255\0")];
5384 +       int err;
5385 +
5386 +       spin_lock(&lp->lock);
5387 +
5388 +       if(lp->fd >= 0){
5389 +               err = -ENXIO;
5390 +               goto out;
5391 +       }
5392 +
5393 +       if(!lp->have_mac){
5394 +               dev_ip_addr(dev, addr, &lp->mac[2]);
5395 +               set_ether_mac(dev, lp->mac);
5396 +       }
5397 +
5398 +       lp->fd = (*lp->open)(&lp->user);
5399 +       if(lp->fd < 0){
5400 +               err = lp->fd;
5401 +               goto out;
5402 +       }
5403 +
5404 +       err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
5405 +                            SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
5406 +       if(err != 0){
5407 +               printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
5408 +               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
5409 +               lp->fd = -1;
5410 +               err = -ENETUNREACH;
5411 +       }
5412 +
5413 +       lp->tl.data = (unsigned long) &lp->user;
5414 +       netif_start_queue(dev);
5415 +
5416 +       spin_lock(&opened_lock);
5417 +       list_add(&lp->list, &opened);
5418 +       spin_unlock(&opened_lock);
5419 +       MOD_INC_USE_COUNT;
5420 + out:
5421 +       spin_unlock(&lp->lock);
5422 +       return(err);
5423 +}
5424 +
5425 +static int uml_net_close(struct net_device *dev)
5426 +{
5427 +       struct uml_net_private *lp = dev->priv;
5428 +       
5429 +       netif_stop_queue(dev);
5430 +       spin_lock(&lp->lock);
5431 +
5432 +       free_irq(dev->irq, dev);
5433 +       if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
5434 +       lp->fd = -1;
5435 +       spin_lock(&opened_lock);
5436 +       list_del(&lp->list);
5437 +       spin_unlock(&opened_lock);
5438 +
5439 +       MOD_DEC_USE_COUNT;
5440 +       spin_unlock(&lp->lock);
5441 +       return 0;
5442 +}
5443 +
5444 +static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
5445 +{
5446 +       struct uml_net_private *lp = dev->priv;
5447 +       unsigned long flags;
5448 +       int len;
5449 +
5450 +       netif_stop_queue(dev);
5451 +
5452 +       spin_lock_irqsave(&lp->lock, flags);
5453 +
5454 +       len = (*lp->write)(lp->fd, &skb, lp);
5455 +
5456 +       if(len == skb->len) {
5457 +               lp->stats.tx_packets++;
5458 +               lp->stats.tx_bytes += skb->len;
5459 +               dev->trans_start = jiffies;
5460 +               netif_start_queue(dev);
5461 +
5462 +               /* this is normally done in the interrupt when tx finishes */
5463 +               netif_wake_queue(dev);
5464 +       } 
5465 +       else if(len == 0){
5466 +               netif_start_queue(dev);
5467 +               lp->stats.tx_dropped++;
5468 +       }
5469 +       else {
5470 +               netif_start_queue(dev);
5471 +               printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
5472 +       }
5473 +
5474 +       spin_unlock_irqrestore(&lp->lock, flags);
5475 +
5476 +       dev_kfree_skb(skb);
5477 +
5478 +       return 0;
5479 +}
5480 +
5481 +static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
5482 +{
5483 +       struct uml_net_private *lp = dev->priv;
5484 +       return &lp->stats;
5485 +}
5486 +
5487 +static void uml_net_set_multicast_list(struct net_device *dev)
5488 +{
5489 +       if (dev->flags & IFF_PROMISC) return;
5490 +       else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
5491 +       else dev->flags &= ~IFF_ALLMULTI;
5492 +}
5493 +
5494 +static void uml_net_tx_timeout(struct net_device *dev)
5495 +{
5496 +       dev->trans_start = jiffies;
5497 +       netif_wake_queue(dev);
5498 +}
5499 +
5500 +static int uml_net_set_mac(struct net_device *dev, void *addr)
5501 +{
5502 +       struct uml_net_private *lp = dev->priv;
5503 +       struct sockaddr *hwaddr = addr;
5504 +
5505 +       spin_lock(&lp->lock);
5506 +       memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
5507 +       spin_unlock(&lp->lock);
5508 +
5509 +       return(0);
5510 +}
5511 +
5512 +static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
5513 +{
5514 +       struct uml_net_private *lp = dev->priv;
5515 +       int err = 0;
5516 +
5517 +       spin_lock(&lp->lock);
5518 +
5519 +       new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
5520 +       if(new_mtu < 0){
5521 +               err = new_mtu;
5522 +               goto out;
5523 +       }
5524 +
5525 +       dev->mtu = new_mtu;
5526 +
5527 + out:
5528 +       spin_unlock(&lp->lock);
5529 +       return err;
5530 +}
5531 +
5532 +static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
5533 +{
5534 +       return(-EINVAL);
5535 +}
5536 +
5537 +void uml_net_user_timer_expire(unsigned long _conn)
5538 +{
5539 +#ifdef undef
5540 +       struct connection *conn = (struct connection *)_conn;
5541 +
5542 +       dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn);
5543 +       do_connect(conn);
5544 +#endif
5545 +}
5546 +
5547 +/*
5548 + * default do nothing hard header packet routines for struct net_device init.
5549 + * real ethernet transports will overwrite with real routines.
5550 + */
5551 +static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
5552 +                 unsigned short type, void *daddr, void *saddr, unsigned len)
5553 +{
5554 +       return(0); /* no change */
5555 +}
5556 +
5557 +static int uml_net_rebuild_header(struct sk_buff *skb)
5558 +{
5559 +       return(0); /* ignore */ 
5560 +}
5561 +
5562 +static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
5563 +{
5564 +       return(-1); /* fail */
5565 +}
5566 +
5567 +static void uml_net_header_cache_update(struct hh_cache *hh,
5568 +                 struct net_device *dev, unsigned char * haddr)
5569 +{
5570 +       /* ignore */
5571 +}
5572 +
5573 +static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
5574 +{
5575 +       return(0); /* nothing */
5576 +}
5577 +
5578 +static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
5579 +static struct list_head devices = LIST_HEAD_INIT(devices);
5580 +
5581 +static int eth_configure(int n, void *init, char *mac,
5582 +                        struct transport *transport)
5583 +{
5584 +       struct uml_net *device;
5585 +       struct net_device *dev;
5586 +       struct uml_net_private *lp;
5587 +       int save, err, size;
5588 +
5589 +       size = transport->private_size + sizeof(struct uml_net_private) + 
5590 +               sizeof(((struct uml_net_private *) 0)->user);
5591 +
5592 +       device = kmalloc(sizeof(*device), GFP_KERNEL);
5593 +       if(device == NULL){
5594 +               printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
5595 +               return(1);
5596 +       }
5597 +
5598 +       *device = ((struct uml_net) { .list     = LIST_HEAD_INIT(device->list),
5599 +                                     .dev      = NULL,
5600 +                                     .index    = n,
5601 +                                     .mac      = { [ 0 ... 5 ] = 0 },
5602 +                                     .have_mac = 0 });
5603 +
5604 +       spin_lock(&devices_lock);
5605 +       list_add(&device->list, &devices);
5606 +       spin_unlock(&devices_lock);
5607 +
5608 +       if(setup_etheraddr(mac, device->mac))
5609 +               device->have_mac = 1;
5610 +
5611 +       printk(KERN_INFO "Netdevice %d ", n);
5612 +       if(device->have_mac) printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
5613 +                                   device->mac[0], device->mac[1], 
5614 +                                   device->mac[2], device->mac[3], 
5615 +                                   device->mac[4], device->mac[5]);
5616 +       printk(": ");
5617 +       dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL);
5618 +       if(dev == NULL){
5619 +               printk(KERN_ERR "eth_configure: failed to allocate device\n");
5620 +               return(1);
5621 +       }
5622 +       memset(dev, 0, sizeof(*dev) + size);
5623 +
5624 +       snprintf(dev->name, sizeof(dev->name), "eth%d", n);
5625 +       dev->priv = (void *) &dev[1];
5626 +       device->dev = dev;
5627 +
5628 +        dev->hard_header = uml_net_hard_header;
5629 +        dev->rebuild_header = uml_net_rebuild_header;
5630 +        dev->hard_header_cache = uml_net_header_cache;
5631 +        dev->header_cache_update= uml_net_header_cache_update;
5632 +        dev->hard_header_parse = uml_net_header_parse;
5633 +
5634 +       (*transport->kern->init)(dev, init);
5635 +
5636 +       dev->mtu = transport->user->max_packet;
5637 +       dev->open = uml_net_open;
5638 +       dev->hard_start_xmit = uml_net_start_xmit;
5639 +       dev->stop = uml_net_close;
5640 +       dev->get_stats = uml_net_get_stats;
5641 +       dev->set_multicast_list = uml_net_set_multicast_list;
5642 +       dev->tx_timeout = uml_net_tx_timeout;
5643 +       dev->set_mac_address = uml_net_set_mac;
5644 +       dev->change_mtu = uml_net_change_mtu;
5645 +       dev->do_ioctl = uml_net_ioctl;
5646 +       dev->watchdog_timeo = (HZ >> 1);
5647 +       dev->irq = UM_ETH_IRQ;
5648 +
5649 +       rtnl_lock();
5650 +       err = register_netdevice(dev);
5651 +       rtnl_unlock();
5652 +       if(err)
5653 +               return(1);
5654 +       lp = dev->priv;
5655 +
5656 +       /* lp.user is the first four bytes of the transport data, which
5657 +        * has already been initialized.  This structure assignment will
5658 +        * overwrite that, so we make sure that .user gets overwritten with
5659 +        * what it already has.
5660 +        */
5661 +       save = lp->user[0];
5662 +       *lp = ((struct uml_net_private) 
5663 +               { .list                 = LIST_HEAD_INIT(lp->list),
5664 +                 .lock                 = SPIN_LOCK_UNLOCKED,
5665 +                 .dev                  = dev,
5666 +                 .fd                   = -1,
5667 +                 .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
5668 +                 .have_mac             = device->have_mac,
5669 +                 .protocol             = transport->kern->protocol,
5670 +                 .open                 = transport->user->open,
5671 +                 .close                = transport->user->close,
5672 +                 .remove               = transport->user->remove,
5673 +                 .read                 = transport->kern->read,
5674 +                 .write                = transport->kern->write,
5675 +                 .add_address          = transport->user->add_address,
5676 +                 .delete_address       = transport->user->delete_address,
5677 +                 .set_mtu              = transport->user->set_mtu,
5678 +                 .user                 = { save } });
5679 +       init_timer(&lp->tl);
5680 +       lp->tl.function = uml_net_user_timer_expire;
5681 +       memset(&lp->stats, 0, sizeof(lp->stats));
5682 +       if(lp->have_mac) memcpy(lp->mac, device->mac, sizeof(lp->mac));
5683 +
5684 +       if(transport->user->init) 
5685 +               (*transport->user->init)(&lp->user, dev);
5686 +
5687 +       if(device->have_mac)
5688 +               set_ether_mac(dev, device->mac);
5689 +       return(0);
5690 +}
5691 +
5692 +static struct uml_net *find_device(int n)
5693 +{
5694 +       struct uml_net *device;
5695 +       struct list_head *ele;
5696 +
5697 +       spin_lock(&devices_lock);
5698 +       list_for_each(ele, &devices){
5699 +               device = list_entry(ele, struct uml_net, list);
5700 +               if(device->index == n)
5701 +                       goto out;
5702 +       }
5703 +       device = NULL;
5704 + out:
5705 +       spin_unlock(&devices_lock);
5706 +       return(device);
5707 +}
5708 +
5709 +static int eth_parse(char *str, int *index_out, char **str_out)
5710 +{
5711 +       char *end;
5712 +       int n;
5713 +
5714 +       n = simple_strtoul(str, &end, 0);
5715 +       if(end == str){
5716 +               printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str);
5717 +               return(1);
5718 +       }
5719 +       if(n < 0){
5720 +               printk(KERN_ERR "eth_setup: device %d is negative\n", n);
5721 +               return(1);
5722 +       }
5723 +       str = end;
5724 +       if(*str != '='){
5725 +               printk(KERN_ERR 
5726 +                      "eth_setup: expected '=' after device number\n");
5727 +               return(1);
5728 +       }
5729 +       str++;
5730 +       if(find_device(n)){
5731 +               printk(KERN_ERR "eth_setup: Device %d already configured\n",
5732 +                      n);
5733 +               return(1);
5734 +       }
5735 +       if(index_out) *index_out = n;
5736 +       *str_out = str;
5737 +       return(0);
5738 +}
5739 +
5740 +struct eth_init {
5741 +       struct list_head list;
5742 +       char *init;
5743 +       int index;
5744 +};
5745 +
5746 +/* Filled in at boot time.  Will need locking if the transports become
5747 + * modular.
5748 + */
5749 +struct list_head transports = LIST_HEAD_INIT(transports);
5750 +
5751 +/* Filled in during early boot */
5752 +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
5753 +
5754 +static int check_transport(struct transport *transport, char *eth, int n,
5755 +                          void **init_out, char **mac_out)
5756 +{
5757 +       int len;
5758 +
5759 +       len = strlen(transport->name);
5760 +       if(strncmp(eth, transport->name, len))
5761 +               return(0);
5762 +
5763 +       eth += len;
5764 +       if(*eth == ',')
5765 +               eth++;
5766 +       else if(*eth != '\0')
5767 +               return(0);
5768 +
5769 +       *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
5770 +       if(*init_out == NULL)
5771 +               return(1);
5772 +
5773 +       if(!transport->setup(eth, mac_out, *init_out)){
5774 +               kfree(*init_out);
5775 +               *init_out = NULL;
5776 +       }
5777 +       return(1);
5778 +}
5779 +
5780 +void register_transport(struct transport *new)
5781 +{
5782 +       struct list_head *ele, *next;
5783 +       struct eth_init *eth;
5784 +       void *init;
5785 +       char *mac = NULL;
5786 +       int match;
5787 +
5788 +       list_add(&new->list, &transports);
5789 +
5790 +       list_for_each_safe(ele, next, &eth_cmd_line){
5791 +               eth = list_entry(ele, struct eth_init, list);
5792 +               match = check_transport(new, eth->init, eth->index, &init,
5793 +                                       &mac);
5794 +               if(!match)
5795 +                       continue;
5796 +               else if(init != NULL){
5797 +                       eth_configure(eth->index, init, mac, new);
5798 +                       kfree(init);
5799 +               }
5800 +               list_del(&eth->list);
5801 +       }
5802 +}
5803 +
5804 +static int eth_setup_common(char *str, int index)
5805 +{
5806 +       struct list_head *ele;
5807 +       struct transport *transport;
5808 +       void *init;
5809 +       char *mac = NULL;
5810 +
5811 +       list_for_each(ele, &transports){
5812 +               transport = list_entry(ele, struct transport, list);
5813 +               if(!check_transport(transport, str, index, &init, &mac))
5814 +                       continue;
5815 +               if(init != NULL){
5816 +                       eth_configure(index, init, mac, transport);
5817 +                       kfree(init);
5818 +               }
5819 +               return(1);
5820 +       }
5821 +       return(0);
5822 +}
5823 +
5824 +static int eth_setup(char *str)
5825 +{
5826 +       struct eth_init *new;
5827 +       int n, err;
5828 +
5829 +       err = eth_parse(str, &n, &str);
5830 +       if(err) return(1);
5831 +
5832 +       new = alloc_bootmem(sizeof(new));
5833 +       if(new == NULL){
5834 +               printk("eth_init : alloc_bootmem failed\n");
5835 +               return(1);
5836 +       }
5837 +       *new = ((struct eth_init) { .list       = LIST_HEAD_INIT(new->list),
5838 +                                   .index      = n,
5839 +                                   .init       = str });
5840 +       list_add_tail(&new->list, &eth_cmd_line);
5841 +       return(1);
5842 +}
5843 +
5844 +__setup("eth", eth_setup);
5845 +__uml_help(eth_setup,
5846 +"eth[0-9]+=<transport>,<options>\n"
5847 +"    Configure a network device.\n\n"
5848 +);
5849 +
5850 +static int eth_init(void)
5851 +{
5852 +       struct list_head *ele, *next;
5853 +       struct eth_init *eth;
5854 +
5855 +       list_for_each_safe(ele, next, &eth_cmd_line){
5856 +               eth = list_entry(ele, struct eth_init, list);
5857 +
5858 +               if(eth_setup_common(eth->init, eth->index))
5859 +                       list_del(&eth->list);
5860 +       }
5861 +       
5862 +       return(1);
5863 +}
5864 +
5865 +__initcall(eth_init);
5866 +
5867 +static int net_config(char *str)
5868 +{
5869 +       int n, err;
5870 +
5871 +       err = eth_parse(str, &n, &str);
5872 +       if(err) return(err);
5873 +
5874 +       str = uml_strdup(str);
5875 +       if(str == NULL){
5876 +               printk(KERN_ERR "net_config failed to strdup string\n");
5877 +               return(-1);
5878 +       }
5879 +       err = !eth_setup_common(str, n);
5880 +       if(err) 
5881 +               kfree(str);
5882 +       return(err);
5883 +}
5884 +
5885 +static int net_remove(char *str)
5886 +{
5887 +       struct uml_net *device;
5888 +       struct net_device *dev;
5889 +       struct uml_net_private *lp;
5890 +       char *end;
5891 +       int n;
5892 +
5893 +       n = simple_strtoul(str, &end, 0);
5894 +       if((*end != '\0') || (end == str))
5895 +               return(-1);
5896 +
5897 +       device = find_device(n);
5898 +       if(device == NULL)
5899 +               return(0);
5900 +
5901 +       dev = device->dev;
5902 +       lp = dev->priv;
5903 +       if(lp->fd > 0) return(-1);
5904 +       if(lp->remove != NULL) (*lp->remove)(&lp->user);
5905 +       unregister_netdev(dev);
5906 +
5907 +       list_del(&device->list);
5908 +       kfree(device);
5909 +       return(0);
5910 +}
5911 +
5912 +static struct mc_device net_mc = {
5913 +       .name           = "eth",
5914 +       .config         = net_config,
5915 +       .get_config     = NULL,
5916 +       .remove         = net_remove,
5917 +};
5918 +
5919 +static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
5920 +                             void *ptr)
5921 +{
5922 +       struct in_ifaddr *ifa = ptr;
5923 +       u32 addr = ifa->ifa_address;
5924 +       u32 netmask = ifa->ifa_mask;
5925 +       struct net_device *dev = ifa->ifa_dev->dev;
5926 +       struct uml_net_private *lp;
5927 +       void (*proc)(unsigned char *, unsigned char *, void *);
5928 +       unsigned char addr_buf[4], netmask_buf[4];
5929 +
5930 +       if(dev->open != uml_net_open) return(NOTIFY_DONE);
5931 +
5932 +       lp = dev->priv;
5933 +
5934 +       proc = NULL;
5935 +       switch (event){
5936 +       case NETDEV_UP:
5937 +               proc = lp->add_address;
5938 +               break;
5939 +       case NETDEV_DOWN:
5940 +               proc = lp->delete_address;
5941 +               break;
5942 +       }
5943 +       if(proc != NULL){
5944 +               addr_buf[0] = addr & 0xff;
5945 +               addr_buf[1] = (addr >> 8) & 0xff;
5946 +               addr_buf[2] = (addr >> 16) & 0xff;
5947 +               addr_buf[3] = addr >> 24;
5948 +               netmask_buf[0] = netmask & 0xff;
5949 +               netmask_buf[1] = (netmask >> 8) & 0xff;
5950 +               netmask_buf[2] = (netmask >> 16) & 0xff;
5951 +               netmask_buf[3] = netmask >> 24;
5952 +               (*proc)(addr_buf, netmask_buf, &lp->user);
5953 +       }
5954 +       return(NOTIFY_DONE);
5955 +}
5956 +
5957 +struct notifier_block uml_inetaddr_notifier = {
5958 +       .notifier_call          = uml_inetaddr_event,
5959 +};
5960 +
5961 +static int uml_net_init(void)
5962 +{
5963 +       struct list_head *ele;
5964 +       struct uml_net_private *lp;     
5965 +       struct in_device *ip;
5966 +       struct in_ifaddr *in;
5967 +
5968 +       mconsole_register_dev(&net_mc);
5969 +       register_inetaddr_notifier(&uml_inetaddr_notifier);
5970 +
5971 +       /* Devices may have been opened already, so the uml_inetaddr_notifier
5972 +        * didn't get a chance to run for them.  This fakes it so that
5973 +        * addresses which have already been set up get handled properly.
5974 +        */
5975 +       list_for_each(ele, &opened){
5976 +               lp = list_entry(ele, struct uml_net_private, list);
5977 +               ip = lp->dev->ip_ptr;
5978 +               if(ip == NULL) continue;
5979 +               in = ip->ifa_list;
5980 +               while(in != NULL){
5981 +                       uml_inetaddr_event(NULL, NETDEV_UP, in);
5982 +                       in = in->ifa_next;
5983 +               }
5984 +       }       
5985 +
5986 +       return(0);
5987 +}
5988 +
5989 +__initcall(uml_net_init);
5990 +
5991 +static void close_devices(void)
5992 +{
5993 +       struct list_head *ele;
5994 +       struct uml_net_private *lp;     
5995 +
5996 +       list_for_each(ele, &opened){
5997 +               lp = list_entry(ele, struct uml_net_private, list);
5998 +               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
5999 +               if(lp->remove != NULL) (*lp->remove)(&lp->user);
6000 +       }
6001 +}
6002 +
6003 +__uml_exitcall(close_devices);
6004 +
6005 +int setup_etheraddr(char *str, unsigned char *addr)
6006 +{
6007 +       char *end;
6008 +       int i;
6009 +
6010 +       if(str == NULL)
6011 +               return(0);
6012 +       for(i=0;i<6;i++){
6013 +               addr[i] = simple_strtoul(str, &end, 16);
6014 +               if((end == str) ||
6015 +                  ((*end != ':') && (*end != ',') && (*end != '\0'))){
6016 +                       printk(KERN_ERR 
6017 +                              "setup_etheraddr: failed to parse '%s' "
6018 +                              "as an ethernet address\n", str);
6019 +                       return(0);
6020 +               }
6021 +               str = end + 1;
6022 +       }
6023 +       if(addr[0] & 1){
6024 +               printk(KERN_ERR 
6025 +                      "Attempt to assign a broadcast ethernet address to a "
6026 +                      "device disallowed\n");
6027 +               return(0);
6028 +       }
6029 +       return(1);
6030 +}
6031 +
6032 +void dev_ip_addr(void *d, char *buf, char *bin_buf)
6033 +{
6034 +       struct net_device *dev = d;
6035 +       struct in_device *ip = dev->ip_ptr;
6036 +       struct in_ifaddr *in;
6037 +       u32 addr;
6038 +
6039 +       if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
6040 +               printk(KERN_WARNING "dev_ip_addr - device not assigned an "
6041 +                      "IP address\n");
6042 +               return;
6043 +       }
6044 +       addr = in->ifa_address;
6045 +       sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, 
6046 +               (addr >> 16) & 0xff, addr >> 24);
6047 +       if(bin_buf){
6048 +               bin_buf[0] = addr & 0xff;
6049 +               bin_buf[1] = (addr >> 8) & 0xff;
6050 +               bin_buf[2] = (addr >> 16) & 0xff;
6051 +               bin_buf[3] = addr >> 24;
6052 +       }
6053 +}
6054 +
6055 +void set_ether_mac(void *d, unsigned char *addr)
6056 +{
6057 +       struct net_device *dev = d;
6058 +
6059 +       memcpy(dev->dev_addr, addr, ETH_ALEN);  
6060 +}
6061 +
6062 +struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
6063 +{
6064 +       if((skb != NULL) && (skb_tailroom(skb) < extra)){
6065 +               struct sk_buff *skb2;
6066 +
6067 +               skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
6068 +               dev_kfree_skb(skb);
6069 +               skb = skb2;
6070 +       }
6071 +       if(skb != NULL) skb_put(skb, extra);
6072 +       return(skb);
6073 +}
6074 +
6075 +void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, 
6076 +                                       void *), 
6077 +                   void *arg)
6078 +{
6079 +       struct net_device *dev = d;
6080 +       struct in_device *ip = dev->ip_ptr;
6081 +       struct in_ifaddr *in;
6082 +       unsigned char address[4], netmask[4];
6083 +
6084 +       if(ip == NULL) return;
6085 +       in = ip->ifa_list;
6086 +       while(in != NULL){
6087 +               address[0] = in->ifa_address & 0xff;
6088 +               address[1] = (in->ifa_address >> 8) & 0xff;
6089 +               address[2] = (in->ifa_address >> 16) & 0xff;
6090 +               address[3] = in->ifa_address >> 24;
6091 +               netmask[0] = in->ifa_mask & 0xff;
6092 +               netmask[1] = (in->ifa_mask >> 8) & 0xff;
6093 +               netmask[2] = (in->ifa_mask >> 16) & 0xff;
6094 +               netmask[3] = in->ifa_mask >> 24;
6095 +               (*cb)(address, netmask, arg);
6096 +               in = in->ifa_next;
6097 +       }
6098 +}
6099 +
6100 +int dev_netmask(void *d, void *m)
6101 +{
6102 +       struct net_device *dev = d;
6103 +       struct in_device *ip = dev->ip_ptr;
6104 +       struct in_ifaddr *in;
6105 +       __u32 *mask_out = m;
6106 +
6107 +       if(ip == NULL) 
6108 +               return(1);
6109 +
6110 +       in = ip->ifa_list;
6111 +       if(in == NULL) 
6112 +               return(1);
6113 +
6114 +       *mask_out = in->ifa_mask;
6115 +       return(0);
6116 +}
6117 +
6118 +void *get_output_buffer(int *len_out)
6119 +{
6120 +       void *ret;
6121 +
6122 +       ret = (void *) __get_free_pages(GFP_KERNEL, 0);
6123 +       if(ret) *len_out = PAGE_SIZE;
6124 +       else *len_out = 0;
6125 +       return(ret);
6126 +}
6127 +
6128 +void free_output_buffer(void *buffer)
6129 +{
6130 +       free_pages((unsigned long) buffer, 0);
6131 +}
6132 +
6133 +int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, 
6134 +                    char **gate_addr)
6135 +{
6136 +       char *remain;
6137 +
6138 +       remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
6139 +       if(remain != NULL){
6140 +               printk("tap_setup_common - Extra garbage on specification : "
6141 +                      "'%s'\n", remain);
6142 +               return(1);
6143 +       }
6144 +
6145 +       return(0);
6146 +}
6147 +
6148 +unsigned short eth_protocol(struct sk_buff *skb)
6149 +{
6150 +       return(eth_type_trans(skb, skb->dev));
6151 +}
6152 +
6153 +/*
6154 + * Overrides for Emacs so that we follow Linus's tabbing style.
6155 + * Emacs will notice this stuff at the end of the file and automatically
6156 + * adjust the settings for this buffer only.  This must remain at the end
6157 + * of the file.
6158 + * ---------------------------------------------------------------------------
6159 + * Local variables:
6160 + * c-file-style: "linux"
6161 + * End:
6162 + */
6163 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_user.c um/arch/um/drivers/net_user.c
6164 --- orig/arch/um/drivers/net_user.c     1969-12-31 19:00:00.000000000 -0500
6165 +++ um/arch/um/drivers/net_user.c       2002-10-23 21:08:04.000000000 -0400
6166 @@ -0,0 +1,254 @@
6167 +/* 
6168 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
6169 + * Licensed under the GPL
6170 + */
6171 +
6172 +#include <stddef.h>
6173 +#include <stdarg.h>
6174 +#include <unistd.h>
6175 +#include <stdio.h>
6176 +#include <errno.h>
6177 +#include <stdlib.h>
6178 +#include <string.h>
6179 +#include <sys/socket.h>
6180 +#include <sys/wait.h>
6181 +#include "user.h"
6182 +#include "user_util.h"
6183 +#include "kern_util.h"
6184 +#include "net_user.h"
6185 +#include "helper.h"
6186 +#include "os.h"
6187 +
6188 +int tap_open_common(void *dev, char *gate_addr)
6189 +{
6190 +       int tap_addr[4];
6191 +
6192 +       if(gate_addr == NULL) return(0);
6193 +       if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
6194 +                 &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
6195 +               printk("Invalid tap IP address - '%s'\n", 
6196 +                      gate_addr);
6197 +               return(-EINVAL);
6198 +       }
6199 +       return(0);
6200 +}
6201 +
6202 +void tap_check_ips(char *gate_addr, char *eth_addr)
6203 +{
6204 +       int tap_addr[4];
6205 +
6206 +       if((gate_addr != NULL) && 
6207 +          (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
6208 +                  &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
6209 +          (eth_addr[0] == tap_addr[0]) && 
6210 +          (eth_addr[1] == tap_addr[1]) && 
6211 +          (eth_addr[2] == tap_addr[2]) && 
6212 +          (eth_addr[3] == tap_addr[3])){
6213 +               printk("The tap IP address and the UML eth IP address"
6214 +                      " must be different\n");
6215 +       }
6216 +}
6217 +
6218 +void read_output(int fd, char *output, int len)
6219 +{
6220 +       int remain, n, actual;
6221 +       char c;
6222 +
6223 +       if(output == NULL){
6224 +               output = &c;
6225 +               len = sizeof(c);
6226 +       }
6227 +               
6228 +       *output = '\0';
6229 +       if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
6230 +               printk("read_output - read of length failed, errno = %d\n",
6231 +                      errno);
6232 +               return;
6233 +       }
6234 +
6235 +       while(remain != 0){
6236 +               n = (remain < len) ? remain : len;
6237 +               actual = read(fd, output, n);
6238 +               if(actual != n){
6239 +                       printk("read_output - read of data failed, "
6240 +                              "errno = %d\n", errno);
6241 +                       return;
6242 +               }
6243 +               remain -= actual;
6244 +       }
6245 +       return;
6246 +}
6247 +
6248 +int net_read(int fd, void *buf, int len)
6249 +{
6250 +       int n;
6251 +
6252 +       while(((n = read(fd,  buf,  len)) < 0) && (errno == EINTR)) ;
6253 +
6254 +       if(n < 0){
6255 +               if(errno == EAGAIN) return(0);
6256 +               return(-errno);
6257 +       }
6258 +       else if(n == 0) return(-ENOTCONN);
6259 +       return(n);
6260 +}
6261 +
6262 +int net_recvfrom(int fd, void *buf, int len)
6263 +{
6264 +       int n;
6265 +
6266 +       while(((n = recvfrom(fd,  buf,  len, 0, NULL, NULL)) < 0) && 
6267 +             (errno == EINTR)) ;
6268 +
6269 +       if(n < 0){
6270 +               if(errno == EAGAIN) return(0);
6271 +               return(-errno);
6272 +       }
6273 +       else if(n == 0) return(-ENOTCONN);
6274 +       return(n);
6275 +}
6276 +
6277 +int net_write(int fd, void *buf, int len)
6278 +{
6279 +       int n;
6280 +
6281 +       while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
6282 +       if(n < 0){
6283 +               if(errno == EAGAIN) return(0);
6284 +               return(-errno);
6285 +       }
6286 +       else if(n == 0) return(-ENOTCONN);
6287 +       return(n);      
6288 +}
6289 +
6290 +int net_send(int fd, void *buf, int len)
6291 +{
6292 +       int n;
6293 +
6294 +       while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
6295 +       if(n < 0){
6296 +               if(errno == EAGAIN) return(0);
6297 +               return(-errno);
6298 +       }
6299 +       else if(n == 0) return(-ENOTCONN);
6300 +       return(n);      
6301 +}
6302 +
6303 +int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
6304 +{
6305 +       int n;
6306 +
6307 +       while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
6308 +                          sock_len)) < 0) && (errno == EINTR)) ;
6309 +       if(n < 0){
6310 +               if(errno == EAGAIN) return(0);
6311 +               return(-errno);
6312 +       }
6313 +       else if(n == 0) return(-ENOTCONN);
6314 +       return(n);      
6315 +}
6316 +
6317 +struct change_pre_exec_data {
6318 +       int close_me;
6319 +       int stdout;
6320 +};
6321 +
6322 +static void change_pre_exec(void *arg)
6323 +{
6324 +       struct change_pre_exec_data *data = arg;
6325 +
6326 +       close(data->close_me);
6327 +       dup2(data->stdout, 1);
6328 +}
6329 +
6330 +static int change_tramp(char **argv, char *output, int output_len)
6331 +{
6332 +       int pid, fds[2], err;
6333 +       struct change_pre_exec_data pe_data;
6334 +
6335 +       err = os_pipe(fds, 1, 0);
6336 +       if(err){
6337 +               printk("change_tramp - pipe failed, errno = %d\n", -err);
6338 +               return(err);
6339 +       }
6340 +       pe_data.close_me = fds[0];
6341 +       pe_data.stdout = fds[1];
6342 +       pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
6343 +
6344 +       close(fds[1]);
6345 +       read_output(fds[0], output, output_len);
6346 +       waitpid(pid, NULL, 0);  
6347 +       return(pid);
6348 +}
6349 +
6350 +static void change(char *dev, char *what, unsigned char *addr,
6351 +                  unsigned char *netmask)
6352 +{
6353 +       char addr_buf[sizeof("255.255.255.255\0")];
6354 +       char netmask_buf[sizeof("255.255.255.255\0")];
6355 +       char version[sizeof("nnnnn\0")];
6356 +       char *argv[] = { "uml_net", version, what, dev, addr_buf, 
6357 +                        netmask_buf, NULL };
6358 +       char *output;
6359 +       int output_len, pid;
6360 +
6361 +       sprintf(version, "%d", UML_NET_VERSION);
6362 +       sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
6363 +       sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], 
6364 +               netmask[2], netmask[3]);
6365 +
6366 +       output_len = page_size();
6367 +       output = um_kmalloc(output_len);
6368 +       if(output == NULL)
6369 +               printk("change : failed to allocate output buffer\n");
6370 +
6371 +       pid = change_tramp(argv, output, output_len);
6372 +       if(pid < 0) return;
6373 +
6374 +       if(output != NULL){
6375 +               printk("%s", output);
6376 +               kfree(output);
6377 +       }
6378 +}
6379 +
6380 +void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
6381 +{
6382 +       change(arg, "add", addr, netmask);
6383 +}
6384 +
6385 +void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
6386 +{
6387 +       change(arg, "del", addr, netmask);
6388 +}
6389 +
6390 +char *split_if_spec(char *str, ...)
6391 +{
6392 +       char **arg, *end;
6393 +       va_list ap;
6394 +
6395 +       va_start(ap, str);
6396 +       while((arg = va_arg(ap, char **)) != NULL){
6397 +               if(*str == '\0')
6398 +                       return(NULL);
6399 +               end = strchr(str, ',');
6400 +               if(end != str)
6401 +                       *arg = str;
6402 +               if(end == NULL)
6403 +                       return(NULL);
6404 +               *end++ = '\0';
6405 +               str = end;
6406 +       }
6407 +       va_end(ap);
6408 +       return(str);
6409 +}
6410 +
6411 +/*
6412 + * Overrides for Emacs so that we follow Linus's tabbing style.
6413 + * Emacs will notice this stuff at the end of the file and automatically
6414 + * adjust the settings for this buffer only.  This must remain at the end
6415 + * of the file.
6416 + * ---------------------------------------------------------------------------
6417 + * Local variables:
6418 + * c-file-style: "linux"
6419 + * End:
6420 + */
6421 diff -Naur -X ../exclude-files orig/arch/um/drivers/null.c um/arch/um/drivers/null.c
6422 --- orig/arch/um/drivers/null.c 1969-12-31 19:00:00.000000000 -0500
6423 +++ um/arch/um/drivers/null.c   2002-12-15 21:04:00.000000000 -0500
6424 @@ -0,0 +1,56 @@
6425 +/* 
6426 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
6427 + * Licensed under the GPL
6428 + */
6429 +
6430 +#include <stdlib.h>
6431 +#include <errno.h>
6432 +#include <fcntl.h>
6433 +#include "chan_user.h"
6434 +#include "os.h"
6435 +
6436 +static int null_chan;
6437 +
6438 +void *null_init(char *str, int device, struct chan_opts *opts)
6439 +{
6440 +       return(&null_chan);
6441 +}
6442 +
6443 +int null_open(int input, int output, int primary, void *d, char **dev_out)
6444 +{
6445 +       *dev_out = NULL;
6446 +       return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
6447 +}
6448 +
6449 +int null_read(int fd, char *c_out, void *unused)
6450 +{
6451 +       return(-ENODEV);
6452 +}
6453 +
6454 +void null_free(void *data)
6455 +{
6456 +}
6457 +
6458 +struct chan_ops null_ops = {
6459 +       .type           = "null",
6460 +       .init           = null_init,
6461 +       .open           = null_open,
6462 +       .close          = generic_close,
6463 +       .read           = null_read,
6464 +       .write          = generic_write,
6465 +       .console_write  = generic_console_write,
6466 +       .window_size    = generic_window_size,
6467 +       .free           = null_free,
6468 +       .winch          = 0,
6469 +};
6470 +
6471 +/*
6472 + * Overrides for Emacs so that we follow Linus's tabbing style.
6473 + * Emacs will notice this stuff at the end of the file and automatically
6474 + * adjust the settings for this buffer only.  This must remain at the end
6475 + * of the file.
6476 + * ---------------------------------------------------------------------------
6477 + * Local variables:
6478 + * c-file-style: "linux"
6479 + * End:
6480 + */
6481 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_kern.c um/arch/um/drivers/pcap_kern.c
6482 --- orig/arch/um/drivers/pcap_kern.c    1969-12-31 19:00:00.000000000 -0500
6483 +++ um/arch/um/drivers/pcap_kern.c      2002-12-15 21:19:15.000000000 -0500
6484 @@ -0,0 +1,127 @@
6485 +/*
6486 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
6487 + * Licensed under the GPL.
6488 + */
6489 +
6490 +#include "linux/init.h"
6491 +#include "linux/netdevice.h"
6492 +#include "linux/etherdevice.h"
6493 +#include "net_kern.h"
6494 +#include "net_user.h"
6495 +#include "pcap_user.h"
6496 +
6497 +struct pcap_init {
6498 +       char *host_if;
6499 +       int promisc;
6500 +       int optimize;
6501 +       char *filter;
6502 +};
6503 +
6504 +void pcap_init(struct net_device *dev, void *data)
6505 +{
6506 +       struct uml_net_private *pri;
6507 +       struct pcap_data *ppri;
6508 +       struct pcap_init *init = data;
6509 +
6510 +       init_etherdev(dev, 0);
6511 +       pri = dev->priv;
6512 +       ppri = (struct pcap_data *) pri->user;
6513 +       *ppri = ((struct pcap_data)
6514 +               { .host_if      = init->host_if,
6515 +                 .promisc      = init->promisc,
6516 +                 .optimize     = init->optimize,
6517 +                 .filter       = init->filter,
6518 +                 .compiled     = NULL,
6519 +                 .pcap         = NULL });
6520 +}
6521 +
6522 +static int pcap_read(int fd, struct sk_buff **skb, 
6523 +                      struct uml_net_private *lp)
6524 +{
6525 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
6526 +       if(*skb == NULL) return(-ENOMEM);
6527 +       return(pcap_user_read(fd, (*skb)->mac.raw, 
6528 +                             (*skb)->dev->mtu + ETH_HEADER_OTHER,
6529 +                             (struct pcap_data *) &lp->user));
6530 +}
6531 +
6532 +static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
6533 +{
6534 +       return(-EPERM);
6535 +}
6536 +
6537 +static struct net_kern_info pcap_kern_info = {
6538 +       .init                   = pcap_init,
6539 +       .protocol               = eth_protocol,
6540 +       .read                   = pcap_read,
6541 +       .write                  = pcap_write,
6542 +};
6543 +
6544 +int pcap_setup(char *str, char **mac_out, void *data)
6545 +{
6546 +       struct pcap_init *init = data;
6547 +       char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
6548 +       int i;
6549 +
6550 +       *init = ((struct pcap_init)
6551 +               { .host_if      = "eth0",
6552 +                 .promisc      = 1,
6553 +                 .optimize     = 0,
6554 +                 .filter       = NULL });
6555 +
6556 +       remain = split_if_spec(str, &host_if, &init->filter, 
6557 +                              &options[0], &options[1], NULL);
6558 +       if(remain != NULL){
6559 +               printk(KERN_ERR "pcap_setup - Extra garbage on "
6560 +                      "specification : '%s'\n", remain);
6561 +               return(0);
6562 +       }
6563 +
6564 +       if(host_if != NULL)
6565 +               init->host_if = host_if;
6566 +
6567 +       for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){
6568 +               if(options[i] == NULL)
6569 +                       continue;
6570 +               if(!strcmp(options[i], "promisc"))
6571 +                       init->promisc = 1;
6572 +               else if(!strcmp(options[i], "nopromisc"))
6573 +                       init->promisc = 0;
6574 +               else if(!strcmp(options[i], "optimize"))
6575 +                       init->optimize = 1;
6576 +               else if(!strcmp(options[i], "nooptimize"))
6577 +                       init->optimize = 0;
6578 +               else printk("pcap_setup : bad option - '%s'\n", options[i]);
6579 +       }
6580 +
6581 +       return(1);
6582 +}
6583 +
6584 +static struct transport pcap_transport = {
6585 +       .list           = LIST_HEAD_INIT(pcap_transport.list),
6586 +       .name           = "pcap",
6587 +       .setup          = pcap_setup,
6588 +       .user           = &pcap_user_info,
6589 +       .kern           = &pcap_kern_info,
6590 +       .private_size   = sizeof(struct pcap_data),
6591 +       .setup_size     = sizeof(struct pcap_init),
6592 +};
6593 +
6594 +static int register_pcap(void)
6595 +{
6596 +       register_transport(&pcap_transport);
6597 +       return(1);
6598 +}
6599 +
6600 +__initcall(register_pcap);
6601 +
6602 +/*
6603 + * Overrides for Emacs so that we follow Linus's tabbing style.
6604 + * Emacs will notice this stuff at the end of the file and automatically
6605 + * adjust the settings for this buffer only.  This must remain at the end
6606 + * of the file.
6607 + * ---------------------------------------------------------------------------
6608 + * Local variables:
6609 + * c-file-style: "linux"
6610 + * End:
6611 + */
6612 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.c um/arch/um/drivers/pcap_user.c
6613 --- orig/arch/um/drivers/pcap_user.c    1969-12-31 19:00:00.000000000 -0500
6614 +++ um/arch/um/drivers/pcap_user.c      2002-12-15 21:04:39.000000000 -0500
6615 @@ -0,0 +1,143 @@
6616 +/*
6617 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
6618 + * Licensed under the GPL.
6619 + */
6620 +
6621 +#include <unistd.h>
6622 +#include <stdlib.h>
6623 +#include <string.h>
6624 +#include <errno.h>
6625 +#include <pcap.h>
6626 +#include <asm/types.h>
6627 +#include "net_user.h"
6628 +#include "pcap_user.h"
6629 +#include "user.h"
6630 +
6631 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
6632 +
6633 +#define PCAP_FD(p) (*(int *)(p))
6634 +
6635 +static void pcap_user_init(void *data, void *dev)
6636 +{
6637 +       struct pcap_data *pri = data;
6638 +       pcap_t *p;
6639 +       char errors[PCAP_ERRBUF_SIZE];
6640 +
6641 +       p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
6642 +       if(p == NULL){
6643 +               printk("pcap_user_init : pcap_open_live failed - '%s'\n", 
6644 +                      errors);
6645 +               return;
6646 +       }
6647 +
6648 +       pri->dev = dev;
6649 +       pri->pcap = p;
6650 +}
6651 +
6652 +static int pcap_open(void *data)
6653 +{
6654 +       struct pcap_data *pri = data;
6655 +       __u32 netmask;
6656 +       int err;
6657 +
6658 +       if(pri->pcap == NULL)
6659 +               return(-ENODEV);
6660 +
6661 +       if(pri->filter != NULL){
6662 +               err = dev_netmask(pri->dev, &netmask);
6663 +               if(err < 0){
6664 +                       printk("pcap_open : dev_netmask failed\n");
6665 +                       return(-EIO);
6666 +               }
6667 +
6668 +               pri->compiled = um_kmalloc(sizeof(struct bpf_program));
6669 +               if(pri->compiled == NULL){
6670 +                       printk("pcap_open : kmalloc failed\n");
6671 +                       return(-ENOMEM);
6672 +               }
6673 +               
6674 +               err = pcap_compile(pri->pcap, 
6675 +                                  (struct bpf_program *) pri->compiled, 
6676 +                                  pri->filter, pri->optimize, netmask);
6677 +               if(err < 0){
6678 +                       printk("pcap_open : pcap_compile failed - '%s'\n", 
6679 +                              pcap_geterr(pri->pcap));
6680 +                       return(-EIO);
6681 +               }
6682 +
6683 +               err = pcap_setfilter(pri->pcap, pri->compiled);
6684 +               if(err < 0){
6685 +                       printk("pcap_open : pcap_setfilter failed - '%s'\n", 
6686 +                              pcap_geterr(pri->pcap));
6687 +                       return(-EIO);
6688 +               }
6689 +       }
6690 +       
6691 +       return(PCAP_FD(pri->pcap));
6692 +}
6693 +
6694 +static void pcap_remove(void *data)
6695 +{
6696 +       struct pcap_data *pri = data;
6697 +
6698 +       if(pri->compiled != NULL)
6699 +               pcap_freecode(pri->compiled);
6700 +
6701 +       pcap_close(pri->pcap);
6702 +}
6703 +
6704 +struct pcap_handler_data {
6705 +       char *buffer;
6706 +       int len;
6707 +};
6708 +
6709 +static void handler(u_char *data, const struct pcap_pkthdr *header, 
6710 +                   const u_char *packet)
6711 +{
6712 +       int len;
6713 +
6714 +       struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
6715 +
6716 +       len = hdata->len < header->caplen ? hdata->len : header->caplen;
6717 +       memcpy(hdata->buffer, packet, len);
6718 +       hdata->len = len;
6719 +}
6720 +
6721 +int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
6722 +{
6723 +       struct pcap_handler_data hdata = ((struct pcap_handler_data)
6724 +                                         { .buffer     = buffer,
6725 +                                           .len        = len });
6726 +       int n;
6727 +
6728 +       n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
6729 +       if(n < 0){
6730 +               printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
6731 +               return(-EIO);
6732 +       }
6733 +       else if(n == 0) 
6734 +               return(0);
6735 +       return(hdata.len);
6736 +}
6737 +
6738 +struct net_user_info pcap_user_info = {
6739 +       .init           = pcap_user_init,
6740 +       .open           = pcap_open,
6741 +       .close          = NULL,
6742 +       .remove         = pcap_remove,
6743 +       .set_mtu        = NULL,
6744 +       .add_address    = NULL,
6745 +       .delete_address = NULL,
6746 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
6747 +};
6748 +
6749 +/*
6750 + * Overrides for Emacs so that we follow Linus's tabbing style.
6751 + * Emacs will notice this stuff at the end of the file and automatically
6752 + * adjust the settings for this buffer only.  This must remain at the end
6753 + * of the file.
6754 + * ---------------------------------------------------------------------------
6755 + * Local variables:
6756 + * c-file-style: "linux"
6757 + * End:
6758 + */
6759 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.h um/arch/um/drivers/pcap_user.h
6760 --- orig/arch/um/drivers/pcap_user.h    1969-12-31 19:00:00.000000000 -0500
6761 +++ um/arch/um/drivers/pcap_user.h      2002-10-23 21:08:04.000000000 -0400
6762 @@ -0,0 +1,31 @@
6763 +/* 
6764 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
6765 + * Licensed under the GPL
6766 + */
6767 +
6768 +#include "net_user.h"
6769 +
6770 +struct pcap_data {
6771 +       char *host_if;
6772 +       int promisc;
6773 +       int optimize;
6774 +       char *filter;
6775 +       void *compiled;
6776 +       void *pcap;
6777 +       void *dev;
6778 +};
6779 +
6780 +extern struct net_user_info pcap_user_info;
6781 +
6782 +extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
6783 +
6784 +/*
6785 + * Overrides for Emacs so that we follow Linus's tabbing style.
6786 + * Emacs will notice this stuff at the end of the file and automatically
6787 + * adjust the settings for this buffer only.  This must remain at the end
6788 + * of the file.
6789 + * ---------------------------------------------------------------------------
6790 + * Local variables:
6791 + * c-file-style: "linux"
6792 + * End:
6793 + */
6794 diff -Naur -X ../exclude-files orig/arch/um/drivers/port.h um/arch/um/drivers/port.h
6795 --- orig/arch/um/drivers/port.h 1969-12-31 19:00:00.000000000 -0500
6796 +++ um/arch/um/drivers/port.h   2002-10-23 21:08:04.000000000 -0400
6797 @@ -0,0 +1,30 @@
6798 +/* 
6799 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
6800 + * Licensed under the GPL
6801 + */
6802 +
6803 +#ifndef __PORT_H__
6804 +#define __PORT_H__
6805 +
6806 +extern void *port_data(int port);
6807 +extern int port_wait(void *data);
6808 +extern void port_kern_close(void *d);
6809 +extern int port_connection(int fd, int *socket_out, int *pid_out);
6810 +extern int port_listen_fd(int port);
6811 +extern void port_read(int fd, void *data);
6812 +extern void port_kern_free(void *d);
6813 +extern int port_rcv_fd(int fd);
6814 +extern void port_remove_dev(void *d);
6815 +
6816 +#endif
6817 +
6818 +/*
6819 + * Overrides for Emacs so that we follow Linus's tabbing style.
6820 + * Emacs will notice this stuff at the end of the file and automatically
6821 + * adjust the settings for this buffer only.  This must remain at the end
6822 + * of the file.
6823 + * ---------------------------------------------------------------------------
6824 + * Local variables:
6825 + * c-file-style: "linux"
6826 + * End:
6827 + */
6828 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_kern.c um/arch/um/drivers/port_kern.c
6829 --- orig/arch/um/drivers/port_kern.c    1969-12-31 19:00:00.000000000 -0500
6830 +++ um/arch/um/drivers/port_kern.c      2002-12-30 20:57:42.000000000 -0500
6831 @@ -0,0 +1,302 @@
6832 +/* 
6833 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
6834 + * Licensed under the GPL
6835 + */
6836 +
6837 +#include "linux/list.h"
6838 +#include "linux/sched.h"
6839 +#include "linux/slab.h"
6840 +#include "linux/irq.h"
6841 +#include "linux/spinlock.h"
6842 +#include "linux/errno.h"
6843 +#include "asm/semaphore.h"
6844 +#include "asm/errno.h"
6845 +#include "kern_util.h"
6846 +#include "kern.h"
6847 +#include "irq_user.h"
6848 +#include "port.h"
6849 +#include "init.h"
6850 +#include "os.h"
6851 +
6852 +struct port_list {
6853 +       struct list_head list;
6854 +       int has_connection;
6855 +       struct semaphore sem;
6856 +       int port;
6857 +       int fd;
6858 +       spinlock_t lock;
6859 +       struct list_head pending;
6860 +       struct list_head connections;
6861 +};
6862 +
6863 +struct port_dev {
6864 +       struct port_list *port;
6865 +       int helper_pid;
6866 +       int telnetd_pid;
6867 +};
6868 +
6869 +struct connection {
6870 +       struct list_head list;
6871 +       int fd;
6872 +       int helper_pid;
6873 +       int socket[2];
6874 +       int telnetd_pid;
6875 +       struct port_list *port;
6876 +};
6877 +
6878 +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
6879 +{
6880 +       struct connection *conn = data;
6881 +       int fd;
6882 +
6883 +       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
6884 +       if(fd < 0){
6885 +               if(fd == -EAGAIN)
6886 +                       return;
6887 +
6888 +               printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
6889 +                      -fd);
6890 +               os_close_file(conn->fd);
6891 +       }
6892 +
6893 +       list_del(&conn->list);
6894 +
6895 +       conn->fd = fd;
6896 +       list_add(&conn->list, &conn->port->connections);
6897 +
6898 +       up(&conn->port->sem);
6899 +}
6900 +
6901 +static int port_accept(struct port_list *port)
6902 +{
6903 +       struct connection *conn;
6904 +       int fd, socket[2], pid, ret = 0;
6905 +
6906 +       fd = port_connection(port->fd, socket, &pid);
6907 +       if(fd < 0){
6908 +               if(fd != -EAGAIN)
6909 +                       printk(KERN_ERR "port_accept : port_connection "
6910 +                              "returned %d\n", -fd);
6911 +               goto out;
6912 +       }
6913 +
6914 +       conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
6915 +       if(conn == NULL){
6916 +               printk(KERN_ERR "port_accept : failed to allocate "
6917 +                      "connection\n");
6918 +               goto out_close;
6919 +       }
6920 +       *conn = ((struct connection) 
6921 +               { .list         = LIST_HEAD_INIT(conn->list),
6922 +                 .fd           = fd,
6923 +                 .socket       = { socket[0], socket[1] },
6924 +                 .telnetd_pid  = pid,
6925 +                 .port         = port });
6926 +
6927 +       if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 
6928 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
6929 +                         "telnetd", conn)){
6930 +               printk(KERN_ERR "port_accept : failed to get IRQ for "
6931 +                      "telnetd\n");
6932 +               goto out_free;
6933 +       }
6934 +
6935 +       list_add(&conn->list, &port->pending);
6936 +       return(1);
6937 +
6938 + out_free:
6939 +       kfree(conn);
6940 + out_close:
6941 +       os_close_file(fd);
6942 +       if(pid != -1) 
6943 +               os_kill_process(pid, 1);
6944 + out:
6945 +       return(ret);
6946 +} 
6947 +
6948 +DECLARE_MUTEX(ports_sem);
6949 +struct list_head ports = LIST_HEAD_INIT(ports);
6950 +
6951 +void port_task_proc(void *unused)
6952 +{
6953 +       struct port_list *port;
6954 +       struct list_head *ele;
6955 +       unsigned long flags;
6956 +
6957 +       save_flags(flags);
6958 +       list_for_each(ele, &ports){
6959 +               port = list_entry(ele, struct port_list, list);
6960 +               if(!port->has_connection)
6961 +                       continue;
6962 +               reactivate_fd(port->fd, ACCEPT_IRQ);
6963 +               while(port_accept(port)) ;
6964 +               port->has_connection = 0;
6965 +       }
6966 +       restore_flags(flags);
6967 +}
6968 +
6969 +struct tq_struct port_task = {
6970 +       .routine        = port_task_proc,
6971 +       .data           = NULL
6972 +};
6973 +
6974 +static void port_interrupt(int irq, void *data, struct pt_regs *regs)
6975 +{
6976 +       struct port_list *port = data;
6977 +
6978 +       port->has_connection = 1;
6979 +       schedule_task(&port_task);
6980 +} 
6981 +
6982 +void *port_data(int port_num)
6983 +{
6984 +       struct list_head *ele;
6985 +       struct port_list *port;
6986 +       struct port_dev *dev = NULL;
6987 +       int fd;
6988 +
6989 +       down(&ports_sem);
6990 +       list_for_each(ele, &ports){
6991 +               port = list_entry(ele, struct port_list, list);
6992 +               if(port->port == port_num) goto found;
6993 +       }
6994 +       port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
6995 +       if(port == NULL){
6996 +               printk(KERN_ERR "Allocation of port list failed\n");
6997 +               goto out;
6998 +       }
6999 +
7000 +       fd = port_listen_fd(port_num);
7001 +       if(fd < 0){
7002 +               printk(KERN_ERR "binding to port %d failed, errno = %d\n",
7003 +                      port_num, -fd);
7004 +               goto out_free;
7005 +       }
7006 +       if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, 
7007 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port",
7008 +                         port)){
7009 +               printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
7010 +               goto out_close;
7011 +       }
7012 +
7013 +       *port = ((struct port_list) 
7014 +               { .list                 = LIST_HEAD_INIT(port->list),
7015 +                 .has_connection       = 0,
7016 +                 .sem                  = __SEMAPHORE_INITIALIZER(port->sem, 
7017 +                                                                 0),
7018 +                 .lock                 = SPIN_LOCK_UNLOCKED,
7019 +                 .port                 = port_num,
7020 +                 .fd                   = fd,
7021 +                 .pending              = LIST_HEAD_INIT(port->pending),
7022 +                 .connections          = LIST_HEAD_INIT(port->connections) });
7023 +       list_add(&port->list, &ports);
7024 +
7025 + found:
7026 +       dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
7027 +       if(dev == NULL){
7028 +               printk(KERN_ERR "Allocation of port device entry failed\n");
7029 +               goto out;
7030 +       }
7031 +
7032 +       *dev = ((struct port_dev) { .port               = port,
7033 +                                   .helper_pid         = -1,
7034 +                                   .telnetd_pid        = -1 });
7035 +       goto out;
7036 +
7037 + out_free:
7038 +       kfree(port);
7039 + out_close:
7040 +       os_close_file(fd);
7041 + out:
7042 +       up(&ports_sem);
7043 +       return(dev);
7044 +}
7045 +
7046 +int port_wait(void *data)
7047 +{
7048 +       struct port_dev *dev = data;
7049 +       struct connection *conn;
7050 +       struct port_list *port = dev->port;
7051 +       int fd;
7052 +
7053 +       while(1){
7054 +               if(down_interruptible(&port->sem)) 
7055 +                       return(-ERESTARTSYS);
7056 +
7057 +               spin_lock(&port->lock);
7058 +
7059 +               conn = list_entry(port->connections.next, struct connection, 
7060 +                                 list);
7061 +               list_del(&conn->list);
7062 +               spin_unlock(&port->lock);
7063 +
7064 +               os_shutdown_socket(conn->socket[0], 1, 1);
7065 +               os_close_file(conn->socket[0]);
7066 +               os_shutdown_socket(conn->socket[1], 1, 1);
7067 +               os_close_file(conn->socket[1]); 
7068 +
7069 +               /* This is done here because freeing an IRQ can't be done
7070 +                * within the IRQ handler.  So, pipe_interrupt always ups
7071 +                * the semaphore regardless of whether it got a successful
7072 +                * connection.  Then we loop here throwing out failed 
7073 +                * connections until a good one is found.
7074 +                */
7075 +               free_irq(TELNETD_IRQ, conn);
7076 +
7077 +               if(conn->fd >= 0) break;
7078 +               os_close_file(conn->fd);
7079 +               kfree(conn);
7080 +       }
7081 +
7082 +       fd = conn->fd;
7083 +       dev->helper_pid = conn->helper_pid;
7084 +       dev->telnetd_pid = conn->telnetd_pid;
7085 +       kfree(conn);
7086 +
7087 +       return(fd);
7088 +}
7089 +
7090 +void port_remove_dev(void *d)
7091 +{
7092 +       struct port_dev *dev = d;
7093 +
7094 +       if(dev->helper_pid != -1)
7095 +               os_kill_process(dev->helper_pid, 0);
7096 +       if(dev->telnetd_pid != -1)
7097 +               os_kill_process(dev->telnetd_pid, 1);
7098 +       dev->helper_pid = -1;
7099 +       dev->telnetd_pid = -1;
7100 +}
7101 +
7102 +void port_kern_free(void *d)
7103 +{
7104 +       struct port_dev *dev = d;
7105 +
7106 +       port_remove_dev(dev);
7107 +       kfree(dev);
7108 +}
7109 +
7110 +static void free_port(void)
7111 +{
7112 +       struct list_head *ele;
7113 +       struct port_list *port;
7114 +
7115 +       list_for_each(ele, &ports){
7116 +               port = list_entry(ele, struct port_list, list);
7117 +               free_irq_by_fd(port->fd);
7118 +               os_close_file(port->fd);
7119 +       }
7120 +}
7121 +
7122 +__uml_exitcall(free_port);
7123 +
7124 +/*
7125 + * Overrides for Emacs so that we follow Linus's tabbing style.
7126 + * Emacs will notice this stuff at the end of the file and automatically
7127 + * adjust the settings for this buffer only.  This must remain at the end
7128 + * of the file.
7129 + * ---------------------------------------------------------------------------
7130 + * Local variables:
7131 + * c-file-style: "linux"
7132 + * End:
7133 + */
7134 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_user.c um/arch/um/drivers/port_user.c
7135 --- orig/arch/um/drivers/port_user.c    1969-12-31 19:00:00.000000000 -0500
7136 +++ um/arch/um/drivers/port_user.c      2002-12-16 22:46:20.000000000 -0500
7137 @@ -0,0 +1,206 @@
7138 +/* 
7139 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7140 + * Licensed under the GPL
7141 + */
7142 +
7143 +#include <stdio.h>
7144 +#include <stddef.h>
7145 +#include <stdlib.h>
7146 +#include <string.h>
7147 +#include <errno.h>
7148 +#include <unistd.h>
7149 +#include <termios.h>
7150 +#include <sys/socket.h>
7151 +#include <sys/un.h>
7152 +#include <netinet/in.h>
7153 +#include "user_util.h"
7154 +#include "kern_util.h"
7155 +#include "user.h"
7156 +#include "chan_user.h"
7157 +#include "port.h"
7158 +#include "helper.h"
7159 +#include "os.h"
7160 +
7161 +struct port_chan {
7162 +       int raw;
7163 +       struct termios tt;
7164 +       void *kernel_data;
7165 +       char dev[sizeof("32768\0")];
7166 +};
7167 +
7168 +void *port_init(char *str, int device, struct chan_opts *opts)
7169 +{
7170 +       struct port_chan *data;
7171 +       void *kern_data;
7172 +       char *end;
7173 +       int port;
7174 +
7175 +       if(*str != ':'){
7176 +               printk("port_init : channel type 'port' must specify a "
7177 +                      "port number\n");
7178 +               return(NULL);
7179 +       }
7180 +       str++;
7181 +       port = strtoul(str, &end, 0);
7182 +       if((*end != '\0') || (end == str)){
7183 +               printk("port_init : couldn't parse port '%s'\n", str);
7184 +               return(NULL);
7185 +       }
7186 +
7187 +       if((kern_data = port_data(port)) == NULL) 
7188 +               return(NULL);
7189 +
7190 +       if((data = um_kmalloc(sizeof(*data))) == NULL) 
7191 +               goto err;
7192 +
7193 +       *data = ((struct port_chan) { .raw              = opts->raw,
7194 +                                     .kernel_data      = kern_data });
7195 +       sprintf(data->dev, "%d", port);
7196 +
7197 +       return(data);
7198 + err:
7199 +       port_kern_free(kern_data);
7200 +       return(NULL);
7201 +}
7202 +
7203 +void port_free(void *d)
7204 +{
7205 +       struct port_chan *data = d;
7206 +
7207 +       port_kern_free(data->kernel_data);
7208 +       kfree(data);
7209 +}
7210 +
7211 +int port_open(int input, int output, int primary, void *d, char **dev_out)
7212 +{
7213 +       struct port_chan *data = d;
7214 +       int fd;
7215 +
7216 +       fd = port_wait(data->kernel_data);
7217 +       if((fd >= 0) && data->raw){
7218 +               tcgetattr(fd, &data->tt);
7219 +               raw(fd, 0);
7220 +       }
7221 +       *dev_out = data->dev;
7222 +       return(fd);
7223 +}
7224 +
7225 +void port_close(int fd, void *d)
7226 +{
7227 +       struct port_chan *data = d;
7228 +
7229 +       port_remove_dev(data->kernel_data);
7230 +       close(fd);
7231 +}
7232 +
7233 +int port_console_write(int fd, const char *buf, int n, void *d)
7234 +{
7235 +       struct port_chan *data = d;
7236 +
7237 +       return(generic_console_write(fd, buf, n, &data->tt));
7238 +}
7239 +
7240 +struct chan_ops port_ops = {
7241 +       .type           = "port",
7242 +       .init           = port_init,
7243 +       .open           = port_open,
7244 +       .close          = port_close,
7245 +       .read           = generic_read,
7246 +       .write          = generic_write,
7247 +       .console_write  = port_console_write,
7248 +       .window_size    = generic_window_size,
7249 +       .free           = port_free,
7250 +       .winch          = 1,
7251 +};
7252 +
7253 +int port_listen_fd(int port)
7254 +{
7255 +       struct sockaddr_in addr;
7256 +       int fd, err;
7257 +
7258 +       fd = socket(PF_INET, SOCK_STREAM, 0);
7259 +       if(fd == -1) 
7260 +               return(-errno);
7261 +
7262 +       addr.sin_family = AF_INET;
7263 +       addr.sin_port = htons(port);
7264 +       addr.sin_addr.s_addr = htonl(INADDR_ANY);
7265 +       if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
7266 +               err = -errno;
7267 +               goto out;
7268 +       }
7269 +  
7270 +       if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
7271 +               err = -errno;
7272 +               goto out;
7273 +       }
7274 +
7275 +       return(fd);
7276 + out:
7277 +       os_close_file(fd);
7278 +       return(err);
7279 +}
7280 +
7281 +struct port_pre_exec_data {
7282 +       int sock_fd;
7283 +       int pipe_fd;
7284 +};
7285 +
7286 +void port_pre_exec(void *arg)
7287 +{
7288 +       struct port_pre_exec_data *data = arg;
7289 +
7290 +       dup2(data->sock_fd, 0);
7291 +       dup2(data->sock_fd, 1);
7292 +       dup2(data->sock_fd, 2);
7293 +       close(data->sock_fd);
7294 +       dup2(data->pipe_fd, 3);
7295 +       os_shutdown_socket(3, 1, 0);
7296 +       close(data->pipe_fd);
7297 +}
7298 +
7299 +int port_connection(int fd, int *socket, int *pid_out)
7300 +{
7301 +       int new, err;
7302 +       char *argv[] = { "/usr/sbin/in.telnetd", "-L", 
7303 +                        "/usr/lib/uml/port-helper", NULL };
7304 +       struct port_pre_exec_data data;
7305 +
7306 +       if((new = os_accept_connection(fd)) < 0)
7307 +               return(-errno);
7308 +
7309 +       err = os_pipe(socket, 0, 0);
7310 +       if(err) 
7311 +               goto out_close;
7312 +
7313 +       data = ((struct port_pre_exec_data)
7314 +               { .sock_fd              = new,
7315 +                 .pipe_fd              = socket[1] });
7316 +
7317 +       err = run_helper(port_pre_exec, &data, argv, NULL);
7318 +       if(err < 0) 
7319 +               goto out_shutdown;
7320 +
7321 +       *pid_out = err;
7322 +       return(new);
7323 +
7324 + out_shutdown:
7325 +       os_shutdown_socket(socket[0], 1, 1);
7326 +       close(socket[0]);
7327 +       os_shutdown_socket(socket[1], 1, 1);    
7328 +       close(socket[1]);
7329 + out_close:
7330 +       close(new);
7331 +       return(err);
7332 +}
7333 +
7334 +/*
7335 + * Overrides for Emacs so that we follow Linus's tabbing style.
7336 + * Emacs will notice this stuff at the end of the file and automatically
7337 + * adjust the settings for this buffer only.  This must remain at the end
7338 + * of the file.
7339 + * ---------------------------------------------------------------------------
7340 + * Local variables:
7341 + * c-file-style: "linux"
7342 + * End:
7343 + */
7344 diff -Naur -X ../exclude-files orig/arch/um/drivers/pty.c um/arch/um/drivers/pty.c
7345 --- orig/arch/um/drivers/pty.c  1969-12-31 19:00:00.000000000 -0500
7346 +++ um/arch/um/drivers/pty.c    2002-12-15 21:06:01.000000000 -0500
7347 @@ -0,0 +1,148 @@
7348 +/* 
7349 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7350 + * Licensed under the GPL
7351 + */
7352 +
7353 +#include <stdio.h>
7354 +#include <unistd.h>
7355 +#include <string.h>
7356 +#include <errno.h>
7357 +#include <fcntl.h>
7358 +#include <termios.h>
7359 +#include "chan_user.h"
7360 +#include "user.h"
7361 +#include "user_util.h"
7362 +#include "kern_util.h"
7363 +
7364 +struct pty_chan {
7365 +       void (*announce)(char *dev_name, int dev);
7366 +       int dev;
7367 +       int raw;
7368 +       struct termios tt;
7369 +       char dev_name[sizeof("/dev/pts/0123456\0")];
7370 +};
7371 +
7372 +void *pty_chan_init(char *str, int device, struct chan_opts *opts)
7373 +{
7374 +       struct pty_chan *data;
7375 +
7376 +       if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
7377 +       *data = ((struct pty_chan) { .announce          = opts->announce, 
7378 +                                    .dev               = device,
7379 +                                    .raw               = opts->raw });
7380 +       return(data);
7381 +}
7382 +
7383 +int pts_open(int input, int output, int primary, void *d, char **dev_out)
7384 +{
7385 +       struct pty_chan *data = d;
7386 +       char *dev;
7387 +       int fd;
7388 +
7389 +       if((fd = get_pty()) < 0){
7390 +               printk("open_pts : Failed to open pts\n");
7391 +               return(-errno);
7392 +       }
7393 +       if(data->raw){
7394 +               tcgetattr(fd, &data->tt);
7395 +               raw(fd, 0);
7396 +       }
7397 +
7398 +       dev = ptsname(fd);
7399 +       sprintf(data->dev_name, "%s", dev);
7400 +       *dev_out = data->dev_name;
7401 +       if(data->announce) (*data->announce)(dev, data->dev);
7402 +       return(fd);
7403 +}
7404 +
7405 +int getmaster(char *line)
7406 +{
7407 +       struct stat stb;
7408 +       char *pty, *bank, *cp;
7409 +       int master;
7410 +
7411 +       pty = &line[strlen("/dev/ptyp")];
7412 +       for (bank = "pqrs"; *bank; bank++) {
7413 +               line[strlen("/dev/pty")] = *bank;
7414 +               *pty = '0';
7415 +               if (stat(line, &stb) < 0)
7416 +                       break;
7417 +               for (cp = "0123456789abcdef"; *cp; cp++) {
7418 +                       *pty = *cp;
7419 +                       master = open(line, O_RDWR);
7420 +                       if (master >= 0) {
7421 +                               char *tp = &line[strlen("/dev/")];
7422 +                               int ok;
7423 +
7424 +                               /* verify slave side is usable */
7425 +                               *tp = 't';
7426 +                               ok = access(line, R_OK|W_OK) == 0;
7427 +                               *tp = 'p';
7428 +                               if (ok) return(master);
7429 +                               (void) close(master);
7430 +                       }
7431 +               }
7432 +       }
7433 +       return(-1);
7434 +}
7435 +
7436 +int pty_open(int input, int output, int primary, void *d, char **dev_out)
7437 +{
7438 +       struct pty_chan *data = d;
7439 +       int fd;
7440 +       char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
7441 +
7442 +       fd = getmaster(dev);
7443 +       if(fd < 0) return(-errno);
7444 +       
7445 +       if(data->raw) raw(fd, 0);
7446 +       if(data->announce) (*data->announce)(dev, data->dev);
7447 +
7448 +       sprintf(data->dev_name, "%s", dev);
7449 +       *dev_out = data->dev_name;
7450 +       return(fd);
7451 +}
7452 +
7453 +int pty_console_write(int fd, const char *buf, int n, void *d)
7454 +{
7455 +       struct pty_chan *data = d;
7456 +
7457 +       return(generic_console_write(fd, buf, n, &data->tt));
7458 +}
7459 +
7460 +struct chan_ops pty_ops = {
7461 +       .type           = "pty",
7462 +       .init           = pty_chan_init,
7463 +       .open           = pty_open,
7464 +       .close          = generic_close,
7465 +       .read           = generic_read,
7466 +       .write          = generic_write,
7467 +       .console_write  = pty_console_write,
7468 +       .window_size    = generic_window_size,
7469 +       .free           = generic_free,
7470 +       .winch          = 0,
7471 +};
7472 +
7473 +struct chan_ops pts_ops = {
7474 +       .type           = "pts",
7475 +       .init           = pty_chan_init,
7476 +       .open           = pts_open,
7477 +       .close          = generic_close,
7478 +       .read           = generic_read,
7479 +       .write          = generic_write,
7480 +       .console_write  = pty_console_write,
7481 +       .window_size    = generic_window_size,
7482 +       .free           = generic_free,
7483 +       .winch          = 0,
7484 +};
7485 +
7486 +/*
7487 + * Overrides for Emacs so that we follow Linus's tabbing style.
7488 + * Emacs will notice this stuff at the end of the file and automatically
7489 + * adjust the settings for this buffer only.  This must remain at the end
7490 + * of the file.
7491 + * ---------------------------------------------------------------------------
7492 + * Local variables:
7493 + * c-file-style: "linux"
7494 + * End:
7495 + */
7496 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip.h um/arch/um/drivers/slip.h
7497 --- orig/arch/um/drivers/slip.h 1969-12-31 19:00:00.000000000 -0500
7498 +++ um/arch/um/drivers/slip.h   2002-10-23 21:08:04.000000000 -0400
7499 @@ -0,0 +1,39 @@
7500 +#ifndef __UM_SLIP_H
7501 +#define __UM_SLIP_H
7502 +
7503 +#define BUF_SIZE 1500
7504 + /* two bytes each for a (pathological) max packet of escaped chars +  * 
7505 +  * terminating END char + initial END char                            */
7506 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
7507 +
7508 +struct slip_data {
7509 +       void *dev;
7510 +       char name[sizeof("slnnnnn\0")];
7511 +       char *addr;
7512 +       char *gate_addr;
7513 +       int slave;
7514 +       char ibuf[ENC_BUF_SIZE];
7515 +       char obuf[ENC_BUF_SIZE];
7516 +       int more; /* more data: do not read fd until ibuf has been drained */
7517 +       int pos;
7518 +       int esc;
7519 +};
7520 +
7521 +extern struct net_user_info slip_user_info;
7522 +
7523 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
7524 +extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
7525 +extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
7526 +
7527 +#endif
7528 +
7529 +/*
7530 + * Overrides for Emacs so that we follow Linus's tabbing style.
7531 + * Emacs will notice this stuff at the end of the file and automatically
7532 + * adjust the settings for this buffer only.  This must remain at the end
7533 + * of the file.
7534 + * ---------------------------------------------------------------------------
7535 + * Local variables:
7536 + * c-file-style: "linux"
7537 + * End:
7538 + */
7539 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_kern.c um/arch/um/drivers/slip_kern.c
7540 --- orig/arch/um/drivers/slip_kern.c    1969-12-31 19:00:00.000000000 -0500
7541 +++ um/arch/um/drivers/slip_kern.c      2002-12-15 21:06:24.000000000 -0500
7542 @@ -0,0 +1,109 @@
7543 +#include "linux/config.h"
7544 +#include "linux/kernel.h"
7545 +#include "linux/stddef.h"
7546 +#include "linux/init.h"
7547 +#include "linux/netdevice.h"
7548 +#include "linux/if_arp.h"
7549 +#include "net_kern.h"
7550 +#include "net_user.h"
7551 +#include "kern.h"
7552 +#include "slip.h"
7553 +
7554 +struct slip_init {
7555 +       char *gate_addr;
7556 +};
7557 +
7558 +void slip_init(struct net_device *dev, void *data)
7559 +{
7560 +       struct uml_net_private *private;
7561 +       struct slip_data *spri;
7562 +       struct slip_init *init = data;
7563 +
7564 +       private = dev->priv;
7565 +       spri = (struct slip_data *) private->user;
7566 +       *spri = ((struct slip_data)
7567 +               { .name         = { '\0' },
7568 +                 .addr         = NULL,
7569 +                 .gate_addr    = init->gate_addr,
7570 +                 .slave        = -1,
7571 +                 .ibuf         = { '\0' },
7572 +                 .obuf         = { '\0' },
7573 +                 .pos          = 0,
7574 +                 .esc          = 0,
7575 +                 .dev          = dev });
7576 +
7577 +       dev->init = NULL;
7578 +       dev->hard_header_len = 0;
7579 +       dev->addr_len = 4;
7580 +       dev->type = ARPHRD_ETHER;
7581 +       dev->tx_queue_len = 256;
7582 +       dev->flags = IFF_NOARP;
7583 +       printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
7584 +}
7585 +
7586 +static unsigned short slip_protocol(struct sk_buff *skbuff)
7587 +{
7588 +       return(htons(ETH_P_IP));
7589 +}
7590 +
7591 +static int slip_read(int fd, struct sk_buff **skb, 
7592 +                      struct uml_net_private *lp)
7593 +{
7594 +       return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 
7595 +                             (struct slip_data *) &lp->user));
7596 +}
7597 +
7598 +static int slip_write(int fd, struct sk_buff **skb,
7599 +                     struct uml_net_private *lp)
7600 +{
7601 +       return(slip_user_write(fd, (*skb)->data, (*skb)->len, 
7602 +                              (struct slip_data *) &lp->user));
7603 +}
7604 +
7605 +struct net_kern_info slip_kern_info = {
7606 +       .init                   = slip_init,
7607 +       .protocol               = slip_protocol,
7608 +       .read                   = slip_read,
7609 +       .write                  = slip_write,
7610 +};
7611 +
7612 +static int slip_setup(char *str, char **mac_out, void *data)
7613 +{
7614 +       struct slip_init *init = data;
7615 +
7616 +       *init = ((struct slip_init)
7617 +               { .gate_addr            = NULL });
7618 +
7619 +       if(str[0] != '\0') 
7620 +               init->gate_addr = str;
7621 +       return(1);
7622 +}
7623 +
7624 +static struct transport slip_transport = {
7625 +       .list           = LIST_HEAD_INIT(slip_transport.list),
7626 +       .name           = "slip",
7627 +       .setup          = slip_setup,
7628 +       .user           = &slip_user_info,
7629 +       .kern           = &slip_kern_info,
7630 +       .private_size   = sizeof(struct slip_data),
7631 +       .setup_size     = sizeof(struct slip_init),
7632 +};
7633 +
7634 +static int register_slip(void)
7635 +{
7636 +       register_transport(&slip_transport);
7637 +       return(1);
7638 +}
7639 +
7640 +__initcall(register_slip);
7641 +
7642 +/*
7643 + * Overrides for Emacs so that we follow Linus's tabbing style.
7644 + * Emacs will notice this stuff at the end of the file and automatically
7645 + * adjust the settings for this buffer only.  This must remain at the end
7646 + * of the file.
7647 + * ---------------------------------------------------------------------------
7648 + * Local variables:
7649 + * c-file-style: "linux"
7650 + * End:
7651 + */
7652 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_proto.h um/arch/um/drivers/slip_proto.h
7653 --- orig/arch/um/drivers/slip_proto.h   1969-12-31 19:00:00.000000000 -0500
7654 +++ um/arch/um/drivers/slip_proto.h     2002-10-23 21:08:04.000000000 -0400
7655 @@ -0,0 +1,93 @@
7656 +/* 
7657 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7658 + * Licensed under the GPL
7659 + */
7660 +
7661 +#ifndef __UM_SLIP_PROTO_H__
7662 +#define __UM_SLIP_PROTO_H__
7663 +
7664 +/* SLIP protocol characters. */
7665 +#define SLIP_END             0300      /* indicates end of frame       */
7666 +#define SLIP_ESC             0333      /* indicates byte stuffing      */
7667 +#define SLIP_ESC_END         0334      /* ESC ESC_END means END 'data' */
7668 +#define SLIP_ESC_ESC         0335      /* ESC ESC_ESC means ESC 'data' */
7669 +
7670 +static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
7671 +{
7672 +       int ret;
7673 +
7674 +       switch(c){
7675 +       case SLIP_END:
7676 +               *esc = 0;
7677 +               ret=*pos;
7678 +               *pos=0;
7679 +               return(ret);
7680 +       case SLIP_ESC:
7681 +               *esc = 1;
7682 +               return(0);
7683 +       case SLIP_ESC_ESC:
7684 +               if(*esc){
7685 +                       *esc = 0;
7686 +                       c = SLIP_ESC;
7687 +               }
7688 +               break;
7689 +       case SLIP_ESC_END:
7690 +               if(*esc){
7691 +                       *esc = 0;
7692 +                       c = SLIP_END;
7693 +               }
7694 +               break;
7695 +       }
7696 +       buf[(*pos)++] = c;
7697 +       return(0);
7698 +}
7699 +
7700 +static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
7701 +{
7702 +       unsigned char *ptr = d;
7703 +       unsigned char c;
7704 +
7705 +       /*
7706 +        * Send an initial END character to flush out any
7707 +        * data that may have accumulated in the receiver
7708 +        * due to line noise.
7709 +        */
7710 +
7711 +       *ptr++ = SLIP_END;
7712 +
7713 +       /*
7714 +        * For each byte in the packet, send the appropriate
7715 +        * character sequence, according to the SLIP protocol.
7716 +        */
7717 +
7718 +       while (len-- > 0) {
7719 +               switch(c = *s++) {
7720 +               case SLIP_END:
7721 +                       *ptr++ = SLIP_ESC;
7722 +                       *ptr++ = SLIP_ESC_END;
7723 +                       break;
7724 +               case SLIP_ESC:
7725 +                       *ptr++ = SLIP_ESC;
7726 +                       *ptr++ = SLIP_ESC_ESC;
7727 +                       break;
7728 +               default:
7729 +                       *ptr++ = c;
7730 +                       break;
7731 +               }
7732 +       }
7733 +       *ptr++ = SLIP_END;
7734 +       return (ptr - d);
7735 +}
7736 +
7737 +#endif
7738 +
7739 +/*
7740 + * Overrides for Emacs so that we follow Linus's tabbing style.
7741 + * Emacs will notice this stuff at the end of the file and automatically
7742 + * adjust the settings for this buffer only.  This must remain at the end
7743 + * of the file.
7744 + * ---------------------------------------------------------------------------
7745 + * Local variables:
7746 + * c-file-style: "linux"
7747 + * End:
7748 + */
7749 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_user.c um/arch/um/drivers/slip_user.c
7750 --- orig/arch/um/drivers/slip_user.c    1969-12-31 19:00:00.000000000 -0500
7751 +++ um/arch/um/drivers/slip_user.c      2002-12-15 21:06:35.000000000 -0500
7752 @@ -0,0 +1,279 @@
7753 +#include <stdio.h>
7754 +#include <stdlib.h>
7755 +#include <unistd.h>
7756 +#include <stddef.h>
7757 +#include <sched.h>
7758 +#include <string.h>
7759 +#include <sys/fcntl.h>
7760 +#include <sys/errno.h>
7761 +#include <sys/termios.h>
7762 +#include <sys/wait.h>
7763 +#include <sys/ioctl.h>
7764 +#include <sys/signal.h>
7765 +#include "user_util.h"
7766 +#include "kern_util.h"
7767 +#include "user.h"
7768 +#include "net_user.h"
7769 +#include "slip.h"
7770 +#include "slip_proto.h"
7771 +#include "helper.h"
7772 +#include "os.h"
7773 +
7774 +void slip_user_init(void *data, void *dev)
7775 +{
7776 +       struct slip_data *pri = data;
7777 +
7778 +       pri->dev = dev;
7779 +}
7780 +
7781 +static int set_up_tty(int fd)
7782 +{
7783 +       int i;
7784 +       struct termios tios;
7785 +
7786 +       if (tcgetattr(fd, &tios) < 0) {
7787 +               printk("could not get initial terminal attributes\n");
7788 +               return(-1);
7789 +       }
7790 +
7791 +       tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
7792 +       tios.c_iflag = IGNBRK | IGNPAR;
7793 +       tios.c_oflag = 0;
7794 +       tios.c_lflag = 0;
7795 +       for (i = 0; i < NCCS; i++)
7796 +               tios.c_cc[i] = 0;
7797 +       tios.c_cc[VMIN] = 1;
7798 +       tios.c_cc[VTIME] = 0;
7799 +
7800 +       cfsetospeed(&tios, B38400);
7801 +       cfsetispeed(&tios, B38400);
7802 +
7803 +       if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
7804 +               printk("failed to set terminal attributes\n");
7805 +               return(-1);
7806 +       }
7807 +       return(0);
7808 +}
7809 +
7810 +struct slip_pre_exec_data {
7811 +       int stdin;
7812 +       int stdout;
7813 +       int close_me;
7814 +};
7815 +
7816 +static void slip_pre_exec(void *arg)
7817 +{
7818 +       struct slip_pre_exec_data *data = arg;
7819 +
7820 +       if(data->stdin != -1) dup2(data->stdin, 0);
7821 +       dup2(data->stdout, 1);
7822 +       if(data->close_me != -1) close(data->close_me);
7823 +}
7824 +
7825 +static int slip_tramp(char **argv, int fd)
7826 +{
7827 +       struct slip_pre_exec_data pe_data;
7828 +       char *output;
7829 +       int status, pid, fds[2], err, output_len;
7830 +
7831 +       err = os_pipe(fds, 1, 0);
7832 +       if(err){
7833 +               printk("slip_tramp : pipe failed, errno = %d\n", -err);
7834 +               return(err);
7835 +       }
7836 +
7837 +       err = 0;
7838 +       pe_data.stdin = fd;
7839 +       pe_data.stdout = fds[1];
7840 +       pe_data.close_me = fds[0];
7841 +       pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
7842 +
7843 +       if(pid < 0) err = pid;
7844 +       else {
7845 +               output_len = page_size();
7846 +               output = um_kmalloc(output_len);
7847 +               if(output == NULL)
7848 +                       printk("slip_tramp : failed to allocate output "
7849 +                              "buffer\n");
7850 +
7851 +               close(fds[1]);
7852 +               read_output(fds[0], output, output_len);
7853 +               if(output != NULL){
7854 +                       printk("%s", output);
7855 +                       kfree(output);
7856 +               }
7857 +               if(waitpid(pid, &status, 0) < 0) err = errno;
7858 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
7859 +                       printk("'%s' didn't exit with status 0\n", argv[0]);
7860 +                       err = EINVAL;
7861 +               }
7862 +       }
7863 +       return(err);
7864 +}
7865 +
7866 +static int slip_open(void *data)
7867 +{
7868 +       struct slip_data *pri = data;
7869 +       char version_buf[sizeof("nnnnn\0")];
7870 +       char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
7871 +       char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, 
7872 +                        NULL };
7873 +       int sfd, mfd, disc, sencap, err;
7874 +
7875 +       if((mfd = get_pty()) < 0){
7876 +               printk("umn : Failed to open pty\n");
7877 +               return(-1);
7878 +       }
7879 +       if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
7880 +               printk("Couldn't open tty for slip line\n");
7881 +               return(-1);
7882 +       }
7883 +       if(set_up_tty(sfd)) return(-1);
7884 +       pri->slave = sfd;
7885 +       pri->pos = 0;
7886 +       pri->esc = 0;
7887 +       if(pri->gate_addr != NULL){
7888 +               sprintf(version_buf, "%d", UML_NET_VERSION);
7889 +               strcpy(gate_buf, pri->gate_addr);
7890 +
7891 +               err = slip_tramp(argv, sfd);
7892 +
7893 +               if(err != 0){
7894 +                       printk("slip_tramp failed - errno = %d\n", err);
7895 +                       return(-err);
7896 +               }
7897 +               if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
7898 +                       printk("SIOCGIFNAME failed, errno = %d\n", errno);
7899 +                       return(-errno);
7900 +               }
7901 +               iter_addresses(pri->dev, open_addr, pri->name);
7902 +       }
7903 +       else {
7904 +               disc = N_SLIP;
7905 +               if(ioctl(sfd, TIOCSETD, &disc) < 0){
7906 +                       printk("Failed to set slip line discipline - "
7907 +                              "errno = %d\n", errno);
7908 +                       return(-errno);
7909 +               }
7910 +               sencap = 0;
7911 +               if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
7912 +                       printk("Failed to set slip encapsulation - "
7913 +                              "errno = %d\n", errno);
7914 +                       return(-errno);
7915 +               }
7916 +       }
7917 +       return(mfd);
7918 +}
7919 +
7920 +static void slip_close(int fd, void *data)
7921 +{
7922 +       struct slip_data *pri = data;
7923 +       char version_buf[sizeof("nnnnn\0")];
7924 +       char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, 
7925 +                        NULL };
7926 +       int err;
7927 +
7928 +       if(pri->gate_addr != NULL)
7929 +               iter_addresses(pri->dev, close_addr, pri->name);
7930 +
7931 +       sprintf(version_buf, "%d", UML_NET_VERSION);
7932 +
7933 +       err = slip_tramp(argv, -1);
7934 +
7935 +       if(err != 0)
7936 +               printk("slip_tramp failed - errno = %d\n", err);
7937 +       close(fd);
7938 +       close(pri->slave);
7939 +       pri->slave = -1;
7940 +}
7941 +
7942 +int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
7943 +{
7944 +       int i, n, size, start;
7945 +
7946 +       if(pri->more>0) {
7947 +               i = 0;
7948 +               while(i < pri->more) {
7949 +                       size = slip_unesc(pri->ibuf[i++],
7950 +                                       pri->ibuf, &pri->pos, &pri->esc);
7951 +                       if(size){
7952 +                               memcpy(buf, pri->ibuf, size);
7953 +                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
7954 +                               pri->more=pri->more-i; 
7955 +                               return(size);
7956 +                       }
7957 +               }
7958 +               pri->more=0;
7959 +       }
7960 +
7961 +       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
7962 +       if(n <= 0) return(n);
7963 +
7964 +       start = pri->pos;
7965 +       for(i = 0; i < n; i++){
7966 +               size = slip_unesc(pri->ibuf[start + i],
7967 +                               pri->ibuf, &pri->pos, &pri->esc);
7968 +               if(size){
7969 +                       memcpy(buf, pri->ibuf, size);
7970 +                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
7971 +                       pri->more=n-(i+1); 
7972 +                       return(size);
7973 +               }
7974 +       }
7975 +       return(0);
7976 +}
7977 +
7978 +int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
7979 +{
7980 +       int actual, n;
7981 +
7982 +       actual = slip_esc(buf, pri->obuf, len);
7983 +       n = net_write(fd, pri->obuf, actual);
7984 +       if(n < 0) return(n);
7985 +       else return(len);
7986 +}
7987 +
7988 +static int slip_set_mtu(int mtu, void *data)
7989 +{
7990 +       return(mtu);
7991 +}
7992 +
7993 +static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
7994 +                         void *data)
7995 +{
7996 +       struct slip_data *pri = data;
7997 +
7998 +       if(pri->slave == -1) return;
7999 +       open_addr(addr, netmask, pri->name);
8000 +}
8001 +
8002 +static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
8003 +                           void *data)
8004 +{
8005 +       struct slip_data *pri = data;
8006 +
8007 +       if(pri->slave == -1) return;
8008 +       close_addr(addr, netmask, pri->name);
8009 +}
8010 +
8011 +struct net_user_info slip_user_info = {
8012 +       .init           = slip_user_init,
8013 +       .open           = slip_open,
8014 +       .close          = slip_close,
8015 +       .remove         = NULL,
8016 +       .set_mtu        = slip_set_mtu,
8017 +       .add_address    = slip_add_addr,
8018 +       .delete_address = slip_del_addr,
8019 +       .max_packet     = BUF_SIZE
8020 +};
8021 +
8022 +/*
8023 + * Overrides for Emacs so that we follow Linus's tabbing style.
8024 + * Emacs will notice this stuff at the end of the file and automatically
8025 + * adjust the settings for this buffer only.  This must remain at the end
8026 + * of the file.
8027 + * ---------------------------------------------------------------------------
8028 + * Local variables:
8029 + * c-file-style: "linux"
8030 + * End:
8031 + */
8032 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp.h um/arch/um/drivers/slirp.h
8033 --- orig/arch/um/drivers/slirp.h        1969-12-31 19:00:00.000000000 -0500
8034 +++ um/arch/um/drivers/slirp.h  2002-10-23 21:08:04.000000000 -0400
8035 @@ -0,0 +1,51 @@
8036 +#ifndef __UM_SLIRP_H
8037 +#define __UM_SLIRP_H
8038 +
8039 +#define BUF_SIZE 1500
8040 + /* two bytes each for a (pathological) max packet of escaped chars +  * 
8041 +  * terminating END char + initial END char                            */
8042 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8043 +
8044 +#define SLIRP_MAX_ARGS 100
8045 +/*
8046 + * XXX this next definition is here because I don't understand why this
8047 + * initializer doesn't work in slirp_kern.c:
8048 + *
8049 + *   argv :  { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] },
8050 + *
8051 + * or why I can't typecast like this:
8052 + *
8053 + *   argv :  (char* [SLIRP_MAX_ARGS])(init->argv), 
8054 + */
8055 +struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; };
8056 +
8057 +struct slirp_data {
8058 +       void *dev;
8059 +       struct arg_list_dummy_wrapper argw;
8060 +       int pid;
8061 +       int slave;
8062 +       char ibuf[ENC_BUF_SIZE];
8063 +       char obuf[ENC_BUF_SIZE];
8064 +       int more; /* more data: do not read fd until ibuf has been drained */
8065 +       int pos;
8066 +       int esc;
8067 +};
8068 +
8069 +extern struct net_user_info slirp_user_info;
8070 +
8071 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8072 +extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
8073 +extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
8074 +
8075 +#endif
8076 +
8077 +/*
8078 + * Overrides for Emacs so that we follow Linus's tabbing style.
8079 + * Emacs will notice this stuff at the end of the file and automatically
8080 + * adjust the settings for this buffer only.  This must remain at the end
8081 + * of the file.
8082 + * ---------------------------------------------------------------------------
8083 + * Local variables:
8084 + * c-file-style: "linux"
8085 + * End:
8086 + */
8087 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_kern.c um/arch/um/drivers/slirp_kern.c
8088 --- orig/arch/um/drivers/slirp_kern.c   1969-12-31 19:00:00.000000000 -0500
8089 +++ um/arch/um/drivers/slirp_kern.c     2002-12-15 21:06:54.000000000 -0500
8090 @@ -0,0 +1,132 @@
8091 +#include "linux/kernel.h"
8092 +#include "linux/stddef.h"
8093 +#include "linux/init.h"
8094 +#include "linux/netdevice.h"
8095 +#include "linux/if_arp.h"
8096 +#include "net_kern.h"
8097 +#include "net_user.h"
8098 +#include "kern.h"
8099 +#include "slirp.h"
8100 +
8101 +struct slirp_init {
8102 +       struct arg_list_dummy_wrapper argw;  /* XXX should be simpler... */
8103 +};
8104 +
8105 +void slirp_init(struct net_device *dev, void *data)
8106 +{
8107 +       struct uml_net_private *private;
8108 +       struct slirp_data *spri;
8109 +       struct slirp_init *init = data;
8110 +       int i;
8111 +
8112 +       private = dev->priv;
8113 +       spri = (struct slirp_data *) private->user;
8114 +       *spri = ((struct slirp_data)
8115 +               { .argw         = init->argw,
8116 +                 .pid          = -1,
8117 +                 .slave        = -1,
8118 +                 .ibuf         = { '\0' },
8119 +                 .obuf         = { '\0' },
8120 +                 .pos          = 0,
8121 +                 .esc          = 0,
8122 +                 .dev          = dev });
8123 +
8124 +       dev->init = NULL;
8125 +       dev->hard_header_len = 0;
8126 +       dev->addr_len = 4;
8127 +       dev->type = ARPHRD_ETHER;
8128 +       dev->tx_queue_len = 256;
8129 +       dev->flags = IFF_NOARP;
8130 +       printk("SLIRP backend - command line:");
8131 +       for(i=0;spri->argw.argv[i]!=NULL;i++) {
8132 +               printk(" '%s'",spri->argw.argv[i]);
8133 +       }
8134 +       printk("\n");
8135 +}
8136 +
8137 +static unsigned short slirp_protocol(struct sk_buff *skbuff)
8138 +{
8139 +       return(htons(ETH_P_IP));
8140 +}
8141 +
8142 +static int slirp_read(int fd, struct sk_buff **skb, 
8143 +                      struct uml_net_private *lp)
8144 +{
8145 +       return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 
8146 +                             (struct slirp_data *) &lp->user));
8147 +}
8148 +
8149 +static int slirp_write(int fd, struct sk_buff **skb,
8150 +                     struct uml_net_private *lp)
8151 +{
8152 +       return(slirp_user_write(fd, (*skb)->data, (*skb)->len, 
8153 +                              (struct slirp_data *) &lp->user));
8154 +}
8155 +
8156 +struct net_kern_info slirp_kern_info = {
8157 +       .init                   = slirp_init,
8158 +       .protocol               = slirp_protocol,
8159 +       .read                   = slirp_read,
8160 +       .write                  = slirp_write,
8161 +};
8162 +
8163 +static int slirp_setup(char *str, char **mac_out, void *data)
8164 +{
8165 +       struct slirp_init *init = data;
8166 +       int i=0;
8167 +
8168 +       *init = ((struct slirp_init)
8169 +               { argw :                { { "slirp", NULL  } } });
8170 +
8171 +       str = split_if_spec(str, mac_out, NULL);
8172 +
8173 +       if(str == NULL) { /* no command line given after MAC addr */
8174 +               return(1);
8175 +       }
8176 +
8177 +       do {
8178 +               if(i>=SLIRP_MAX_ARGS-1) {
8179 +                       printk("slirp_setup: truncating slirp arguments\n");
8180 +                       break;
8181 +               }
8182 +               init->argw.argv[i++] = str;
8183 +               while(*str && *str!=',') {
8184 +                       if(*str=='_') *str=' ';
8185 +                       str++;
8186 +               }
8187 +               if(*str!=',')
8188 +                       break;
8189 +               *str++='\0';
8190 +       } while(1);
8191 +       init->argw.argv[i]=NULL;
8192 +       return(1);
8193 +}
8194 +
8195 +static struct transport slirp_transport = {
8196 +       .list           = LIST_HEAD_INIT(slirp_transport.list),
8197 +       .name           = "slirp",
8198 +       .setup          = slirp_setup,
8199 +       .user           = &slirp_user_info,
8200 +       .kern           = &slirp_kern_info,
8201 +       .private_size   = sizeof(struct slirp_data),
8202 +       .setup_size     = sizeof(struct slirp_init),
8203 +};
8204 +
8205 +static int register_slirp(void)
8206 +{
8207 +       register_transport(&slirp_transport);
8208 +       return(1);
8209 +}
8210 +
8211 +__initcall(register_slirp);
8212 +
8213 +/*
8214 + * Overrides for Emacs so that we follow Linus's tabbing style.
8215 + * Emacs will notice this stuff at the end of the file and automatically
8216 + * adjust the settings for this buffer only.  This must remain at the end
8217 + * of the file.
8218 + * ---------------------------------------------------------------------------
8219 + * Local variables:
8220 + * c-file-style: "linux"
8221 + * End:
8222 + */
8223 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_user.c um/arch/um/drivers/slirp_user.c
8224 --- orig/arch/um/drivers/slirp_user.c   1969-12-31 19:00:00.000000000 -0500
8225 +++ um/arch/um/drivers/slirp_user.c     2002-12-15 21:07:08.000000000 -0500
8226 @@ -0,0 +1,202 @@
8227 +#include <stdio.h>
8228 +#include <stdlib.h>
8229 +#include <unistd.h>
8230 +#include <stddef.h>
8231 +#include <sched.h>
8232 +#include <string.h>
8233 +#include <sys/fcntl.h>
8234 +#include <sys/errno.h>
8235 +#include <sys/wait.h>
8236 +#include <sys/signal.h>
8237 +#include "user_util.h"
8238 +#include "kern_util.h"
8239 +#include "user.h"
8240 +#include "net_user.h"
8241 +#include "slirp.h"
8242 +#include "slip_proto.h"
8243 +#include "helper.h"
8244 +#include "os.h"
8245 +
8246 +void slirp_user_init(void *data, void *dev)
8247 +{
8248 +       struct slirp_data *pri = data;
8249 +
8250 +       pri->dev = dev;
8251 +}
8252 +
8253 +struct slirp_pre_exec_data {
8254 +       int stdin;
8255 +       int stdout;
8256 +};
8257 +
8258 +static void slirp_pre_exec(void *arg)
8259 +{
8260 +       struct slirp_pre_exec_data *data = arg;
8261 +
8262 +       if(data->stdin != -1) dup2(data->stdin, 0);
8263 +       if(data->stdout != -1) dup2(data->stdout, 1);
8264 +}
8265 +
8266 +static int slirp_tramp(char **argv, int fd)
8267 +{
8268 +       struct slirp_pre_exec_data pe_data;
8269 +       int pid;
8270 +
8271 +       pe_data.stdin = fd;
8272 +       pe_data.stdout = fd;
8273 +       pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);
8274 +
8275 +       return(pid);
8276 +}
8277
8278 +static int slirp_datachan(int *mfd, int *sfd)
8279 +{
8280 +       int fds[2], err;
8281 +
8282 +       err = os_pipe(fds, 1, 1);
8283 +       if(err){
8284 +               printk("slirp_datachan: Failed to open pipe, errno = %d\n",
8285 +                      -err);
8286 +               return(err);
8287 +       }
8288 +
8289 +       *mfd = fds[0];
8290 +       *sfd = fds[1];
8291 +       return(0);
8292 +}
8293 +
8294 +static int slirp_open(void *data)
8295 +{
8296 +       struct slirp_data *pri = data;
8297 +       int sfd, mfd, pid, err;
8298 +
8299 +       err = slirp_datachan(&mfd, &sfd);
8300 +       if(err)
8301 +               return(err);
8302 +
8303 +       pid = slirp_tramp(pri->argw.argv, sfd);
8304 +
8305 +       if(pid < 0){
8306 +               printk("slirp_tramp failed - errno = %d\n", pid);
8307 +               os_close_file(sfd);     
8308 +               os_close_file(mfd);     
8309 +               return(pid);
8310 +       }
8311 +
8312 +       pri->slave = sfd;
8313 +       pri->pos = 0;
8314 +       pri->esc = 0;
8315 +
8316 +       pri->pid = pid;
8317 +
8318 +       return(mfd);
8319 +}
8320 +
8321 +static void slirp_close(int fd, void *data)
8322 +{
8323 +       struct slirp_data *pri = data;
8324 +       int status,err;
8325 +
8326 +       close(fd);
8327 +       close(pri->slave);
8328 +
8329 +       pri->slave = -1;
8330 +
8331 +       if(pri->pid<1) {
8332 +               printk("slirp_close: no child process to shut down\n");
8333 +               return;
8334 +       }
8335 +
8336 +#if 0
8337 +       if(kill(pri->pid, SIGHUP)<0) {
8338 +               printk("slirp_close: sending hangup to %d failed (%d)\n",
8339 +                       pri->pid, errno);
8340 +       }
8341 +#endif
8342 +
8343 +       err = waitpid(pri->pid, &status, WNOHANG);
8344 +       if(err<0) {
8345 +               printk("slirp_close: waitpid returned %d\n", errno);
8346 +               return;
8347 +       }
8348 +
8349 +       if(err==0) {
8350 +               printk("slirp_close: process %d has not exited\n");
8351 +               return;
8352 +       }
8353 +
8354 +       pri->pid = -1;
8355 +}
8356 +
8357 +int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
8358 +{
8359 +       int i, n, size, start;
8360 +
8361 +       if(pri->more>0) {
8362 +               i = 0;
8363 +               while(i < pri->more) {
8364 +                       size = slip_unesc(pri->ibuf[i++],
8365 +                                       pri->ibuf,&pri->pos,&pri->esc);
8366 +                       if(size){
8367 +                               memcpy(buf, pri->ibuf, size);
8368 +                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8369 +                               pri->more=pri->more-i; 
8370 +                               return(size);
8371 +                       }
8372 +               }
8373 +               pri->more=0;
8374 +       }
8375 +
8376 +       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8377 +       if(n <= 0) return(n);
8378 +
8379 +       start = pri->pos;
8380 +       for(i = 0; i < n; i++){
8381 +               size = slip_unesc(pri->ibuf[start + i],
8382 +                               pri->ibuf,&pri->pos,&pri->esc);
8383 +               if(size){
8384 +                       memcpy(buf, pri->ibuf, size);
8385 +                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8386 +                       pri->more=n-(i+1); 
8387 +                       return(size);
8388 +               }
8389 +       }
8390 +       return(0);
8391 +}
8392 +
8393 +int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
8394 +{
8395 +       int actual, n;
8396 +
8397 +       actual = slip_esc(buf, pri->obuf, len);
8398 +       n = net_write(fd, pri->obuf, actual);
8399 +       if(n < 0) return(n);
8400 +       else return(len);
8401 +}
8402 +
8403 +static int slirp_set_mtu(int mtu, void *data)
8404 +{
8405 +       return(mtu);
8406 +}
8407 +
8408 +struct net_user_info slirp_user_info = {
8409 +       .init           = slirp_user_init,
8410 +       .open           = slirp_open,
8411 +       .close          = slirp_close,
8412 +       .remove         = NULL,
8413 +       .set_mtu        = slirp_set_mtu,
8414 +       .add_address    = NULL,
8415 +       .delete_address = NULL,
8416 +       .max_packet     = BUF_SIZE
8417 +};
8418 +
8419 +/*
8420 + * Overrides for Emacs so that we follow Linus's tabbing style.
8421 + * Emacs will notice this stuff at the end of the file and automatically
8422 + * adjust the settings for this buffer only.  This must remain at the end
8423 + * of the file.
8424 + * ---------------------------------------------------------------------------
8425 + * Local variables:
8426 + * c-file-style: "linux"
8427 + * End:
8428 + */
8429 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.c um/arch/um/drivers/ssl.c
8430 --- orig/arch/um/drivers/ssl.c  1969-12-31 19:00:00.000000000 -0500
8431 +++ um/arch/um/drivers/ssl.c    2003-03-06 18:55:01.000000000 -0500
8432 @@ -0,0 +1,265 @@
8433 +/* 
8434 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
8435 + * Licensed under the GPL
8436 + */
8437 +
8438 +#include "linux/config.h"
8439 +#include "linux/fs.h"
8440 +#include "linux/tty.h"
8441 +#include "linux/tty_driver.h"
8442 +#include "linux/major.h"
8443 +#include "linux/mm.h"
8444 +#include "linux/init.h"
8445 +#include "asm/termbits.h"
8446 +#include "asm/irq.h"
8447 +#include "line.h"
8448 +#include "ssl.h"
8449 +#include "chan_kern.h"
8450 +#include "user_util.h"
8451 +#include "kern_util.h"
8452 +#include "kern.h"
8453 +#include "init.h"
8454 +#include "irq_user.h"
8455 +#include "mconsole_kern.h"
8456 +#include "2_5compat.h"
8457 +
8458 +static int ssl_version = 1;
8459 +
8460 +/* Referenced only by tty_driver below - presumably it's locked correctly
8461 + * by the tty driver.
8462 + */
8463 +static int ssl_refcount = 0;
8464 +
8465 +static struct tty_driver ssl_driver;
8466 +
8467 +#define NR_PORTS 64
8468 +
8469 +void ssl_announce(char *dev_name, int dev)
8470 +{
8471 +       printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
8472 +              dev_name);
8473 +}
8474 +
8475 +static struct chan_opts opts = {
8476 +       .announce       = ssl_announce,
8477 +       .xterm_title    = "Serial Line #%d",
8478 +       .raw            = 1,
8479 +       .tramp_stack    = 0,
8480 +       .in_kernel      = 1,
8481 +};
8482 +
8483 +static int ssl_config(char *str);
8484 +static int ssl_get_config(char *dev, char *str, int size, char **error_out);
8485 +static int ssl_remove(char *str);
8486 +
8487 +static struct line_driver driver = {
8488 +       .name                   = "UML serial line",
8489 +       .devfs_name             = "tts/%d",
8490 +       .major                  = TTY_MAJOR,
8491 +       .minor_start            = 64,
8492 +       .type                   = TTY_DRIVER_TYPE_SERIAL,
8493 +       .subtype                = 0,
8494 +       .read_irq               = SSL_IRQ,
8495 +       .read_irq_name          = "ssl",
8496 +       .write_irq              = SSL_WRITE_IRQ,
8497 +       .write_irq_name         = "ssl-write",
8498 +       .symlink_from           = "serial",
8499 +       .symlink_to             = "tts",
8500 +       .mc  = {
8501 +               .name           = "ssl",
8502 +               .config         = ssl_config,
8503 +               .get_config     = ssl_get_config,
8504 +               .remove         = ssl_remove,
8505 +       },
8506 +};
8507 +
8508 +/* The array is initialized by line_init, which is an initcall.  The 
8509 + * individual elements are protected by individual semaphores.
8510 + */
8511 +static struct line serial_lines[NR_PORTS] =
8512 +       { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
8513 +
8514 +static struct lines lines = LINES_INIT(NR_PORTS);
8515 +
8516 +static int ssl_config(char *str)
8517 +{
8518 +       return(line_config(serial_lines, 
8519 +                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
8520 +}
8521 +
8522 +static int ssl_get_config(char *dev, char *str, int size, char **error_out)
8523 +{
8524 +       return(line_get_config(dev, serial_lines, 
8525 +                              sizeof(serial_lines)/sizeof(serial_lines[0]), 
8526 +                              str, size, error_out));
8527 +}
8528 +
8529 +static int ssl_remove(char *str)
8530 +{
8531 +       return(line_remove(serial_lines, 
8532 +                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
8533 +}
8534 +
8535 +int ssl_open(struct tty_struct *tty, struct file *filp)
8536 +{
8537 +       return(line_open(serial_lines, tty, &opts));
8538 +}
8539 +
8540 +static void ssl_close(struct tty_struct *tty, struct file * filp)
8541 +{
8542 +       line_close(serial_lines, tty);
8543 +}
8544 +
8545 +static int ssl_write(struct tty_struct * tty, int from_user,
8546 +                    const unsigned char *buf, int count)
8547 +{
8548 +       return(line_write(serial_lines, tty, from_user, buf, count));
8549 +}
8550 +
8551 +static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
8552 +{
8553 +       line_write(serial_lines, tty, 0, &ch, sizeof(ch));
8554 +}
8555 +
8556 +static void ssl_flush_chars(struct tty_struct *tty)
8557 +{
8558 +       return;
8559 +}
8560 +
8561 +static int ssl_chars_in_buffer(struct tty_struct *tty)
8562 +{
8563 +       return(0);
8564 +}
8565 +
8566 +static void ssl_flush_buffer(struct tty_struct *tty)
8567 +{
8568 +       return;
8569 +}
8570 +
8571 +static int ssl_ioctl(struct tty_struct *tty, struct file * file,
8572 +                    unsigned int cmd, unsigned long arg)
8573 +{
8574 +       int ret;
8575 +
8576 +       ret = 0;
8577 +       switch(cmd){
8578 +       case TCGETS:
8579 +       case TCSETS:
8580 +       case TCFLSH:
8581 +       case TCSETSF:
8582 +       case TCSETSW:
8583 +       case TCGETA:
8584 +       case TIOCMGET:
8585 +               ret = -ENOIOCTLCMD;
8586 +               break;
8587 +       default:
8588 +               printk(KERN_ERR 
8589 +                      "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
8590 +               ret = -ENOIOCTLCMD;
8591 +               break;
8592 +       }
8593 +       return(ret);
8594 +}
8595 +
8596 +static void ssl_throttle(struct tty_struct * tty)
8597 +{
8598 +       printk(KERN_ERR "Someone should implement ssl_throttle\n");
8599 +}
8600 +
8601 +static void ssl_unthrottle(struct tty_struct * tty)
8602 +{
8603 +       printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
8604 +}
8605 +
8606 +static void ssl_set_termios(struct tty_struct *tty, 
8607 +                           struct termios *old_termios)
8608 +{
8609 +}
8610 +
8611 +static void ssl_stop(struct tty_struct *tty)
8612 +{
8613 +       printk(KERN_ERR "Someone should implement ssl_stop\n");
8614 +}
8615 +
8616 +static void ssl_start(struct tty_struct *tty)
8617 +{
8618 +       printk(KERN_ERR "Someone should implement ssl_start\n");
8619 +}
8620 +
8621 +void ssl_hangup(struct tty_struct *tty)
8622 +{
8623 +}
8624 +
8625 +static struct tty_driver ssl_driver = {
8626 +       .refcount               = &ssl_refcount,
8627 +       .open                   = ssl_open,
8628 +       .close                  = ssl_close,
8629 +       .write                  = ssl_write,
8630 +       .put_char               = ssl_put_char,
8631 +       .flush_chars            = ssl_flush_chars,
8632 +       .chars_in_buffer        = ssl_chars_in_buffer,
8633 +       .flush_buffer           = ssl_flush_buffer,
8634 +       .ioctl                  = ssl_ioctl,
8635 +       .throttle               = ssl_throttle,
8636 +       .unthrottle             = ssl_unthrottle,
8637 +       .set_termios            = ssl_set_termios,
8638 +       .stop                   = ssl_stop,
8639 +       .start                  = ssl_start,
8640 +       .hangup                 = ssl_hangup
8641 +};
8642 +
8643 +/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
8644 + * by being an initcall and exitcall, respectively.
8645 + */
8646 +static int ssl_init_done = 0;
8647 +
8648 +int ssl_init(void)
8649 +{
8650 +       char *new_title;
8651 +
8652 +       printk(KERN_INFO "Initializing software serial port version %d\n", 
8653 +              ssl_version);
8654 +
8655 +       line_register_devfs(&lines, &driver, &ssl_driver, serial_lines, 
8656 +                           sizeof(serial_lines)/sizeof(serial_lines[0]));
8657 +
8658 +       lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
8659 +
8660 +       new_title = add_xterm_umid(opts.xterm_title);
8661 +       if(new_title != NULL) opts.xterm_title = new_title;
8662 +
8663 +       ssl_init_done = 1;
8664 +       return(0);
8665 +}
8666 +
8667 +__initcall(ssl_init);
8668 +
8669 +static int ssl_chan_setup(char *str)
8670 +{
8671 +       line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
8672 +                  str, 1);
8673 +       return(1);
8674 +}
8675 +
8676 +__setup("ssl", ssl_chan_setup);
8677 +__channel_help(ssl_chan_setup, "ssl");
8678 +
8679 +static void ssl_exit(void)
8680 +{
8681 +       if(!ssl_init_done) return;
8682 +       close_lines(serial_lines, 
8683 +                   sizeof(serial_lines)/sizeof(serial_lines[0]));
8684 +}
8685 +
8686 +__uml_exitcall(ssl_exit);
8687 +
8688 +/*
8689 + * Overrides for Emacs so that we follow Linus's tabbing style.
8690 + * Emacs will notice this stuff at the end of the file and automatically
8691 + * adjust the settings for this buffer only.  This must remain at the end
8692 + * of the file.
8693 + * ---------------------------------------------------------------------------
8694 + * Local variables:
8695 + * c-file-style: "linux"
8696 + * End:
8697 + */
8698 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.h um/arch/um/drivers/ssl.h
8699 --- orig/arch/um/drivers/ssl.h  1969-12-31 19:00:00.000000000 -0500
8700 +++ um/arch/um/drivers/ssl.h    2002-10-23 21:08:04.000000000 -0400
8701 @@ -0,0 +1,23 @@
8702 +/* 
8703 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
8704 + * Licensed under the GPL
8705 + */
8706 +
8707 +#ifndef __SSL_H__
8708 +#define __SSL_H__
8709 +
8710 +extern int ssl_read(int fd, int line);
8711 +extern void ssl_receive_char(int line, char ch);
8712 +
8713 +#endif
8714 +
8715 +/*
8716 + * Overrides for Emacs so that we follow Linus's tabbing style.
8717 + * Emacs will notice this stuff at the end of the file and automatically
8718 + * adjust the settings for this buffer only.  This must remain at the end
8719 + * of the file.
8720 + * ---------------------------------------------------------------------------
8721 + * Local variables:
8722 + * c-file-style: "linux"
8723 + * End:
8724 + */
8725 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.c um/arch/um/drivers/stdio_console.c
8726 --- orig/arch/um/drivers/stdio_console.c        1969-12-31 19:00:00.000000000 -0500
8727 +++ um/arch/um/drivers/stdio_console.c  2002-12-15 21:08:20.000000000 -0500
8728 @@ -0,0 +1,250 @@
8729 +/* 
8730 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
8731 + * Licensed under the GPL
8732 + */
8733 +
8734 +#include "linux/config.h"
8735 +#include "linux/posix_types.h"
8736 +#include "linux/tty.h"
8737 +#include "linux/tty_flip.h"
8738 +#include "linux/types.h"
8739 +#include "linux/major.h"
8740 +#include "linux/kdev_t.h"
8741 +#include "linux/console.h"
8742 +#include "linux/string.h"
8743 +#include "linux/sched.h"
8744 +#include "linux/list.h"
8745 +#include "linux/init.h"
8746 +#include "linux/interrupt.h"
8747 +#include "linux/slab.h"
8748 +#include "asm/current.h"
8749 +#include "asm/softirq.h"
8750 +#include "asm/hardirq.h"
8751 +#include "asm/irq.h"
8752 +#include "stdio_console.h"
8753 +#include "line.h"
8754 +#include "chan_kern.h"
8755 +#include "user_util.h"
8756 +#include "kern_util.h"
8757 +#include "irq_user.h"
8758 +#include "mconsole_kern.h"
8759 +#include "init.h"
8760 +#include "2_5compat.h"
8761 +
8762 +#define MAX_TTYS (8)
8763 +
8764 +/* Referenced only by tty_driver below - presumably it's locked correctly
8765 + * by the tty driver.
8766 + */
8767 +
8768 +static struct tty_driver console_driver;
8769 +
8770 +static int console_refcount = 0;
8771 +
8772 +static struct chan_ops init_console_ops = {
8773 +       .type           = "you shouldn't see this",
8774 +       .init           = NULL,
8775 +       .open           = NULL,
8776 +       .close          = NULL,
8777 +       .read           = NULL,
8778 +       .write          = NULL,
8779 +       .console_write  = generic_write,
8780 +       .window_size    = NULL,
8781 +       .free           = NULL,
8782 +       .winch          = 0,
8783 +};
8784 +
8785 +static struct chan init_console_chan = {
8786 +       .list           = { },
8787 +       .primary        = 1,
8788 +       .input          = 0,
8789 +       .output         = 1,
8790 +       .opened         = 1,
8791 +       .fd             = 1,
8792 +       .pri            = INIT_STATIC,
8793 +       .ops            = &init_console_ops,
8794 +       .data           = NULL
8795 +};
8796 +
8797 +void stdio_announce(char *dev_name, int dev)
8798 +{
8799 +       printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
8800 +              dev_name);
8801 +}
8802 +
8803 +static struct chan_opts opts = {
8804 +       .announce       = stdio_announce,
8805 +       .xterm_title    = "Virtual Console #%d",
8806 +       .raw            = 1,
8807 +       .tramp_stack    = 0,
8808 +       .in_kernel      = 1,
8809 +};
8810 +
8811 +static int con_config(char *str);
8812 +static int con_get_config(char *dev, char *str, int size, char **error_out);
8813 +static int con_remove(char *str);
8814 +
8815 +static struct line_driver driver = {
8816 +       .name                   = "UML console",
8817 +       .devfs_name             = "vc/%d",
8818 +       .major                  = TTY_MAJOR,
8819 +       .minor_start            = 0,
8820 +       .type                   = TTY_DRIVER_TYPE_CONSOLE,
8821 +       .subtype                = SYSTEM_TYPE_CONSOLE,
8822 +       .read_irq               = CONSOLE_IRQ,
8823 +       .read_irq_name          = "console",
8824 +       .write_irq              = CONSOLE_WRITE_IRQ,
8825 +       .write_irq_name         = "console-write",
8826 +       .symlink_from           = "ttys",
8827 +       .symlink_to             = "vc",
8828 +       .mc  = {
8829 +               .name           = "con",
8830 +               .config         = con_config,
8831 +               .get_config     = con_get_config,
8832 +               .remove         = con_remove,
8833 +       },
8834 +};
8835 +
8836 +static struct lines console_lines = LINES_INIT(MAX_TTYS);
8837 +
8838 +/* The array is initialized by line_init, which is an initcall.  The 
8839 + * individual elements are protected by individual semaphores.
8840 + */
8841 +struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
8842 +                             [ 1 ... MAX_TTYS - 1 ] = 
8843 +                             LINE_INIT(CONFIG_CON_CHAN, &driver) };
8844 +
8845 +static int con_config(char *str)
8846 +{
8847 +       return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
8848 +}
8849 +
8850 +static int con_get_config(char *dev, char *str, int size, char **error_out)
8851 +{
8852 +       return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str, 
8853 +                              size, error_out));
8854 +}
8855 +
8856 +static int con_remove(char *str)
8857 +{
8858 +       return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
8859 +}
8860 +
8861 +static int open_console(struct tty_struct *tty)
8862 +{
8863 +       return(line_open(vts, tty, &opts));
8864 +}
8865 +
8866 +static int con_open(struct tty_struct *tty, struct file *filp)
8867 +{
8868 +       return(open_console(tty));
8869 +}
8870 +
8871 +static void con_close(struct tty_struct *tty, struct file *filp)
8872 +{
8873 +       line_close(vts, tty);
8874 +}
8875 +
8876 +static int con_write(struct tty_struct *tty, int from_user, 
8877 +                    const unsigned char *buf, int count)
8878 +{
8879 +        return(line_write(vts, tty, from_user, buf, count));
8880 +}
8881 +
8882 +static void set_termios(struct tty_struct *tty, struct termios * old)
8883 +{
8884 +}
8885 +
8886 +static int chars_in_buffer(struct tty_struct *tty)
8887 +{
8888 +       return(0);
8889 +}
8890 +
8891 +static int con_init_done = 0;
8892 +
8893 +int stdio_init(void)
8894 +{
8895 +       char *new_title;
8896 +
8897 +       printk(KERN_INFO "Initializing stdio console driver\n");
8898 +
8899 +       line_register_devfs(&console_lines, &driver, &console_driver, vts, 
8900 +                           sizeof(vts)/sizeof(vts[0]));
8901 +
8902 +       lines_init(vts, sizeof(vts)/sizeof(vts[0]));
8903 +
8904 +       new_title = add_xterm_umid(opts.xterm_title);
8905 +       if(new_title != NULL) opts.xterm_title = new_title;
8906 +
8907 +       open_console(NULL);
8908 +       con_init_done = 1;
8909 +       return(0);
8910 +}
8911 +
8912 +__initcall(stdio_init);
8913 +
8914 +static void console_write(struct console *console, const char *string, 
8915 +                         unsigned len)
8916 +{
8917 +       if(con_init_done) down(&vts[console->index].sem);
8918 +       console_write_chan(&vts[console->index].chan_list, string, len);
8919 +       if(con_init_done) up(&vts[console->index].sem);
8920 +}
8921 +
8922 +static struct tty_driver console_driver = {
8923 +       .refcount               = &console_refcount,
8924 +       .open                   = con_open,
8925 +       .close                  = con_close,
8926 +       .write                  = con_write,
8927 +       .chars_in_buffer        = chars_in_buffer,
8928 +       .set_termios            = set_termios
8929 +};
8930 +
8931 +static kdev_t console_device(struct console *c)
8932 +{
8933 +       return mk_kdev(TTY_MAJOR, c->index);
8934 +}
8935 +
8936 +static int console_setup(struct console *co, char *options)
8937 +{
8938 +       return(0);
8939 +}
8940 +
8941 +static struct console stdiocons = INIT_CONSOLE("tty", console_write, 
8942 +                                              console_device, console_setup,
8943 +                                              CON_PRINTBUFFER);
8944 +
8945 +void stdio_console_init(void)
8946 +{
8947 +       INIT_LIST_HEAD(&vts[0].chan_list);
8948 +       list_add(&init_console_chan.list, &vts[0].chan_list);
8949 +       register_console(&stdiocons);
8950 +}
8951 +
8952 +static int console_chan_setup(char *str)
8953 +{
8954 +       line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
8955 +       return(1);
8956 +}
8957 +
8958 +__setup("con", console_chan_setup);
8959 +__channel_help(console_chan_setup, "con");
8960 +
8961 +static void console_exit(void)
8962 +{
8963 +       if(!con_init_done) return;
8964 +       close_lines(vts, sizeof(vts)/sizeof(vts[0]));
8965 +}
8966 +
8967 +__uml_exitcall(console_exit);
8968 +
8969 +/*
8970 + * Overrides for Emacs so that we follow Linus's tabbing style.
8971 + * Emacs will notice this stuff at the end of the file and automatically
8972 + * adjust the settings for this buffer only.  This must remain at the end
8973 + * of the file.
8974 + * ---------------------------------------------------------------------------
8975 + * Local variables:
8976 + * c-file-style: "linux"
8977 + * End:
8978 + */
8979 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.h um/arch/um/drivers/stdio_console.h
8980 --- orig/arch/um/drivers/stdio_console.h        1969-12-31 19:00:00.000000000 -0500
8981 +++ um/arch/um/drivers/stdio_console.h  2002-10-23 21:08:04.000000000 -0400
8982 @@ -0,0 +1,21 @@
8983 +/* 
8984 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
8985 + * Licensed under the GPL
8986 + */
8987 +
8988 +#ifndef __STDIO_CONSOLE_H
8989 +#define __STDIO_CONSOLE_H
8990 +
8991 +extern void save_console_flags(void);
8992 +#endif
8993 +
8994 +/*
8995 + * Overrides for Emacs so that we follow Linus's tabbing style.
8996 + * Emacs will notice this stuff at the end of the file and automatically
8997 + * adjust the settings for this buffer only.  This must remain at the end
8998 + * of the file.
8999 + * ---------------------------------------------------------------------------
9000 + * Local variables:
9001 + * c-file-style: "linux"
9002 + * End:
9003 + */
9004 diff -Naur -X ../exclude-files orig/arch/um/drivers/tty.c um/arch/um/drivers/tty.c
9005 --- orig/arch/um/drivers/tty.c  1969-12-31 19:00:00.000000000 -0500
9006 +++ um/arch/um/drivers/tty.c    2002-12-15 21:08:41.000000000 -0500
9007 @@ -0,0 +1,86 @@
9008 +/* 
9009 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
9010 + * Licensed under the GPL
9011 + */
9012 +
9013 +#include <stdio.h>
9014 +#include <termios.h>
9015 +#include <fcntl.h>
9016 +#include <errno.h>
9017 +#include <unistd.h>
9018 +#include "chan_user.h"
9019 +#include "user_util.h"
9020 +#include "user.h"
9021 +#include "os.h"
9022 +
9023 +struct tty_chan {
9024 +       char *dev;
9025 +       int raw;
9026 +       struct termios tt;
9027 +};
9028 +
9029 +void *tty_chan_init(char *str, int device, struct chan_opts *opts)
9030 +{
9031 +       struct tty_chan *data;
9032 +
9033 +       if(*str != ':'){
9034 +               printk("tty_init : channel type 'tty' must specify "
9035 +                      "a device\n");
9036 +               return(NULL);
9037 +       }
9038 +       str++;
9039 +
9040 +       if((data = um_kmalloc(sizeof(*data))) == NULL) 
9041 +               return(NULL);
9042 +       *data = ((struct tty_chan) { .dev       = str,
9043 +                                    .raw       = opts->raw });
9044 +                                    
9045 +       return(data);
9046 +}
9047 +
9048 +int tty_open(int input, int output, int primary, void *d, char **dev_out)
9049 +{
9050 +       struct tty_chan *data = d;
9051 +       int fd;
9052 +
9053 +       fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
9054 +       if(fd < 0) return(fd);
9055 +       if(data->raw){
9056 +               tcgetattr(fd, &data->tt);
9057 +               raw(fd, 0);
9058 +       }
9059 +
9060 +       *dev_out = data->dev;
9061 +       return(fd);
9062 +}
9063 +
9064 +int tty_console_write(int fd, const char *buf, int n, void *d)
9065 +{
9066 +       struct tty_chan *data = d;
9067 +
9068 +       return(generic_console_write(fd, buf, n, &data->tt));
9069 +}
9070 +
9071 +struct chan_ops tty_ops = {
9072 +       .type           = "tty",
9073 +       .init           = tty_chan_init,
9074 +       .open           = tty_open,
9075 +       .close          = generic_close,
9076 +       .read           = generic_read,
9077 +       .write          = generic_write,
9078 +       .console_write  = tty_console_write,
9079 +       .window_size    = generic_window_size,
9080 +       .free           = generic_free,
9081 +       .winch          = 0,
9082 +};
9083 +
9084 +/*
9085 + * Overrides for Emacs so that we follow Linus's tabbing style.
9086 + * Emacs will notice this stuff at the end of the file and automatically
9087 + * adjust the settings for this buffer only.  This must remain at the end
9088 + * of the file.
9089 + * ---------------------------------------------------------------------------
9090 + * Local variables:
9091 + * c-file-style: "linux"
9092 + * End:
9093 + */
9094 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_kern.c um/arch/um/drivers/ubd_kern.c
9095 --- orig/arch/um/drivers/ubd_kern.c     1969-12-31 19:00:00.000000000 -0500
9096 +++ um/arch/um/drivers/ubd_kern.c       2003-03-11 15:46:36.000000000 -0500
9097 @@ -0,0 +1,1067 @@
9098 +/* 
9099 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9100 + * Licensed under the GPL
9101 + */
9102 +
9103 +/* 2001-09-28...2002-04-17
9104 + * Partition stuff by James_McMechan@hotmail.com
9105 + * old style ubd by setting UBD_SHIFT to 0
9106 + */
9107 +
9108 +#define MAJOR_NR UBD_MAJOR
9109 +#define UBD_SHIFT 4
9110 +
9111 +#include "linux/config.h"
9112 +#include "linux/blk.h"
9113 +#include "linux/blkdev.h"
9114 +#include "linux/hdreg.h"
9115 +#include "linux/init.h"
9116 +#include "linux/devfs_fs_kernel.h"
9117 +#include "linux/cdrom.h"
9118 +#include "linux/proc_fs.h"
9119 +#include "linux/ctype.h"
9120 +#include "linux/capability.h"
9121 +#include "linux/mm.h"
9122 +#include "linux/vmalloc.h"
9123 +#include "linux/blkpg.h"
9124 +#include "linux/genhd.h"
9125 +#include "linux/spinlock.h"
9126 +#include "asm/segment.h"
9127 +#include "asm/uaccess.h"
9128 +#include "asm/irq.h"
9129 +#include "asm/types.h"
9130 +#include "user_util.h"
9131 +#include "mem_user.h"
9132 +#include "kern_util.h"
9133 +#include "kern.h"
9134 +#include "mconsole_kern.h"
9135 +#include "init.h"
9136 +#include "irq_user.h"
9137 +#include "ubd_user.h"
9138 +#include "2_5compat.h"
9139 +#include "os.h"
9140 +
9141 +static int ubd_open(struct inode * inode, struct file * filp);
9142 +static int ubd_release(struct inode * inode, struct file * file);
9143 +static int ubd_ioctl(struct inode * inode, struct file * file,
9144 +                    unsigned int cmd, unsigned long arg);
9145 +static int ubd_revalidate(kdev_t rdev);
9146 +static int ubd_revalidate1(kdev_t rdev);
9147 +
9148 +#define MAX_DEV (8)
9149 +#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
9150 +
9151 +/* Not modified by this driver */
9152 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
9153 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
9154 +
9155 +/* Protected by ubd_lock */
9156 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
9157 +
9158 +static struct block_device_operations ubd_blops = {
9159 +        .open          = ubd_open,
9160 +        .release       = ubd_release,
9161 +        .ioctl         = ubd_ioctl,
9162 +        .revalidate    = ubd_revalidate,
9163 +};
9164 +
9165 +/* Protected by ubd_lock, except in prepare_request and ubd_ioctl because 
9166 + * the block layer should ensure that the device is idle before closing it.
9167 + */
9168 +static struct hd_struct        ubd_part[MAX_MINOR] =
9169 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
9170 +
9171 +/* Protected by io_request_lock */
9172 +static request_queue_t *ubd_queue;
9173 +
9174 +/* Protected by ubd_lock */
9175 +static int fake_major = MAJOR_NR;
9176 +
9177 +static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
9178 +
9179 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
9180 +{ \
9181 +       .major          = maj, \
9182 +       .major_name     = name, \
9183 +       .minor_shift    = shift, \
9184 +       .max_p          = 1 << shift, \
9185 +       .part           = parts, \
9186 +       .sizes          = bsizes, \
9187 +       .nr_real        = max, \
9188 +       .real_devices   = NULL, \
9189 +       .next           = NULL, \
9190 +       .fops           = blops, \
9191 +       .de_arr         = NULL, \
9192 +       .flags          = 0 \
9193 +}
9194 +
9195 +static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part,
9196 +                                                UBD_SHIFT, sizes, MAX_DEV, 
9197 +                                                &ubd_blops);
9198 +static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part, 
9199 +                                                 UBD_SHIFT, sizes, MAX_DEV, 
9200 +                                                 &ubd_blops);
9201 +
9202 +#ifdef CONFIG_BLK_DEV_UBD_SYNC
9203 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
9204 +                                        .cl = 1 })
9205 +#else
9206 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
9207 +                                        .cl = 1 })
9208 +#endif
9209 +
9210 +/* Not protected - changed only in ubd_setup_common and then only to
9211 + * to enable O_SYNC.
9212 + */
9213 +static struct openflags global_openflags = OPEN_FLAGS;
9214 +
9215 +struct cow {
9216 +       char *file;
9217 +       int fd;
9218 +       unsigned long *bitmap;
9219 +       unsigned long bitmap_len;
9220 +       int bitmap_offset;
9221 +        int data_offset;
9222 +};
9223 +
9224 +struct ubd {
9225 +       char *file;
9226 +       int count;
9227 +       int fd;
9228 +       __u64 size;
9229 +       struct openflags boot_openflags;
9230 +       struct openflags openflags;
9231 +       devfs_handle_t devfs;
9232 +       struct cow cow;
9233 +};
9234 +
9235 +#define DEFAULT_COW { \
9236 +       .file                   = NULL, \
9237 +        .fd                    = -1, \
9238 +        .bitmap                        = NULL, \
9239 +       .bitmap_offset          = 0, \
9240 +        .data_offset           = 0, \
9241 +}
9242 +
9243 +#define DEFAULT_UBD { \
9244 +       .file                   = NULL, \
9245 +       .count                  = 0, \
9246 +       .fd                     = -1, \
9247 +       .size                   = -1, \
9248 +       .boot_openflags         = OPEN_FLAGS, \
9249 +       .openflags              = OPEN_FLAGS, \
9250 +       .devfs                  = NULL, \
9251 +        .cow                   = DEFAULT_COW, \
9252 +}
9253 +
9254 +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
9255 +
9256 +static int ubd0_init(void)
9257 +{
9258 +       struct ubd *dev = &ubd_dev[0];
9259 +
9260 +       if(dev->file == NULL)
9261 +               dev->file = "root_fs";
9262 +       return(0);
9263 +}
9264 +
9265 +__initcall(ubd0_init);
9266 +
9267 +/* Only changed by fake_ide_setup which is a setup */
9268 +static int fake_ide = 0;
9269 +static struct proc_dir_entry *proc_ide_root = NULL;
9270 +static struct proc_dir_entry *proc_ide = NULL;
9271 +
9272 +static void make_proc_ide(void)
9273 +{
9274 +       proc_ide_root = proc_mkdir("ide", 0);
9275 +       proc_ide = proc_mkdir("ide0", proc_ide_root);
9276 +}
9277 +
9278 +static int proc_ide_read_media(char *page, char **start, off_t off, int count,
9279 +                              int *eof, void *data)
9280 +{
9281 +       int len;
9282 +
9283 +       strcpy(page, "disk\n");
9284 +       len = strlen("disk\n");
9285 +       len -= off;
9286 +       if (len < count){
9287 +               *eof = 1;
9288 +               if (len <= 0) return 0;
9289 +       }
9290 +       else len = count;
9291 +       *start = page + off;
9292 +       return len;
9293 +}
9294 +
9295 +static void make_ide_entries(char *dev_name)
9296 +{
9297 +       struct proc_dir_entry *dir, *ent;
9298 +       char name[64];
9299 +
9300 +       if(!fake_ide) return;
9301 +
9302 +       /* Without locking this could race if a UML was booted with no 
9303 +        * disks and then two mconsole requests which add disks came in 
9304 +        * at the same time.
9305 +        */
9306 +       spin_lock(&ubd_lock);
9307 +       if(proc_ide_root == NULL) make_proc_ide();
9308 +       spin_unlock(&ubd_lock);
9309 +
9310 +       dir = proc_mkdir(dev_name, proc_ide);
9311 +       if(!dir) return;
9312 +
9313 +       ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
9314 +       if(!ent) return;
9315 +       ent->nlink = 1;
9316 +       ent->data = NULL;
9317 +       ent->read_proc = proc_ide_read_media;
9318 +       ent->write_proc = NULL;
9319 +       sprintf(name,"ide0/%s", dev_name);
9320 +       proc_symlink(dev_name, proc_ide_root, name);
9321 +}
9322 +
9323 +static int fake_ide_setup(char *str)
9324 +{
9325 +       fake_ide = 1;
9326 +       return(1);
9327 +}
9328 +
9329 +__setup("fake_ide", fake_ide_setup);
9330 +
9331 +__uml_help(fake_ide_setup,
9332 +"fake_ide\n"
9333 +"    Create ide0 entries that map onto ubd devices.\n\n"
9334 +);
9335 +
9336 +static int parse_unit(char **ptr)
9337 +{
9338 +       char *str = *ptr, *end;
9339 +       int n = -1;
9340 +
9341 +       if(isdigit(*str)) {
9342 +               n = simple_strtoul(str, &end, 0);
9343 +               if(end == str)
9344 +                       return(-1);
9345 +               *ptr = end;
9346 +       }
9347 +       else if (('a' <= *str) && (*str <= 'h')) {
9348 +               n = *str - 'a';
9349 +               str++;
9350 +               *ptr = str;
9351 +       }
9352 +       return(n);
9353 +}
9354 +
9355 +static int ubd_setup_common(char *str, int *index_out)
9356 +{
9357 +       struct openflags flags = global_openflags;
9358 +       struct ubd *dev;
9359 +       char *backing_file;
9360 +       int n, err;
9361 +
9362 +       if(index_out) *index_out = -1;
9363 +       n = *str;
9364 +       if(n == '='){
9365 +               char *end;
9366 +               int major;
9367 +
9368 +               str++;
9369 +               if(!strcmp(str, "sync")){
9370 +                       global_openflags.s = 1;
9371 +                       return(0);
9372 +               }
9373 +               major = simple_strtoul(str, &end, 0);
9374 +               if((*end != '\0') || (end == str)){
9375 +                       printk(KERN_ERR 
9376 +                              "ubd_setup : didn't parse major number\n");
9377 +                       return(1);
9378 +               }
9379 +
9380 +               err = 1;
9381 +               spin_lock(&ubd_lock);
9382 +               if(fake_major != MAJOR_NR){
9383 +                       printk(KERN_ERR "Can't assign a fake major twice\n");
9384 +                       goto out1;
9385 +               }
9386 +
9387 +               fake_gendisk.major = major;
9388 +               fake_major = major;
9389 +       
9390 +               printk(KERN_INFO "Setting extra ubd major number to %d\n",
9391 +                      major);
9392 +               err = 0;
9393 +       out1:
9394 +               spin_unlock(&ubd_lock);
9395 +               return(err);
9396 +       }
9397 +
9398 +       n = parse_unit(&str);
9399 +       if(n < 0){
9400 +               printk(KERN_ERR "ubd_setup : couldn't parse unit number "
9401 +                      "'%s'\n", str);
9402 +               return(1);
9403 +       }
9404 +
9405 +       if(n >= MAX_DEV){
9406 +               printk(KERN_ERR "ubd_setup : index %d out of range "
9407 +                      "(%d devices)\n", n, MAX_DEV);   
9408 +               return(1);
9409 +       }
9410 +
9411 +       err = 1;
9412 +       spin_lock(&ubd_lock);
9413 +
9414 +       dev = &ubd_dev[n];
9415 +       if(dev->file != NULL){
9416 +               printk(KERN_ERR "ubd_setup : device already configured\n");
9417 +               goto out2;
9418 +       }
9419 +
9420 +       if(index_out) *index_out = n;
9421 +
9422 +       if (*str == 'r'){
9423 +               flags.w = 0;
9424 +               str++;
9425 +       }
9426 +       if (*str == 's'){
9427 +               flags.s = 1;
9428 +               str++;
9429 +       }
9430 +       if(*str++ != '='){
9431 +               printk(KERN_ERR "ubd_setup : Expected '='\n");
9432 +               goto out2;
9433 +       }
9434 +
9435 +       err = 0;
9436 +       backing_file = strchr(str, ',');
9437 +       if(backing_file){
9438 +               *backing_file = '\0';
9439 +               backing_file++;
9440 +       }
9441 +       dev->file = str;
9442 +       dev->cow.file = backing_file;
9443 +       dev->boot_openflags = flags;
9444 + out2:
9445 +       spin_unlock(&ubd_lock);
9446 +       return(err);
9447 +}
9448 +
9449 +static int ubd_setup(char *str)
9450 +{
9451 +       ubd_setup_common(str, NULL);
9452 +       return(1);
9453 +}
9454 +
9455 +__setup("ubd", ubd_setup);
9456 +__uml_help(ubd_setup,
9457 +"ubd<n>=<filename>\n"
9458 +"    This is used to associate a device with a file in the underlying\n"
9459 +"    filesystem. Usually, there is a filesystem in the file, but \n"
9460 +"    that's not required. Swap devices containing swap files can be\n"
9461 +"    specified like this. Also, a file which doesn't contain a\n"
9462 +"    filesystem can have its contents read in the virtual \n"
9463 +"    machine by running dd on the device. n must be in the range\n"
9464 +"    0 to 7. Appending an 'r' to the number will cause that device\n"
9465 +"    to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
9466 +"    an 's' (has to be _after_ 'r', if there is one) will cause data\n"
9467 +"    to be written to disk on the host immediately.\n\n"
9468 +);
9469 +
9470 +static int fakehd(char *str)
9471 +{
9472 +       printk(KERN_INFO 
9473 +              "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n");
9474 +       ubd_gendisk.major_name = "hd";
9475 +       return(1);
9476 +}
9477 +
9478 +__setup("fakehd", fakehd);
9479 +__uml_help(fakehd,
9480 +"fakehd\n"
9481 +"    Change the ubd device name to \"hd\".\n\n"
9482 +);
9483 +
9484 +static void do_ubd_request(request_queue_t * q);
9485 +
9486 +/* Only changed by ubd_init, which is an initcall. */
9487 +int thread_fd = -1;
9488 +
9489 +/* Changed by ubd_handler, which is serialized because interrupts only
9490 + * happen on CPU 0.
9491 + */
9492 +int intr_count = 0;
9493 +
9494 +static void ubd_finish(int error)
9495 +{
9496 +       int nsect;
9497 +
9498 +       if(error){
9499 +               end_request(0);
9500 +               return;
9501 +       }
9502 +       nsect = CURRENT->current_nr_sectors;
9503 +       CURRENT->sector += nsect;
9504 +       CURRENT->buffer += nsect << 9;
9505 +       CURRENT->errors = 0;
9506 +       CURRENT->nr_sectors -= nsect;
9507 +       CURRENT->current_nr_sectors = 0;
9508 +       end_request(1);
9509 +}
9510 +
9511 +static void ubd_handler(void)
9512 +{
9513 +       struct io_thread_req req;
9514 +       int n;
9515 +
9516 +       DEVICE_INTR = NULL;
9517 +       intr_count++;
9518 +       n = read_ubd_fs(thread_fd, &req, sizeof(req));
9519 +       if(n != sizeof(req)){
9520 +               printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
9521 +                      "errno = %d\n", os_getpid(), -n);
9522 +               spin_lock(&io_request_lock);
9523 +               end_request(0);
9524 +               spin_unlock(&io_request_lock);
9525 +               return;
9526 +       }
9527 +        
9528 +        if((req.offset != ((__u64) (CURRENT->sector)) << 9) ||
9529 +          (req.length != (CURRENT->current_nr_sectors) << 9))
9530 +               panic("I/O op mismatch");
9531 +       
9532 +       spin_lock(&io_request_lock);
9533 +       ubd_finish(req.error);
9534 +       reactivate_fd(thread_fd, UBD_IRQ);      
9535 +       do_ubd_request(ubd_queue);
9536 +       spin_unlock(&io_request_lock);
9537 +}
9538 +
9539 +static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
9540 +{
9541 +       ubd_handler();
9542 +}
9543 +
9544 +/* Only changed by ubd_init, which is an initcall. */
9545 +static int io_pid = -1;
9546 +
9547 +void kill_io_thread(void)
9548 +{
9549 +       if(io_pid != -1)
9550 +               os_kill_process(io_pid, 1);
9551 +}
9552 +
9553 +__uml_exitcall(kill_io_thread);
9554 +
9555 +/* Initialized in an initcall, and unchanged thereafter */
9556 +devfs_handle_t ubd_dir_handle;
9557 +
9558 +static int ubd_add(int n)
9559 +{
9560 +       struct ubd *dev = &ubd_dev[n];
9561 +       char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")];
9562 +       int err = -EISDIR;
9563 +
9564 +       if(dev->file == NULL)
9565 +               goto out;
9566 +
9567 +       err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT));
9568 +       if(err)
9569 +               goto out;
9570 +
9571 +       sprintf(name, "%d", n);
9572 +       dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
9573 +                                   MAJOR_NR, n << UBD_SHIFT, S_IFBLK | 
9574 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
9575 +                                   &ubd_blops, NULL);
9576 +
9577 +       if(!strcmp(ubd_gendisk.major_name, "ubd"))
9578 +               sprintf(dev_name, "%s%d", ubd_gendisk.major_name, n);
9579 +       else sprintf(dev_name, "%s%c", ubd_gendisk.major_name, 
9580 +                    n + 'a');
9581 +
9582 +       make_ide_entries(dev_name);
9583 +       return(0);
9584 +
9585 + out:
9586 +       return(err);
9587 +}
9588 +
9589 +static int ubd_config(char *str)
9590 +{
9591 +       int n, err;
9592 +
9593 +       str = uml_strdup(str);
9594 +       if(str == NULL){
9595 +               printk(KERN_ERR "ubd_config failed to strdup string\n");
9596 +               return(1);
9597 +       }
9598 +       err = ubd_setup_common(str, &n);
9599 +       if(err){
9600 +               kfree(str);
9601 +               return(-1);
9602 +       }
9603 +       if(n == -1) return(0);
9604 +
9605 +       spin_lock(&ubd_lock);
9606 +       err = ubd_add(n);
9607 +       if(err)
9608 +               ubd_dev[n].file = NULL;
9609 +       spin_unlock(&ubd_lock);
9610 +
9611 +       return(err);
9612 +}
9613 +
9614 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
9615 +{
9616 +       struct ubd *dev;
9617 +       char *end;
9618 +       int n, len = 0;
9619 +
9620 +       n = simple_strtoul(name, &end, 0);
9621 +       if((*end != '\0') || (end == name)){
9622 +               *error_out = "ubd_get_config : didn't parse device number";
9623 +               return(-1);
9624 +       }
9625 +
9626 +       if((n >= MAX_DEV) || (n < 0)){
9627 +               *error_out = "ubd_get_config : device number out of range";
9628 +               return(-1);
9629 +       }
9630 +
9631 +       dev = &ubd_dev[n];
9632 +       spin_lock(&ubd_lock);
9633 +
9634 +       if(dev->file == NULL){
9635 +               CONFIG_CHUNK(str, size, len, "", 1);
9636 +               goto out;
9637 +       }
9638 +
9639 +       CONFIG_CHUNK(str, size, len, dev->file, 0);
9640 +
9641 +       if(dev->cow.file != NULL){
9642 +               CONFIG_CHUNK(str, size, len, ",", 0);
9643 +               CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
9644 +       }
9645 +       else CONFIG_CHUNK(str, size, len, "", 1);
9646 +
9647 + out:
9648 +       spin_unlock(&ubd_lock);
9649 +       return(len);
9650 +}
9651 +
9652 +static int ubd_remove(char *str)
9653 +{
9654 +       struct ubd *dev;
9655 +       int n, err = -ENODEV;
9656 +
9657 +       if(isdigit(*str)){
9658 +               char *end;
9659 +               n = simple_strtoul(str, &end, 0);
9660 +               if ((*end != '\0') || (end == str)) 
9661 +                       return(err);
9662 +       }
9663 +       else if (('a' <= *str) && (*str <= 'h'))
9664 +               n = *str - 'a';
9665 +       else
9666 +               return(err);    /* it should be a number 0-7/a-h */
9667 +
9668 +       if((n < 0) || (n >= MAX_DEV))
9669 +               return(err);
9670 +
9671 +       dev = &ubd_dev[n];
9672 +
9673 +       spin_lock(&ubd_lock);
9674 +       err = 0;
9675 +       if(dev->file == NULL)
9676 +               goto out;
9677 +       err = -1;
9678 +       if(dev->count > 0)
9679 +               goto out;
9680 +       if(dev->devfs != NULL) 
9681 +               devfs_unregister(dev->devfs);
9682 +
9683 +       *dev = ((struct ubd) DEFAULT_UBD);
9684 +       err = 0;
9685 + out:
9686 +       spin_unlock(&ubd_lock);
9687 +       return(err);
9688 +}
9689 +
9690 +static struct mc_device ubd_mc = {
9691 +       .name           = "ubd",
9692 +       .config         = ubd_config,
9693 +       .get_config     = ubd_get_config,
9694 +       .remove         = ubd_remove,
9695 +};
9696 +
9697 +static int ubd_mc_init(void)
9698 +{
9699 +       mconsole_register_dev(&ubd_mc);
9700 +       return(0);
9701 +}
9702 +
9703 +__initcall(ubd_mc_init);
9704 +
9705 +static request_queue_t *ubd_get_queue(kdev_t device)
9706 +{
9707 +       return(ubd_queue);
9708 +}
9709 +
9710 +int ubd_init(void)
9711 +{
9712 +       unsigned long stack;
9713 +        int i, err;
9714 +
9715 +       ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL);
9716 +       if (devfs_register_blkdev(MAJOR_NR, "ubd", &ubd_blops)) {
9717 +               printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
9718 +               return -1;
9719 +       }
9720 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
9721 +       blksize_size[MAJOR_NR] = blk_sizes;
9722 +       blk_size[MAJOR_NR] = sizes;
9723 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
9724 +
9725 +       ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
9726 +       blk_init_queue(ubd_queue, DEVICE_REQUEST);
9727 +       INIT_ELV(ubd_queue, &ubd_queue->elevator);
9728 +
9729 +        add_gendisk(&ubd_gendisk);
9730 +       if (fake_major != MAJOR_NR){
9731 +               /* major number 0 is used to auto select */
9732 +               err = devfs_register_blkdev(fake_major, "fake", &ubd_blops);
9733 +               if(fake_major == 0){
9734 +               /* auto device number case */
9735 +                       fake_major = err;
9736 +                       if(err == 0)
9737 +                               return(-ENODEV);
9738 +               } 
9739 +               else if (err){
9740 +                       /* not auto so normal error */
9741 +                       printk(KERN_ERR "ubd: error %d getting major %d\n", 
9742 +                              err, fake_major);
9743 +                       return(-ENODEV);
9744 +               }
9745 +
9746 +               blk_dev[fake_major].queue = ubd_get_queue;
9747 +               read_ahead[fake_major] = 8;     /* 8 sector (4kB) read-ahead */
9748 +               blksize_size[fake_major] = blk_sizes;
9749 +               blk_size[fake_major] = sizes;
9750 +               INIT_HARDSECT(hardsect_size, fake_major, hardsect_sizes);
9751 +                add_gendisk(&fake_gendisk);
9752 +       }
9753 +
9754 +       for(i=0;i<MAX_DEV;i++) 
9755 +               ubd_add(i);
9756 +
9757 +       if(global_openflags.s){
9758 +               printk(KERN_INFO "ubd : Synchronous mode\n");
9759 +               return(0);
9760 +       }
9761 +       stack = alloc_stack(0, 0);
9762 +       io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 
9763 +                                &thread_fd);
9764 +       if(io_pid < 0){
9765 +               printk(KERN_ERR 
9766 +                      "ubd : Failed to start I/O thread (errno = %d) - "
9767 +                      "falling back to synchronous I/O\n", -io_pid);
9768 +               return(0);
9769 +       }
9770 +       err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 
9771 +                            SA_INTERRUPT, "ubd", ubd_dev);
9772 +       if(err != 0) printk(KERN_ERR 
9773 +                           "um_request_irq failed - errno = %d\n", -err);
9774 +       return(err);
9775 +}
9776 +
9777 +__initcall(ubd_init);
9778 +
9779 +static void ubd_close(struct ubd *dev)
9780 +{
9781 +       os_close_file(dev->fd);
9782 +       if(dev->cow.file != NULL) {
9783 +               os_close_file(dev->cow.fd);
9784 +               vfree(dev->cow.bitmap);
9785 +               dev->cow.bitmap = NULL;
9786 +       }
9787 +}
9788 +
9789 +static int ubd_open_dev(struct ubd *dev)
9790 +{
9791 +       struct openflags flags;
9792 +       int err, create_cow, *create_ptr;
9793 +
9794 +       dev->openflags = dev->boot_openflags;
9795 +       create_cow = 0;
9796 +       create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
9797 +       dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
9798 +                               &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
9799 +                               &dev->cow.data_offset, create_ptr);
9800 +
9801 +       if((dev->fd == -ENOENT) && create_cow){
9802 +               dev->fd = create_cow_file(dev->file, dev->cow.file, 
9803 +                                         dev->openflags, 1 << 9,
9804 +                                         &dev->cow.bitmap_offset, 
9805 +                                         &dev->cow.bitmap_len,
9806 +                                         &dev->cow.data_offset);
9807 +               if(dev->fd >= 0){
9808 +                       printk(KERN_INFO "Creating \"%s\" as COW file for "
9809 +                              "\"%s\"\n", dev->file, dev->cow.file);
9810 +               }
9811 +       }
9812 +
9813 +       if(dev->fd < 0) return(dev->fd);
9814 +
9815 +       if(dev->cow.file != NULL){
9816 +               err = -ENOMEM;
9817 +               dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
9818 +               if(dev->cow.bitmap == NULL) goto error;
9819 +               flush_tlb_kernel_vm();
9820 +
9821 +               err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
9822 +                                     dev->cow.bitmap_offset, 
9823 +                                     dev->cow.bitmap_len);
9824 +               if(err) goto error;
9825 +
9826 +               flags = dev->openflags;
9827 +               flags.w = 0;
9828 +               err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, 
9829 +                                   NULL, NULL);
9830 +               if(err < 0) goto error;
9831 +               dev->cow.fd = err;
9832 +       }
9833 +       return(0);
9834 + error:
9835 +       os_close_file(dev->fd);
9836 +       return(err);
9837 +}
9838 +
9839 +static int ubd_file_size(struct ubd *dev, __u64 *size_out)
9840 +{
9841 +       char *file;
9842 +
9843 +       file = dev->cow.file ? dev->cow.file : dev->file;
9844 +       return(os_file_size(file, size_out));
9845 +}
9846 +
9847 +static int ubd_open(struct inode *inode, struct file *filp)
9848 +{
9849 +       struct ubd *dev;
9850 +       int n, offset, err = 0;
9851 +
9852 +       n = DEVICE_NR(inode->i_rdev);
9853 +       dev = &ubd_dev[n];
9854 +       if(n >= MAX_DEV)
9855 +               return -ENODEV;
9856 +
9857 +       spin_lock(&ubd_lock);
9858 +       offset = n << UBD_SHIFT;
9859 +
9860 +       if(dev->count == 0){
9861 +               err = ubd_open_dev(dev);
9862 +               if(err){
9863 +                       printk(KERN_ERR "ubd%d: Can't open \"%s\": "
9864 +                              "errno = %d\n", n, dev->file, -err);
9865 +                       goto out;
9866 +               }
9867 +               err = ubd_file_size(dev, &dev->size);
9868 +               if(err)
9869 +                       goto out;
9870 +               sizes[offset] = dev->size / BLOCK_SIZE;
9871 +               ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset];
9872 +       }
9873 +       dev->count++;
9874 +       if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
9875 +               if(--dev->count == 0) ubd_close(dev);
9876 +               err = -EROFS;
9877 +       }
9878 + out:
9879 +       spin_unlock(&ubd_lock);
9880 +       return(err);
9881 +}
9882 +
9883 +static int ubd_release(struct inode * inode, struct file * file)
9884 +{
9885 +        int n, offset;
9886 +
9887 +       n =  DEVICE_NR(inode->i_rdev);
9888 +       offset = n << UBD_SHIFT;
9889 +       if(n >= MAX_DEV)
9890 +               return -ENODEV;
9891 +
9892 +       spin_lock(&ubd_lock);
9893 +       if(--ubd_dev[n].count == 0)
9894 +               ubd_close(&ubd_dev[n]);
9895 +       spin_unlock(&ubd_lock);
9896 +
9897 +       return(0);
9898 +}
9899 +
9900 +void cowify_req(struct io_thread_req *req, struct ubd *dev)
9901 +{
9902 +        int i, update_bitmap, sector = req->offset >> 9;
9903 +
9904 +       if(req->length > (sizeof(req->sector_mask) * 8) << 9)
9905 +               panic("Operation too long");
9906 +       if(req->op == UBD_READ) {
9907 +               for(i = 0; i < req->length >> 9; i++){
9908 +                       if(ubd_test_bit(sector + i, (unsigned char *) 
9909 +                                       dev->cow.bitmap)){
9910 +                               ubd_set_bit(i, (unsigned char *) 
9911 +                                           &req->sector_mask);
9912 +                       }
9913 +                }
9914 +        } 
9915 +        else {
9916 +               update_bitmap = 0;
9917 +               for(i = 0; i < req->length >> 9; i++){
9918 +                       ubd_set_bit(i, (unsigned char *) 
9919 +                                   &req->sector_mask);
9920 +                       if(!ubd_test_bit(sector + i, (unsigned char *) 
9921 +                                        dev->cow.bitmap))
9922 +                               update_bitmap = 1;
9923 +                       ubd_set_bit(sector + i, (unsigned char *) 
9924 +                                   dev->cow.bitmap);
9925 +               }
9926 +               if(update_bitmap){
9927 +                       req->cow_offset = sector / (sizeof(unsigned long) * 8);
9928 +                       req->bitmap_words[0] = 
9929 +                               dev->cow.bitmap[req->cow_offset];
9930 +                       req->bitmap_words[1] = 
9931 +                               dev->cow.bitmap[req->cow_offset + 1];
9932 +                       req->cow_offset *= sizeof(unsigned long);
9933 +                       req->cow_offset += dev->cow.bitmap_offset;
9934 +               }
9935 +       }
9936 +}
9937 +
9938 +static int prepare_request(struct request *req, struct io_thread_req *io_req)
9939 +{
9940 +       struct ubd *dev;
9941 +       __u64 block;
9942 +       int nsect, minor, n;
9943 +
9944 +       if(req->rq_status == RQ_INACTIVE) return(1);
9945 +
9946 +       minor = MINOR(req->rq_dev);
9947 +       n = minor >> UBD_SHIFT;
9948 +       dev = &ubd_dev[n];
9949 +       if(IS_WRITE(req) && !dev->openflags.w){
9950 +               printk("Write attempted on readonly ubd device %d\n", n);
9951 +               end_request(0);
9952 +               return(1);
9953 +       }
9954 +
9955 +        req->sector += ubd_part[minor].start_sect;
9956 +        block = req->sector;
9957 +        nsect = req->current_nr_sectors;
9958 +
9959 +       io_req->op = (req->cmd == READ) ? UBD_READ : UBD_WRITE;
9960 +       io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
9961 +       io_req->fds[1] = dev->fd;
9962 +       io_req->offsets[0] = 0;
9963 +       io_req->offsets[1] = dev->cow.data_offset;
9964 +       io_req->offset = ((__u64) block) << 9;
9965 +       io_req->length = nsect << 9;
9966 +       io_req->buffer = req->buffer;
9967 +       io_req->sectorsize = 1 << 9;
9968 +       io_req->sector_mask = 0;
9969 +       io_req->cow_offset = -1;
9970 +       io_req->error = 0;
9971 +
9972 +        if(dev->cow.file != NULL) cowify_req(io_req, dev);
9973 +       return(0);
9974 +}
9975 +
9976 +static void do_ubd_request(request_queue_t *q)
9977 +{
9978 +       struct io_thread_req io_req;
9979 +       struct request *req;
9980 +       int err, n;
9981 +
9982 +       if(thread_fd == -1){
9983 +               while(!list_empty(&q->queue_head)){
9984 +                       req = blkdev_entry_next_request(&q->queue_head);
9985 +                       err = prepare_request(req, &io_req);
9986 +                       if(!err){
9987 +                               do_io(&io_req);
9988 +                               ubd_finish(io_req.error);
9989 +                       }
9990 +               }
9991 +       }
9992 +       else {
9993 +               if(DEVICE_INTR || list_empty(&q->queue_head)) return;
9994 +               req = blkdev_entry_next_request(&q->queue_head);
9995 +               err = prepare_request(req, &io_req);
9996 +               if(!err){
9997 +                       SET_INTR(ubd_handler);
9998 +                       n = write_ubd_fs(thread_fd, (char *) &io_req, 
9999 +                                        sizeof(io_req));
10000 +                       if(n != sizeof(io_req))
10001 +                               printk("write to io thread failed, "
10002 +                                      "errno = %d\n", -n);
10003 +               }
10004 +       }
10005 +}
10006 +
10007 +static int ubd_ioctl(struct inode * inode, struct file * file,
10008 +                    unsigned int cmd, unsigned long arg)
10009 +{
10010 +       struct hd_geometry *loc = (struct hd_geometry *) arg;
10011 +       struct ubd *dev;
10012 +       int n, minor, err;
10013 +       struct hd_driveid ubd_id = {
10014 +               .cyls           = 0,
10015 +               .heads          = 128,
10016 +               .sectors        = 32,
10017 +       };
10018 +       
10019 +        if(!inode) return(-EINVAL);
10020 +       minor = MINOR(inode->i_rdev);
10021 +       n = minor >> UBD_SHIFT;
10022 +       if(n >= MAX_DEV)
10023 +               return(-EINVAL);
10024 +       dev = &ubd_dev[n];
10025 +       switch (cmd) {
10026 +               struct hd_geometry g;
10027 +               struct cdrom_volctrl volume;
10028 +       case HDIO_GETGEO:
10029 +               if(!loc) return(-EINVAL);
10030 +               g.heads = 128;
10031 +               g.sectors = 32;
10032 +               g.cylinders = dev->size / (128 * 32 * hardsect_sizes[minor]);
10033 +               g.start = 2;
10034 +               return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
10035 +       case BLKGETSIZE:   /* Return device size */
10036 +               if(!arg) return(-EINVAL);
10037 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10038 +               if(err)
10039 +                       return(err);
10040 +               put_user(ubd_part[minor].nr_sects, (long *) arg);
10041 +               return(0);
10042 +       case BLKRRPART: /* Re-read partition tables */
10043 +               return(ubd_revalidate(inode->i_rdev));
10044 +
10045 +       case HDIO_SET_UNMASKINTR:
10046 +               if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
10047 +               if((arg > 1) || (minor & 0x3F)) return(-EINVAL);
10048 +               return(0);
10049 +
10050 +       case HDIO_GET_UNMASKINTR:
10051 +               if(!arg)  return(-EINVAL);
10052 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10053 +               if(err)
10054 +                       return(err);
10055 +               return(0);
10056 +
10057 +       case HDIO_GET_MULTCOUNT:
10058 +               if(!arg)  return(-EINVAL);
10059 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
10060 +               if(err)
10061 +                       return(err);
10062 +               return(0);
10063 +
10064 +       case HDIO_SET_MULTCOUNT:
10065 +               if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
10066 +               if(MINOR(inode->i_rdev) & 0x3F) return(-EINVAL);
10067 +               return(0);
10068 +
10069 +       case HDIO_GET_IDENTITY:
10070 +               ubd_id.cyls = dev->size / (128 * 32 * hardsect_sizes[minor]);
10071 +               if(copy_to_user((char *) arg, (char *) &ubd_id, 
10072 +                                sizeof(ubd_id)))
10073 +                       return(-EFAULT);
10074 +               return(0);
10075 +               
10076 +       case CDROMVOLREAD:
10077 +               if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
10078 +                       return(-EFAULT);
10079 +               volume.channel0 = 255;
10080 +               volume.channel1 = 255;
10081 +               volume.channel2 = 255;
10082 +               volume.channel3 = 255;
10083 +               if(copy_to_user((char *) arg, &volume, sizeof(volume)))
10084 +                       return(-EFAULT);
10085 +               return(0);
10086 +
10087 +       default:
10088 +               return blk_ioctl(inode->i_rdev, cmd, arg);
10089 +       }
10090 +}
10091 +
10092 +static int ubd_revalidate1(kdev_t rdev)
10093 +{
10094 +       int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT;
10095 +       struct ubd *dev;
10096 +       struct hd_struct *part;
10097 +
10098 +       n = DEVICE_NR(rdev);
10099 +       offset = n << UBD_SHIFT;
10100 +       dev = &ubd_dev[n];
10101 +
10102 +       part = &ubd_part[offset];
10103 +
10104 +       /* clear all old partition counts */
10105 +       for(i = 1; i < pcount; i++) {
10106 +               part[i].start_sect = 0;
10107 +               part[i].nr_sects = 0;
10108 +       }
10109 +
10110 +       /* If it already has been opened we can check the partitions 
10111 +        * directly 
10112 +        */
10113 +       if(dev->count){
10114 +               part->start_sect = 0;
10115 +               register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, 
10116 +                             &ubd_blops, part->nr_sects);
10117 +       } 
10118 +       else if(dev->file){
10119 +               err = ubd_open_dev(dev);
10120 +               if(err){
10121 +                       printk(KERN_ERR "unable to open %s for validation\n",
10122 +                              dev->file);
10123 +                       goto out;
10124 +               }
10125 +
10126 +               /* have to recompute sizes since we opened it */
10127 +               err = ubd_file_size(dev, &dev->size);
10128 +               if(err) {
10129 +                       ubd_close(dev);
10130 +                       goto out;
10131 +               }
10132 +               part->start_sect = 0;
10133 +               part->nr_sects = dev->size / hardsect_sizes[offset];
10134 +               register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, 
10135 +                             &ubd_blops, part->nr_sects);
10136 +
10137 +               /* we are done so close it */
10138 +               ubd_close(dev);
10139 +       } 
10140 +       else err = -ENODEV;
10141 + out:
10142 +       return(err);
10143 +}
10144 +
10145 +static int ubd_revalidate(kdev_t rdev)
10146 +{
10147 +       int err;
10148 +
10149 +       spin_lock(&ubd_lock);
10150 +       err = ubd_revalidate1(rdev);
10151 +       spin_unlock(&ubd_lock);
10152 +       return(err);
10153 +}
10154 +
10155 +/*
10156 + * Overrides for Emacs so that we follow Linus's tabbing style.
10157 + * Emacs will notice this stuff at the end of the file and automatically
10158 + * adjust the settings for this buffer only.  This must remain at the end
10159 + * of the file.
10160 + * ---------------------------------------------------------------------------
10161 + * Local variables:
10162 + * c-file-style: "linux"
10163 + * End:
10164 + */
10165 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_user.c um/arch/um/drivers/ubd_user.c
10166 --- orig/arch/um/drivers/ubd_user.c     1969-12-31 19:00:00.000000000 -0500
10167 +++ um/arch/um/drivers/ubd_user.c       2003-06-05 14:39:22.000000000 -0400
10168 @@ -0,0 +1,372 @@
10169 +/* 
10170 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
10171 + * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
10172 + * Licensed under the GPL
10173 + */
10174 +
10175 +#include <stddef.h>
10176 +#include <unistd.h>
10177 +#include <errno.h>
10178 +#include <sched.h>
10179 +#include <signal.h>
10180 +#include <string.h>
10181 +#include <netinet/in.h>
10182 +#include <sys/stat.h>
10183 +#include <sys/time.h>
10184 +#include <sys/fcntl.h>
10185 +#include <sys/socket.h>
10186 +#include <string.h>
10187 +#include <sys/mman.h>
10188 +#include <sys/param.h>
10189 +#include "asm/types.h"
10190 +#include "user_util.h"
10191 +#include "kern_util.h"
10192 +#include "user.h"
10193 +#include "ubd_user.h"
10194 +#include "os.h"
10195 +#include "cow.h"
10196 +
10197 +#include <endian.h>
10198 +#include <byteswap.h>
10199 +
10200 +static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
10201 +{
10202 +       struct stat64 buf1, buf2;
10203 +
10204 +       if(from_cmdline == NULL) return(1);
10205 +       if(!strcmp(from_cmdline, from_cow)) return(1);
10206 +
10207 +       if(stat64(from_cmdline, &buf1) < 0){
10208 +               printk("Couldn't stat '%s', errno = %d\n", from_cmdline, 
10209 +                      errno);
10210 +               return(1);
10211 +       }
10212 +       if(stat64(from_cow, &buf2) < 0){
10213 +               printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
10214 +               return(1);
10215 +       }
10216 +       if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino))
10217 +               return(1);
10218 +
10219 +       printk("Backing file mismatch - \"%s\" requested,\n"
10220 +              "\"%s\" specified in COW header of \"%s\"\n",
10221 +              from_cmdline, from_cow, cow);
10222 +       return(0);
10223 +}
10224 +
10225 +static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
10226 +{
10227 +       struct stat64 buf;
10228 +       long long actual;
10229 +       int err;
10230 +
10231 +       printk("%ld", htonll(size));
10232 +       if(stat64(file, &buf) < 0){
10233 +               printk("Failed to stat backing file \"%s\", errno = %d\n",
10234 +                      file, errno);
10235 +               return(-errno);
10236 +       }
10237 +
10238 +       err = os_file_size(file, &actual);
10239 +       if(err){
10240 +               printk("Failed to get size of backing file \"%s\", "
10241 +                      "errno = %d\n", file, -err);
10242 +               return(err);
10243 +       }
10244 +
10245 +       if(actual != size){
10246 +               printk("Size mismatch (%ld vs %ld) of COW header vs backing "
10247 +                      "file\n", size, actual);
10248 +               return(-EINVAL);
10249 +       }
10250 +       if(buf.st_mtime != mtime){
10251 +               printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
10252 +                      "file\n", mtime, buf.st_mtime);
10253 +               return(-EINVAL);
10254 +       }
10255 +       return(0);
10256 +}
10257 +
10258 +int read_cow_bitmap(int fd, void *buf, int offset, int len)
10259 +{
10260 +       int err;
10261 +
10262 +       err = os_seek_file(fd, offset);
10263 +       if(err != 0) return(-errno);
10264 +       err = read(fd, buf, len);
10265 +       if(err < 0) return(-errno);
10266 +       return(0);
10267 +}
10268 +
10269 +int open_ubd_file(char *file, struct openflags *openflags, 
10270 +                 char **backing_file_out, int *bitmap_offset_out, 
10271 +                 unsigned long *bitmap_len_out, int *data_offset_out, 
10272 +                 int *create_cow_out)
10273 +{
10274 +       time_t mtime;
10275 +       __u64 size;
10276 +       char *backing_file;
10277 +        int fd, err, sectorsize, magic, same, mode = 0644;
10278 +
10279 +        if((fd = os_open_file(file, *openflags, mode)) < 0){
10280 +               if((fd == -ENOENT) && (create_cow_out != NULL))
10281 +                       *create_cow_out = 1;
10282 +                if(!openflags->w ||
10283 +                   ((errno != EROFS) && (errno != EACCES))) return(-errno);
10284 +               openflags->w = 0;
10285 +                if((fd = os_open_file(file, *openflags, mode)) < 0) 
10286 +                       return(fd);
10287 +        }
10288 +
10289 +       err = os_lock_file(fd, openflags->w);
10290 +       if(err){
10291 +               printk("Failed to lock '%s', errno = %d\n", file, -err);
10292 +               goto error;
10293 +       }
10294 +       
10295 +       if(backing_file_out == NULL) return(fd);
10296 +
10297 +       err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, 
10298 +                             &sectorsize, bitmap_offset_out);
10299 +       if(err && (*backing_file_out != NULL)){
10300 +               printk("Failed to read COW header from COW file \"%s\", "
10301 +                      "errno = %d\n", file, err);
10302 +               goto error;
10303 +       }
10304 +       if(err) return(fd);
10305 +
10306 +       if(backing_file_out == NULL) return(fd);
10307 +       
10308 +       same = same_backing_files(*backing_file_out, backing_file, file);
10309 +
10310 +       if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
10311 +               printk("Switching backing file to '%s'\n", *backing_file_out);
10312 +               err = write_cow_header(file, fd, *backing_file_out, 
10313 +                                      sectorsize, &size);
10314 +               if(err){
10315 +                       printk("Switch failed, errno = %d\n", err);
10316 +                       return(err);
10317 +               }
10318 +       }
10319 +       else {
10320 +               *backing_file_out = backing_file;
10321 +               err = backing_file_mismatch(*backing_file_out, size, mtime);
10322 +               if(err) goto error;
10323 +       }
10324 +
10325 +       cow_sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
10326 +                 data_offset_out);
10327 +
10328 +        return(fd);
10329 + error:
10330 +       os_close_file(fd);
10331 +       return(err);
10332 +}
10333 +
10334 +int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
10335 +                   int sectorsize, int *bitmap_offset_out, 
10336 +                   unsigned long *bitmap_len_out, int *data_offset_out)
10337 +{
10338 +       int err, fd;
10339 +
10340 +       flags.c = 1;
10341 +       fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
10342 +       if(fd < 0){
10343 +               err = fd;
10344 +               printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
10345 +                      -err);
10346 +               goto out;
10347 +       }
10348 +
10349 +       err = init_cow_file(fd, cow_file, backing_file, sectorsize, 
10350 +                           bitmap_offset_out, bitmap_len_out, 
10351 +                           data_offset_out);
10352 +       if(!err)
10353 +               return(fd);
10354 +
10355 +       os_close_file(fd);
10356 + out:
10357 +       return(err);
10358 +}
10359 +
10360 +int read_ubd_fs(int fd, void *buffer, int len)
10361 +{
10362 +       int n;
10363 +
10364 +       n = read(fd, buffer, len);
10365 +       if(n < 0) return(-errno);
10366 +       else return(n);
10367 +}
10368 +
10369 +int write_ubd_fs(int fd, char *buffer, int len)
10370 +{
10371 +       int n;
10372 +
10373 +       n = write(fd, buffer, len);
10374 +       if(n < 0) return(-errno);
10375 +       else return(n);
10376 +}
10377 +
10378 +void do_io(struct io_thread_req *req)
10379 +{
10380 +       char *buf;
10381 +       unsigned long len;
10382 +       int n, nsectors, start, end, bit;
10383 +       __u64 off;
10384 +
10385 +       nsectors = req->length / req->sectorsize;
10386 +       start = 0;
10387 +       do {
10388 +               bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
10389 +               end = start;
10390 +               while((end < nsectors) && 
10391 +                     (ubd_test_bit(end, (unsigned char *) 
10392 +                                   &req->sector_mask) == bit))
10393 +                       end++;
10394 +
10395 +               if(end != nsectors)
10396 +                       printk("end != nsectors\n");
10397 +               off = req->offset + req->offsets[bit] + 
10398 +                       start * req->sectorsize;
10399 +               len = (end - start) * req->sectorsize;
10400 +               buf = &req->buffer[start * req->sectorsize];
10401 +
10402 +               if(os_seek_file(req->fds[bit], off) != 0){
10403 +                       printk("do_io - lseek failed : errno = %d\n", errno);
10404 +                       req->error = 1;
10405 +                       return;
10406 +               }
10407 +               if(req->op == UBD_READ){
10408 +                       n = 0;
10409 +                       do {
10410 +                               buf = &buf[n];
10411 +                               len -= n;
10412 +                               n = read(req->fds[bit], buf, len);
10413 +                               if (n < 0) {
10414 +                                       printk("do_io - read returned %d : "
10415 +                                              "errno = %d fd = %d\n", n,
10416 +                                              errno, req->fds[bit]);
10417 +                                       req->error = 1;
10418 +                                       return;
10419 +                               }
10420 +                       } while((n < len) && (n != 0));
10421 +                       if (n < len) memset(&buf[n], 0, len - n);
10422 +               }
10423 +               else {
10424 +                       n = write(req->fds[bit], buf, len);
10425 +                       if(n != len){
10426 +                               printk("do_io - write returned %d : "
10427 +                                      "errno = %d fd = %d\n", n, 
10428 +                                      errno, req->fds[bit]);
10429 +                               req->error = 1;
10430 +                               return;
10431 +                       }
10432 +               }
10433 +
10434 +               start = end;
10435 +       } while(start < nsectors);
10436 +
10437 +       if(req->cow_offset != -1){
10438 +               if(os_seek_file(req->fds[1], req->cow_offset) != 0){
10439 +                       printk("do_io - bitmap lseek failed : errno = %d\n",
10440 +                              errno);
10441 +                       req->error = 1;
10442 +                       return;
10443 +               }
10444 +               n = write(req->fds[1], &req->bitmap_words, 
10445 +                         sizeof(req->bitmap_words));
10446 +               if(n != sizeof(req->bitmap_words)){
10447 +                       printk("do_io - bitmap update returned %d : "
10448 +                              "errno = %d fd = %d\n", n, errno, req->fds[1]);
10449 +                       req->error = 1;
10450 +                       return;
10451 +               }
10452 +       }
10453 +       req->error = 0;
10454 +       return;
10455 +}
10456 +
10457 +/* Changed in start_io_thread, which is serialized by being called only
10458 + * from ubd_init, which is an initcall.
10459 + */
10460 +int kernel_fd = -1;
10461 +
10462 +/* Only changed by the io thread */
10463 +int io_count = 0;
10464 +
10465 +int io_thread(void *arg)
10466 +{
10467 +       struct io_thread_req req;
10468 +       int n;
10469 +
10470 +       signal(SIGWINCH, SIG_IGN);
10471 +       while(1){
10472 +               n = read(kernel_fd, &req, sizeof(req));
10473 +               if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
10474 +                                n, errno);
10475 +               else if(n < sizeof(req)){
10476 +                       printk("io_thread - short read : length = %d\n", n);
10477 +                       continue;
10478 +               }
10479 +               io_count++;
10480 +               do_io(&req);
10481 +               n = write(kernel_fd, &req, sizeof(req));
10482 +               if(n != sizeof(req))
10483 +                       printk("io_thread - write failed, errno = %d\n",
10484 +                              errno);
10485 +       }
10486 +}
10487 +
10488 +int start_io_thread(unsigned long sp, int *fd_out)
10489 +{
10490 +       int pid, fds[2], err;
10491 +
10492 +       err = os_pipe(fds, 1, 1);
10493 +       if(err){
10494 +               printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
10495 +               return(-1);
10496 +       }
10497 +       kernel_fd = fds[0];
10498 +       *fd_out = fds[1];
10499 +
10500 +       pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
10501 +                   NULL);
10502 +       if(pid < 0){
10503 +               printk("start_io_thread - clone failed : errno = %d\n", errno);
10504 +               return(-errno);
10505 +       }
10506 +       return(pid);
10507 +}
10508 +
10509 +#ifdef notdef
10510 +int start_io_thread(unsigned long sp, int *fd_out)
10511 +{
10512 +       int pid;
10513 +
10514 +       if((kernel_fd = get_pty()) < 0) return(-1);
10515 +       raw(kernel_fd, 0);
10516 +       if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){
10517 +               printk("Couldn't open tty for IO\n");
10518 +               return(-1);
10519 +       }
10520 +
10521 +       pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
10522 +                   NULL);
10523 +       if(pid < 0){
10524 +               printk("start_io_thread - clone failed : errno = %d\n", errno);
10525 +               return(-errno);
10526 +       }
10527 +       return(pid);
10528 +}
10529 +#endif
10530 +
10531 +/*
10532 + * Overrides for Emacs so that we follow Linus's tabbing style.
10533 + * Emacs will notice this stuff at the end of the file and automatically
10534 + * adjust the settings for this buffer only.  This must remain at the end
10535 + * of the file.
10536 + * ---------------------------------------------------------------------------
10537 + * Local variables:
10538 + * c-file-style: "linux"
10539 + * End:
10540 + */
10541 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.c um/arch/um/drivers/xterm.c
10542 --- orig/arch/um/drivers/xterm.c        1969-12-31 19:00:00.000000000 -0500
10543 +++ um/arch/um/drivers/xterm.c  2002-12-30 20:49:22.000000000 -0500
10544 @@ -0,0 +1,200 @@
10545 +/* 
10546 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
10547 + * Licensed under the GPL
10548 + */
10549 +
10550 +#include <stdio.h>
10551 +#include <stdlib.h>
10552 +#include <unistd.h>
10553 +#include <string.h>
10554 +#include <errno.h>
10555 +#include <fcntl.h>
10556 +#include <termios.h>
10557 +#include <signal.h>
10558 +#include <sched.h>
10559 +#include <sys/socket.h>
10560 +#include "kern_util.h"
10561 +#include "chan_user.h"
10562 +#include "helper.h"
10563 +#include "user_util.h"
10564 +#include "user.h"
10565 +#include "os.h"
10566 +#include "xterm.h"
10567 +
10568 +struct xterm_chan {
10569 +       int pid;
10570 +       int helper_pid;
10571 +       char *title;
10572 +       int device;
10573 +       int raw;
10574 +       struct termios tt;
10575 +       unsigned long stack;
10576 +       int direct_rcv;
10577 +};
10578 +
10579 +void *xterm_init(char *str, int device, struct chan_opts *opts)
10580 +{
10581 +       struct xterm_chan *data;
10582 +
10583 +       if((data = malloc(sizeof(*data))) == NULL) return(NULL);
10584 +       *data = ((struct xterm_chan) { .pid             = -1, 
10585 +                                      .helper_pid      = -1,
10586 +                                      .device          = device, 
10587 +                                      .title           = opts->xterm_title,
10588 +                                      .raw             = opts->raw,
10589 +                                      .stack           = opts->tramp_stack,
10590 +                                      .direct_rcv      = !opts->in_kernel } );
10591 +       return(data);
10592 +}
10593 +
10594 +/* Only changed by xterm_setup, which is a setup */
10595 +static char *terminal_emulator = "xterm";
10596 +static char *title_switch = "-T";
10597 +static char *exec_switch = "-e";
10598 +
10599 +static int __init xterm_setup(char *line, int *add)
10600 +{
10601 +       *add = 0;
10602 +       terminal_emulator = line;
10603 +
10604 +       line = strchr(line, ',');
10605 +       if(line == NULL) return(0);
10606 +       *line++ = '\0';
10607 +       if(*line) title_switch = line;
10608 +
10609 +       line = strchr(line, ',');
10610 +       if(line == NULL) return(0);
10611 +       *line++ = '\0';
10612 +       if(*line) exec_switch = line;
10613 +
10614 +       return(0);
10615 +}
10616 +
10617 +__uml_setup("xterm=", xterm_setup,
10618 +"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
10619 +"    Specifies an alternate terminal emulator to use for the debugger,\n"
10620 +"    consoles, and serial lines when they are attached to the xterm channel.\n"
10621 +"    The values are the terminal emulator binary, the switch it uses to set\n"
10622 +"    its title, and the switch it uses to execute a subprocess,\n"
10623 +"    respectively.  The title switch must have the form '<switch> title',\n"
10624 +"    not '<switch>=title'.  Similarly, the exec switch must have the form\n"
10625 +"    '<switch> command arg1 arg2 ...'.\n"
10626 +"    The default values are 'xterm=xterm,-T,-e'.  Values for gnome-terminal\n"
10627 +"    are 'xterm=gnome-terminal,-t,-x'.\n\n"
10628 +);
10629 +
10630 +int xterm_open(int input, int output, int primary, void *d, char **dev_out)
10631 +{
10632 +       struct xterm_chan *data = d;
10633 +       unsigned long stack;
10634 +       int pid, fd, new, err;
10635 +       char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
10636 +       char *argv[] = { terminal_emulator, title_switch, title, exec_switch, 
10637 +                        "/usr/lib/uml/port-helper", "-uml-socket",
10638 +                        file, NULL };
10639 +
10640 +       if(access(argv[4], X_OK))
10641 +               argv[4] = "port-helper";
10642 +
10643 +       fd = mkstemp(file);
10644 +       if(fd < 0){
10645 +               printk("xterm_open : mkstemp failed, errno = %d\n", errno);
10646 +               return(-errno);
10647 +       }
10648 +
10649 +       if(unlink(file)){
10650 +               printk("xterm_open : unlink failed, errno = %d\n", errno);
10651 +               return(-errno);
10652 +       }
10653 +       close(fd);
10654 +
10655 +       fd = create_unix_socket(file, sizeof(file));
10656 +       if(fd < 0){
10657 +               printk("xterm_open : create_unix_socket failed, errno = %d\n", 
10658 +                      -fd);
10659 +               return(-fd);
10660 +       }
10661 +
10662 +       sprintf(title, data->title, data->device);
10663 +       stack = data->stack;
10664 +       pid = run_helper(NULL, NULL, argv, &stack);
10665 +       if(pid < 0){
10666 +               printk("xterm_open : run_helper failed, errno = %d\n", -pid);
10667 +               return(pid);
10668 +       }
10669 +
10670 +       if(data->stack == 0) free_stack(stack, 0);
10671 +
10672 +       if(data->direct_rcv)
10673 +               new = os_rcv_fd(fd, &data->helper_pid);
10674 +       else {
10675 +               if((err = os_set_fd_block(fd, 0)) != 0){
10676 +                       printk("xterm_open : failed to set descriptor "
10677 +                              "non-blocking, errno = %d\n", err);
10678 +                       return(err);
10679 +               }
10680 +               new = xterm_fd(fd, &data->helper_pid);
10681 +       }
10682 +       if(new < 0){
10683 +               printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
10684 +               goto out;
10685 +       }
10686 +
10687 +       tcgetattr(new, &data->tt);
10688 +       if(data->raw) raw(new, 0);
10689 +
10690 +       data->pid = pid;
10691 +       *dev_out = NULL;
10692 + out:
10693 +       unlink(file);
10694 +       return(new);
10695 +}
10696 +
10697 +void xterm_close(int fd, void *d)
10698 +{
10699 +       struct xterm_chan *data = d;
10700 +       
10701 +       if(data->pid != -1) 
10702 +               os_kill_process(data->pid, 1);
10703 +       data->pid = -1;
10704 +       if(data->helper_pid != -1) 
10705 +               os_kill_process(data->helper_pid, 0);
10706 +       data->helper_pid = -1;
10707 +       close(fd);
10708 +}
10709 +
10710 +void xterm_free(void *d)
10711 +{
10712 +       free(d);
10713 +}
10714 +
10715 +int xterm_console_write(int fd, const char *buf, int n, void *d)
10716 +{
10717 +       struct xterm_chan *data = d;
10718 +
10719 +       return(generic_console_write(fd, buf, n, &data->tt));
10720 +}
10721 +
10722 +struct chan_ops xterm_ops = {
10723 +       .type           = "xterm",
10724 +       .init           = xterm_init,
10725 +       .open           = xterm_open,
10726 +       .close          = xterm_close,
10727 +       .read           = generic_read,
10728 +       .write          = generic_write,
10729 +       .console_write  = xterm_console_write,
10730 +       .window_size    = generic_window_size,
10731 +       .free           = xterm_free,
10732 +       .winch          = 1,
10733 +};
10734 +
10735 +/*
10736 + * Overrides for Emacs so that we follow Linus's tabbing style.
10737 + * Emacs will notice this stuff at the end of the file and automatically
10738 + * adjust the settings for this buffer only.  This must remain at the end
10739 + * of the file.
10740 + * ---------------------------------------------------------------------------
10741 + * Local variables:
10742 + * c-file-style: "linux"
10743 + * End:
10744 + */
10745 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.h um/arch/um/drivers/xterm.h
10746 --- orig/arch/um/drivers/xterm.h        1969-12-31 19:00:00.000000000 -0500
10747 +++ um/arch/um/drivers/xterm.h  2002-10-23 21:08:04.000000000 -0400
10748 @@ -0,0 +1,22 @@
10749 +/* 
10750 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10751 + * Licensed under the GPL
10752 + */
10753 +
10754 +#ifndef __XTERM_H__
10755 +#define __XTERM_H__
10756 +
10757 +extern int xterm_fd(int socket, int *pid_out);
10758 +
10759 +#endif
10760 +
10761 +/*
10762 + * Overrides for Emacs so that we follow Linus's tabbing style.
10763 + * Emacs will notice this stuff at the end of the file and automatically
10764 + * adjust the settings for this buffer only.  This must remain at the end
10765 + * of the file.
10766 + * ---------------------------------------------------------------------------
10767 + * Local variables:
10768 + * c-file-style: "linux"
10769 + * End:
10770 + */
10771 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm_kern.c um/arch/um/drivers/xterm_kern.c
10772 --- orig/arch/um/drivers/xterm_kern.c   1969-12-31 19:00:00.000000000 -0500
10773 +++ um/arch/um/drivers/xterm_kern.c     2002-12-17 17:31:20.000000000 -0500
10774 @@ -0,0 +1,79 @@
10775 +/* 
10776 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10777 + * Licensed under the GPL
10778 + */
10779 +
10780 +#include "linux/errno.h"
10781 +#include "linux/slab.h"
10782 +#include "asm/semaphore.h"
10783 +#include "asm/irq.h"
10784 +#include "irq_user.h"
10785 +#include "kern_util.h"
10786 +#include "os.h"
10787 +#include "xterm.h"
10788 +
10789 +struct xterm_wait {
10790 +       struct semaphore sem;
10791 +       int fd;
10792 +       int pid;
10793 +       int new_fd;
10794 +};
10795 +
10796 +static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
10797 +{
10798 +       struct xterm_wait *xterm = data;
10799 +       int fd;
10800 +
10801 +       fd = os_rcv_fd(xterm->fd, &xterm->pid);
10802 +       if(fd == -EAGAIN)
10803 +               return;
10804 +
10805 +       xterm->new_fd = fd;
10806 +       up(&xterm->sem);
10807 +}
10808 +
10809 +int xterm_fd(int socket, int *pid_out)
10810 +{
10811 +       struct xterm_wait *data;
10812 +       int err, ret;
10813 +
10814 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
10815 +       if(data == NULL){
10816 +               printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
10817 +               return(-ENOMEM);
10818 +       }
10819 +       *data = ((struct xterm_wait) 
10820 +               { .sem          = __SEMAPHORE_INITIALIZER(data->sem, 0),
10821 +                 .fd           = socket,
10822 +                 .pid          = -1,
10823 +                 .new_fd       = -1 });
10824 +
10825 +       err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 
10826 +                            SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
10827 +                            "xterm", data);
10828 +       if(err){
10829 +               printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
10830 +                      "err = %d\n",  err);
10831 +               return(err);
10832 +       }
10833 +       down(&data->sem);
10834 +
10835 +       free_irq(XTERM_IRQ, data);
10836 +
10837 +       ret = data->new_fd;
10838 +       *pid_out = data->pid;
10839 +       kfree(data);
10840 +
10841 +       return(ret);
10842 +}
10843 +
10844 +/*
10845 + * Overrides for Emacs so that we follow Linus's tabbing style.
10846 + * Emacs will notice this stuff at the end of the file and automatically
10847 + * adjust the settings for this buffer only.  This must remain at the end
10848 + * of the file.
10849 + * ---------------------------------------------------------------------------
10850 + * Local variables:
10851 + * c-file-style: "linux"
10852 + * End:
10853 + */
10854 diff -Naur -X ../exclude-files orig/arch/um/dyn_link.ld.in um/arch/um/dyn_link.ld.in
10855 --- orig/arch/um/dyn_link.ld.in 1969-12-31 19:00:00.000000000 -0500
10856 +++ um/arch/um/dyn_link.ld.in   2003-01-17 23:37:27.000000000 -0500
10857 @@ -0,0 +1,172 @@
10858 +OUTPUT_FORMAT("ELF_FORMAT")
10859 +OUTPUT_ARCH(ELF_ARCH)
10860 +ENTRY(_start)
10861 +SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
10862 +/* Do we need any of these for elf?
10863 +   __DYNAMIC = 0;    */
10864 +SECTIONS
10865 +{
10866 +  . = START() + SIZEOF_HEADERS;
10867 +  .interp         : { *(.interp) }
10868 +  . = ALIGN(4096);
10869 +  __binary_start = .;
10870 +  . = ALIGN(4096);             /* Init code and data */
10871 +  _stext = .;
10872 +  __init_begin = .;
10873 +  .text.init : { *(.text.init) }
10874 +
10875 +  . = ALIGN(4096);
10876 +
10877 +  /* Read-only sections, merged into text segment: */
10878 +  .hash           : { *(.hash) }
10879 +  .dynsym         : { *(.dynsym) }
10880 +  .dynstr         : { *(.dynstr) }
10881 +  .gnu.version    : { *(.gnu.version) }
10882 +  .gnu.version_d  : { *(.gnu.version_d) }
10883 +  .gnu.version_r  : { *(.gnu.version_r) }
10884 +  .rel.init       : { *(.rel.init) }
10885 +  .rela.init      : { *(.rela.init) }
10886 +  .rel.text       : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
10887 +  .rela.text      : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
10888 +  .rel.fini       : { *(.rel.fini) }
10889 +  .rela.fini      : { *(.rela.fini) }
10890 +  .rel.rodata     : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
10891 +  .rela.rodata    : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
10892 +  .rel.data       : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
10893 +  .rela.data      : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
10894 +  .rel.tdata     : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
10895 +  .rela.tdata    : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
10896 +  .rel.tbss      : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
10897 +  .rela.tbss     : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
10898 +  .rel.ctors      : { *(.rel.ctors) }
10899 +  .rela.ctors     : { *(.rela.ctors) }
10900 +  .rel.dtors      : { *(.rel.dtors) }
10901 +  .rela.dtors     : { *(.rela.dtors) }
10902 +  .rel.got        : { *(.rel.got) }
10903 +  .rela.got       : { *(.rela.got) }
10904 +  .rel.bss        : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
10905 +  .rela.bss       : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
10906 +  .rel.plt        : { *(.rel.plt) }
10907 +  .rela.plt       : { *(.rela.plt) }
10908 +  .init           : {
10909 +    KEEP (*(.init))
10910 +  } =0x90909090
10911 +  .plt            : { *(.plt) }
10912 +  .text           : {
10913 +    *(.text .stub .text.* .gnu.linkonce.t.*)
10914 +    /* .gnu.warning sections are handled specially by elf32.em.  */
10915 +    *(.gnu.warning)
10916 +  } =0x90909090
10917 +  .fini           : {
10918 +    KEEP (*(.fini))
10919 +  } =0x90909090
10920 +
10921 +  PROVIDE (__etext = .);
10922 +  PROVIDE (_etext = .);
10923 +  PROVIDE (etext = .);
10924 +  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
10925 +  .rodata1        : { *(.rodata1) }
10926 +  .eh_frame_hdr : { *(.eh_frame_hdr) }
10927 +
10928 +
10929 +  . = ALIGN(4096);
10930 +  PROVIDE (_sdata = .);
10931 +
10932 +include(`arch/um/common.ld.in')
10933 +
10934 +  /* Ensure the __preinit_array_start label is properly aligned.  We
10935 +     could instead move the label definition inside the section, but
10936 +     the linker would then create the section even if it turns out to
10937 +     be empty, which isn't pretty.  */
10938 +  . = ALIGN(32 / 8);
10939 +  .preinit_array     : { *(.preinit_array) }
10940 +  .init_array     : { *(.init_array) }
10941 +  .fini_array     : { *(.fini_array) }
10942 +  .data           : {
10943 +    . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
10944 +    *(.data.init_task)
10945 +    *(.data .data.* .gnu.linkonce.d.*)
10946 +    SORT(CONSTRUCTORS)
10947 +  }
10948 +  .data1          : { *(.data1) }
10949 +  .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
10950 +  .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
10951 +  .eh_frame       : { KEEP (*(.eh_frame)) }
10952 +  .gcc_except_table   : { *(.gcc_except_table) }
10953 +  .dynamic        : { *(.dynamic) }
10954 +  .ctors          : {
10955 +    /* gcc uses crtbegin.o to find the start of
10956 +       the constructors, so we make sure it is
10957 +       first.  Because this is a wildcard, it
10958 +       doesn't matter if the user does not
10959 +       actually link against crtbegin.o; the
10960 +       linker won't look for a file to match a
10961 +       wildcard.  The wildcard also means that it
10962 +       doesn't matter which directory crtbegin.o
10963 +       is in.  */
10964 +    KEEP (*crtbegin.o(.ctors))
10965 +    /* We don't want to include the .ctor section from
10966 +       from the crtend.o file until after the sorted ctors.
10967 +       The .ctor section from the crtend file contains the
10968 +       end of ctors marker and it must be last */
10969 +    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
10970 +    KEEP (*(SORT(.ctors.*)))
10971 +    KEEP (*(.ctors))
10972 +  }
10973 +  .dtors          : {
10974 +    KEEP (*crtbegin.o(.dtors))
10975 +    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
10976 +    KEEP (*(SORT(.dtors.*)))
10977 +    KEEP (*(.dtors))
10978 +  }
10979 +  .jcr            : { KEEP (*(.jcr)) }
10980 +  .got            : { *(.got.plt) *(.got) }
10981 +  _edata = .;
10982 +  PROVIDE (edata = .);
10983 +  __bss_start = .;
10984 +  .bss            : {
10985 +   *(.dynbss)
10986 +   *(.bss .bss.* .gnu.linkonce.b.*)
10987 +   *(COMMON)
10988 +   /* Align here to ensure that the .bss section occupies space up to
10989 +      _end.  Align after .bss to ensure correct alignment even if the
10990 +      .bss section disappears because there are no input sections.  */
10991 +   . = ALIGN(32 / 8);
10992 +  . = ALIGN(32 / 8);
10993 +  }
10994 +  _end = .;
10995 +  PROVIDE (end = .);
10996 +   /* Stabs debugging sections.  */
10997 +  .stab          0 : { *(.stab) }
10998 +  .stabstr       0 : { *(.stabstr) }
10999 +  .stab.excl     0 : { *(.stab.excl) }
11000 +  .stab.exclstr  0 : { *(.stab.exclstr) }
11001 +  .stab.index    0 : { *(.stab.index) }
11002 +  .stab.indexstr 0 : { *(.stab.indexstr) }
11003 +  .comment       0 : { *(.comment) }
11004 +  /* DWARF debug sections.
11005 +     Symbols in the DWARF debugging sections are relative to the beginning
11006 +     of the section so we begin them at 0.  */
11007 +  /* DWARF 1 */
11008 +  .debug          0 : { *(.debug) }
11009 +  .line           0 : { *(.line) }
11010 +  /* GNU DWARF 1 extensions */
11011 +  .debug_srcinfo  0 : { *(.debug_srcinfo) }
11012 +  .debug_sfnames  0 : { *(.debug_sfnames) }
11013 +  /* DWARF 1.1 and DWARF 2 */
11014 +  .debug_aranges  0 : { *(.debug_aranges) }
11015 +  .debug_pubnames 0 : { *(.debug_pubnames) }
11016 +  /* DWARF 2 */
11017 +  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
11018 +  .debug_abbrev   0 : { *(.debug_abbrev) }
11019 +  .debug_line     0 : { *(.debug_line) }
11020 +  .debug_frame    0 : { *(.debug_frame) }
11021 +  .debug_str      0 : { *(.debug_str) }
11022 +  .debug_loc      0 : { *(.debug_loc) }
11023 +  .debug_macinfo  0 : { *(.debug_macinfo) }
11024 +  /* SGI/MIPS DWARF 2 extensions */
11025 +  .debug_weaknames 0 : { *(.debug_weaknames) }
11026 +  .debug_funcnames 0 : { *(.debug_funcnames) }
11027 +  .debug_typenames 0 : { *(.debug_typenames) }
11028 +  .debug_varnames  0 : { *(.debug_varnames) }
11029 +}
11030 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs.h um/arch/um/fs/hostfs/hostfs.h
11031 --- orig/arch/um/fs/hostfs/hostfs.h     1969-12-31 19:00:00.000000000 -0500
11032 +++ um/arch/um/fs/hostfs/hostfs.h       2003-05-22 11:03:20.000000000 -0400
11033 @@ -0,0 +1,69 @@
11034 +#ifndef __UM_FS_HOSTFS
11035 +#define __UM_FS_HOSTFS
11036 +
11037 +#include "os.h"
11038 +
11039 +/* These are exactly the same definitions as in fs.h, but the names are 
11040 + * changed so that this file can be included in both kernel and user files.
11041 + */
11042 +
11043 +#define HOSTFS_ATTR_MODE       1
11044 +#define HOSTFS_ATTR_UID        2
11045 +#define HOSTFS_ATTR_GID        4
11046 +#define HOSTFS_ATTR_SIZE       8
11047 +#define HOSTFS_ATTR_ATIME      16
11048 +#define HOSTFS_ATTR_MTIME      32
11049 +#define HOSTFS_ATTR_CTIME      64
11050 +#define HOSTFS_ATTR_ATIME_SET  128
11051 +#define HOSTFS_ATTR_MTIME_SET  256
11052 +#define HOSTFS_ATTR_FORCE      512     /* Not a change, but a change it */
11053 +#define HOSTFS_ATTR_ATTR_FLAG  1024
11054 +
11055 +struct hostfs_iattr {
11056 +       unsigned int    ia_valid;
11057 +       mode_t          ia_mode;
11058 +       uid_t           ia_uid;
11059 +       gid_t           ia_gid;
11060 +       loff_t          ia_size;
11061 +       time_t          ia_atime;
11062 +       time_t          ia_mtime;
11063 +       time_t          ia_ctime;
11064 +       unsigned int    ia_attr_flags;
11065 +};
11066 +
11067 +extern int stat_file(const char *path, int *dev_out, 
11068 +                    unsigned long long *inode_out, int *mode_out, 
11069 +                    int *nlink_out, int *uid_out, int *gid_out, 
11070 +                    unsigned long long *size_out, unsigned long *atime_out, 
11071 +                    unsigned long *mtime_out, unsigned long *ctime_out, 
11072 +                    int *blksize_out, unsigned long long *blocks_out);
11073 +extern int access_file(char *path, int r, int w, int x);
11074 +extern int open_file(char *path, int r, int w, int append);
11075 +extern int file_type(const char *path, int *rdev);
11076 +extern void *open_dir(char *path, int *err_out);
11077 +extern char *read_dir(void *stream, unsigned long long *pos, 
11078 +                     unsigned long long *ino_out, int *len_out);
11079 +extern void close_file(void *stream);
11080 +extern void close_dir(void *stream);
11081 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
11082 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
11083 +                     int len);
11084 +extern int lseek_file(int fd, long long offset, int whence);
11085 +extern int file_create(char *name, int ur, int uw, int ux, int gr, 
11086 +                      int gw, int gx, int or, int ow, int ox);
11087 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
11088 +extern int make_symlink(const char *from, const char *to);
11089 +extern int unlink_file(const char *file);
11090 +extern int do_mkdir(const char *file, int mode);
11091 +extern int do_rmdir(const char *file);
11092 +extern int do_mknod(const char *file, int mode, int dev);
11093 +extern int link_file(const char *from, const char *to);
11094 +extern int do_readlink(char *file, char *buf, int size);
11095 +extern int rename_file(char *from, char *to);
11096 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
11097 +                    long long *bfree_out, long long *bavail_out, 
11098 +                    long long *files_out, long long *ffree_out, 
11099 +                    void *fsid_out, int fsid_size, long *namelen_out, 
11100 +                    long *spare_out);
11101 +
11102 +#endif
11103 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_kern.c um/arch/um/fs/hostfs/hostfs_kern.c
11104 --- orig/arch/um/fs/hostfs/hostfs_kern.c        1969-12-31 19:00:00.000000000 -0500
11105 +++ um/arch/um/fs/hostfs/hostfs_kern.c  2003-05-22 11:26:25.000000000 -0400
11106 @@ -0,0 +1,923 @@
11107 +/* 
11108 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
11109 + * Licensed under the GPL
11110 + */
11111 +
11112 +#include <linux/stddef.h>
11113 +#include <linux/fs.h>
11114 +#include <linux/version.h>
11115 +#include <linux/module.h>
11116 +#include <linux/init.h>
11117 +#include <linux/slab.h>
11118 +#include <linux/pagemap.h>
11119 +#include <linux/blkdev.h>
11120 +#include <asm/uaccess.h>
11121 +#include "hostfs.h"
11122 +#include "kern_util.h"
11123 +#include "kern.h"
11124 +#include "user_util.h"
11125 +#include "2_5compat.h"
11126 +#include "init.h"
11127 +
11128 +#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i)
11129 +
11130 +int hostfs_d_delete(struct dentry *dentry)
11131 +{
11132 +       return(1);
11133 +}
11134 +
11135 +struct dentry_operations hostfs_dentry_ops = {
11136 +       .d_delete               = hostfs_d_delete,
11137 +};
11138 +
11139 +/* Changed in hostfs_args before the kernel starts running */
11140 +static char *root_ino = "/";
11141 +static int append = 0;
11142 +
11143 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
11144 +
11145 +static struct inode_operations hostfs_iops;
11146 +static struct inode_operations hostfs_dir_iops;
11147 +static struct address_space_operations hostfs_link_aops;
11148 +
11149 +static int __init hostfs_args(char *options, int *add)
11150 +{
11151 +       char *ptr;
11152 +
11153 +       ptr = strchr(options, ',');
11154 +       if(ptr != NULL)
11155 +               *ptr++ = '\0';
11156 +       if(*options != '\0')
11157 +               root_ino = options;
11158 +
11159 +       options = ptr;
11160 +       while(options){
11161 +               ptr = strchr(options, ',');
11162 +               if(ptr != NULL)
11163 +                       *ptr++ = '\0';
11164 +               if(*options != '\0'){
11165 +                       if(!strcmp(options, "append"))
11166 +                               append = 1;
11167 +                       else printf("hostfs_args - unsupported option - %s\n",
11168 +                                   options);
11169 +               }
11170 +               options = ptr;
11171 +       }
11172 +       return(0);
11173 +}
11174 +
11175 +__uml_setup("hostfs=", hostfs_args,
11176 +"hostfs=<root dir>,<flags>,...\n"
11177 +"    This is used to set hostfs parameters.  The root directory argument\n"
11178 +"    is used to confine all hostfs mounts to within the specified directory\n"
11179 +"    tree on the host.  If this isn't specified, then a user inside UML can\n"
11180 +"    mount anything on the host that's accessible to the user that's running\n"
11181 +"    it.\n"
11182 +"    The only flag currently supported is 'append', which specifies that all\n"
11183 +"    files opened by hostfs will be opened in append mode.\n\n"
11184 +);
11185 +
11186 +static char *dentry_name(struct dentry *dentry, int extra)
11187 +{
11188 +       struct dentry *parent;
11189 +       char *root, *name;
11190 +       int len;
11191 +
11192 +       len = 0;
11193 +       parent = dentry;
11194 +       while(parent->d_parent != parent){
11195 +               len += parent->d_name.len + 1;
11196 +               parent = parent->d_parent;
11197 +       }
11198 +       
11199 +       root = parent->d_inode->u.hostfs_i.host_filename;
11200 +       len += strlen(root);
11201 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
11202 +       if(name == NULL) return(NULL);
11203 +
11204 +       name[len] = '\0';
11205 +       parent = dentry;
11206 +       while(parent->d_parent != parent){
11207 +               len -= parent->d_name.len + 1;
11208 +               name[len] = '/';
11209 +               strncpy(&name[len + 1], parent->d_name.name, 
11210 +                       parent->d_name.len);
11211 +               parent = parent->d_parent;
11212 +       }
11213 +       strncpy(name, root, strlen(root));
11214 +       return(name);
11215 +}
11216 +
11217 +static char *inode_name(struct inode *ino, int extra)
11218 +{
11219 +       struct dentry *dentry;
11220 +
11221 +       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
11222 +       return(dentry_name(dentry, extra));
11223 +}
11224 +
11225 +static int read_name(struct inode *ino, char *name)
11226 +{
11227 +       /* The non-int inode fields are copied into ints by stat_file and
11228 +        * then copied into the inode because passing the actual pointers
11229 +        * in and having them treated as int * breaks on big-endian machines
11230 +        */
11231 +       int err;
11232 +       int i_dev, i_mode, i_nlink, i_blksize;
11233 +       unsigned long long i_size;
11234 +       unsigned long long i_ino;
11235 +       unsigned long long i_blocks;
11236 +       err = stat_file(name, &i_dev, &i_ino, &i_mode, &i_nlink, 
11237 +                       &ino->i_uid, &ino->i_gid, &i_size, &ino->i_atime, 
11238 +                       &ino->i_mtime, &ino->i_ctime, &i_blksize, &i_blocks);
11239 +       if(err) return(err);
11240 +       ino->i_ino = i_ino;
11241 +       ino->i_dev = i_dev;
11242 +       ino->i_mode = i_mode;
11243 +       ino->i_nlink = i_nlink;
11244 +       ino->i_size = i_size;
11245 +       ino->i_blksize = i_blksize;
11246 +       ino->i_blocks = i_blocks;
11247 +       if(kdev_same(ino->i_sb->s_dev, ROOT_DEV) && (ino->i_uid == getuid()))
11248 +               ino->i_uid = 0;
11249 +       return(0);
11250 +}
11251 +
11252 +static char *follow_link(char *link)
11253 +{
11254 +       int len, n;
11255 +       char *name, *resolved, *end;
11256 +
11257 +       len = 64;
11258 +       while(1){
11259 +               n = -ENOMEM;
11260 +               name = kmalloc(len, GFP_KERNEL);
11261 +               if(name == NULL)
11262 +                       goto out;
11263 +
11264 +               n = do_readlink(link, name, len);
11265 +               if(n < len)
11266 +                       break;
11267 +               len *= 2;
11268 +               kfree(name);
11269 +       }
11270 +       if(n < 0)
11271 +               goto out_free;
11272 +
11273 +       if(*name == '/')
11274 +               return(name);
11275 +
11276 +       end = strrchr(link, '/');
11277 +       if(end == NULL)
11278 +               return(name);
11279 +
11280 +       *(end + 1) = '\0';
11281 +       len = strlen(link) + strlen(name) + 1;
11282 +
11283 +       resolved = kmalloc(len, GFP_KERNEL);
11284 +       if(resolved == NULL){
11285 +               n = -ENOMEM;
11286 +               goto out_free;
11287 +       }
11288 +
11289 +       sprintf(resolved, "%s%s", link, name);
11290 +       kfree(name);
11291 +       kfree(link);
11292 +       return(resolved);
11293 +
11294 + out_free:
11295 +       kfree(name);
11296 + out:
11297 +       return(ERR_PTR(n));
11298 +}
11299 +
11300 +static int read_inode(struct inode *ino)
11301 +{
11302 +       char *name;
11303 +       int err;
11304 +
11305 +       err = -ENOMEM;
11306 +       name = inode_name(ino, 0);
11307 +       if(name == NULL) 
11308 +               goto out;
11309 +
11310 +       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
11311 +               name = follow_link(name);
11312 +               if(IS_ERR(name)){
11313 +                       err = PTR_ERR(name);
11314 +                       goto out;
11315 +               }
11316 +       }
11317 +       
11318 +       err = read_name(ino, name);
11319 +       kfree(name);
11320 + out:
11321 +       return(err);
11322 +}
11323 +
11324 +void hostfs_delete_inode(struct inode *ino)
11325 +{
11326 +       if(ino->u.hostfs_i.host_filename) 
11327 +               kfree(ino->u.hostfs_i.host_filename);
11328 +       ino->u.hostfs_i.host_filename = NULL;
11329 +
11330 +       if(ino->u.hostfs_i.fd != -1) 
11331 +               close_file(&ino->u.hostfs_i.fd);
11332 +
11333 +       ino->u.hostfs_i.mode = 0;
11334 +       clear_inode(ino);
11335 +}
11336 +
11337 +int hostfs_statfs(struct super_block *sb, struct statfs *sf)
11338 +{
11339 +       /* do_statfs uses struct statfs64 internally, but the linux kernel
11340 +        * struct statfs still has 32-bit versions for most of these fields,
11341 +        * so we convert them here
11342 +        */
11343 +       int err;
11344 +       long long f_blocks;
11345 +       long long f_bfree;
11346 +       long long f_bavail;
11347 +       long long f_files;
11348 +       long long f_ffree;
11349 +
11350 +       err = do_statfs(sb->s_root->d_inode->u.hostfs_i.host_filename,
11351 +                       &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
11352 +                       &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
11353 +                       &sf->f_namelen, sf->f_spare);
11354 +       if(err) return(err);
11355 +       sf->f_blocks = f_blocks;
11356 +       sf->f_bfree = f_bfree;
11357 +       sf->f_bavail = f_bavail;
11358 +       sf->f_files = f_files;
11359 +       sf->f_ffree = f_ffree;
11360 +       sf->f_type = HOSTFS_SUPER_MAGIC;
11361 +       return(0);
11362 +}
11363 +
11364 +static struct super_operations hostfs_sbops = { 
11365 +       .put_inode      = force_delete,
11366 +       .delete_inode   = hostfs_delete_inode,
11367 +       .statfs         = hostfs_statfs,
11368 +};
11369 +
11370 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
11371 +{
11372 +       void *dir;
11373 +       char *name;
11374 +       unsigned long long next, ino;
11375 +       int error, len;
11376 +
11377 +       name = dentry_name(file->f_dentry, 0);
11378 +       if(name == NULL) return(-ENOMEM);
11379 +       dir = open_dir(name, &error);
11380 +       kfree(name);
11381 +       if(dir == NULL) return(-error);
11382 +       next = file->f_pos;
11383 +       while((name = read_dir(dir, &next, &ino, &len)) != NULL){
11384 +               error = (*filldir)(ent, name, len, file->f_pos, 
11385 +                                  ino, DT_UNKNOWN);
11386 +               if(error) break;
11387 +               file->f_pos = next;
11388 +       }
11389 +       close_dir(dir);
11390 +       return(0);
11391 +}
11392 +
11393 +int hostfs_file_open(struct inode *ino, struct file *file)
11394 +{
11395 +       char *name;
11396 +       int mode = 0, r = 0, w = 0, fd;
11397 +
11398 +       mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
11399 +       if((mode & ino->u.hostfs_i.mode) == mode)
11400 +               return(0);
11401 +
11402 +       /* The file may already have been opened, but with the wrong access,
11403 +        * so this resets things and reopens the file with the new access.
11404 +        */
11405 +       if(ino->u.hostfs_i.fd != -1){
11406 +               close_file(&ino->u.hostfs_i.fd);
11407 +               ino->u.hostfs_i.fd = -1;
11408 +       }
11409 +
11410 +       ino->u.hostfs_i.mode |= mode;
11411 +       if(ino->u.hostfs_i.mode & FMODE_READ) 
11412 +               r = 1;
11413 +       if(ino->u.hostfs_i.mode & FMODE_WRITE) 
11414 +               w = 1;
11415 +       if(w) 
11416 +               r = 1;
11417 +
11418 +       name = dentry_name(file->f_dentry, 0);
11419 +       if(name == NULL) 
11420 +               return(-ENOMEM);
11421 +
11422 +       fd = open_file(name, r, w, append);
11423 +       kfree(name);
11424 +       if(fd < 0) return(fd);
11425 +       file_hostfs_i(file)->fd = fd;
11426 +
11427 +       return(0);
11428 +}
11429 +
11430 +int hostfs_dir_open(struct inode *ino, struct file *file)
11431 +{
11432 +       return(0);      
11433 +}
11434 +
11435 +int hostfs_dir_release(struct inode *ino, struct file *file)
11436 +{
11437 +       return(0);
11438 +}
11439 +
11440 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
11441 +{
11442 +       return(0);
11443 +}
11444 +
11445 +static struct file_operations hostfs_file_fops = {
11446 +       .owner          = NULL,
11447 +       .read           = generic_file_read,
11448 +       .write          = generic_file_write,
11449 +       .mmap           = generic_file_mmap,
11450 +       .open           = hostfs_file_open,
11451 +       .release        = NULL,
11452 +       .fsync          = hostfs_fsync,
11453 +};
11454 +
11455 +static struct file_operations hostfs_dir_fops = {
11456 +       .owner          = NULL,
11457 +       .readdir        = hostfs_readdir,
11458 +       .open           = hostfs_dir_open,
11459 +       .release        = hostfs_dir_release,
11460 +       .fsync          = hostfs_fsync,
11461 +};
11462 +
11463 +int hostfs_writepage(struct page *page)
11464 +{
11465 +       struct address_space *mapping = page->mapping;
11466 +       struct inode *inode = mapping->host;
11467 +       char *buffer;
11468 +       unsigned long long base;
11469 +       int count = PAGE_CACHE_SIZE;
11470 +       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
11471 +       int err;
11472 +
11473 +       if (page->index >= end_index)
11474 +               count = inode->i_size & (PAGE_CACHE_SIZE-1);
11475 +
11476 +       buffer = kmap(page);
11477 +       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
11478 +
11479 +       err = write_file(inode->u.hostfs_i.fd, &base, buffer, count);
11480 +       if(err != count){
11481 +               ClearPageUptodate(page);
11482 +               goto out;
11483 +       }
11484 +
11485 +       if (base > inode->i_size)
11486 +               inode->i_size = base;
11487 +
11488 +       if (PageError(page))
11489 +               ClearPageError(page);   
11490 +       err = 0;
11491 +
11492 + out:  
11493 +       kunmap(page);
11494 +
11495 +       UnlockPage(page);
11496 +       return err; 
11497 +}
11498 +
11499 +int hostfs_readpage(struct file *file, struct page *page)
11500 +{
11501 +       char *buffer;
11502 +       long long start;
11503 +       int err = 0;
11504 +
11505 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
11506 +       buffer = kmap(page);
11507 +       err = read_file(file_hostfs_i(file)->fd, &start, buffer,
11508 +                       PAGE_CACHE_SIZE);
11509 +       if(err < 0) goto out;
11510 +
11511 +       memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
11512 +
11513 +       flush_dcache_page(page);
11514 +       SetPageUptodate(page);
11515 +       if (PageError(page)) ClearPageError(page);
11516 +       err = 0;
11517 + out:
11518 +       kunmap(page);
11519 +       UnlockPage(page);
11520 +       return(err);
11521 +}
11522 +
11523 +int hostfs_prepare_write(struct file *file, struct page *page, 
11524 +                        unsigned int from, unsigned int to)
11525 +{
11526 +       char *buffer;
11527 +       long long start, tmp;
11528 +       int err;
11529 +
11530 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
11531 +       buffer = kmap(page);
11532 +       if(from != 0){
11533 +               tmp = start;
11534 +               err = read_file(file_hostfs_i(file)->fd, &tmp, buffer,
11535 +                               from);
11536 +               if(err < 0) goto out;
11537 +       }
11538 +       if(to != PAGE_CACHE_SIZE){
11539 +               start += to;
11540 +               err = read_file(file_hostfs_i(file)->fd, &start, buffer + to,
11541 +                               PAGE_CACHE_SIZE - to);
11542 +               if(err < 0) goto out;           
11543 +       }
11544 +       err = 0;
11545 + out:
11546 +       kunmap(page);
11547 +       return(err);
11548 +}
11549 +
11550 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
11551 +                unsigned to)
11552 +{
11553 +       struct address_space *mapping = page->mapping;
11554 +       struct inode *inode = mapping->host;
11555 +       char *buffer;
11556 +       long long start;
11557 +       int err = 0;
11558 +
11559 +       start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
11560 +       buffer = kmap(page);
11561 +       err = write_file(file_hostfs_i(file)->fd, &start, buffer + from, 
11562 +                        to - from);
11563 +       if(err > 0) err = 0;
11564 +       if(!err && (start > inode->i_size))
11565 +               inode->i_size = start;
11566 +
11567 +       kunmap(page);
11568 +       return(err);
11569 +}
11570 +
11571 +static struct address_space_operations hostfs_aops = {
11572 +       .writepage      = hostfs_writepage,
11573 +       .readpage       = hostfs_readpage,
11574 +/*     .set_page_dirty = __set_page_dirty_nobuffers, */
11575 +       .prepare_write  = hostfs_prepare_write,
11576 +       .commit_write   = hostfs_commit_write
11577 +};
11578 +
11579 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
11580 +                              int *error)
11581 +{
11582 +       struct inode *inode;
11583 +       char *name;
11584 +       int type, err = -ENOMEM, rdev;
11585 +
11586 +       inode = new_inode(sb);
11587 +       if(inode == NULL) 
11588 +               goto out;
11589 +
11590 +       inode->u.hostfs_i.host_filename = NULL;
11591 +       inode->u.hostfs_i.fd = -1;
11592 +       inode->u.hostfs_i.mode = 0;
11593 +       insert_inode_hash(inode);
11594 +       if(dentry){
11595 +               name = dentry_name(dentry, 0);
11596 +               if(name == NULL){
11597 +                       err = -ENOMEM;
11598 +                       goto out_put;
11599 +               }
11600 +               type = file_type(name, &rdev);
11601 +               kfree(name);
11602 +       }
11603 +       else type = OS_TYPE_DIR;
11604 +       inode->i_sb = sb;
11605 +
11606 +       err = 0;
11607 +       if(type == OS_TYPE_SYMLINK)
11608 +               inode->i_op = &page_symlink_inode_operations;
11609 +       else if(type == OS_TYPE_DIR)
11610 +               inode->i_op = &hostfs_dir_iops;
11611 +       else inode->i_op = &hostfs_iops;
11612 +
11613 +       if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
11614 +       else inode->i_fop = &hostfs_file_fops;
11615 +
11616 +       if(type == OS_TYPE_SYMLINK) 
11617 +               inode->i_mapping->a_ops = &hostfs_link_aops;
11618 +       else inode->i_mapping->a_ops = &hostfs_aops;
11619 +
11620 +       switch (type) {
11621 +       case OS_TYPE_CHARDEV:
11622 +               init_special_inode(inode, S_IFCHR, rdev);
11623 +               break;
11624 +       case OS_TYPE_BLOCKDEV:
11625 +               init_special_inode(inode, S_IFBLK, rdev);
11626 +               break;
11627 +       case OS_TYPE_FIFO:
11628 +               init_special_inode(inode, S_IFIFO, 0);
11629 +               break;
11630 +       case OS_TYPE_SOCK:
11631 +               init_special_inode(inode, S_IFSOCK, 0);
11632 +               break;
11633 +       }
11634 +       
11635 +       if(error) *error = err;
11636 +       return(inode);
11637 + out_put:
11638 +       iput(inode);
11639 + out:
11640 +       if(error) *error = err;
11641 +       return(NULL);
11642 +}
11643 +
11644 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode)
11645 +{
11646 +       struct inode *inode;
11647 +       char *name;
11648 +       int error, fd;
11649 +
11650 +       inode = get_inode(dir->i_sb, dentry, &error);
11651 +       if(error) return(error);
11652 +       name = dentry_name(dentry, 0);
11653 +       if(name == NULL){
11654 +               iput(inode);
11655 +               return(-ENOMEM);
11656 +       }
11657 +       fd = file_create(name, 
11658 +                        mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
11659 +                        mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
11660 +                        mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
11661 +       if(fd < 0) 
11662 +               error = fd;
11663 +       else error = read_name(inode, name);
11664 +
11665 +       kfree(name);
11666 +       if(error){
11667 +               iput(inode);
11668 +               return(error);
11669 +       }
11670 +       inode->u.hostfs_i.fd = fd;
11671 +       inode->u.hostfs_i.mode = FMODE_READ | FMODE_WRITE;
11672 +       d_instantiate(dentry, inode);
11673 +       return(0);
11674 +}
11675
11676 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry)
11677 +{
11678 +       struct inode *inode;
11679 +       char *name;
11680 +       int error;
11681 +
11682 +       inode = get_inode(ino->i_sb, dentry, &error);
11683 +       if(error != 0) return(ERR_PTR(error));
11684 +       name = dentry_name(dentry, 0);
11685 +       if(name == NULL) return(ERR_PTR(-ENOMEM));
11686 +       error = read_name(inode, name);
11687 +       kfree(name);
11688 +       if(error){
11689 +               iput(inode);
11690 +               if(error == -ENOENT) inode = NULL;
11691 +               else return(ERR_PTR(error));
11692 +       }
11693 +       d_add(dentry, inode);
11694 +       dentry->d_op = &hostfs_dentry_ops;
11695 +       return(NULL);
11696 +}
11697 +
11698 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
11699 +{
11700 +        char *file;
11701 +       int len;
11702 +
11703 +       file = inode_name(ino, dentry->d_name.len + 1);
11704 +       if(file == NULL) return(NULL);
11705 +        strcat(file, "/");
11706 +       len = strlen(file);
11707 +        strncat(file, dentry->d_name.name, dentry->d_name.len);
11708 +       file[len + dentry->d_name.len] = '\0';
11709 +        return(file);
11710 +}
11711 +
11712 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
11713 +{
11714 +        char *from_name, *to_name;
11715 +        int err;
11716 +
11717 +        if((from_name = inode_dentry_name(ino, from)) == NULL) 
11718 +                return(-ENOMEM);
11719 +        to_name = dentry_name(to, 0);
11720 +       if(to_name == NULL){
11721 +               kfree(from_name);
11722 +               return(-ENOMEM);
11723 +       }
11724 +        err = link_file(to_name, from_name);
11725 +        kfree(from_name);
11726 +        kfree(to_name);
11727 +        return(err);
11728 +}
11729 +
11730 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
11731 +{
11732 +       char *file;
11733 +       int err;
11734 +
11735 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
11736 +       if(append)
11737 +               return(-EPERM);
11738 +
11739 +       err = unlink_file(file);
11740 +       kfree(file);
11741 +       return(err);
11742 +}
11743 +
11744 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
11745 +{
11746 +       char *file;
11747 +       int err;
11748 +
11749 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
11750 +       err = make_symlink(file, to);
11751 +       kfree(file);
11752 +       return(err);
11753 +}
11754 +
11755 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
11756 +{
11757 +       char *file;
11758 +       int err;
11759 +
11760 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
11761 +       err = do_mkdir(file, mode);
11762 +       kfree(file);
11763 +       return(err);
11764 +}
11765 +
11766 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
11767 +{
11768 +       char *file;
11769 +       int err;
11770 +
11771 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
11772 +       err = do_rmdir(file);
11773 +       kfree(file);
11774 +       return(err);
11775 +}
11776 +
11777 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
11778 +{
11779 +       struct inode *inode;
11780 +       char *name;
11781 +       int error;
11782
11783 +       inode = get_inode(dir->i_sb, dentry, &error);
11784 +       if(error) return(error);
11785 +       name = dentry_name(dentry, 0);
11786 +       if(name == NULL){
11787 +               iput(inode);
11788 +               return(-ENOMEM);
11789 +       }
11790 +       init_special_inode(inode, mode, dev);
11791 +       error = do_mknod(name, mode, dev);
11792 +       if(!error) error = read_name(inode, name);
11793 +       kfree(name);
11794 +       if(error){
11795 +               iput(inode);
11796 +               return(error);
11797 +       }
11798 +       d_instantiate(dentry, inode);
11799 +       return(0);
11800 +}
11801 +
11802 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
11803 +                 struct inode *to_ino, struct dentry *to)
11804 +{
11805 +       char *from_name, *to_name;
11806 +       int err;
11807 +
11808 +       if((from_name = inode_dentry_name(from_ino, from)) == NULL)
11809 +               return(-ENOMEM);
11810 +       if((to_name = inode_dentry_name(to_ino, to)) == NULL){
11811 +               kfree(from_name);
11812 +               return(-ENOMEM);
11813 +       }
11814 +       err = rename_file(from_name, to_name);
11815 +       kfree(from_name);
11816 +       kfree(to_name);
11817 +       return(err);
11818 +}
11819 +
11820 +void hostfs_truncate(struct inode *ino)
11821 +{
11822 +       not_implemented();
11823 +}
11824 +
11825 +int hostfs_permission(struct inode *ino, int desired)
11826 +{
11827 +       char *name;
11828 +       int r = 0, w = 0, x = 0, err;
11829 +
11830 +       if(desired & MAY_READ) r = 1;
11831 +       if(desired & MAY_WRITE) w = 1;
11832 +       if(desired & MAY_EXEC) x = 1;
11833 +       name = inode_name(ino, 0);
11834 +       if(name == NULL) return(-ENOMEM);
11835 +       err = access_file(name, r, w, x);
11836 +       kfree(name);
11837 +       if(!err) err = vfs_permission(ino, desired);
11838 +       return(err);
11839 +}
11840 +
11841 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
11842 +{
11843 +       struct hostfs_iattr attrs;
11844 +       char *name;
11845 +       int err;
11846 +       
11847 +       if(append) 
11848 +               attr->ia_valid &= ~ATTR_SIZE;
11849 +
11850 +       attrs.ia_valid = 0;
11851 +       if(attr->ia_valid & ATTR_MODE){
11852 +               attrs.ia_valid |= HOSTFS_ATTR_MODE;
11853 +               attrs.ia_mode = attr->ia_mode;
11854 +       }
11855 +       if(attr->ia_valid & ATTR_UID){
11856 +               if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) && 
11857 +                  (attr->ia_uid == 0))
11858 +                       attr->ia_uid = getuid();
11859 +               attrs.ia_valid |= HOSTFS_ATTR_UID;
11860 +               attrs.ia_uid = attr->ia_uid;
11861 +       }
11862 +       if(attr->ia_valid & ATTR_GID){
11863 +               if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) && 
11864 +                  (attr->ia_gid == 0))
11865 +                       attr->ia_gid = getuid();
11866 +               attrs.ia_valid |= HOSTFS_ATTR_GID;
11867 +               attrs.ia_gid = attr->ia_gid;
11868 +       }
11869 +       if(attr->ia_valid & ATTR_SIZE){
11870 +               attrs.ia_valid |= HOSTFS_ATTR_SIZE;
11871 +               attrs.ia_size = attr->ia_size;
11872 +       }
11873 +       if(attr->ia_valid & ATTR_ATIME){
11874 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME;
11875 +               attrs.ia_atime = attr->ia_atime;
11876 +       }
11877 +       if(attr->ia_valid & ATTR_MTIME){
11878 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME;
11879 +               attrs.ia_mtime = attr->ia_mtime;
11880 +       }
11881 +       if(attr->ia_valid & ATTR_CTIME){
11882 +               attrs.ia_valid |= HOSTFS_ATTR_CTIME;
11883 +               attrs.ia_ctime = attr->ia_ctime;
11884 +       }
11885 +       if(attr->ia_valid & ATTR_ATIME_SET){
11886 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
11887 +       }
11888 +       if(attr->ia_valid & ATTR_MTIME_SET){
11889 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
11890 +       }
11891 +       name = dentry_name(dentry, 0);
11892 +       if(name == NULL) return(-ENOMEM);
11893 +       err = set_attr(name, &attrs);
11894 +       kfree(name);
11895 +       if(err)
11896 +               return(err);
11897 +
11898 +       return(inode_setattr(dentry->d_inode, attr));
11899 +}
11900 +
11901 +int hostfs_getattr(struct dentry *dentry, struct iattr *attr)
11902 +{
11903 +       not_implemented();
11904 +       return(-EINVAL);
11905 +}
11906 +
11907 +static struct inode_operations hostfs_iops = {
11908 +       .create         = hostfs_create,
11909 +       .link           = hostfs_link,
11910 +       .unlink         = hostfs_unlink,
11911 +       .symlink        = hostfs_symlink,
11912 +       .mkdir          = hostfs_mkdir,
11913 +       .rmdir          = hostfs_rmdir,
11914 +       .mknod          = hostfs_mknod,
11915 +       .rename         = hostfs_rename,
11916 +       .truncate       = hostfs_truncate,
11917 +       .permission     = hostfs_permission,
11918 +       .setattr        = hostfs_setattr,
11919 +       .getattr        = hostfs_getattr,
11920 +};
11921 +
11922 +static struct inode_operations hostfs_dir_iops = {
11923 +       .create         = hostfs_create,
11924 +       .lookup         = hostfs_lookup,
11925 +       .link           = hostfs_link,
11926 +       .unlink         = hostfs_unlink,
11927 +       .symlink        = hostfs_symlink,
11928 +       .mkdir          = hostfs_mkdir,
11929 +       .rmdir          = hostfs_rmdir,
11930 +       .mknod          = hostfs_mknod,
11931 +       .rename         = hostfs_rename,
11932 +       .truncate       = hostfs_truncate,
11933 +       .permission     = hostfs_permission,
11934 +       .setattr        = hostfs_setattr,
11935 +       .getattr        = hostfs_getattr,
11936 +};
11937 +
11938 +int hostfs_link_readpage(struct file *file, struct page *page)
11939 +{
11940 +       char *buffer, *name;
11941 +       long long start;
11942 +       int err;
11943 +
11944 +       start = page->index << PAGE_CACHE_SHIFT;
11945 +       buffer = kmap(page);
11946 +       name = inode_name(page->mapping->host, 0);
11947 +       if(name == NULL) return(-ENOMEM);
11948 +       err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
11949 +       kfree(name);
11950 +       if(err == PAGE_CACHE_SIZE)
11951 +               err = -E2BIG;
11952 +       else if(err > 0){
11953 +               flush_dcache_page(page);
11954 +               SetPageUptodate(page);
11955 +               if (PageError(page)) ClearPageError(page);
11956 +               err = 0;
11957 +       }
11958 +       kunmap(page);
11959 +       UnlockPage(page);
11960 +       return(err);
11961 +}
11962 +
11963 +static struct address_space_operations hostfs_link_aops = {
11964 +       .readpage       = hostfs_link_readpage,
11965 +};
11966 +
11967 +static struct super_block *hostfs_read_super_common(struct super_block *sb, 
11968 +                                                   char *data)
11969 +{
11970 +       struct inode *root_inode;
11971 +       char *name;
11972 +
11973 +       sb->s_blocksize = 1024;
11974 +       sb->s_blocksize_bits = 10;
11975 +       sb->s_magic = HOSTFS_SUPER_MAGIC;
11976 +       sb->s_op = &hostfs_sbops;
11977 +       if((data == NULL) || (*((char *) data) == '\0')) data = root_ino;
11978 +       name = kmalloc(strlen(data) + 1, GFP_KERNEL);
11979 +       if(name == NULL) return(NULL);
11980 +       strcpy(name, data);
11981 +       root_inode = get_inode(sb, NULL, NULL);
11982 +       if(root_inode == NULL)
11983 +               goto out_free;
11984 +
11985 +       root_inode->u.hostfs_i.host_filename = name;
11986 +       sb->s_root = d_alloc_root(root_inode);
11987 +       if(read_inode(root_inode))
11988 +               goto out_put;
11989 +       return(sb);
11990 +
11991 + out_free:
11992 +       kfree(name);
11993 + out_put:
11994 +       iput(root_inode);
11995 +       return(NULL);
11996 +}
11997 +
11998 +struct super_block *hostfs_read_super(struct super_block *sb, void *data, 
11999 +                                     int silent)
12000 +{
12001 +       return(hostfs_read_super_common(sb, data));
12002 +}
12003 +
12004 +DECLARE_FSTYPE(hostfs_type, "hostfs", hostfs_read_super, 0);
12005 +
12006 +static int __init init_hostfs(void)
12007 +{
12008 +       return(register_filesystem(&hostfs_type));
12009 +}
12010 +
12011 +static void __exit exit_hostfs(void)
12012 +{
12013 +       unregister_filesystem(&hostfs_type);
12014 +}
12015 +
12016 +module_init(init_hostfs)
12017 +module_exit(exit_hostfs)
12018 +MODULE_LICENSE("GPL");
12019 +
12020 +/*
12021 + * Overrides for Emacs so that we follow Linus's tabbing style.
12022 + * Emacs will notice this stuff at the end of the file and automatically
12023 + * adjust the settings for this buffer only.  This must remain at the end
12024 + * of the file.
12025 + * ---------------------------------------------------------------------------
12026 + * Local variables:
12027 + * c-file-style: "linux"
12028 + * End:
12029 + */
12030 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_user.c um/arch/um/fs/hostfs/hostfs_user.c
12031 --- orig/arch/um/fs/hostfs/hostfs_user.c        1969-12-31 19:00:00.000000000 -0500
12032 +++ um/arch/um/fs/hostfs/hostfs_user.c  2003-05-22 11:06:46.000000000 -0400
12033 @@ -0,0 +1,347 @@
12034 +/* 
12035 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12036 + * Licensed under the GPL
12037 + */
12038 +
12039 +#include <unistd.h>
12040 +#include <stdio.h>
12041 +#include <fcntl.h>
12042 +#include <dirent.h>
12043 +#include <errno.h>
12044 +#include <utime.h>
12045 +#include <string.h>
12046 +#include <sys/stat.h>
12047 +#include <sys/time.h>
12048 +#include <sys/vfs.h>
12049 +#include "hostfs.h"
12050 +#include "kern_util.h"
12051 +#include "user.h"
12052 +
12053 +int stat_file(const char *path, int *dev_out, unsigned long long *inode_out,
12054 +             int *mode_out, int *nlink_out, int *uid_out, int *gid_out, 
12055 +             unsigned long long *size_out, unsigned long *atime_out,
12056 +             unsigned long *mtime_out, unsigned long *ctime_out,
12057 +             int *blksize_out, unsigned long long *blocks_out)
12058 +{
12059 +       struct stat64 buf;
12060 +
12061 +       if(lstat64(path, &buf) < 0) 
12062 +               return(-errno);
12063 +       if(dev_out != NULL) *dev_out = buf.st_dev;
12064 +
12065 +       /* See the Makefile for why STAT64_INO_FIELD is passed in
12066 +        * by the build
12067 +        */
12068 +       if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
12069 +       if(mode_out != NULL) *mode_out = buf.st_mode;
12070 +       if(nlink_out != NULL) *nlink_out = buf.st_nlink;
12071 +       if(uid_out != NULL) *uid_out = buf.st_uid;
12072 +       if(gid_out != NULL) *gid_out = buf.st_gid;
12073 +       if(size_out != NULL) *size_out = buf.st_size;
12074 +       if(atime_out != NULL) *atime_out = buf.st_atime;
12075 +       if(mtime_out != NULL) *mtime_out = buf.st_mtime;
12076 +       if(ctime_out != NULL) *ctime_out = buf.st_ctime;
12077 +       if(blksize_out != NULL) *blksize_out = buf.st_blksize;
12078 +       if(blocks_out != NULL) *blocks_out = buf.st_blocks;
12079 +       return(0);
12080 +}
12081 +
12082 +int file_type(const char *path, int *rdev)
12083 +{
12084 +       struct stat64 buf;
12085 +
12086 +       if(lstat64(path, &buf) < 0) 
12087 +               return(-errno);
12088 +       if(rdev != NULL) 
12089 +               *rdev = buf.st_rdev;
12090 +
12091 +       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
12092 +       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
12093 +       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
12094 +       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
12095 +       else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
12096 +       else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
12097 +       else return(OS_TYPE_FILE);
12098 +}
12099 +
12100 +int access_file(char *path, int r, int w, int x)
12101 +{
12102 +       int mode = 0;
12103 +
12104 +       if(r) mode = R_OK;
12105 +       if(w) mode |= W_OK;
12106 +       if(x) mode |= X_OK;
12107 +       if(access(path, mode) != 0) return(-errno);
12108 +       else return(0);
12109 +}
12110 +
12111 +int open_file(char *path, int r, int w, int append)
12112 +{
12113 +       int mode = 0, fd;
12114 +
12115 +       if(r && !w) 
12116 +               mode = O_RDONLY;
12117 +       else if(!r && w) 
12118 +               mode = O_WRONLY;
12119 +       else if(r && w) 
12120 +               mode = O_RDWR;
12121 +       else panic("Impossible mode in open_file");
12122 +
12123 +       if(append)
12124 +               mode |= O_APPEND;
12125 +       fd = open64(path, mode);
12126 +       if(fd < 0) return(-errno);
12127 +       else return(fd);
12128 +}
12129 +
12130 +void *open_dir(char *path, int *err_out)
12131 +{
12132 +       DIR *dir;
12133 +
12134 +       dir = opendir(path);
12135 +       *err_out = errno;
12136 +       if(dir == NULL) return(NULL);
12137 +       return(dir);
12138 +}
12139 +
12140 +char *read_dir(void *stream, unsigned long long *pos, 
12141 +              unsigned long long *ino_out, int *len_out)
12142 +{
12143 +       DIR *dir = stream;
12144 +       struct dirent *ent;
12145 +
12146 +       seekdir(dir, *pos);
12147 +       ent = readdir(dir);
12148 +       if(ent == NULL) return(NULL);
12149 +       *len_out = strlen(ent->d_name);
12150 +       *ino_out = ent->d_ino;
12151 +       *pos = telldir(dir);
12152 +       return(ent->d_name);
12153 +}
12154 +
12155 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
12156 +{
12157 +       int n;
12158 +
12159 +       n = pread64(fd, buf, len, *offset);
12160 +       if(n < 0) return(-errno);
12161 +       *offset += n;
12162 +       return(n);
12163 +}
12164 +
12165 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
12166 +{
12167 +       int n;
12168 +
12169 +       n = pwrite64(fd, buf, len, *offset);
12170 +       if(n < 0) return(-errno);
12171 +       *offset += n;
12172 +       return(n);
12173 +}
12174 +
12175 +int lseek_file(int fd, long long offset, int whence)
12176 +{
12177 +       int ret;
12178 +
12179 +       ret = lseek64(fd, offset, whence);
12180 +       if(ret < 0) return(-errno);
12181 +       return(0);
12182 +}
12183 +
12184 +void close_file(void *stream)
12185 +{
12186 +       close(*((int *) stream));
12187 +}
12188 +
12189 +void close_dir(void *stream)
12190 +{
12191 +       closedir(stream);
12192 +}
12193 +
12194 +int file_create(char *name, int ur, int uw, int ux, int gr, 
12195 +               int gw, int gx, int or, int ow, int ox)
12196 +{
12197 +       int mode, fd;
12198 +
12199 +       mode = 0;
12200 +       mode |= ur ? S_IRUSR : 0;
12201 +       mode |= uw ? S_IWUSR : 0;
12202 +       mode |= ux ? S_IXUSR : 0;
12203 +       mode |= gr ? S_IRGRP : 0;
12204 +       mode |= gw ? S_IWGRP : 0;
12205 +       mode |= gx ? S_IXGRP : 0;
12206 +       mode |= or ? S_IROTH : 0;
12207 +       mode |= ow ? S_IWOTH : 0;
12208 +       mode |= ox ? S_IXOTH : 0;
12209 +       fd = open64(name, O_CREAT | O_RDWR, mode);
12210 +       if(fd < 0) 
12211 +               return(-errno);
12212 +       return(fd);
12213 +}
12214 +
12215 +int set_attr(const char *file, struct hostfs_iattr *attrs)
12216 +{
12217 +       struct utimbuf buf;
12218 +       int err, ma;
12219 +
12220 +       if(attrs->ia_valid & HOSTFS_ATTR_MODE){
12221 +               if(chmod(file, attrs->ia_mode) != 0) return(-errno);
12222 +       }
12223 +       if(attrs->ia_valid & HOSTFS_ATTR_UID){
12224 +               if(chown(file, attrs->ia_uid, -1)) return(-errno);
12225 +       }
12226 +       if(attrs->ia_valid & HOSTFS_ATTR_GID){
12227 +               if(chown(file, -1, attrs->ia_gid)) return(-errno);
12228 +       }
12229 +       if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
12230 +               if(truncate(file, attrs->ia_size)) return(-errno);
12231 +       }
12232 +       ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
12233 +       if((attrs->ia_valid & ma) == ma){
12234 +               buf.actime = attrs->ia_atime;
12235 +               buf.modtime = attrs->ia_mtime;
12236 +               if(utime(file, &buf) != 0) return(-errno);
12237 +       }
12238 +       else {
12239 +               if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
12240 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
12241 +                                       NULL, NULL, NULL, &buf.modtime, NULL,
12242 +                                       NULL, NULL);
12243 +                       if(err != 0) return(err);
12244 +                       buf.actime = attrs->ia_atime;
12245 +                       if(utime(file, &buf) != 0) return(-errno);
12246 +               }
12247 +               if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
12248 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
12249 +                                       NULL, NULL, &buf.actime, NULL, NULL, 
12250 +                                       NULL, NULL);
12251 +                       if(err != 0) return(err);
12252 +                       buf.modtime = attrs->ia_mtime;
12253 +                       if(utime(file, &buf) != 0) return(-errno);
12254 +               }
12255 +       }
12256 +       if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
12257 +       if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
12258 +               err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
12259 +                               NULL, NULL, &attrs->ia_atime, &attrs->ia_mtime,
12260 +                               NULL, NULL, NULL);
12261 +               if(err != 0) return(err);
12262 +       }
12263 +       return(0);
12264 +}
12265 +
12266 +int make_symlink(const char *from, const char *to)
12267 +{
12268 +       int err;
12269 +
12270 +       err = symlink(to, from);
12271 +       if(err) return(-errno);
12272 +       return(0);
12273 +}
12274 +
12275 +int unlink_file(const char *file)
12276 +{
12277 +       int err;
12278 +
12279 +       err = unlink(file);
12280 +       if(err) return(-errno);
12281 +       return(0);
12282 +}
12283 +
12284 +int do_mkdir(const char *file, int mode)
12285 +{
12286 +       int err;
12287 +
12288 +       err = mkdir(file, mode);
12289 +       if(err) return(-errno);
12290 +       return(0);
12291 +}
12292 +
12293 +int do_rmdir(const char *file)
12294 +{
12295 +       int err;
12296 +
12297 +       err = rmdir(file);
12298 +       if(err) return(-errno);
12299 +       return(0);
12300 +}
12301 +
12302 +int do_mknod(const char *file, int mode, int dev)
12303 +{
12304 +       int err;
12305 +
12306 +       err = mknod(file, mode, dev);
12307 +       if(err) return(-errno);
12308 +       return(0);
12309 +}
12310 +
12311 +int link_file(const char *to, const char *from)
12312 +{
12313 +       int err;
12314 +
12315 +       err = link(to, from);
12316 +       if(err) return(-errno);
12317 +       return(0);
12318 +}
12319 +
12320 +int do_readlink(char *file, char *buf, int size)
12321 +{
12322 +       int n;
12323 +
12324 +       n = readlink(file, buf, size);
12325 +       if(n < 0) 
12326 +               return(-errno);
12327 +       if(n < size) 
12328 +               buf[n] = '\0';
12329 +       return(n);
12330 +}
12331 +
12332 +int rename_file(char *from, char *to)
12333 +{
12334 +       int err;
12335 +
12336 +       err = rename(from, to);
12337 +       if(err < 0) return(-errno);
12338 +       return(0);      
12339 +}
12340 +
12341 +int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
12342 +             long long *bfree_out, long long *bavail_out, 
12343 +             long long *files_out, long long *ffree_out,
12344 +             void *fsid_out, int fsid_size, long *namelen_out, 
12345 +             long *spare_out)
12346 +{
12347 +       struct statfs64 buf;
12348 +       int err;
12349 +
12350 +       err = statfs64(root, &buf);
12351 +       if(err < 0) return(-errno);
12352 +       *bsize_out = buf.f_bsize;
12353 +       *blocks_out = buf.f_blocks;
12354 +       *bfree_out = buf.f_bfree;
12355 +       *bavail_out = buf.f_bavail;
12356 +       *files_out = buf.f_files;
12357 +       *ffree_out = buf.f_ffree;
12358 +       memcpy(fsid_out, &buf.f_fsid, 
12359 +              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
12360 +              sizeof(buf.f_fsid));
12361 +       *namelen_out = buf.f_namelen;
12362 +       spare_out[0] = buf.f_spare[0];
12363 +       spare_out[1] = buf.f_spare[1];
12364 +       spare_out[2] = buf.f_spare[2];
12365 +       spare_out[3] = buf.f_spare[3];
12366 +       spare_out[4] = buf.f_spare[4];
12367 +       spare_out[5] = buf.f_spare[5];
12368 +       return(0);
12369 +}
12370 +
12371 +/*
12372 + * Overrides for Emacs so that we follow Linus's tabbing style.
12373 + * Emacs will notice this stuff at the end of the file and automatically
12374 + * adjust the settings for this buffer only.  This must remain at the end
12375 + * of the file.
12376 + * ---------------------------------------------------------------------------
12377 + * Local variables:
12378 + * c-file-style: "linux"
12379 + * End:
12380 + */
12381 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/Makefile um/arch/um/fs/hostfs/Makefile
12382 --- orig/arch/um/fs/hostfs/Makefile     1969-12-31 19:00:00.000000000 -0500
12383 +++ um/arch/um/fs/hostfs/Makefile       2002-10-23 21:08:04.000000000 -0400
12384 @@ -0,0 +1,24 @@
12385 +# 
12386 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12387 +# Licensed under the GPL
12388 +#
12389 +
12390 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
12391 +# to __st_ino.  It stayed in the same place, so as long as the correct name
12392 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
12393 +
12394 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
12395 +                               echo __)st_ino
12396 +
12397 +USER_CFLAGS := $(USER_CFLAGS) -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
12398 +
12399 +O_TARGET := hostfs.o
12400 +obj-y = hostfs_kern.o hostfs_user.o
12401 +obj-m = $(O_TARGET)
12402 +
12403 +USER_OBJS = $(filter %_user.o,$(obj-y))
12404 +
12405 +include $(TOPDIR)/Rules.make
12406 +
12407 +$(USER_OBJS) : %.o: %.c
12408 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
12409 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/hppfs_kern.c um/arch/um/fs/hppfs/hppfs_kern.c
12410 --- orig/arch/um/fs/hppfs/hppfs_kern.c  1969-12-31 19:00:00.000000000 -0500
12411 +++ um/arch/um/fs/hppfs/hppfs_kern.c    2003-02-27 13:14:26.000000000 -0500
12412 @@ -0,0 +1,725 @@
12413 +/* 
12414 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12415 + * Licensed under the GPL
12416 + */
12417 +
12418 +#include <linux/fs.h>
12419 +#include <linux/module.h>
12420 +#include <linux/slab.h>
12421 +#include <linux/list.h>
12422 +#include <linux/kernel.h>
12423 +#include <linux/ctype.h>
12424 +#include <asm/uaccess.h>
12425 +#include "os.h"
12426 +
12427 +struct hppfs_data {
12428 +       struct list_head list;
12429 +       char contents[PAGE_SIZE - sizeof(struct list_head)];
12430 +};
12431 +
12432 +struct hppfs_private {
12433 +       struct file proc_file;
12434 +       int host_fd;
12435 +       loff_t len;
12436 +       struct hppfs_data *contents;
12437 +};
12438 +
12439 +#define HPPFS_SUPER_MAGIC 0xb00000ee
12440 +
12441 +static struct super_operations hppfs_sbops;
12442 +
12443 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
12444 +                              int *error);
12445 +
12446 +static int is_pid(struct dentry *dentry)
12447 +{
12448 +       struct super_block *sb;
12449 +       int i;
12450 +
12451 +       sb = dentry->d_sb;
12452 +       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
12453 +               return(0);
12454 +
12455 +       for(i = 0; i < dentry->d_name.len; i++){
12456 +               if(!isdigit(dentry->d_name.name[i]))
12457 +                       return(0);
12458 +       }
12459 +       return(1);
12460 +}
12461 +
12462 +static char *dentry_name(struct dentry *dentry, int extra)
12463 +{
12464 +       struct dentry *parent;
12465 +       char *root, *name;
12466 +       const char *seg_name;
12467 +       int len, seg_len;
12468 +
12469 +       len = 0;
12470 +       parent = dentry;
12471 +       while(parent->d_parent != parent){
12472 +               if(is_pid(parent))
12473 +                       len += strlen("pid") + 1;
12474 +               else len += parent->d_name.len + 1;
12475 +               parent = parent->d_parent;
12476 +       }
12477 +       
12478 +       root = "proc";
12479 +       len += strlen(root);
12480 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
12481 +       if(name == NULL) return(NULL);
12482 +
12483 +       name[len] = '\0';
12484 +       parent = dentry;
12485 +       while(parent->d_parent != parent){
12486 +               if(is_pid(parent)){
12487 +                       seg_name = "pid";
12488 +                       seg_len = strlen("pid");
12489 +               }
12490 +               else {
12491 +                       seg_name = parent->d_name.name;
12492 +                       seg_len = parent->d_name.len;
12493 +               }
12494 +
12495 +               len -= seg_len + 1;
12496 +               name[len] = '/';
12497 +               strncpy(&name[len + 1], seg_name, seg_len);
12498 +               parent = parent->d_parent;
12499 +       }
12500 +       strncpy(name, root, strlen(root));
12501 +       return(name);
12502 +}
12503 +
12504 +struct dentry_operations hppfs_dentry_ops = {
12505 +};
12506 +
12507 +static int file_removed(struct dentry *dentry, const char *file)
12508 +{
12509 +       char *host_file;
12510 +       int extra, fd;
12511 +
12512 +       extra = 0;
12513 +       if(file != NULL) extra += strlen(file) + 1;
12514 +
12515 +       host_file = dentry_name(dentry, extra + strlen("/remove"));
12516 +       if(host_file == NULL){
12517 +               printk("file_removed : allocation failed\n");
12518 +               return(-ENOMEM);
12519 +       }
12520 +
12521 +       if(file != NULL){
12522 +               strcat(host_file, "/");
12523 +               strcat(host_file, file);
12524 +       }
12525 +       strcat(host_file, "/remove");
12526 +
12527 +       fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
12528 +       kfree(host_file);
12529 +       if(fd > 0){
12530 +               os_close_file(fd);
12531 +               return(1);
12532 +       }
12533 +       return(0);
12534 +}
12535 +
12536 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry)
12537 +{
12538 +       struct dentry *proc_dentry;
12539 +       struct inode *inode;
12540 +       int err, deleted;
12541 +
12542 +       deleted = file_removed(dentry, NULL);
12543 +       if(deleted < 0)
12544 +               return(ERR_PTR(deleted));
12545 +       else if(deleted)
12546 +               return(ERR_PTR(-ENOENT));
12547 +
12548 +       proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry);
12549 +       if(IS_ERR(proc_dentry))
12550 +               return(proc_dentry);
12551 +
12552 +       inode = get_inode(ino->i_sb, proc_dentry, &err);
12553 +       if(err != 0) 
12554 +               return(ERR_PTR(err));
12555 +
12556 +       d_add(dentry, inode);
12557 +       dentry->d_op = &hppfs_dentry_ops;
12558 +       return(NULL);
12559 +}
12560 +
12561 +static struct inode_operations hppfs_file_iops = {
12562 +};
12563 +
12564 +static struct inode_operations hppfs_dir_iops = {
12565 +       .lookup         = hppfs_lookup,
12566 +};
12567 +
12568 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
12569 +                        loff_t *ppos, int is_user)
12570 +{
12571 +       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
12572 +       ssize_t n;
12573 +
12574 +       read = file->f_dentry->d_inode->i_fop->read;
12575 +
12576 +       if(!is_user)
12577 +               set_fs(KERNEL_DS);
12578 +               
12579 +       n = (*read)(file, buf, count, &file->f_pos);
12580 +
12581 +       if(!is_user)
12582 +               set_fs(USER_DS);
12583 +
12584 +       if(ppos) *ppos = file->f_pos;
12585 +       return(n);
12586 +}
12587 +
12588 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
12589 +{
12590 +       ssize_t n;
12591 +       int cur, err;
12592 +       char *new_buf;
12593 +
12594 +       n = -ENOMEM;
12595 +       new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
12596 +       if(new_buf == NULL){
12597 +               printk("hppfs_read_file : kmalloc failed\n");
12598 +               goto out;
12599 +       }
12600 +       n = 0;
12601 +       while(count > 0){
12602 +               cur = min_t(ssize_t, count, PAGE_SIZE);
12603 +               err = os_read_file(fd, new_buf, cur);
12604 +               if(err < 0){
12605 +                       printk("hppfs_read : read failed, errno = %d\n",
12606 +                              count);
12607 +                       n = err;
12608 +                       goto out_free;
12609 +               }
12610 +               else if(err == 0)
12611 +                       break;
12612 +
12613 +               if(copy_to_user(buf, new_buf, err)){
12614 +                       n = -EFAULT;
12615 +                       goto out_free;
12616 +               }
12617 +               n += err;
12618 +               count -= err;
12619 +       }
12620 + out_free:
12621 +       kfree(new_buf);
12622 + out:
12623 +       return(n);
12624 +}
12625 +
12626 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
12627 +                         loff_t *ppos)
12628 +{
12629 +       struct hppfs_private *hppfs = file->private_data;
12630 +       struct hppfs_data *data;
12631 +       loff_t off;
12632 +       int err;
12633 +
12634 +       if(hppfs->contents != NULL){
12635 +               if(*ppos >= hppfs->len) return(0);
12636 +
12637 +               data = hppfs->contents;
12638 +               off = *ppos;
12639 +               while(off >= sizeof(data->contents)){
12640 +                       data = list_entry(data->list.next, struct hppfs_data,
12641 +                                         list);
12642 +                       off -= sizeof(data->contents);
12643 +               }
12644 +
12645 +               if(off + count > hppfs->len)
12646 +                       count = hppfs->len - off;
12647 +               copy_to_user(buf, &data->contents[off], count);
12648 +               *ppos += count;
12649 +       }
12650 +       else if(hppfs->host_fd != -1){
12651 +               err = os_seek_file(hppfs->host_fd, *ppos);
12652 +               if(err){
12653 +                       printk("hppfs_read : seek failed, errno = %d\n", err);
12654 +                       return(err);
12655 +               }
12656 +               count = hppfs_read_file(hppfs->host_fd, buf, count);
12657 +               if(count > 0)
12658 +                       *ppos += count;
12659 +       }
12660 +       else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
12661 +
12662 +       return(count);
12663 +}
12664 +
12665 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
12666 +                          loff_t *ppos)
12667 +{
12668 +       struct hppfs_private *data = file->private_data;
12669 +       struct file *proc_file = &data->proc_file;
12670 +       ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
12671 +       int err;
12672 +
12673 +       write = proc_file->f_dentry->d_inode->i_fop->write;
12674 +
12675 +       proc_file->f_pos = file->f_pos;
12676 +       err = (*write)(proc_file, buf, len, &proc_file->f_pos);
12677 +       file->f_pos = proc_file->f_pos;
12678 +
12679 +       return(err);
12680 +}
12681 +
12682 +static int open_host_sock(char *host_file, int *filter_out)
12683 +{
12684 +       char *end;
12685 +       int fd;
12686 +
12687 +       end = &host_file[strlen(host_file)];
12688 +       strcpy(end, "/rw");
12689 +       *filter_out = 1;
12690 +       fd = os_connect_socket(host_file);
12691 +       if(fd > 0)
12692 +               return(fd);
12693 +
12694 +       strcpy(end, "/r");
12695 +       *filter_out = 0;
12696 +       fd = os_connect_socket(host_file);
12697 +       return(fd);
12698 +}
12699 +
12700 +static void free_contents(struct hppfs_data *head)
12701 +{
12702 +       struct hppfs_data *data;
12703 +       struct list_head *ele, *next;
12704 +
12705 +       if(head == NULL) return;
12706 +
12707 +       list_for_each_safe(ele, next, &head->list){
12708 +               data = list_entry(ele, struct hppfs_data, list);
12709 +               kfree(data);
12710 +       }
12711 +       kfree(head);
12712 +}
12713 +
12714 +static struct hppfs_data *hppfs_get_data(int fd, int filter, 
12715 +                                        struct file *proc_file, 
12716 +                                        struct file *hppfs_file, 
12717 +                                        loff_t *size_out)
12718 +{
12719 +       struct hppfs_data *data, *new, *head;
12720 +       int n, err;
12721 +
12722 +       err = -ENOMEM;
12723 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
12724 +       if(data == NULL){
12725 +               printk("hppfs_get_data : head allocation failed\n");
12726 +               goto failed;
12727 +       }
12728 +
12729 +       INIT_LIST_HEAD(&data->list);
12730 +
12731 +       head = data;
12732 +       *size_out = 0;
12733 +
12734 +       if(filter){
12735 +               while((n = read_proc(proc_file, data->contents,
12736 +                                    sizeof(data->contents), NULL, 0)) > 0)
12737 +                       os_write_file(fd, data->contents, n);
12738 +               err = os_shutdown_socket(fd, 0, 1);
12739 +               if(err){
12740 +                       printk("hppfs_get_data : failed to shut down "
12741 +                              "socket\n");
12742 +                       goto failed_free;
12743 +               }
12744 +       }
12745 +       while(1){
12746 +               n = os_read_file(fd, data->contents, sizeof(data->contents));
12747 +               if(n < 0){
12748 +                       err = n;
12749 +                       printk("hppfs_get_data : read failed, errno = %d\n",
12750 +                              err);
12751 +                       goto failed_free;
12752 +               }
12753 +               else if(n == 0)
12754 +                       break;
12755 +
12756 +               *size_out += n;
12757 +
12758 +               if(n < sizeof(data->contents))
12759 +                       break;
12760 +
12761 +               new = kmalloc(sizeof(*data), GFP_KERNEL);
12762 +               if(new == 0){
12763 +                       printk("hppfs_get_data : data allocation failed\n");
12764 +                       err = -ENOMEM;
12765 +                       goto failed_free;
12766 +               }
12767 +       
12768 +               INIT_LIST_HEAD(&new->list);
12769 +               list_add(&new->list, &data->list);
12770 +               data = new;
12771 +       }
12772 +       return(head);
12773 +
12774 + failed_free:
12775 +       free_contents(head);
12776 + failed:               
12777 +       return(ERR_PTR(err));
12778 +}
12779 +
12780 +static struct hppfs_private *hppfs_data(void)
12781 +{
12782 +       struct hppfs_private *data;
12783 +
12784 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
12785 +       if(data == NULL)
12786 +               return(data);
12787 +
12788 +       *data = ((struct hppfs_private ) { .host_fd             = -1,
12789 +                                          .len                 = -1,
12790 +                                          .contents            = NULL } );
12791 +       return(data);
12792 +}
12793 +
12794 +static int hppfs_open(struct inode *inode, struct file *file)
12795 +{
12796 +       struct hppfs_private *data;
12797 +       struct dentry *proc_dentry;
12798 +       char *host_file;
12799 +       int err, fd, type, filter;
12800 +
12801 +       err = -ENOMEM;
12802 +       data = hppfs_data();
12803 +       if(data == NULL)
12804 +               goto out;
12805 +
12806 +       host_file = dentry_name(file->f_dentry, strlen("/rw"));
12807 +       if(host_file == NULL)
12808 +               goto out_free2;
12809 +
12810 +       proc_dentry = inode->u.hppfs_i.proc_dentry;
12811 +       err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
12812 +       if(err)
12813 +               goto out_free1;
12814 +
12815 +       type = os_file_type(host_file);
12816 +       if(type == OS_TYPE_FILE){
12817 +               fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
12818 +               if(fd >= 0) 
12819 +                       data->host_fd = fd;
12820 +               else printk("hppfs_open : failed to open '%s', errno = %d\n",
12821 +                           host_file, -fd);
12822 +
12823 +               data->contents = NULL;
12824 +       }
12825 +       else if(type == OS_TYPE_DIR){
12826 +               fd = open_host_sock(host_file, &filter);
12827 +               if(fd > 0){
12828 +                       data->contents = hppfs_get_data(fd, filter, 
12829 +                                                       &data->proc_file, 
12830 +                                                       file, &data->len);
12831 +                       if(!IS_ERR(data->contents))
12832 +                               data->host_fd = fd;
12833 +               }
12834 +               else printk("hppfs_open : failed to open a socket in "
12835 +                           "'%s', errno = %d\n", host_file, -fd);
12836 +       }
12837 +       kfree(host_file);
12838 +
12839 +       file->private_data = data;
12840 +       return(0);
12841 +
12842 + out_free1:
12843 +       kfree(host_file);
12844 + out_free2:
12845 +       free_contents(data->contents);
12846 +       kfree(data);
12847 + out:
12848 +       return(err);
12849 +}
12850 +
12851 +static int hppfs_dir_open(struct inode *inode, struct file *file)
12852 +{
12853 +       struct hppfs_private *data;
12854 +       struct dentry *proc_dentry;
12855 +       int err;
12856 +
12857 +       err = -ENOMEM;
12858 +       data = hppfs_data();
12859 +       if(data == NULL)
12860 +               goto out;
12861 +
12862 +       proc_dentry = inode->u.hppfs_i.proc_dentry;
12863 +       err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
12864 +       if(err)
12865 +               goto out_free;
12866 +
12867 +       file->private_data = data;
12868 +       return(0);
12869 +
12870 + out_free:
12871 +       kfree(data);
12872 + out:
12873 +       return(err);
12874 +}
12875 +
12876 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
12877 +{
12878 +       struct hppfs_private *data = file->private_data;
12879 +       struct file *proc_file = &data->proc_file;
12880 +       loff_t (*llseek)(struct file *, loff_t, int);
12881 +       loff_t ret;
12882 +
12883 +       llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
12884 +       if(llseek != NULL){
12885 +               ret = (*llseek)(proc_file, off, where);
12886 +               if(ret < 0)
12887 +                       return(ret);
12888 +       }
12889 +
12890 +       return(default_llseek(file, off, where));
12891 +}
12892 +
12893 +struct hppfs_dirent {
12894 +       void *vfs_dirent;
12895 +       filldir_t filldir;
12896 +       struct dentry *dentry;
12897 +};
12898 +
12899 +static int hppfs_filldir(void *d, const char *name, int size, 
12900 +                        loff_t offset, ino_t inode, unsigned int type)
12901 +{
12902 +       struct hppfs_dirent *dirent = d;
12903 +
12904 +       if(file_removed(dirent->dentry, name))
12905 +               return(0);
12906 +
12907 +       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
12908 +                                 inode, type));
12909 +}
12910 +
12911 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
12912 +{
12913 +       struct hppfs_private *data = file->private_data;
12914 +       struct file *proc_file = &data->proc_file;
12915 +       int (*readdir)(struct file *, void *, filldir_t);
12916 +       struct hppfs_dirent dirent = ((struct hppfs_dirent)
12917 +                                     { .vfs_dirent     = ent,
12918 +                                       .filldir        = filldir,
12919 +                                       .dentry         = file->f_dentry } );
12920 +       int err;
12921 +
12922 +       readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
12923 +
12924 +       proc_file->f_pos = file->f_pos;
12925 +       err = (*readdir)(proc_file, &dirent, hppfs_filldir);
12926 +       file->f_pos = proc_file->f_pos;
12927 +
12928 +       return(err);
12929 +}
12930 +
12931 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
12932 +{
12933 +       return(0);
12934 +}
12935 +
12936 +static struct file_operations hppfs_file_fops = {
12937 +       .owner          = NULL,
12938 +       .llseek         = hppfs_llseek,
12939 +       .read           = hppfs_read,
12940 +       .write          = hppfs_write,
12941 +       .open           = hppfs_open,
12942 +};
12943 +
12944 +static struct file_operations hppfs_dir_fops = {
12945 +       .owner          = NULL,
12946 +       .readdir        = hppfs_readdir,
12947 +       .open           = hppfs_dir_open,
12948 +       .fsync          = hppfs_fsync,
12949 +};
12950 +
12951 +static int hppfs_statfs(struct super_block *sb, struct statfs *sf)
12952 +{
12953 +       sf->f_blocks = 0;
12954 +       sf->f_bfree = 0;
12955 +       sf->f_bavail = 0;
12956 +       sf->f_files = 0;
12957 +       sf->f_ffree = 0;
12958 +       sf->f_type = HPPFS_SUPER_MAGIC;
12959 +       return(0);
12960 +}
12961 +
12962 +static struct super_operations hppfs_sbops = { 
12963 +       .put_inode      = force_delete,
12964 +       .delete_inode   = NULL,
12965 +       .statfs         = hppfs_statfs,
12966 +};
12967 +
12968 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
12969 +{
12970 +       struct file proc_file;
12971 +       struct dentry *proc_dentry;
12972 +       int (*readlink)(struct dentry *, char *, int);
12973 +       int err, n;
12974 +
12975 +       proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
12976 +       err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
12977 +       if(err) 
12978 +               return(err);
12979 +
12980 +       readlink = proc_dentry->d_inode->i_op->readlink;
12981 +       n = (*readlink)(proc_dentry, buffer, buflen);
12982 +
12983 +       if(proc_file.f_op->release)
12984 +               (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
12985 +       
12986 +       return(n);
12987 +}
12988 +
12989 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
12990 +{
12991 +       struct file proc_file;
12992 +       struct dentry *proc_dentry;
12993 +       int (*follow_link)(struct dentry *, struct nameidata *);
12994 +       int err, n;
12995 +
12996 +       proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
12997 +       err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
12998 +       if(err) 
12999 +               return(err);
13000 +
13001 +       follow_link = proc_dentry->d_inode->i_op->follow_link;
13002 +       n = (*follow_link)(proc_dentry, nd);
13003 +
13004 +       if(proc_file.f_op->release)
13005 +               (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
13006 +       
13007 +       return(n);
13008 +}
13009 +
13010 +static struct inode_operations hppfs_link_iops = {
13011 +       .readlink       = hppfs_readlink,
13012 +       .follow_link    = hppfs_follow_link,
13013 +};
13014 +
13015 +static void read_inode(struct inode *ino)
13016 +{
13017 +       struct inode *proc_ino;
13018 +
13019 +       proc_ino = ino->u.hppfs_i.proc_dentry->d_inode;
13020 +       ino->i_uid = proc_ino->i_uid;
13021 +       ino->i_gid = proc_ino->i_gid;
13022 +       ino->i_atime = proc_ino->i_atime;
13023 +       ino->i_mtime = proc_ino->i_mtime;
13024 +       ino->i_ctime = proc_ino->i_ctime;
13025 +       ino->i_ino = proc_ino->i_ino;
13026 +       ino->i_dev = proc_ino->i_dev;
13027 +       ino->i_mode = proc_ino->i_mode;
13028 +       ino->i_nlink = proc_ino->i_nlink;
13029 +       ino->i_size = proc_ino->i_size;
13030 +       ino->i_blksize = proc_ino->i_blksize;
13031 +       ino->i_blocks = proc_ino->i_blocks;
13032 +}
13033 +
13034 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
13035 +                              int *error)
13036 +{
13037 +       struct inode *inode;
13038 +       int err = -ENOMEM;
13039 +
13040 +       inode = new_inode(sb);
13041 +       if(inode == NULL) 
13042 +               goto out;
13043 +
13044 +       insert_inode_hash(inode);
13045 +       if(S_ISDIR(dentry->d_inode->i_mode)){
13046 +               inode->i_op = &hppfs_dir_iops;
13047 +               inode->i_fop = &hppfs_dir_fops;
13048 +       }
13049 +       else if(S_ISLNK(dentry->d_inode->i_mode)){
13050 +               inode->i_op = &hppfs_link_iops;
13051 +               inode->i_fop = &hppfs_file_fops;
13052 +       }
13053 +       else {
13054 +               inode->i_op = &hppfs_file_iops;
13055 +               inode->i_fop = &hppfs_file_fops;
13056 +       }
13057 +
13058 +       inode->i_sb = sb;
13059 +       inode->u.hppfs_i.proc_dentry = dentry;
13060 +
13061 +       read_inode(inode);
13062 +       err = 0;
13063 +
13064 +       if(error) *error = err;
13065 +       return(inode);
13066 + out:
13067 +       if(error) *error = err;
13068 +       return(NULL);
13069 +}
13070 +
13071 +static struct super_block *hppfs_read_super(struct super_block *sb, void *d, 
13072 +                                           int silent)
13073 +{
13074 +       struct inode *root_inode;
13075 +       struct file_system_type *procfs;
13076 +       struct super_block *proc_sb;
13077 +
13078 +       procfs = get_fs_type("proc");
13079 +       if(procfs == NULL) 
13080 +               goto out;
13081 +
13082 +       if(list_empty(&procfs->fs_supers))
13083 +               goto out;
13084 +
13085 +       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
13086 +                            s_instances);
13087 +       
13088 +       sb->s_blocksize = 1024;
13089 +       sb->s_blocksize_bits = 10;
13090 +       sb->s_magic = HPPFS_SUPER_MAGIC;
13091 +       sb->s_op = &hppfs_sbops;
13092 +
13093 +       dget(proc_sb->s_root);
13094 +       root_inode = get_inode(sb, proc_sb->s_root, NULL);
13095 +       if(root_inode == NULL)
13096 +               goto out_dput;
13097 +
13098 +       sb->s_root = d_alloc_root(root_inode);
13099 +       if(sb->s_root == NULL)
13100 +               goto out_put;
13101 +
13102 +       return(sb);
13103 +
13104 + out_put:
13105 +       iput(root_inode);
13106 + out_dput:
13107 +       dput(proc_sb->s_root);
13108 + out:
13109 +       return(NULL);
13110 +}
13111 +
13112 +DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0);
13113 +
13114 +static int __init init_hppfs(void)
13115 +{
13116 +       return(register_filesystem(&hppfs_type));
13117 +}
13118 +
13119 +static void __exit exit_hppfs(void)
13120 +{
13121 +       unregister_filesystem(&hppfs_type);
13122 +}
13123 +
13124 +module_init(init_hppfs)
13125 +module_exit(exit_hppfs)
13126 +MODULE_LICENSE("GPL");
13127 +
13128 +/*
13129 + * Overrides for Emacs so that we follow Linus's tabbing style.
13130 + * Emacs will notice this stuff at the end of the file and automatically
13131 + * adjust the settings for this buffer only.  This must remain at the end
13132 + * of the file.
13133 + * ---------------------------------------------------------------------------
13134 + * Local variables:
13135 + * c-file-style: "linux"
13136 + * End:
13137 + */
13138 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/Makefile um/arch/um/fs/hppfs/Makefile
13139 --- orig/arch/um/fs/hppfs/Makefile      1969-12-31 19:00:00.000000000 -0500
13140 +++ um/arch/um/fs/hppfs/Makefile        2002-10-23 21:08:04.000000000 -0400
13141 @@ -0,0 +1,10 @@
13142 +O_TARGET := hppfs.o
13143 +obj-y = hppfs_kern.o #hppfs_user.o
13144 +obj-m = $(O_TARGET)
13145 +
13146 +CFLAGS_hppfs_kern.o := $(CFLAGS)
13147 +#CFLAGS_hppfs_user.o := $(USER_CFLAGS)
13148 +
13149 +override CFLAGS =  
13150 +
13151 +include $(TOPDIR)/Rules.make
13152 diff -Naur -X ../exclude-files orig/arch/um/fs/Makefile um/arch/um/fs/Makefile
13153 --- orig/arch/um/fs/Makefile    1969-12-31 19:00:00.000000000 -0500
13154 +++ um/arch/um/fs/Makefile      2002-10-23 21:08:04.000000000 -0400
13155 @@ -0,0 +1,23 @@
13156 +# 
13157 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13158 +# Licensed under the GPL
13159 +#
13160 +
13161 +O_TARGET := built-in.o
13162 +
13163 +subdir-y =
13164 +subdir-m =
13165 +
13166 +subdir-$(CONFIG_HOSTFS) += hostfs
13167 +subdir-$(CONFIG_HPPFS) += hppfs
13168 +
13169 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
13170 +obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o))
13171 +
13172 +include $(TOPDIR)/Rules.make
13173 +
13174 +dep:
13175 +
13176 +clean:
13177 +
13178 +archmrproper:
13179 diff -Naur -X ../exclude-files orig/arch/um/include/2_5compat.h um/arch/um/include/2_5compat.h
13180 --- orig/arch/um/include/2_5compat.h    1969-12-31 19:00:00.000000000 -0500
13181 +++ um/arch/um/include/2_5compat.h      2003-02-27 20:15:19.000000000 -0500
13182 @@ -0,0 +1,46 @@
13183 +/* 
13184 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
13185 + * Licensed under the GPL
13186 + */
13187 +
13188 +#ifndef __2_5_COMPAT_H__
13189 +#define __2_5_COMPAT_H__
13190 +
13191 +#include "linux/version.h"
13192 +
13193 +#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
13194 +       name :          dev_name, \
13195 +       write :         write_proc, \
13196 +       read :          NULL, \
13197 +       device :        device_proc, \
13198 +       unblank :       NULL, \
13199 +       setup :         setup_proc, \
13200 +       flags :         f, \
13201 +       index :         -1, \
13202 +       cflag :         0, \
13203 +       next :          NULL \
13204 +}
13205 +
13206 +#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP)
13207 +
13208 +#define ELV_NOOP ELEVATOR_NOOP
13209 +
13210 +#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes
13211 +
13212 +#define IS_WRITE(req) ((req)->cmd == WRITE)
13213 +
13214 +#define SET_PRI(task) \
13215 +       do { (task)->nice = 20; (task)->counter = -100; } while(0);
13216 +
13217 +#endif
13218 +
13219 +/*
13220 + * Overrides for Emacs so that we follow Linus's tabbing style.
13221 + * Emacs will notice this stuff at the end of the file and automatically
13222 + * adjust the settings for this buffer only.  This must remain at the end
13223 + * of the file.
13224 + * ---------------------------------------------------------------------------
13225 + * Local variables:
13226 + * c-file-style: "linux"
13227 + * End:
13228 + */
13229 diff -Naur -X ../exclude-files orig/arch/um/include/chan_kern.h um/arch/um/include/chan_kern.h
13230 --- orig/arch/um/include/chan_kern.h    1969-12-31 19:00:00.000000000 -0500
13231 +++ um/arch/um/include/chan_kern.h      2002-11-15 13:32:35.000000000 -0500
13232 @@ -0,0 +1,56 @@
13233 +/* 
13234 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
13235 + * Licensed under the GPL
13236 + */
13237 +
13238 +#ifndef __CHAN_KERN_H__
13239 +#define __CHAN_KERN_H__
13240 +
13241 +#include "linux/tty.h"
13242 +#include "linux/list.h"
13243 +#include "chan_user.h"
13244 +
13245 +struct chan {
13246 +       struct list_head list;
13247 +       char *dev;
13248 +       unsigned int primary:1;
13249 +       unsigned int input:1;
13250 +       unsigned int output:1;
13251 +       unsigned int opened:1;
13252 +       int fd;
13253 +       enum chan_init_pri pri;
13254 +       struct chan_ops *ops;
13255 +       void *data;
13256 +};
13257 +
13258 +extern void chan_interrupt(struct list_head *chans, struct tq_struct *task,
13259 +                          struct tty_struct *tty, int irq, void *dev);
13260 +extern int parse_chan_pair(char *str, struct list_head *chans, int pri, 
13261 +                          int device, struct chan_opts *opts);
13262 +extern int open_chan(struct list_head *chans);
13263 +extern int write_chan(struct list_head *chans, const char *buf, int len,
13264 +                            int write_irq);
13265 +extern int console_write_chan(struct list_head *chans, const char *buf, 
13266 +                             int len);
13267 +extern void close_chan(struct list_head *chans);
13268 +extern void chan_enable_winch(struct list_head *chans, void *line);
13269 +extern void enable_chan(struct list_head *chans, void *data);
13270 +extern int chan_window_size(struct list_head *chans, 
13271 +                            unsigned short *rows_out, 
13272 +                            unsigned short *cols_out);
13273 +extern int chan_out_fd(struct list_head *chans);
13274 +extern int chan_config_string(struct list_head *chans, char *str, int size,
13275 +                             char **error_out);
13276 +
13277 +#endif
13278 +
13279 +/*
13280 + * Overrides for Emacs so that we follow Linus's tabbing style.
13281 + * Emacs will notice this stuff at the end of the file and automatically
13282 + * adjust the settings for this buffer only.  This must remain at the end
13283 + * of the file.
13284 + * ---------------------------------------------------------------------------
13285 + * Local variables:
13286 + * c-file-style: "linux"
13287 + * End:
13288 + */
13289 diff -Naur -X ../exclude-files orig/arch/um/include/chan_user.h um/arch/um/include/chan_user.h
13290 --- orig/arch/um/include/chan_user.h    1969-12-31 19:00:00.000000000 -0500
13291 +++ um/arch/um/include/chan_user.h      2002-11-06 16:44:00.000000000 -0500
13292 @@ -0,0 +1,66 @@
13293 +/* 
13294 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
13295 + * Licensed under the GPL
13296 + */
13297 +
13298 +#ifndef __CHAN_USER_H__
13299 +#define __CHAN_USER_H__
13300 +
13301 +#include "init.h"
13302 +
13303 +struct chan_opts {
13304 +       void (*announce)(char *dev_name, int dev);
13305 +       char *xterm_title;
13306 +       int raw;
13307 +       unsigned long tramp_stack;
13308 +       int in_kernel;
13309 +};
13310 +
13311 +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
13312 +
13313 +struct chan_ops {
13314 +       char *type;
13315 +       void *(*init)(char *, int, struct chan_opts *);
13316 +       int (*open)(int, int, int, void *, char **);
13317 +       void (*close)(int, void *);
13318 +       int (*read)(int, char *, void *);
13319 +       int (*write)(int, const char *, int, void *);
13320 +       int (*console_write)(int, const char *, int, void *);
13321 +       int (*window_size)(int, void *, unsigned short *, unsigned short *);
13322 +       void (*free)(void *);
13323 +       int winch;
13324 +};
13325 +
13326 +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
13327 +       xterm_ops;
13328 +
13329 +extern void generic_close(int fd, void *unused);
13330 +extern int generic_read(int fd, char *c_out, void *unused);
13331 +extern int generic_write(int fd, const char *buf, int n, void *unused);
13332 +extern int generic_console_write(int fd, const char *buf, int n, void *state);
13333 +extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
13334 +                              unsigned short *cols_out);
13335 +extern void generic_free(void *data);
13336 +
13337 +extern void register_winch(int fd, void *device_data);
13338 +extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
13339 +
13340 +#define __channel_help(fn, prefix) \
13341 +__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
13342 +"    Attach a console or serial line to a host channel.  See\n" \
13343 +"    http://user-mode-linux.sourceforge.net/input.html for a complete\n" \
13344 +"    description of this switch.\n\n" \
13345 +);
13346 +
13347 +#endif
13348 +
13349 +/*
13350 + * Overrides for Emacs so that we follow Linus's tabbing style.
13351 + * Emacs will notice this stuff at the end of the file and automatically
13352 + * adjust the settings for this buffer only.  This must remain at the end
13353 + * of the file.
13354 + * ---------------------------------------------------------------------------
13355 + * Local variables:
13356 + * c-file-style: "linux"
13357 + * End:
13358 + */
13359 diff -Naur -X ../exclude-files orig/arch/um/include/choose-mode.h um/arch/um/include/choose-mode.h
13360 --- orig/arch/um/include/choose-mode.h  1969-12-31 19:00:00.000000000 -0500
13361 +++ um/arch/um/include/choose-mode.h    2003-01-17 13:23:32.000000000 -0500
13362 @@ -0,0 +1,35 @@
13363 +/* 
13364 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13365 + * Licensed under the GPL
13366 + */
13367 +
13368 +#ifndef __CHOOSE_MODE_H__
13369 +#define __CHOOSE_MODE_H__
13370 +
13371 +#include "uml-config.h"
13372 +
13373 +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
13374 +#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
13375 +
13376 +#elif defined(UML_CONFIG_MODE_SKAS)
13377 +#define CHOOSE_MODE(tt, skas) (skas)
13378 +
13379 +#elif defined(UML_CONFIG_MODE_TT)
13380 +#define CHOOSE_MODE(tt, skas) (tt)
13381 +#endif
13382 +
13383 +#define CHOOSE_MODE_PROC(tt, skas, args...) \
13384 +       CHOOSE_MODE(tt(args), skas(args))
13385 +
13386 +#endif
13387 +
13388 +/*
13389 + * Overrides for Emacs so that we follow Linus's tabbing style.
13390 + * Emacs will notice this stuff at the end of the file and automatically
13391 + * adjust the settings for this buffer only.  This must remain at the end
13392 + * of the file.
13393 + * ---------------------------------------------------------------------------
13394 + * Local variables:
13395 + * c-file-style: "linux"
13396 + * End:
13397 + */
13398 diff -Naur -X ../exclude-files orig/arch/um/include/frame.h um/arch/um/include/frame.h
13399 --- orig/arch/um/include/frame.h        1969-12-31 19:00:00.000000000 -0500
13400 +++ um/arch/um/include/frame.h  2002-12-02 21:43:03.000000000 -0500
13401 @@ -0,0 +1,53 @@
13402 +/* 
13403 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13404 + * Licensed under the GPL
13405 + */
13406 +
13407 +#ifndef __FRAME_H_
13408 +#define __FRAME_H_
13409 +
13410 +#include "sysdep/frame.h"
13411 +
13412 +struct frame_common {
13413 +       void *data;
13414 +       int len;
13415 +       int sig_index;
13416 +       int sr_index;
13417 +       int sr_relative;
13418 +       int sp_index;
13419 +       struct arch_frame_data arch;
13420 +};
13421 +
13422 +struct sc_frame {
13423 +       struct frame_common common;
13424 +       int sc_index;
13425 +};
13426 +
13427 +extern struct sc_frame signal_frame_sc;
13428 +
13429 +extern struct sc_frame signal_frame_sc_sr;
13430 +
13431 +struct si_frame {
13432 +       struct frame_common common;
13433 +       int sip_index;
13434 +       int si_index;
13435 +       int ucp_index;
13436 +       int uc_index;
13437 +};
13438 +
13439 +extern struct si_frame signal_frame_si;
13440 +
13441 +extern void capture_signal_stack(void);
13442 +
13443 +#endif
13444 +
13445 +/*
13446 + * Overrides for Emacs so that we follow Linus's tabbing style.
13447 + * Emacs will notice this stuff at the end of the file and automatically
13448 + * adjust the settings for this buffer only.  This must remain at the end
13449 + * of the file.
13450 + * ---------------------------------------------------------------------------
13451 + * Local variables:
13452 + * c-file-style: "linux"
13453 + * End:
13454 + */
13455 diff -Naur -X ../exclude-files orig/arch/um/include/frame_kern.h um/arch/um/include/frame_kern.h
13456 --- orig/arch/um/include/frame_kern.h   1969-12-31 19:00:00.000000000 -0500
13457 +++ um/arch/um/include/frame_kern.h     2002-10-23 21:08:04.000000000 -0400
13458 @@ -0,0 +1,34 @@
13459 +/* 
13460 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13461 + * Licensed under the GPL
13462 + */
13463 +
13464 +#ifndef __FRAME_KERN_H_
13465 +#define __FRAME_KERN_H_
13466 +
13467 +#include "frame.h"
13468 +#include "sysdep/frame_kern.h"
13469 +
13470 +extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 
13471 +                                unsigned long handler,
13472 +                                void (*restorer)(void), 
13473 +                                struct pt_regs *regs, 
13474 +                                sigset_t *mask);
13475 +extern int setup_signal_stack_si(unsigned long stack_top, int sig, 
13476 +                                unsigned long handler, 
13477 +                                void (*restorer)(void), 
13478 +                                struct pt_regs *regs, siginfo_t *info, 
13479 +                                sigset_t *mask);
13480 +
13481 +#endif
13482 +
13483 +/*
13484 + * Overrides for Emacs so that we follow Linus's tabbing style.
13485 + * Emacs will notice this stuff at the end of the file and automatically
13486 + * adjust the settings for this buffer only.  This must remain at the end
13487 + * of the file.
13488 + * ---------------------------------------------------------------------------
13489 + * Local variables:
13490 + * c-file-style: "linux"
13491 + * End:
13492 + */
13493 diff -Naur -X ../exclude-files orig/arch/um/include/frame_user.h um/arch/um/include/frame_user.h
13494 --- orig/arch/um/include/frame_user.h   1969-12-31 19:00:00.000000000 -0500
13495 +++ um/arch/um/include/frame_user.h     2002-10-23 21:08:04.000000000 -0400
13496 @@ -0,0 +1,23 @@
13497 +/* 
13498 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13499 + * Licensed under the GPL
13500 + */
13501 +
13502 +#ifndef __FRAME_USER_H_
13503 +#define __FRAME_USER_H_
13504 +
13505 +#include "sysdep/frame_user.h"
13506 +#include "frame.h"
13507 +
13508 +#endif
13509 +
13510 +/*
13511 + * Overrides for Emacs so that we follow Linus's tabbing style.
13512 + * Emacs will notice this stuff at the end of the file and automatically
13513 + * adjust the settings for this buffer only.  This must remain at the end
13514 + * of the file.
13515 + * ---------------------------------------------------------------------------
13516 + * Local variables:
13517 + * c-file-style: "linux"
13518 + * End:
13519 + */
13520 diff -Naur -X ../exclude-files orig/arch/um/include/helper.h um/arch/um/include/helper.h
13521 --- orig/arch/um/include/helper.h       1969-12-31 19:00:00.000000000 -0500
13522 +++ um/arch/um/include/helper.h 2002-10-23 21:08:04.000000000 -0400
13523 @@ -0,0 +1,27 @@
13524 +/* 
13525 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13526 + * Licensed under the GPL
13527 + */
13528 +
13529 +#ifndef __HELPER_H__
13530 +#define __HELPER_H__
13531 +
13532 +extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
13533 +                     unsigned long *stack_out);
13534 +extern int run_helper_thread(int (*proc)(void *), void *arg, 
13535 +                            unsigned int flags, unsigned long *stack_out,
13536 +                            int stack_order);
13537 +extern int helper_wait(int pid);
13538 +
13539 +#endif
13540 +
13541 +/*
13542 + * Overrides for Emacs so that we follow Linus's tabbing style.
13543 + * Emacs will notice this stuff at the end of the file and automatically
13544 + * adjust the settings for this buffer only.  This must remain at the end
13545 + * of the file.
13546 + * ---------------------------------------------------------------------------
13547 + * Local variables:
13548 + * c-file-style: "linux"
13549 + * End:
13550 + */
13551 diff -Naur -X ../exclude-files orig/arch/um/include/hostaudio.h um/arch/um/include/hostaudio.h
13552 --- orig/arch/um/include/hostaudio.h    1969-12-31 19:00:00.000000000 -0500
13553 +++ um/arch/um/include/hostaudio.h      2002-10-23 21:08:04.000000000 -0400
13554 @@ -0,0 +1,48 @@
13555 +/* 
13556 + * Copyright (C) 2002 Steve Schmidtke 
13557 + * Licensed under the GPL
13558 + */
13559 +
13560 +#ifndef HOSTAUDIO_H
13561 +#define HOSTAUDIO_H
13562 +
13563 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
13564 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
13565 +
13566 +struct hostaudio_state {
13567 +  int fd;
13568 +};
13569 +
13570 +struct hostmixer_state {
13571 +  int fd;
13572 +};
13573 +
13574 +/* UML user-side protoypes */
13575 +extern ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
13576 +                                  size_t count, loff_t *ppos);
13577 +extern ssize_t hostaudio_write_user(struct hostaudio_state *state, 
13578 +                                   const char *buffer, size_t count, 
13579 +                                   loff_t *ppos);
13580 +extern int hostaudio_ioctl_user(struct hostaudio_state *state, 
13581 +                               unsigned int cmd, unsigned long arg);
13582 +extern int hostaudio_open_user(struct hostaudio_state *state, int r, int w, 
13583 +                              char *dsp);
13584 +extern int hostaudio_release_user(struct hostaudio_state *state);
13585 +extern int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
13586 +                               unsigned int cmd, unsigned long arg);
13587 +extern int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, 
13588 +                                     int w, char *mixer);
13589 +extern int hostmixer_release_mixdev_user(struct hostmixer_state *state);
13590 +
13591 +#endif /* HOSTAUDIO_H */
13592 +
13593 +/*
13594 + * Overrides for Emacs so that we follow Linus's tabbing style.
13595 + * Emacs will notice this stuff at the end of the file and automatically
13596 + * adjust the settings for this buffer only.  This must remain at the end
13597 + * of the file.
13598 + * ---------------------------------------------------------------------------
13599 + * Local variables:
13600 + * c-file-style: "linux"
13601 + * End:
13602 + */
13603 diff -Naur -X ../exclude-files orig/arch/um/include/init.h um/arch/um/include/init.h
13604 --- orig/arch/um/include/init.h 1969-12-31 19:00:00.000000000 -0500
13605 +++ um/arch/um/include/init.h   2002-10-23 21:08:04.000000000 -0400
13606 @@ -0,0 +1,114 @@
13607 +#ifndef _LINUX_UML_INIT_H
13608 +#define _LINUX_UML_INIT_H
13609 +
13610 +/* These macros are used to mark some functions or
13611 + * initialized data (doesn't apply to uninitialized data)
13612 + * as `initialization' functions. The kernel can take this
13613 + * as hint that the function is used only during the initialization
13614 + * phase and free up used memory resources after
13615 + *
13616 + * Usage:
13617 + * For functions:
13618 + *
13619 + * You should add __init immediately before the function name, like:
13620 + *
13621 + * static void __init initme(int x, int y)
13622 + * {
13623 + *    extern int z; z = x * y;
13624 + * }
13625 + *
13626 + * If the function has a prototype somewhere, you can also add
13627 + * __init between closing brace of the prototype and semicolon:
13628 + *
13629 + * extern int initialize_foobar_device(int, int, int) __init;
13630 + *
13631 + * For initialized data:
13632 + * You should insert __initdata between the variable name and equal
13633 + * sign followed by value, e.g.:
13634 + *
13635 + * static int init_variable __initdata = 0;
13636 + * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
13637 + *
13638 + * Don't forget to initialize data not at file scope, i.e. within a function,
13639 + * as gcc otherwise puts the data into the bss section and not into the init
13640 + * section.
13641 + *
13642 + * Also note, that this data cannot be "const".
13643 + */
13644 +
13645 +#ifndef _LINUX_INIT_H
13646 +typedef int (*initcall_t)(void);
13647 +typedef void (*exitcall_t)(void);
13648 +
13649 +#define __init          __attribute__ ((__section__ (".text.init")))
13650 +#define __exit          __attribute__ ((unused, __section__(".text.exit")))
13651 +#define __initdata      __attribute__ ((__section__ (".data.init")))
13652 +
13653 +#endif
13654 +
13655 +#ifndef MODULE
13656 +struct uml_param {
13657 +        const char *str;
13658 +        int (*setup_func)(char *, int *);
13659 +};
13660 +
13661 +extern initcall_t __uml_initcall_start, __uml_initcall_end;
13662 +extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
13663 +extern const char *__uml_help_start, *__uml_help_end;
13664 +#endif
13665 +
13666 +#define __uml_initcall(fn)                                             \
13667 +       static initcall_t __uml_initcall_##fn __uml_init_call = fn
13668 +
13669 +#define __uml_exitcall(fn)                                             \
13670 +       static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
13671 +
13672 +extern struct uml_param __uml_setup_start, __uml_setup_end;
13673 +
13674 +#define __uml_postsetup(fn)                                            \
13675 +       static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
13676 +
13677 +#define __non_empty_string(dummyname,string)                           \
13678 +       struct __uml_non_empty_string_struct_##dummyname                \
13679 +       {                                                               \
13680 +               char _string[sizeof(string)-2];                         \
13681 +       }
13682 +
13683 +#ifndef MODULE
13684 +#define __uml_setup(str, fn, help...)                                  \
13685 +       __non_empty_string(fn ##_setup, str);                           \
13686 +       __uml_help(fn, help);                                           \
13687 +       static char __uml_setup_str_##fn[] __initdata = str;            \
13688 +       static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
13689 +#else
13690 +#define __uml_setup(str, fn, help...)                                  \
13691 +
13692 +#endif
13693 +
13694 +#define __uml_help(fn, help...)                                                \
13695 +       __non_empty_string(fn ##__help, help);                          \
13696 +       static char __uml_help_str_##fn[] __initdata = help;            \
13697 +       static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
13698 +
13699 +/*
13700 + * Mark functions and data as being only used at initialization
13701 + * or exit time.
13702 + */
13703 +#define __uml_init_setup       __attribute__ ((unused,__section__ (".uml.setup.init")))
13704 +#define __uml_setup_help       __attribute__ ((unused,__section__ (".uml.help.init")))
13705 +#define __uml_init_call                __attribute__ ((unused,__section__ (".uml.initcall.init")))
13706 +#define __uml_postsetup_call   __attribute__ ((unused,__section__ (".uml.postsetup.init")))
13707 +#define __uml_exit_call                __attribute__ ((unused,__section__ (".uml.exitcall.exit")))
13708 +
13709 +#endif /* _LINUX_UML_INIT_H */
13710 +
13711 +/*
13712 + * Overrides for Emacs so that we follow Linus's tabbing style.
13713 + * Emacs will notice this stuff at the end of the file and automatically
13714 + * adjust the settings for this buffer only.  This must remain at the end
13715 + * of the file.
13716 + * ---------------------------------------------------------------------------
13717 + * Local variables:
13718 + * c-file-style: "linux"
13719 + * End:
13720 + */
13721 diff -Naur -X ../exclude-files orig/arch/um/include/initrd.h um/arch/um/include/initrd.h
13722 --- orig/arch/um/include/initrd.h       1969-12-31 19:00:00.000000000 -0500
13723 +++ um/arch/um/include/initrd.h 2002-10-23 21:08:04.000000000 -0400
13724 @@ -0,0 +1,22 @@
13725 +/*
13726 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13727 + * Licensed under the GPL
13728 + */
13729 +
13730 +#ifndef __INITRD_USER_H__
13731 +#define __INITRD_USER_H__
13732 +
13733 +extern int load_initrd(char *filename, void *buf, int size);
13734 +
13735 +#endif
13736 +
13737 +/*
13738 + * Overrides for Emacs so that we follow Linus's tabbing style.
13739 + * Emacs will notice this stuff at the end of the file and automatically
13740 + * adjust the settings for this buffer only.  This must remain at the end
13741 + * of the file.
13742 + * ---------------------------------------------------------------------------
13743 + * Local variables:
13744 + * c-file-style: "linux"
13745 + * End:
13746 + */
13747 diff -Naur -X ../exclude-files orig/arch/um/include/irq_kern.h um/arch/um/include/irq_kern.h
13748 --- orig/arch/um/include/irq_kern.h     1969-12-31 19:00:00.000000000 -0500
13749 +++ um/arch/um/include/irq_kern.h       2003-05-15 13:57:48.000000000 -0400
13750 @@ -0,0 +1,27 @@
13751 +/* 
13752 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
13753 + * Licensed under the GPL
13754 + */
13755 +
13756 +#ifndef __IRQ_KERN_H__
13757 +#define __IRQ_KERN_H__
13758 +
13759 +#include "linux/interrupt.h"
13760 +
13761 +extern int um_request_irq(unsigned int irq, int fd, int type,
13762 +                         void (*handler)(int, void *, struct pt_regs *),
13763 +                         unsigned long irqflags,  const char * devname,
13764 +                         void *dev_id);
13765 +
13766 +#endif
13767 +
13768 +/*
13769 + * Overrides for Emacs so that we follow Linus's tabbing style.
13770 + * Emacs will notice this stuff at the end of the file and automatically
13771 + * adjust the settings for this buffer only.  This must remain at the end
13772 + * of the file.
13773 + * ---------------------------------------------------------------------------
13774 + * Local variables:
13775 + * c-file-style: "linux"
13776 + * End:
13777 + */
13778 diff -Naur -X ../exclude-files orig/arch/um/include/irq_user.h um/arch/um/include/irq_user.h
13779 --- orig/arch/um/include/irq_user.h     1969-12-31 19:00:00.000000000 -0500
13780 +++ um/arch/um/include/irq_user.h       2002-12-08 20:38:42.000000000 -0500
13781 @@ -0,0 +1,35 @@
13782 +/* 
13783 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
13784 + * Licensed under the GPL
13785 + */
13786 +
13787 +#ifndef __IRQ_USER_H__
13788 +#define __IRQ_USER_H__
13789 +
13790 +enum { IRQ_READ, IRQ_WRITE };
13791 +
13792 +extern void sigio_handler(int sig, union uml_pt_regs *regs);
13793 +extern int activate_fd(int irq, int fd, int type, void *dev_id);
13794 +extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
13795 +extern void free_irq_by_fd(int fd);
13796 +extern void reactivate_fd(int fd, int irqnum);
13797 +extern void deactivate_fd(int fd, int irqnum);
13798 +extern void forward_interrupts(int pid);
13799 +extern void init_irq_signals(int on_sigstack);
13800 +extern void forward_ipi(int fd, int pid);
13801 +extern void free_irq_later(int irq, void *dev_id);
13802 +extern int activate_ipi(int fd, int pid);
13803 +extern unsigned long irq_lock(void);
13804 +extern void irq_unlock(unsigned long flags);
13805 +#endif
13806 +
13807 +/*
13808 + * Overrides for Emacs so that we follow Linus's tabbing style.
13809 + * Emacs will notice this stuff at the end of the file and automatically
13810 + * adjust the settings for this buffer only.  This must remain at the end
13811 + * of the file.
13812 + * ---------------------------------------------------------------------------
13813 + * Local variables:
13814 + * c-file-style: "linux"
13815 + * End:
13816 + */
13817 diff -Naur -X ../exclude-files orig/arch/um/include/kern.h um/arch/um/include/kern.h
13818 --- orig/arch/um/include/kern.h 1969-12-31 19:00:00.000000000 -0500
13819 +++ um/arch/um/include/kern.h   2002-11-02 21:38:02.000000000 -0500
13820 @@ -0,0 +1,48 @@
13821 +/* 
13822 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13823 + * Licensed under the GPL
13824 + */
13825 +
13826 +#ifndef __KERN_H__
13827 +#define __KERN_H__
13828 +
13829 +/* These are all user-mode things which are convenient to call directly
13830 + * from kernel code and for which writing a wrapper is too much of a pain.
13831 + * The regular include files can't be included because this file is included
13832 + * only into kernel code, and user-space includes conflict with kernel
13833 + * includes.
13834 + */
13835 +
13836 +extern int errno;
13837 +
13838 +extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
13839 +extern int sleep(int);
13840 +extern int printf(char *fmt, ...);
13841 +extern char *strerror(int errnum);
13842 +extern char *ptsname(int __fd);
13843 +extern int munmap(void *, int);
13844 +extern void *sbrk(int increment);
13845 +extern void *malloc(int size);
13846 +extern void perror(char *err);
13847 +extern int kill(int pid, int sig);
13848 +extern int getuid(void);
13849 +extern int pause(void);
13850 +extern int write(int, const void *, int);
13851 +extern int exit(int);
13852 +extern int close(int);
13853 +extern int read(unsigned int, char *, int);
13854 +extern int pipe(int *);
13855 +extern int sched_yield(void);
13856 +extern int ptrace(int op, int pid, long addr, long data);
13857 +#endif
13858 +
13859 +/*
13860 + * Overrides for Emacs so that we follow Linus's tabbing style.
13861 + * Emacs will notice this stuff at the end of the file and automatically
13862 + * adjust the settings for this buffer only.  This must remain at the end
13863 + * of the file.
13864 + * ---------------------------------------------------------------------------
13865 + * Local variables:
13866 + * c-file-style: "linux"
13867 + * End:
13868 + */
13869 diff -Naur -X ../exclude-files orig/arch/um/include/kern_util.h um/arch/um/include/kern_util.h
13870 --- orig/arch/um/include/kern_util.h    1969-12-31 19:00:00.000000000 -0500
13871 +++ um/arch/um/include/kern_util.h      2003-04-16 16:00:11.000000000 -0400
13872 @@ -0,0 +1,121 @@
13873 +/* 
13874 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
13875 + * Licensed under the GPL
13876 + */
13877 +
13878 +#ifndef __KERN_UTIL_H__
13879 +#define __KERN_UTIL_H__
13880 +
13881 +#include "sysdep/ptrace.h"
13882 +
13883 +extern int ncpus;
13884 +extern char *linux_prog;
13885 +extern char *gdb_init;
13886 +extern int kmalloc_ok;
13887 +extern int timer_irq_inited;
13888 +extern int jail;
13889 +extern int nsyscalls;
13890 +
13891 +#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
13892 +#define UML_ROUND_UP(addr) \
13893 +       UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
13894 +
13895 +extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
13896 +extern unsigned long stack_sp(unsigned long page);
13897 +extern int kernel_thread_proc(void *data);
13898 +extern void syscall_segv(int sig);
13899 +extern int current_pid(void);
13900 +extern unsigned long alloc_stack(int order, int atomic);
13901 +extern int do_signal(int error);
13902 +extern int is_stack_fault(unsigned long sp);
13903 +extern unsigned long segv(unsigned long address, unsigned long ip, 
13904 +                         int is_write, int is_user, void *sc);
13905 +extern unsigned long handle_page_fault(unsigned long address, unsigned long ip,
13906 +                                      int is_write, int is_user, 
13907 +                                      int *code_out);
13908 +extern void syscall_ready(void);
13909 +extern int segv_syscall(void);
13910 +extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
13911 +extern int page_size(void);
13912 +extern int page_mask(void);
13913 +extern int need_finish_fork(void);
13914 +extern void free_stack(unsigned long stack, int order);
13915 +extern void add_input_request(int op, void (*proc)(int), void *arg);
13916 +extern int sys_execve(char *file, char **argv, char **env);
13917 +extern char *current_cmd(void);
13918 +extern void timer_handler(int sig, union uml_pt_regs *regs);
13919 +extern int set_signals(int enable);
13920 +extern void force_sigbus(void);
13921 +extern int pid_to_processor_id(int pid);
13922 +extern void block_signals(void);
13923 +extern void unblock_signals(void);
13924 +extern void deliver_signals(void *t);
13925 +extern int next_syscall_index(int max);
13926 +extern int next_trap_index(int max);
13927 +extern void cpu_idle(void);
13928 +extern void finish_fork(void);
13929 +extern void paging_init(void);
13930 +extern void init_flush_vm(void);
13931 +extern void *syscall_sp(void *t);
13932 +extern void syscall_trace(void);
13933 +extern int hz(void);
13934 +extern void idle_timer(void);
13935 +extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
13936 +extern int external_pid(void *t);
13937 +extern void boot_timer_handler(int sig);
13938 +extern void interrupt_end(void);
13939 +extern void initial_thread_cb(void (*proc)(void *), void *arg);
13940 +extern int debugger_signal(int status, int pid);
13941 +extern void debugger_parent_signal(int status, int pid);
13942 +extern void child_signal(int pid, int status);
13943 +extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
13944 +extern int init_parent_proxy(int pid);
13945 +extern void check_stack_overflow(void *ptr);
13946 +extern void relay_signal(int sig, union uml_pt_regs *regs);
13947 +extern void not_implemented(void);
13948 +extern int user_context(unsigned long sp);
13949 +extern void timer_irq(union uml_pt_regs *regs);
13950 +extern void unprotect_stack(unsigned long stack);
13951 +extern void do_uml_exitcalls(void);
13952 +extern int attach_debugger(int idle_pid, int pid, int stop);
13953 +extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
13954 +extern int config_gdb(char *str);
13955 +extern int remove_gdb(void);
13956 +extern char *uml_strdup(char *string);
13957 +extern void unprotect_kernel_mem(void);
13958 +extern void protect_kernel_mem(void);
13959 +extern void set_kmem_end(unsigned long);
13960 +extern void uml_cleanup(void);
13961 +extern void set_current(void *t);
13962 +extern void lock_signalled_task(void *t);
13963 +extern void IPI_handler(int cpu);
13964 +extern int jail_setup(char *line, int *add);
13965 +extern void *get_init_task(void);
13966 +extern int clear_user_proc(void *buf, int size);
13967 +extern int copy_to_user_proc(void *to, void *from, int size);
13968 +extern int copy_from_user_proc(void *to, void *from, int size);
13969 +extern int strlen_user_proc(char *str);
13970 +extern void bus_handler(int sig, union uml_pt_regs *regs);
13971 +extern void winch(int sig, union uml_pt_regs *regs);
13972 +extern long execute_syscall(void *r);
13973 +extern int smp_sigio_handler(void);
13974 +extern void *get_current(void);
13975 +extern struct task_struct *get_task(int pid, int require);
13976 +extern void machine_halt(void);
13977 +extern int is_syscall(unsigned long addr);
13978 +extern void arch_switch(void);
13979 +extern void free_irq(unsigned int, void *);
13980 +extern int um_in_interrupt(void);
13981 +extern int cpu(void);
13982 +#endif
13983 +
13984 +/*
13985 + * Overrides for Emacs so that we follow Linus's tabbing style.
13986 + * Emacs will notice this stuff at the end of the file and automatically
13987 + * adjust the settings for this buffer only.  This must remain at the end
13988 + * of the file.
13989 + * ---------------------------------------------------------------------------
13990 + * Local variables:
13991 + * c-file-style: "linux"
13992 + * End:
13993 + */
13994 diff -Naur -X ../exclude-files orig/arch/um/include/line.h um/arch/um/include/line.h
13995 --- orig/arch/um/include/line.h 1969-12-31 19:00:00.000000000 -0500
13996 +++ um/arch/um/include/line.h   2002-11-15 13:44:44.000000000 -0500
13997 @@ -0,0 +1,106 @@
13998 +/* 
13999 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14000 + * Licensed under the GPL
14001 + */
14002 +
14003 +#ifndef __LINE_H__
14004 +#define __LINE_H__
14005 +
14006 +#include "linux/list.h"
14007 +#include "linux/tqueue.h"
14008 +#include "linux/tty.h"
14009 +#include "asm/semaphore.h"
14010 +#include "chan_user.h"
14011 +#include "mconsole_kern.h"
14012 +
14013 +struct line_driver {
14014 +       char *name;
14015 +       char *devfs_name;
14016 +       short major;
14017 +       short minor_start;
14018 +       short type;
14019 +       short subtype;
14020 +       int read_irq;
14021 +       char *read_irq_name;
14022 +       int write_irq;
14023 +       char *write_irq_name;
14024 +       char *symlink_from;
14025 +       char *symlink_to;
14026 +       struct mc_device mc;
14027 +};
14028 +
14029 +struct line {
14030 +       char *init_str;
14031 +       int init_pri;
14032 +       struct list_head chan_list;
14033 +       int valid;
14034 +       int count;
14035 +       struct tty_struct *tty;
14036 +       struct semaphore sem;
14037 +       char *buffer;
14038 +       char *head;
14039 +       char *tail;
14040 +       int sigio;
14041 +       struct tq_struct task;
14042 +       struct line_driver *driver;
14043 +       int have_irq;
14044 +};
14045 +
14046 +#define LINE_INIT(str, d) \
14047 +       { init_str :    str, \
14048 +         init_pri :    INIT_STATIC, \
14049 +         chan_list :   { }, \
14050 +         valid :       1, \
14051 +         count :       0, \
14052 +         tty :         NULL, \
14053 +         sem :         { }, \
14054 +         buffer :      NULL, \
14055 +         head :        NULL, \
14056 +         tail :        NULL, \
14057 +         sigio :       0, \
14058 +         driver :      d, \
14059 +          have_irq :   0 }
14060 +
14061 +struct lines {
14062 +       int num;
14063 +};
14064 +
14065 +#define LINES_INIT(n) {  num :         n }
14066 +
14067 +extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
14068 +extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
14069 +extern void line_close(struct line *lines, struct tty_struct *tty);
14070 +extern int line_open(struct line *lines, struct tty_struct *tty, 
14071 +                    struct chan_opts *opts);
14072 +extern int line_setup(struct line *lines, int num, char *init, 
14073 +                     int all_allowed);
14074 +extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
14075 +                     const char *buf, int len);
14076 +extern int line_write_room(struct tty_struct *tty);
14077 +extern char *add_xterm_umid(char *base);
14078 +extern int line_setup_irq(int fd, int input, int output, void *data);
14079 +extern void line_close_chan(struct line *line);
14080 +extern void line_disable(struct line *line, int current_irq);
14081 +extern void line_register_devfs(struct lines *set, 
14082 +                               struct line_driver *line_driver, 
14083 +                               struct tty_driver *driver, struct line *lines,
14084 +                               int nlines);
14085 +extern void lines_init(struct line *lines, int nlines);
14086 +extern void close_lines(struct line *lines, int nlines);
14087 +extern int line_config(struct line *lines, int num, char *str);
14088 +extern int line_remove(struct line *lines, int num, char *str);
14089 +extern int line_get_config(char *dev, struct line *lines, int num, char *str, 
14090 +                          int size, char **error_out);
14091 +
14092 +#endif
14093 +
14094 +/*
14095 + * Overrides for Emacs so that we follow Linus's tabbing style.
14096 + * Emacs will notice this stuff at the end of the file and automatically
14097 + * adjust the settings for this buffer only.  This must remain at the end
14098 + * of the file.
14099 + * ---------------------------------------------------------------------------
14100 + * Local variables:
14101 + * c-file-style: "linux"
14102 + * End:
14103 + */
14104 diff -Naur -X ../exclude-files orig/arch/um/include/Makefile um/arch/um/include/Makefile
14105 --- orig/arch/um/include/Makefile       1969-12-31 19:00:00.000000000 -0500
14106 +++ um/arch/um/include/Makefile 2002-10-23 21:08:04.000000000 -0400
14107 @@ -0,0 +1,7 @@
14108 +all : sc.h
14109 +
14110 +sc.h : ../util/mk_sc
14111 +       ../util/mk_sc > $@
14112 +
14113 +../util/mk_sc :
14114 +       $(MAKE) -C ../util mk_sc
14115 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole.h um/arch/um/include/mconsole.h
14116 --- orig/arch/um/include/mconsole.h     1969-12-31 19:00:00.000000000 -0500
14117 +++ um/arch/um/include/mconsole.h       2003-01-17 13:48:25.000000000 -0500
14118 @@ -0,0 +1,99 @@
14119 +/*
14120 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
14121 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14122 + * Licensed under the GPL
14123 + */
14124 +
14125 +#ifndef __MCONSOLE_H__
14126 +#define __MCONSOLE_H__
14127 +
14128 +#ifndef __KERNEL__
14129 +#include <stdint.h>
14130 +#define u32 uint32_t
14131 +#endif
14132 +
14133 +#define MCONSOLE_MAGIC (0xcafebabe)
14134 +#define MCONSOLE_MAX_DATA (512)
14135 +#define MCONSOLE_VERSION 2
14136 +
14137 +struct mconsole_request {
14138 +       u32 magic;
14139 +       u32 version;
14140 +       u32 len;
14141 +       char data[MCONSOLE_MAX_DATA];
14142 +};
14143 +
14144 +struct mconsole_reply {
14145 +       u32 err;
14146 +       u32 more;
14147 +       u32 len;
14148 +       char data[MCONSOLE_MAX_DATA];
14149 +};
14150 +
14151 +struct mconsole_notify {
14152 +       u32 magic;
14153 +       u32 version;    
14154 +       enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
14155 +              MCONSOLE_USER_NOTIFY } type;
14156 +       u32 len;
14157 +       char data[MCONSOLE_MAX_DATA];
14158 +};
14159 +
14160 +struct mc_request;
14161 +
14162 +struct mconsole_command
14163 +{
14164 +       char *command;
14165 +       void (*handler)(struct mc_request *req);
14166 +       int as_interrupt;
14167 +};
14168 +
14169 +struct mc_request
14170 +{
14171 +       int len;
14172 +       int as_interrupt;
14173 +
14174 +       int originating_fd;
14175 +       int originlen;
14176 +       unsigned char origin[128];                      /* sockaddr_un */
14177 +
14178 +       struct mconsole_request request;
14179 +       struct mconsole_command *cmd;
14180 +};
14181 +
14182 +extern char mconsole_socket_name[];
14183 +
14184 +extern int mconsole_unlink_socket(void);
14185 +extern int mconsole_reply(struct mc_request *req, char *reply, int err,
14186 +                         int more);
14187 +
14188 +extern void mconsole_version(struct mc_request *req);
14189 +extern void mconsole_help(struct mc_request *req);
14190 +extern void mconsole_halt(struct mc_request *req);
14191 +extern void mconsole_reboot(struct mc_request *req);
14192 +extern void mconsole_config(struct mc_request *req);
14193 +extern void mconsole_remove(struct mc_request *req);
14194 +extern void mconsole_sysrq(struct mc_request *req);
14195 +extern void mconsole_cad(struct mc_request *req);
14196 +extern void mconsole_stop(struct mc_request *req);
14197 +extern void mconsole_go(struct mc_request *req);
14198 +
14199 +extern int mconsole_get_request(int fd, struct mc_request *req);
14200 +extern int mconsole_notify(char *sock_name, int type, const void *data, 
14201 +                          int len);
14202 +extern char *mconsole_notify_socket(void);
14203 +extern void lock_notify(void);
14204 +extern void unlock_notify(void);
14205 +
14206 +#endif
14207 +
14208 +/*
14209 + * Overrides for Emacs so that we follow Linus's tabbing style.
14210 + * Emacs will notice this stuff at the end of the file and automatically
14211 + * adjust the settings for this buffer only.  This must remain at the end
14212 + * of the file.
14213 + * ---------------------------------------------------------------------------
14214 + * Local variables:
14215 + * c-file-style: "linux"
14216 + * End:
14217 + */
14218 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole_kern.h um/arch/um/include/mconsole_kern.h
14219 --- orig/arch/um/include/mconsole_kern.h        1969-12-31 19:00:00.000000000 -0500
14220 +++ um/arch/um/include/mconsole_kern.h  2002-11-15 15:21:58.000000000 -0500
14221 @@ -0,0 +1,62 @@
14222 +/*
14223 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14224 + * Licensed under the GPL
14225 + */
14226 +
14227 +#ifndef __MCONSOLE_KERN_H__
14228 +#define __MCONSOLE_KERN_H__
14229 +
14230 +#include "linux/config.h"
14231 +#include "linux/list.h"
14232 +#include "mconsole.h"
14233 +
14234 +struct mconsole_entry {
14235 +       struct list_head list;
14236 +       struct mc_request request;
14237 +};
14238 +
14239 +struct mc_device {
14240 +       struct list_head list;
14241 +       char *name;
14242 +       int (*config)(char *);
14243 +       int (*get_config)(char *, char *, int, char **);
14244 +       int (*remove)(char *);
14245 +};
14246 +
14247 +#define CONFIG_CHUNK(str, size, current, chunk, end) \
14248 +do { \
14249 +       current += strlen(chunk); \
14250 +       if(current >= size) \
14251 +               str = NULL; \
14252 +       if(str != NULL){ \
14253 +               strcpy(str, chunk); \
14254 +               str += strlen(chunk); \
14255 +       } \
14256 +       if(end) \
14257 +               current++; \
14258 +} while(0)
14259 +
14260 +#ifdef CONFIG_MCONSOLE
14261 +
14262 +extern void mconsole_register_dev(struct mc_device *new);
14263 +
14264 +#else
14265 +
14266 +static inline void mconsole_register_dev(struct mc_device *new)
14267 +{
14268 +}
14269 +
14270 +#endif
14271 +
14272 +#endif
14273 +
14274 +/*
14275 + * Overrides for Emacs so that we follow Linus's tabbing style.
14276 + * Emacs will notice this stuff at the end of the file and automatically
14277 + * adjust the settings for this buffer only.  This must remain at the end
14278 + * of the file.
14279 + * ---------------------------------------------------------------------------
14280 + * Local variables:
14281 + * c-file-style: "linux"
14282 + * End:
14283 + */
14284 diff -Naur -X ../exclude-files orig/arch/um/include/mem.h um/arch/um/include/mem.h
14285 --- orig/arch/um/include/mem.h  1969-12-31 19:00:00.000000000 -0500
14286 +++ um/arch/um/include/mem.h    2002-10-23 21:08:04.000000000 -0400
14287 @@ -0,0 +1,29 @@
14288 +/* 
14289 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14290 + * Licensed under the GPL
14291 + */
14292 +
14293 +#ifndef __MEM_H__
14294 +#define __MEM_H__
14295 +
14296 +struct vm_reserved {
14297 +       struct list_head list;
14298 +       unsigned long start;
14299 +       unsigned long end;
14300 +};
14301 +
14302 +extern void set_usable_vm(unsigned long start, unsigned long end);
14303 +extern void set_kmem_end(unsigned long new);
14304 +
14305 +#endif
14306 +
14307 +/*
14308 + * Overrides for Emacs so that we follow Linus's tabbing style.
14309 + * Emacs will notice this stuff at the end of the file and automatically
14310 + * adjust the settings for this buffer only.  This must remain at the end
14311 + * of the file.
14312 + * ---------------------------------------------------------------------------
14313 + * Local variables:
14314 + * c-file-style: "linux"
14315 + * End:
14316 + */
14317 diff -Naur -X ../exclude-files orig/arch/um/include/mem_user.h um/arch/um/include/mem_user.h
14318 --- orig/arch/um/include/mem_user.h     1969-12-31 19:00:00.000000000 -0500
14319 +++ um/arch/um/include/mem_user.h       2002-10-23 21:08:04.000000000 -0400
14320 @@ -0,0 +1,87 @@
14321 +/*
14322 + * arch/um/include/mem_user.h
14323 + *
14324 + * BRIEF MODULE DESCRIPTION
14325 + * user side memory interface for support IO memory inside user mode linux
14326 + *
14327 + * Copyright (C) 2001 RidgeRun, Inc.
14328 + * Author: RidgeRun, Inc.
14329 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
14330 + *
14331 + *  This program is free software; you can redistribute  it and/or modify it
14332 + *  under  the terms of  the GNU General  Public License as published by the
14333 + *  Free Software Foundation;  either version 2 of the  License, or (at your
14334 + *  option) any later version.
14335 + *
14336 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
14337 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
14338 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
14339 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
14340 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14341 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
14342 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
14343 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
14344 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
14345 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14346 + *
14347 + *  You should have received a copy of the  GNU General Public License along
14348 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
14349 + *  675 Mass Ave, Cambridge, MA 02139, USA.
14350 + */
14351 +
14352 +#ifndef _MEM_USER_H
14353 +#define _MEM_USER_H
14354 +
14355 +struct mem_region {
14356 +       char *driver;
14357 +       unsigned long start_pfn;
14358 +       unsigned long start;
14359 +       unsigned long len;
14360 +       void *mem_map;
14361 +       int fd;
14362 +};
14363 +
14364 +extern struct mem_region *regions[];
14365 +extern struct mem_region physmem_region;
14366 +
14367 +#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
14368 +
14369 +extern unsigned long host_task_size;
14370 +extern unsigned long task_size;
14371 +
14372 +extern int init_mem_user(void);
14373 +extern int create_mem_file(unsigned long len);
14374 +extern void setup_range(int fd, char *driver, unsigned long start,
14375 +                       unsigned long pfn, unsigned long total, int need_vm, 
14376 +                       struct mem_region *region, void *reserved);
14377 +extern void setup_memory(void *entry);
14378 +extern unsigned long find_iomem(char *driver, unsigned long *len_out);
14379 +extern int init_maps(struct mem_region *region);
14380 +extern int nregions(void);
14381 +extern int reserve_vm(unsigned long start, unsigned long end, void *e);
14382 +extern unsigned long get_vm(unsigned long len);
14383 +extern void setup_physmem(unsigned long start, unsigned long usable,
14384 +                         unsigned long len);
14385 +extern int setup_region(struct mem_region *region, void *entry);
14386 +extern void add_iomem(char *name, int fd, unsigned long size);
14387 +extern struct mem_region *phys_region(unsigned long phys);
14388 +extern unsigned long phys_offset(unsigned long phys);
14389 +extern void unmap_physmem(void);
14390 +extern int map_memory(unsigned long virt, unsigned long phys, 
14391 +                     unsigned long len, int r, int w, int x);
14392 +extern int protect_memory(unsigned long addr, unsigned long len, 
14393 +                         int r, int w, int x, int must_succeed);
14394 +extern unsigned long get_kmem_end(void);
14395 +
14396 +#endif
14397 +
14398 +/*
14399 + * Overrides for Emacs so that we follow Linus's tabbing style.
14400 + * Emacs will notice this stuff at the end of the file and automatically
14401 + * adjust the settings for this buffer only.  This must remain at the end
14402 + * of the file.
14403 + * ---------------------------------------------------------------------------
14404 + * Local variables:
14405 + * c-file-style: "linux"
14406 + * End:
14407 + */
14408 diff -Naur -X ../exclude-files orig/arch/um/include/mode.h um/arch/um/include/mode.h
14409 --- orig/arch/um/include/mode.h 1969-12-31 19:00:00.000000000 -0500
14410 +++ um/arch/um/include/mode.h   2003-01-17 13:23:32.000000000 -0500
14411 @@ -0,0 +1,30 @@
14412 +/* 
14413 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14414 + * Licensed under the GPL
14415 + */
14416 +
14417 +#ifndef __MODE_H__
14418 +#define __MODE_H__
14419 +
14420 +#include "uml-config.h"
14421 +
14422 +#ifdef UML_CONFIG_MODE_TT
14423 +#include "../kernel/tt/include/mode.h"
14424 +#endif
14425 +
14426 +#ifdef UML_CONFIG_MODE_SKAS
14427 +#include "../kernel/skas/include/mode.h"
14428 +#endif
14429 +
14430 +#endif
14431 +
14432 +/*
14433 + * Overrides for Emacs so that we follow Linus's tabbing style.
14434 + * Emacs will notice this stuff at the end of the file and automatically
14435 + * adjust the settings for this buffer only.  This must remain at the end
14436 + * of the file.
14437 + * ---------------------------------------------------------------------------
14438 + * Local variables:
14439 + * c-file-style: "linux"
14440 + * End:
14441 + */
14442 diff -Naur -X ../exclude-files orig/arch/um/include/mode_kern.h um/arch/um/include/mode_kern.h
14443 --- orig/arch/um/include/mode_kern.h    1969-12-31 19:00:00.000000000 -0500
14444 +++ um/arch/um/include/mode_kern.h      2002-10-23 21:08:04.000000000 -0400
14445 @@ -0,0 +1,30 @@
14446 +/* 
14447 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14448 + * Licensed under the GPL
14449 + */
14450 +
14451 +#ifndef __MODE_KERN_H__
14452 +#define __MODE_KERN_H__
14453 +
14454 +#include "linux/config.h"
14455 +
14456 +#ifdef CONFIG_MODE_TT
14457 +#include "../kernel/tt/include/mode_kern.h"
14458 +#endif
14459 +
14460 +#ifdef CONFIG_MODE_SKAS
14461 +#include "../kernel/skas/include/mode_kern.h"
14462 +#endif
14463 +
14464 +#endif
14465 +
14466 +/*
14467 + * Overrides for Emacs so that we follow Linus's tabbing style.
14468 + * Emacs will notice this stuff at the end of the file and automatically
14469 + * adjust the settings for this buffer only.  This must remain at the end
14470 + * of the file.
14471 + * ---------------------------------------------------------------------------
14472 + * Local variables:
14473 + * c-file-style: "linux"
14474 + * End:
14475 + */
14476 diff -Naur -X ../exclude-files orig/arch/um/include/net_kern.h um/arch/um/include/net_kern.h
14477 --- orig/arch/um/include/net_kern.h     1969-12-31 19:00:00.000000000 -0500
14478 +++ um/arch/um/include/net_kern.h       2002-10-23 21:08:04.000000000 -0400
14479 @@ -0,0 +1,81 @@
14480 +/* 
14481 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14482 + * Licensed under the GPL
14483 + */
14484 +
14485 +#ifndef __UM_NET_KERN_H
14486 +#define __UM_NET_KERN_H
14487 +
14488 +#include "linux/netdevice.h"
14489 +#include "linux/skbuff.h"
14490 +#include "linux/socket.h"
14491 +#include "linux/list.h"
14492 +
14493 +struct uml_net {
14494 +       struct list_head list;
14495 +       struct net_device *dev;
14496 +       int index;
14497 +       unsigned char mac[ETH_ALEN];
14498 +       int have_mac;
14499 +};
14500 +
14501 +struct uml_net_private {
14502 +       struct list_head list;
14503 +       spinlock_t lock;
14504 +       struct net_device *dev;
14505 +       struct timer_list tl;
14506 +       struct net_device_stats stats;
14507 +       int fd;
14508 +       unsigned char mac[ETH_ALEN];
14509 +       int have_mac;
14510 +       unsigned short (*protocol)(struct sk_buff *);
14511 +       int (*open)(void *);
14512 +       void (*close)(int, void *);
14513 +       void (*remove)(void *);
14514 +       int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
14515 +       int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
14516 +       
14517 +       void (*add_address)(unsigned char *, unsigned char *, void *);
14518 +       void (*delete_address)(unsigned char *, unsigned char *, void *);
14519 +       int (*set_mtu)(int mtu, void *);
14520 +       int user[1];
14521 +};
14522 +
14523 +struct net_kern_info {
14524 +       void (*init)(struct net_device *, void *);
14525 +       unsigned short (*protocol)(struct sk_buff *);
14526 +       int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
14527 +       int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
14528 +};
14529 +
14530 +struct transport {
14531 +       struct list_head list;
14532 +       char *name;
14533 +       int (*setup)(char *, char **, void *);
14534 +       struct net_user_info *user;
14535 +       struct net_kern_info *kern;
14536 +       int private_size;
14537 +       int setup_size;
14538 +};
14539 +
14540 +extern struct net_device *ether_init(int);
14541 +extern unsigned short ether_protocol(struct sk_buff *);
14542 +extern int setup_etheraddr(char *str, unsigned char *addr);
14543 +extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
14544 +extern int tap_setup_common(char *str, char *type, char **dev_name, 
14545 +                           char **mac_out, char **gate_addr);
14546 +extern void register_transport(struct transport *new);
14547 +extern unsigned short eth_protocol(struct sk_buff *skb);
14548 +
14549 +#endif
14550 +
14551 +/*
14552 + * Overrides for Emacs so that we follow Linus's tabbing style.
14553 + * Emacs will notice this stuff at the end of the file and automatically
14554 + * adjust the settings for this buffer only.  This must remain at the end
14555 + * of the file.
14556 + * ---------------------------------------------------------------------------
14557 + * Local variables:
14558 + * c-file-style: "linux"
14559 + * End:
14560 + */
14561 diff -Naur -X ../exclude-files orig/arch/um/include/net_user.h um/arch/um/include/net_user.h
14562 --- orig/arch/um/include/net_user.h     1969-12-31 19:00:00.000000000 -0500
14563 +++ um/arch/um/include/net_user.h       2002-10-23 21:08:04.000000000 -0400
14564 @@ -0,0 +1,66 @@
14565 +/* 
14566 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14567 + * Licensed under the GPL
14568 + */
14569 +
14570 +#ifndef __UM_NET_USER_H__
14571 +#define __UM_NET_USER_H__
14572 +
14573 +#define ETH_ADDR_LEN (6)
14574 +#define ETH_HEADER_ETHERTAP (16)
14575 +#define ETH_HEADER_OTHER (14)
14576 +#define ETH_MAX_PACKET (1500)
14577 +
14578 +#define UML_NET_VERSION (4)
14579 +
14580 +struct net_user_info {
14581 +       void (*init)(void *, void *);
14582 +       int (*open)(void *);
14583 +       void (*close)(int, void *);
14584 +       void (*remove)(void *);
14585 +       int (*set_mtu)(int mtu, void *);
14586 +       void (*add_address)(unsigned char *, unsigned char *, void *);
14587 +       void (*delete_address)(unsigned char *, unsigned char *, void *);
14588 +       int max_packet;
14589 +};
14590 +
14591 +extern void ether_user_init(void *data, void *dev);
14592 +extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
14593 +extern void set_ether_mac(void *d, unsigned char *addr);
14594 +extern void iter_addresses(void *d, void (*cb)(unsigned char *, 
14595 +                                              unsigned char *, void *), 
14596 +                          void *arg);
14597 +
14598 +extern void *get_output_buffer(int *len_out);
14599 +extern void free_output_buffer(void *buffer);
14600 +
14601 +extern int tap_open_common(void *dev, char *gate_addr);
14602 +extern void tap_check_ips(char *gate_addr, char *eth_addr);
14603 +
14604 +extern void read_output(int fd, char *output_out, int len);
14605 +
14606 +extern int net_read(int fd, void *buf, int len);
14607 +extern int net_recvfrom(int fd, void *buf, int len);
14608 +extern int net_write(int fd, void *buf, int len);
14609 +extern int net_send(int fd, void *buf, int len);
14610 +extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len);
14611 +
14612 +extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg);
14613 +extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg);
14614 +
14615 +extern char *split_if_spec(char *str, ...);
14616 +
14617 +extern int dev_netmask(void *d, void *m);
14618 +
14619 +#endif
14620 +
14621 +/*
14622 + * Overrides for Emacs so that we follow Linus's tabbing style.
14623 + * Emacs will notice this stuff at the end of the file and automatically
14624 + * adjust the settings for this buffer only.  This must remain at the end
14625 + * of the file.
14626 + * ---------------------------------------------------------------------------
14627 + * Local variables:
14628 + * c-file-style: "linux"
14629 + * End:
14630 + */
14631 diff -Naur -X ../exclude-files orig/arch/um/include/os.h um/arch/um/include/os.h
14632 --- orig/arch/um/include/os.h   1969-12-31 19:00:00.000000000 -0500
14633 +++ um/arch/um/include/os.h     2003-02-04 19:11:32.000000000 -0500
14634 @@ -0,0 +1,137 @@
14635 +/* 
14636 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14637 + * Licensed under the GPL
14638 + */
14639 +
14640 +#ifndef __OS_H__
14641 +#define __OS_H__
14642 +
14643 +#include "asm/types.h"
14644 +#include "../os/include/file.h"
14645 +
14646 +#define OS_TYPE_FILE 1 
14647 +#define OS_TYPE_DIR 2 
14648 +#define OS_TYPE_SYMLINK 3 
14649 +#define OS_TYPE_CHARDEV 4
14650 +#define OS_TYPE_BLOCKDEV 5
14651 +#define OS_TYPE_FIFO 6
14652 +#define OS_TYPE_SOCK 7
14653 +
14654 +struct openflags {
14655 +       unsigned int r : 1;
14656 +       unsigned int w : 1;
14657 +       unsigned int s : 1;     /* O_SYNC */
14658 +       unsigned int c : 1;     /* O_CREAT */
14659 +       unsigned int t : 1;     /* O_TRUNC */
14660 +       unsigned int a : 1;     /* O_APPEND */
14661 +       unsigned int e : 1;     /* O_EXCL */
14662 +       unsigned int cl : 1;    /* FD_CLOEXEC */
14663 +};
14664 +
14665 +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
14666 +                                         .t = 0, .a = 0, .e = 0, .cl = 0 })
14667 +
14668 +static inline struct openflags of_read(struct openflags flags)
14669 +{
14670 +       flags.r = 1; 
14671 +       return(flags);
14672 +}
14673 +
14674 +static inline struct openflags of_write(struct openflags flags)
14675 +{
14676 +       flags.w = 1; 
14677 +       return(flags); 
14678 +}
14679 +
14680 +static inline struct openflags of_rdwr(struct openflags flags)
14681 +{
14682 +       return(of_read(of_write(flags)));
14683 +}
14684 +
14685 +static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
14686 +{
14687 +       flags.r = r;
14688 +       flags.w = w;
14689 +       return(flags);
14690 +}
14691 +
14692 +static inline struct openflags of_sync(struct openflags flags)
14693 +{ 
14694 +       flags.s = 1; 
14695 +       return(flags); 
14696 +}
14697 +
14698 +static inline struct openflags of_create(struct openflags flags)
14699 +{ 
14700 +       flags.c = 1; 
14701 +       return(flags); 
14702 +}
14703
14704 +static inline struct openflags of_trunc(struct openflags flags)
14705 +{ 
14706 +       flags.t = 1; 
14707 +       return(flags); 
14708 +}
14709
14710 +static inline struct openflags of_append(struct openflags flags)
14711 +{ 
14712 +       flags.a = 1; 
14713 +       return(flags); 
14714 +}
14715
14716 +static inline struct openflags of_excl(struct openflags flags)
14717 +{ 
14718 +       flags.e = 1; 
14719 +       return(flags); 
14720 +}
14721 +
14722 +static inline struct openflags of_cloexec(struct openflags flags)
14723 +{ 
14724 +       flags.cl = 1; 
14725 +       return(flags); 
14726 +}
14727
14728 +extern int os_seek_file(int fd, __u64 offset);
14729 +extern int os_open_file(char *file, struct openflags flags, int mode);
14730 +extern int os_read_file(int fd, void *buf, int len);
14731 +extern int os_write_file(int fd, void *buf, int count);
14732 +extern int os_file_size(char *file, long long *size_out);
14733 +extern int os_pipe(int *fd, int stream, int close_on_exec);
14734 +extern int os_set_fd_async(int fd, int owner);
14735 +extern int os_set_fd_block(int fd, int blocking);
14736 +extern int os_accept_connection(int fd);
14737 +extern int os_shutdown_socket(int fd, int r, int w);
14738 +extern void os_close_file(int fd);
14739 +extern int os_rcv_fd(int fd, int *helper_pid_out);
14740 +extern int create_unix_socket(char *file, int len);
14741 +extern int os_connect_socket(char *name);
14742 +extern int os_file_type(char *file);
14743 +extern int os_file_mode(char *file, struct openflags *mode_out);
14744 +extern int os_lock_file(int fd, int excl);
14745 +
14746 +extern unsigned long os_process_pc(int pid);
14747 +extern int os_process_parent(int pid);
14748 +extern void os_stop_process(int pid);
14749 +extern void os_kill_process(int pid, int reap_child);
14750 +extern void os_usr1_process(int pid);
14751 +extern int os_getpid(void);
14752 +
14753 +extern int os_map_memory(void *virt, int fd, unsigned long off, 
14754 +                        unsigned long len, int r, int w, int x);
14755 +extern int os_protect_memory(void *addr, unsigned long len, 
14756 +                            int r, int w, int x);
14757 +extern int os_unmap_memory(void *addr, int len);
14758 +extern void os_flush_stdout(void);
14759 +
14760 +#endif
14761 +
14762 +/*
14763 + * Overrides for Emacs so that we follow Linus's tabbing style.
14764 + * Emacs will notice this stuff at the end of the file and automatically
14765 + * adjust the settings for this buffer only.  This must remain at the end
14766 + * of the file.
14767 + * ---------------------------------------------------------------------------
14768 + * Local variables:
14769 + * c-file-style: "linux"
14770 + * End:
14771 + */
14772 diff -Naur -X ../exclude-files orig/arch/um/include/process.h um/arch/um/include/process.h
14773 --- orig/arch/um/include/process.h      1969-12-31 19:00:00.000000000 -0500
14774 +++ um/arch/um/include/process.h        2002-10-23 21:08:04.000000000 -0400
14775 @@ -0,0 +1,25 @@
14776 +/* 
14777 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14778 + * Licensed under the GPL
14779 + */
14780 +
14781 +#ifndef __PROCESS_H__
14782 +#define __PROCESS_H__
14783 +
14784 +#include <asm/sigcontext.h>
14785 +
14786 +extern void sig_handler(int sig, struct sigcontext sc);
14787 +extern void alarm_handler(int sig, struct sigcontext sc);
14788 +
14789 +#endif
14790 +
14791 +/*
14792 + * Overrides for Emacs so that we follow Linus's tabbing style.
14793 + * Emacs will notice this stuff at the end of the file and automatically
14794 + * adjust the settings for this buffer only.  This must remain at the end
14795 + * of the file.
14796 + * ---------------------------------------------------------------------------
14797 + * Local variables:
14798 + * c-file-style: "linux"
14799 + * End:
14800 + */
14801 diff -Naur -X ../exclude-files orig/arch/um/include/ptrace_user.h um/arch/um/include/ptrace_user.h
14802 --- orig/arch/um/include/ptrace_user.h  1969-12-31 19:00:00.000000000 -0500
14803 +++ um/arch/um/include/ptrace_user.h    2002-10-23 21:08:04.000000000 -0400
14804 @@ -0,0 +1,18 @@
14805 +/* 
14806 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14807 + * Licensed under the GPL
14808 + */
14809 +
14810 +#ifndef __PTRACE_USER_H__
14811 +#define __PTRACE_USER_H__
14812 +
14813 +#include "sysdep/ptrace_user.h"
14814 +
14815 +extern int ptrace_getregs(long pid, unsigned long *regs_out);
14816 +extern int ptrace_setregs(long pid, unsigned long *regs_in);
14817 +extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
14818 +extern void arch_enter_kernel(void *task, int pid);
14819 +extern void arch_leave_kernel(void *task, int pid);
14820 +extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
14821 +
14822 +#endif
14823 diff -Naur -X ../exclude-files orig/arch/um/include/sigcontext.h um/arch/um/include/sigcontext.h
14824 --- orig/arch/um/include/sigcontext.h   1969-12-31 19:00:00.000000000 -0500
14825 +++ um/arch/um/include/sigcontext.h     2002-10-23 21:08:04.000000000 -0400
14826 @@ -0,0 +1,25 @@
14827 +/* 
14828 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14829 + * Licensed under the GPL
14830 + */
14831 +
14832 +#ifndef __UML_SIGCONTEXT_H__
14833 +#define __UML_SIGCONTEXT_H__
14834 +
14835 +#include "sysdep/sigcontext.h"
14836 +
14837 +extern int sc_size(void *data);
14838 +extern void sc_to_sc(void *to_ptr, void *from_ptr);
14839 +
14840 +#endif
14841 +
14842 +/*
14843 + * Overrides for Emacs so that we follow Linus's tabbing style.
14844 + * Emacs will notice this stuff at the end of the file and automatically
14845 + * adjust the settings for this buffer only.  This must remain at the end
14846 + * of the file.
14847 + * ---------------------------------------------------------------------------
14848 + * Local variables:
14849 + * c-file-style: "linux"
14850 + * End:
14851 + */
14852 diff -Naur -X ../exclude-files orig/arch/um/include/sigio.h um/arch/um/include/sigio.h
14853 --- orig/arch/um/include/sigio.h        1969-12-31 19:00:00.000000000 -0500
14854 +++ um/arch/um/include/sigio.h  2002-10-23 21:08:04.000000000 -0400
14855 @@ -0,0 +1,28 @@
14856 +/* 
14857 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14858 + * Licensed under the GPL
14859 + */
14860 +
14861 +#ifndef __SIGIO_H__
14862 +#define __SIGIO_H__
14863 +
14864 +extern int write_sigio_irq(int fd);
14865 +extern int register_sigio_fd(int fd);
14866 +extern int read_sigio_fd(int fd);
14867 +extern int add_sigio_fd(int fd, int read);
14868 +extern int ignore_sigio_fd(int fd);
14869 +extern void sigio_lock(void);
14870 +extern void sigio_unlock(void);
14871 +
14872 +#endif
14873 +
14874 +/*
14875 + * Overrides for Emacs so that we follow Linus's tabbing style.
14876 + * Emacs will notice this stuff at the end of the file and automatically
14877 + * adjust the settings for this buffer only.  This must remain at the end
14878 + * of the file.
14879 + * ---------------------------------------------------------------------------
14880 + * Local variables:
14881 + * c-file-style: "linux"
14882 + * End:
14883 + */
14884 diff -Naur -X ../exclude-files orig/arch/um/include/signal_kern.h um/arch/um/include/signal_kern.h
14885 --- orig/arch/um/include/signal_kern.h  1969-12-31 19:00:00.000000000 -0500
14886 +++ um/arch/um/include/signal_kern.h    2002-12-05 18:08:47.000000000 -0500
14887 @@ -0,0 +1,22 @@
14888 +/* 
14889 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
14890 + * Licensed under the GPL
14891 + */
14892 +
14893 +#ifndef __SIGNAL_KERN_H__
14894 +#define __SIGNAL_KERN_H__
14895 +
14896 +extern int have_signals(void *t);
14897 +
14898 +#endif
14899 +
14900 +/*
14901 + * Overrides for Emacs so that we follow Linus's tabbing style.
14902 + * Emacs will notice this stuff at the end of the file and automatically
14903 + * adjust the settings for this buffer only.  This must remain at the end
14904 + * of the file.
14905 + * ---------------------------------------------------------------------------
14906 + * Local variables:
14907 + * c-file-style: "linux"
14908 + * End:
14909 + */
14910 diff -Naur -X ../exclude-files orig/arch/um/include/signal_user.h um/arch/um/include/signal_user.h
14911 --- orig/arch/um/include/signal_user.h  1969-12-31 19:00:00.000000000 -0500
14912 +++ um/arch/um/include/signal_user.h    2002-10-23 21:08:04.000000000 -0400
14913 @@ -0,0 +1,26 @@
14914 +/* 
14915 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
14916 + * Licensed under the GPL
14917 + */
14918 +
14919 +#ifndef __SIGNAL_USER_H__
14920 +#define __SIGNAL_USER_H__
14921 +
14922 +extern int signal_stack_size;
14923 +
14924 +extern int change_sig(int signal, int on);
14925 +extern void set_sigstack(void *stack, int size);
14926 +extern void set_handler(int sig, void (*handler)(int), int flags, ...);
14927 +
14928 +#endif
14929 +
14930 +/*
14931 + * Overrides for Emacs so that we follow Linus's tabbing style.
14932 + * Emacs will notice this stuff at the end of the file and automatically
14933 + * adjust the settings for this buffer only.  This must remain at the end
14934 + * of the file.
14935 + * ---------------------------------------------------------------------------
14936 + * Local variables:
14937 + * c-file-style: "linux"
14938 + * End:
14939 + */
14940 diff -Naur -X ../exclude-files orig/arch/um/include/skas_ptrace.h um/arch/um/include/skas_ptrace.h
14941 --- orig/arch/um/include/skas_ptrace.h  1969-12-31 19:00:00.000000000 -0500
14942 +++ um/arch/um/include/skas_ptrace.h    2002-12-16 11:54:52.000000000 -0500
14943 @@ -0,0 +1,36 @@
14944 +/* 
14945 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
14946 + * Licensed under the GPL
14947 + */
14948 +
14949 +#ifndef __SKAS_PTRACE_H
14950 +#define __SKAS_PTRACE_H
14951 +
14952 +struct ptrace_faultinfo {
14953 +       int is_write;
14954 +       unsigned long addr;
14955 +};
14956 +
14957 +struct ptrace_ldt {
14958 +       int func;
14959 +       void *ptr;
14960 +       unsigned long bytecount;
14961 +};
14962 +
14963 +#define PTRACE_FAULTINFO 52
14964 +#define PTRACE_SIGPENDING 53
14965 +#define PTRACE_LDT 54
14966 +#define PTRACE_SWITCH_MM 55
14967 +
14968 +#endif
14969 +
14970 +/*
14971 + * Overrides for Emacs so that we follow Linus's tabbing style.
14972 + * Emacs will notice this stuff at the end of the file and automatically
14973 + * adjust the settings for this buffer only.  This must remain at the end
14974 + * of the file.
14975 + * ---------------------------------------------------------------------------
14976 + * Local variables:
14977 + * c-file-style: "linux"
14978 + * End:
14979 + */
14980 diff -Naur -X ../exclude-files orig/arch/um/include/syscall_user.h um/arch/um/include/syscall_user.h
14981 --- orig/arch/um/include/syscall_user.h 1969-12-31 19:00:00.000000000 -0500
14982 +++ um/arch/um/include/syscall_user.h   2002-10-23 21:08:04.000000000 -0400
14983 @@ -0,0 +1,23 @@
14984 +/* 
14985 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14986 + * Licensed under the GPL
14987 + */
14988 +
14989 +#ifndef __SYSCALL_USER_H
14990 +#define __SYSCALL_USER_H
14991 +
14992 +extern int record_syscall_start(int syscall);
14993 +extern void record_syscall_end(int index, int result);
14994 +
14995 +#endif
14996 +
14997 +/*
14998 + * Overrides for Emacs so that we follow Linus's tabbing style.
14999 + * Emacs will notice this stuff at the end of the file and automatically
15000 + * adjust the settings for this buffer only.  This must remain at the end
15001 + * of the file.
15002 + * ---------------------------------------------------------------------------
15003 + * Local variables:
15004 + * c-file-style: "linux"
15005 + * End:
15006 + */
15007 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/checksum.h um/arch/um/include/sysdep-i386/checksum.h
15008 --- orig/arch/um/include/sysdep-i386/checksum.h 1969-12-31 19:00:00.000000000 -0500
15009 +++ um/arch/um/include/sysdep-i386/checksum.h   2002-10-29 21:23:02.000000000 -0500
15010 @@ -0,0 +1,217 @@
15011 +/* 
15012 + * Licensed under the GPL
15013 + */
15014 +
15015 +#ifndef __UM_SYSDEP_CHECKSUM_H
15016 +#define __UM_SYSDEP_CHECKSUM_H
15017 +
15018 +#include "linux/string.h"
15019 +
15020 +/*
15021 + * computes the checksum of a memory block at buff, length len,
15022 + * and adds in "sum" (32-bit)
15023 + *
15024 + * returns a 32-bit number suitable for feeding into itself
15025 + * or csum_tcpudp_magic
15026 + *
15027 + * this function must be called with even lengths, except
15028 + * for the last fragment, which may be odd
15029 + *
15030 + * it's best to have buff aligned on a 32-bit boundary
15031 + */
15032 +unsigned int csum_partial(const unsigned char * buff, int len, 
15033 +                         unsigned int sum);
15034 +
15035 +/*
15036 + * the same as csum_partial, but copies from src while it
15037 + * checksums, and handles user-space pointer exceptions correctly, when needed.
15038 + *
15039 + * here even more important to align src and dst on a 32-bit (or even
15040 + * better 64-bit) boundary
15041 + */
15042 +
15043 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
15044 +                                 int sum, int *err_ptr);
15045 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
15046 +                                   int sum, int *err_ptr);
15047 +
15048 +/*
15049 + *     Note: when you get a NULL pointer exception here this means someone
15050 + *     passed in an incorrect kernel address to one of these functions.
15051 + *
15052 + *     If you use these functions directly please don't forget the
15053 + *     verify_area().
15054 + */
15055 +
15056 +static __inline__
15057 +unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
15058 +                                      int len, int sum)
15059 +{
15060 +       memcpy(dst, src, len);
15061 +       return(csum_partial(dst, len, sum));
15062 +}
15063 +
15064 +static __inline__
15065 +unsigned int csum_partial_copy_from_user(const char *src, char *dst,
15066 +                                        int len, int sum, int *err_ptr)
15067 +{
15068 +       return csum_partial_copy_from(src, dst, len, sum, err_ptr);
15069 +}
15070 +
15071 +/*
15072 + * These are the old (and unsafe) way of doing checksums, a warning message 
15073 + * will be printed if they are used and an exeption occurs.
15074 + *
15075 + * these functions should go away after some time.
15076 + */
15077 +
15078 +#define csum_partial_copy_fromuser csum_partial_copy_from_user
15079 +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
15080 +
15081 +/*
15082 + *     This is a version of ip_compute_csum() optimized for IP headers,
15083 + *     which always checksum on 4 octet boundaries.
15084 + *
15085 + *     By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
15086 + *     Arnt Gulbrandsen.
15087 + */
15088 +static inline unsigned short ip_fast_csum(unsigned char * iph,
15089 +                                         unsigned int ihl)
15090 +{
15091 +       unsigned int sum;
15092 +
15093 +       __asm__ __volatile__(
15094 +           "movl (%1), %0      ;\n"
15095 +           "subl $4, %2        ;\n"
15096 +           "jbe 2f             ;\n"
15097 +           "addl 4(%1), %0     ;\n"
15098 +           "adcl 8(%1), %0     ;\n"
15099 +           "adcl 12(%1), %0    ;\n"
15100 +"1:        adcl 16(%1), %0     ;\n"
15101 +           "lea 4(%1), %1      ;\n"
15102 +           "decl %2            ;\n"
15103 +           "jne 1b             ;\n"
15104 +           "adcl $0, %0        ;\n"
15105 +           "movl %0, %2        ;\n"
15106 +           "shrl $16, %0       ;\n"
15107 +           "addw %w2, %w0      ;\n"
15108 +           "adcl $0, %0        ;\n"
15109 +           "notl %0            ;\n"
15110 +"2:                            ;\n"
15111 +       /* Since the input registers which are loaded with iph and ipl
15112 +          are modified, we must also specify them as outputs, or gcc
15113 +          will assume they contain their original values. */
15114 +       : "=r" (sum), "=r" (iph), "=r" (ihl)
15115 +       : "1" (iph), "2" (ihl));
15116 +       return(sum);
15117 +}
15118 +
15119 +/*
15120 + *     Fold a partial checksum
15121 + */
15122 +
15123 +static inline unsigned int csum_fold(unsigned int sum)
15124 +{
15125 +       __asm__(
15126 +               "addl %1, %0            ;\n"
15127 +               "adcl $0xffff, %0       ;\n"
15128 +               : "=r" (sum)
15129 +               : "r" (sum << 16), "0" (sum & 0xffff0000)
15130 +       );
15131 +       return (~sum) >> 16;
15132 +}
15133 +
15134 +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
15135 +                                                  unsigned long daddr,
15136 +                                                  unsigned short len,
15137 +                                                  unsigned short proto,
15138 +                                                  unsigned int sum)
15139 +{
15140 +    __asm__(
15141 +       "addl %1, %0    ;\n"
15142 +       "adcl %2, %0    ;\n"
15143 +       "adcl %3, %0    ;\n"
15144 +       "adcl $0, %0    ;\n"
15145 +       : "=r" (sum)
15146 +       : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
15147 +    return sum;
15148 +}
15149 +
15150 +/*
15151 + * computes the checksum of the TCP/UDP pseudo-header
15152 + * returns a 16-bit checksum, already complemented
15153 + */
15154 +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
15155 +                                                  unsigned long daddr,
15156 +                                                  unsigned short len,
15157 +                                                  unsigned short proto,
15158 +                                                  unsigned int sum)
15159 +{
15160 +       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
15161 +}
15162 +
15163 +/*
15164 + * this routine is used for miscellaneous IP-like checksums, mainly
15165 + * in icmp.c
15166 + */
15167 +
15168 +static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
15169 +{
15170 +    return csum_fold (csum_partial(buff, len, 0));
15171 +}
15172 +
15173 +#define _HAVE_ARCH_IPV6_CSUM
15174 +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
15175 +                                                    struct in6_addr *daddr,
15176 +                                                    __u32 len,
15177 +                                                    unsigned short proto,
15178 +                                                    unsigned int sum)
15179 +{
15180 +       __asm__(
15181 +               "addl 0(%1), %0         ;\n"
15182 +               "adcl 4(%1), %0         ;\n"
15183 +               "adcl 8(%1), %0         ;\n"
15184 +               "adcl 12(%1), %0        ;\n"
15185 +               "adcl 0(%2), %0         ;\n"
15186 +               "adcl 4(%2), %0         ;\n"
15187 +               "adcl 8(%2), %0         ;\n"
15188 +               "adcl 12(%2), %0        ;\n"
15189 +               "adcl %3, %0            ;\n"
15190 +               "adcl %4, %0            ;\n"
15191 +               "adcl $0, %0            ;\n"
15192 +               : "=&r" (sum)
15193 +               : "r" (saddr), "r" (daddr),
15194 +                 "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
15195 +
15196 +       return csum_fold(sum);
15197 +}
15198 +
15199 +/*
15200 + *     Copy and checksum to user
15201 + */
15202 +#define HAVE_CSUM_COPY_USER
15203 +static __inline__ unsigned int csum_and_copy_to_user(const char *src, 
15204 +                                                    char *dst, int len,
15205 +                                                    int sum, int *err_ptr)
15206 +{
15207 +       if (access_ok(VERIFY_WRITE, dst, len))
15208 +               return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
15209 +
15210 +       if (len)
15211 +               *err_ptr = -EFAULT;
15212 +
15213 +       return -1; /* invalid checksum */
15214 +}
15215 +
15216 +#endif
15217 +
15218 +/*
15219 + * Overrides for Emacs so that we follow Linus's tabbing style.
15220 + * Emacs will notice this stuff at the end of the file and automatically
15221 + * adjust the settings for this buffer only.  This must remain at the end
15222 + * of the file.
15223 + * ---------------------------------------------------------------------------
15224 + * Local variables:
15225 + * c-file-style: "linux"
15226 + * End:
15227 + */
15228 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame.h um/arch/um/include/sysdep-i386/frame.h
15229 --- orig/arch/um/include/sysdep-i386/frame.h    1969-12-31 19:00:00.000000000 -0500
15230 +++ um/arch/um/include/sysdep-i386/frame.h      2002-12-06 14:07:54.000000000 -0500
15231 @@ -0,0 +1,29 @@
15232 +/* 
15233 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15234 + * Licensed under the GPL
15235 + */
15236 +
15237 +#ifndef __FRAME_I386_H
15238 +#define __FRAME_I386_H
15239 +
15240 +struct arch_frame_data_raw {
15241 +       unsigned long fp_start;
15242 +       unsigned long sr;
15243 +};
15244 +
15245 +struct arch_frame_data {
15246 +       int fpstate_size;
15247 +};
15248 +
15249 +#endif
15250 +
15251 +/*
15252 + * Overrides for Emacs so that we follow Linus's tabbing style.
15253 + * Emacs will notice this stuff at the end of the file and automatically
15254 + * adjust the settings for this buffer only.  This must remain at the end
15255 + * of the file.
15256 + * ---------------------------------------------------------------------------
15257 + * Local variables:
15258 + * c-file-style: "linux"
15259 + * End:
15260 + */
15261 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_kern.h um/arch/um/include/sysdep-i386/frame_kern.h
15262 --- orig/arch/um/include/sysdep-i386/frame_kern.h       1969-12-31 19:00:00.000000000 -0500
15263 +++ um/arch/um/include/sysdep-i386/frame_kern.h 2002-12-02 21:45:04.000000000 -0500
15264 @@ -0,0 +1,69 @@
15265 +/* 
15266 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15267 + * Licensed under the GPL
15268 + */
15269 +
15270 +#ifndef __FRAME_KERN_I386_H
15271 +#define __FRAME_KERN_I386_H
15272 +
15273 +/* This is called from sys_sigreturn.  It takes the sp at the point of the
15274 + * sigreturn system call and returns the address of the sigcontext struct
15275 + * on the stack.
15276 + */
15277 +
15278 +static inline void *sp_to_sc(unsigned long sp)
15279 +{
15280 +       return((void *) sp);
15281 +}
15282 +
15283 +static inline void *sp_to_uc(unsigned long sp)
15284 +{
15285 +       unsigned long uc;
15286 +
15287 +       uc = sp + signal_frame_si.uc_index - 
15288 +               signal_frame_si.common.sp_index - 4;
15289 +       return((void *) uc);
15290 +}
15291 +
15292 +static inline void *sp_to_rt_sc(unsigned long sp)
15293 +{
15294 +       unsigned long sc;
15295 +
15296 +       sc = sp - signal_frame_si.common.sp_index + 
15297 +               signal_frame_si.common.len - 4;
15298 +       return((void *) sc);
15299 +}
15300 +
15301 +static inline void *sp_to_mask(unsigned long sp)
15302 +{
15303 +       unsigned long mask;
15304 +
15305 +       mask = sp - signal_frame_sc.common.sp_index + 
15306 +               signal_frame_sc.common.len - 8;
15307 +       return((void *) mask);
15308 +}
15309 +
15310 +extern int sc_size(void *data);
15311 +
15312 +static inline void *sp_to_rt_mask(unsigned long sp)
15313 +{
15314 +       unsigned long mask;
15315 +
15316 +       mask = sp - signal_frame_si.common.sp_index + 
15317 +               signal_frame_si.common.len + 
15318 +               sc_size(&signal_frame_si.common.arch) - 4;
15319 +       return((void *) mask);
15320 +}
15321 +
15322 +#endif
15323 +
15324 +/*
15325 + * Overrides for Emacs so that we follow Linus's tabbing style.
15326 + * Emacs will notice this stuff at the end of the file and automatically
15327 + * adjust the settings for this buffer only.  This must remain at the end
15328 + * of the file.
15329 + * ---------------------------------------------------------------------------
15330 + * Local variables:
15331 + * c-file-style: "linux"
15332 + * End:
15333 + */
15334 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_user.h um/arch/um/include/sysdep-i386/frame_user.h
15335 --- orig/arch/um/include/sysdep-i386/frame_user.h       1969-12-31 19:00:00.000000000 -0500
15336 +++ um/arch/um/include/sysdep-i386/frame_user.h 2002-12-06 14:13:59.000000000 -0500
15337 @@ -0,0 +1,91 @@
15338 +/* 
15339 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15340 + * Licensed under the GPL
15341 + */
15342 +
15343 +#ifndef __FRAME_USER_I386_H
15344 +#define __FRAME_USER_I386_H
15345 +
15346 +#include <asm/page.h>
15347 +#include "sysdep/frame.h"
15348 +
15349 +/* This stuff is to calculate the size of the fp state struct at runtime
15350 + * because it has changed between 2.2 and 2.4 and it would be good for a
15351 + * UML compiled on one to work on the other.
15352 + * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
15353 + * just contains the address of the end of the sigcontext.  This is invoked
15354 + * from the signal handler.
15355 + * setup_arch_frame uses that data to figure out what 
15356 + * arch_frame_data.fpstate_size should be.  It really has no idea, since it's
15357 + * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
15358 + * everything from the end of the sigcontext up to the top of the stack.  So,
15359 + * it masks off the page number to get the offset within the page and subtracts
15360 + * that from the page size, and that's how big the fpstate struct will be
15361 + * considered to be.
15362 + */
15363 +
15364 +static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
15365 +                                       void *end, unsigned long srp)
15366 +{
15367 +       unsigned long sr = *((unsigned long *) srp);
15368 +
15369 +       data->fp_start = (unsigned long) end;
15370 +       if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
15371 +               data->sr = sr;
15372 +       else data->sr = 0;
15373 +}
15374 +
15375 +static inline void setup_arch_frame(struct arch_frame_data_raw *in, 
15376 +                                   struct arch_frame_data *out)
15377 +{
15378 +       unsigned long fpstate_start = in->fp_start;
15379 +
15380 +       if(in->sr == 0){
15381 +               fpstate_start &= ~PAGE_MASK;
15382 +               out->fpstate_size = PAGE_SIZE - fpstate_start;
15383 +       }
15384 +       else {
15385 +               out->fpstate_size = in->sr - fpstate_start;
15386 +       }
15387 +}
15388 +
15389 +/* This figures out where on the stack the SA_RESTORER function address
15390 + * is stored.  For i386, it's the signal handler return address, so it's
15391 + * located next to the frame pointer.
15392 + * This is inlined, so __builtin_frame_address(0) is correct.  Otherwise,
15393 + * it would have to be __builtin_frame_address(1).
15394 + */
15395 +
15396 +static inline unsigned long frame_restorer(void)
15397 +{
15398 +       unsigned long *fp;
15399 +
15400 +       fp = __builtin_frame_address(0);
15401 +       return((unsigned long) (fp + 1));
15402 +}
15403 +
15404 +/* Similarly, this returns the value of sp when the handler was first
15405 + * entered.  This is used to calculate the proper sp when delivering
15406 + * signals.
15407 + */
15408 +
15409 +static inline unsigned long frame_sp(void)
15410 +{
15411 +       unsigned long *fp;
15412 +
15413 +       fp = __builtin_frame_address(0);
15414 +       return((unsigned long) (fp + 1));
15415 +}
15416 +
15417 +#endif
15418 +
15419 +/*
15420 + * Overrides for Emacs so that we follow Linus's tabbing style.
15421 + * Emacs will notice this stuff at the end of the file and automatically
15422 + * adjust the settings for this buffer only.  This must remain at the end
15423 + * of the file.
15424 + * ---------------------------------------------------------------------------
15425 + * Local variables:
15426 + * c-file-style: "linux"
15427 + * End:
15428 + */
15429 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace.h um/arch/um/include/sysdep-i386/ptrace.h
15430 --- orig/arch/um/include/sysdep-i386/ptrace.h   1969-12-31 19:00:00.000000000 -0500
15431 +++ um/arch/um/include/sysdep-i386/ptrace.h     2003-01-17 13:23:31.000000000 -0500
15432 @@ -0,0 +1,193 @@
15433 +/* 
15434 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15435 + * Licensed under the GPL
15436 + */
15437 +
15438 +#ifndef __SYSDEP_I386_PTRACE_H
15439 +#define __SYSDEP_I386_PTRACE_H
15440 +
15441 +#include "uml-config.h"
15442 +
15443 +#ifdef UML_CONFIG_MODE_TT
15444 +#include "ptrace-tt.h"
15445 +#endif
15446 +
15447 +#ifdef UML_CONFIG_MODE_SKAS
15448 +#include "ptrace-skas.h"
15449 +#endif
15450 +
15451 +#include "choose-mode.h"
15452 +
15453 +union uml_pt_regs {
15454 +#ifdef UML_CONFIG_MODE_TT
15455 +       struct tt_regs {
15456 +               long syscall;
15457 +               void *sc;
15458 +       } tt;
15459 +#endif
15460 +#ifdef UML_CONFIG_MODE_SKAS
15461 +       struct skas_regs {
15462 +               unsigned long regs[HOST_FRAME_SIZE];
15463 +               unsigned long fp[HOST_FP_SIZE];
15464 +               unsigned long xfp[HOST_XFP_SIZE];
15465 +               unsigned long fault_addr;
15466 +               unsigned long fault_type;
15467 +               unsigned long trap_type;
15468 +               long syscall;
15469 +               int is_user;
15470 +       } skas;
15471 +#endif
15472 +};
15473 +
15474 +#define EMPTY_UML_PT_REGS { }
15475 +
15476 +extern int mode_tt;
15477 +
15478 +#define UPT_SC(r) ((r)->tt.sc)
15479 +#define UPT_IP(r) \
15480 +       CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
15481 +#define UPT_SP(r) \
15482 +       CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
15483 +#define UPT_EFLAGS(r) \
15484 +       CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
15485 +#define UPT_EAX(r) \
15486 +       CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
15487 +#define UPT_EBX(r) \
15488 +       CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
15489 +#define UPT_ECX(r) \
15490 +       CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
15491 +#define UPT_EDX(r) \
15492 +       CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
15493 +#define UPT_ESI(r) \
15494 +       CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
15495 +#define UPT_EDI(r) \
15496 +       CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
15497 +#define UPT_EBP(r) \
15498 +       CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
15499 +#define UPT_ORIG_EAX(r) \
15500 +       CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
15501 +#define UPT_CS(r) \
15502 +       CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
15503 +#define UPT_SS(r) \
15504 +       CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
15505 +#define UPT_DS(r) \
15506 +       CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
15507 +#define UPT_ES(r) \
15508 +       CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
15509 +#define UPT_FS(r) \
15510 +       CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
15511 +#define UPT_GS(r) \
15512 +       CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
15513 +
15514 +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
15515 +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
15516 +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
15517 +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
15518 +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
15519 +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
15520 +
15521 +extern int user_context(unsigned long sp);
15522 +
15523 +#define UPT_IS_USER(r) \
15524 +       CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
15525 +
15526 +struct syscall_args {
15527 +       unsigned long args[6];
15528 +};
15529 +
15530 +#define SYSCALL_ARGS(r) ((struct syscall_args) \
15531 +                        { .args = { UPT_SYSCALL_ARG1(r), \
15532 +                                    UPT_SYSCALL_ARG2(r), \
15533 +                                   UPT_SYSCALL_ARG3(r), \
15534 +                                    UPT_SYSCALL_ARG4(r), \
15535 +                                   UPT_SYSCALL_ARG5(r), \
15536 +                                    UPT_SYSCALL_ARG6(r) } } )
15537 +
15538 +#define UPT_REG(regs, reg) \
15539 +       ({      unsigned long val; \
15540 +               switch(reg){ \
15541 +               case EIP: val = UPT_IP(regs); break; \
15542 +               case UESP: val = UPT_SP(regs); break; \
15543 +               case EAX: val = UPT_EAX(regs); break; \
15544 +               case EBX: val = UPT_EBX(regs); break; \
15545 +               case ECX: val = UPT_ECX(regs); break; \
15546 +               case EDX: val = UPT_EDX(regs); break; \
15547 +               case ESI: val = UPT_ESI(regs); break; \
15548 +               case EDI: val = UPT_EDI(regs); break; \
15549 +               case EBP: val = UPT_EBP(regs); break; \
15550 +               case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \
15551 +               case CS: val = UPT_CS(regs); break; \
15552 +               case SS: val = UPT_SS(regs); break; \
15553 +               case DS: val = UPT_DS(regs); break; \
15554 +               case ES: val = UPT_ES(regs); break; \
15555 +               case FS: val = UPT_FS(regs); break; \
15556 +               case GS: val = UPT_GS(regs); break; \
15557 +               case EFL: val = UPT_EFLAGS(regs); break; \
15558 +               default :  \
15559 +                       panic("Bad register in UPT_REG : %d\n", reg);  \
15560 +                       val = -1; \
15561 +               } \
15562 +               val; \
15563 +       })
15564 +       
15565 +
15566 +#define UPT_SET(regs, reg, val) \
15567 +       do { \
15568 +               switch(reg){ \
15569 +               case EIP: UPT_IP(regs) = val; break; \
15570 +               case UESP: UPT_SP(regs) = val; break; \
15571 +               case EAX: UPT_EAX(regs) = val; break; \
15572 +               case EBX: UPT_EBX(regs) = val; break; \
15573 +               case ECX: UPT_ECX(regs) = val; break; \
15574 +               case EDX: UPT_EDX(regs) = val; break; \
15575 +               case ESI: UPT_ESI(regs) = val; break; \
15576 +               case EDI: UPT_EDI(regs) = val; break; \
15577 +               case EBP: UPT_EBP(regs) = val; break; \
15578 +               case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \
15579 +               case CS: UPT_CS(regs) = val; break; \
15580 +               case SS: UPT_SS(regs) = val; break; \
15581 +               case DS: UPT_DS(regs) = val; break; \
15582 +               case ES: UPT_ES(regs) = val; break; \
15583 +               case FS: UPT_FS(regs) = val; break; \
15584 +               case GS: UPT_GS(regs) = val; break; \
15585 +               case EFL: UPT_EFLAGS(regs) = val; break; \
15586 +               default :  \
15587 +                       panic("Bad register in UPT_SET : %d\n", reg);  \
15588 +                       break; \
15589 +               } \
15590 +       } while (0)
15591 +
15592 +#define UPT_SET_SYSCALL_RETURN(r, res) \
15593 +       CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
15594 +                    REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
15595 +
15596 +#define UPT_RESTART_SYSCALL(r) \
15597 +       CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
15598 +                   REGS_RESTART_SYSCALL((r)->skas.regs))
15599 +
15600 +#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
15601 +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
15602 +#define UPT_SYSCALL_RET(r) UPT_EAX(r)
15603 +
15604 +#define UPT_SEGV_IS_FIXABLE(r) \
15605 +       CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
15606 +                    REGS_SEGV_IS_FIXABLE(&r->skas))
15607 +
15608 +#define UPT_FAULT_ADDR(r) \
15609 +       CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
15610 +
15611 +#define UPT_FAULT_WRITE(r) \
15612 +       CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
15613 +
15614 +#endif
15615 +
15616 +/*
15617 + * Overrides for Emacs so that we follow Linus's tabbing style.
15618 + * Emacs will notice this stuff at the end of the file and automatically
15619 + * adjust the settings for this buffer only.  This must remain at the end
15620 + * of the file.
15621 + * ---------------------------------------------------------------------------
15622 + * Local variables:
15623 + * c-file-style: "linux"
15624 + * End:
15625 + */
15626 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace_user.h um/arch/um/include/sysdep-i386/ptrace_user.h
15627 --- orig/arch/um/include/sysdep-i386/ptrace_user.h      1969-12-31 19:00:00.000000000 -0500
15628 +++ um/arch/um/include/sysdep-i386/ptrace_user.h        2002-10-23 21:08:04.000000000 -0400
15629 @@ -0,0 +1,62 @@
15630 +/* 
15631 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15632 + * Licensed under the GPL
15633 + */
15634 +
15635 +#ifndef __SYSDEP_I386_PTRACE_USER_H__
15636 +#define __SYSDEP_I386_PTRACE_USER_H__
15637 +
15638 +#include <asm/ptrace.h>
15639 +
15640 +#define PT_OFFSET(r) ((r) * sizeof(long))
15641 +
15642 +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX])
15643 +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX)
15644 +
15645 +#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX)
15646 +#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX)
15647 +#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
15648 +#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
15649 +#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
15650 +
15651 +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
15652 +
15653 +#define PT_IP_OFFSET PT_OFFSET(EIP)
15654 +#define PT_IP(regs) ((regs)[EIP])
15655 +#define PT_SP(regs) ((regs)[UESP])
15656 +
15657 +#ifndef FRAME_SIZE
15658 +#define FRAME_SIZE (17)
15659 +#endif
15660 +#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
15661 +
15662 +#define FP_FRAME_SIZE (27)
15663 +#define FPX_FRAME_SIZE (128)
15664 +
15665 +#ifdef PTRACE_GETREGS
15666 +#define UM_HAVE_GETREGS
15667 +#endif
15668 +
15669 +#ifdef PTRACE_SETREGS
15670 +#define UM_HAVE_SETREGS
15671 +#endif
15672 +
15673 +#ifdef PTRACE_GETFPREGS
15674 +#define UM_HAVE_GETFPREGS
15675 +#endif
15676 +
15677 +#ifdef PTRACE_SETFPREGS
15678 +#define UM_HAVE_SETFPREGS
15679 +#endif
15680 +
15681 +#ifdef PTRACE_GETFPXREGS
15682 +#define UM_HAVE_GETFPXREGS
15683 +#endif
15684 +
15685 +#ifdef PTRACE_SETFPXREGS
15686 +#define UM_HAVE_SETFPXREGS
15687 +#endif
15688 +
15689 +extern void update_debugregs(int seq);
15690 +
15691 +#endif
15692 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/sigcontext.h um/arch/um/include/sysdep-i386/sigcontext.h
15693 --- orig/arch/um/include/sysdep-i386/sigcontext.h       1969-12-31 19:00:00.000000000 -0500
15694 +++ um/arch/um/include/sysdep-i386/sigcontext.h 2002-12-08 18:21:33.000000000 -0500
15695 @@ -0,0 +1,49 @@
15696 +/* 
15697 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15698 + * Licensed under the GPL
15699 + */
15700 +
15701 +#ifndef __SYS_SIGCONTEXT_I386_H
15702 +#define __SYS_SIGCONTEXT_I386_H
15703 +
15704 +#include "sc.h"
15705 +
15706 +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
15707 +
15708 +#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
15709 +#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
15710 +
15711 +#define SC_FAULT_ADDR(sc) SC_CR2(sc)
15712 +#define SC_FAULT_TYPE(sc) SC_ERR(sc)
15713 +
15714 +#define FAULT_WRITE(err) (err & 2)
15715 +#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
15716 +
15717 +#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
15718 +
15719 +#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
15720 +
15721 +/* ptrace expects that, at the start of a system call, %eax contains
15722 + * -ENOSYS, so this makes it so.
15723 + */
15724 +#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
15725 +
15726 +/* These are General Protection and Page Fault */
15727 +#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
15728 +
15729 +#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
15730 +
15731 +extern unsigned long *sc_sigmask(void *sc_ptr);
15732 +extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
15733 +
15734 +#endif
15735 +/*
15736 + * Overrides for Emacs so that we follow Linus's tabbing style.
15737 + * Emacs will notice this stuff at the end of the file and automatically
15738 + * adjust the settings for this buffer only.  This must remain at the end
15739 + * of the file.
15740 + * ---------------------------------------------------------------------------
15741 + * Local variables:
15742 + * c-file-style: "linux"
15743 + * End:
15744 + */
15745 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/syscalls.h um/arch/um/include/sysdep-i386/syscalls.h
15746 --- orig/arch/um/include/sysdep-i386/syscalls.h 1969-12-31 19:00:00.000000000 -0500
15747 +++ um/arch/um/include/sysdep-i386/syscalls.h   2002-12-08 18:04:15.000000000 -0500
15748 @@ -0,0 +1,61 @@
15749 +/* 
15750 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15751 + * Licensed under the GPL
15752 + */
15753 +
15754 +#include "asm/unistd.h"
15755 +#include "sysdep/ptrace.h"
15756 +
15757 +typedef long syscall_handler_t(struct pt_regs);
15758 +
15759 +#define EXECUTE_SYSCALL(syscall, regs) \
15760 +       ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
15761 +
15762 +extern syscall_handler_t sys_modify_ldt;
15763 +extern syscall_handler_t old_mmap_i386;
15764 +extern syscall_handler_t old_select;
15765 +extern syscall_handler_t sys_ni_syscall;
15766 +
15767 +#define ARCH_SYSCALLS \
15768 +       [ __NR_mmap ] = old_mmap_i386, \
15769 +       [ __NR_select ] = old_select, \
15770 +       [ __NR_vm86old ] = sys_ni_syscall, \
15771 +        [ __NR_modify_ldt ] = sys_modify_ldt, \
15772 +       [ __NR_lchown32 ] = sys_lchown, \
15773 +       [ __NR_getuid32 ] = sys_getuid, \
15774 +       [ __NR_getgid32 ] = sys_getgid, \
15775 +       [ __NR_geteuid32 ] = sys_geteuid, \
15776 +       [ __NR_getegid32 ] = sys_getegid, \
15777 +       [ __NR_setreuid32 ] = sys_setreuid, \
15778 +       [ __NR_setregid32 ] = sys_setregid, \
15779 +       [ __NR_getgroups32 ] = sys_getgroups, \
15780 +       [ __NR_setgroups32 ] = sys_setgroups, \
15781 +       [ __NR_fchown32 ] = sys_fchown, \
15782 +       [ __NR_setresuid32 ] = sys_setresuid, \
15783 +       [ __NR_getresuid32 ] = sys_getresuid, \
15784 +       [ __NR_setresgid32 ] = sys_setresgid, \
15785 +       [ __NR_getresgid32 ] = sys_getresgid, \
15786 +       [ __NR_chown32 ] = sys_chown, \
15787 +       [ __NR_setuid32 ] = sys_setuid, \
15788 +       [ __NR_setgid32 ] = sys_setgid, \
15789 +       [ __NR_setfsuid32 ] = sys_setfsuid, \
15790 +       [ __NR_setfsgid32 ] = sys_setfsgid, \
15791 +       [ __NR_pivot_root ] = sys_pivot_root, \
15792 +       [ __NR_mincore ] = sys_mincore, \
15793 +       [ __NR_madvise ] = sys_madvise, \
15794 +        [ 222 ] = sys_ni_syscall, 
15795 +        
15796 +/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
15797 +
15798 +#define LAST_ARCH_SYSCALL 222
15799 +
15800 +/*
15801 + * Overrides for Emacs so that we follow Linus's tabbing style.
15802 + * Emacs will notice this stuff at the end of the file and automatically
15803 + * adjust the settings for this buffer only.  This must remain at the end
15804 + * of the file.
15805 + * ---------------------------------------------------------------------------
15806 + * Local variables:
15807 + * c-file-style: "linux"
15808 + * End:
15809 + */
15810 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/ptrace.h um/arch/um/include/sysdep-ia64/ptrace.h
15811 --- orig/arch/um/include/sysdep-ia64/ptrace.h   1969-12-31 19:00:00.000000000 -0500
15812 +++ um/arch/um/include/sysdep-ia64/ptrace.h     2002-10-23 21:08:04.000000000 -0400
15813 @@ -0,0 +1,26 @@
15814 +/* 
15815 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15816 + * Licensed under the GPL
15817 + */
15818 +
15819 +#ifndef __SYSDEP_IA64_PTRACE_H
15820 +#define __SYSDEP_IA64_PTRACE_H
15821 +
15822 +struct sys_pt_regs {
15823 +  int foo;
15824 +};
15825 +
15826 +#define EMPTY_REGS { 0 }
15827 +
15828 +#endif
15829 +
15830 +/*
15831 + * Overrides for Emacs so that we follow Linus's tabbing style.
15832 + * Emacs will notice this stuff at the end of the file and automatically
15833 + * adjust the settings for this buffer only.  This must remain at the end
15834 + * of the file.
15835 + * ---------------------------------------------------------------------------
15836 + * Local variables:
15837 + * c-file-style: "linux"
15838 + * End:
15839 + */
15840 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/sigcontext.h um/arch/um/include/sysdep-ia64/sigcontext.h
15841 --- orig/arch/um/include/sysdep-ia64/sigcontext.h       1969-12-31 19:00:00.000000000 -0500
15842 +++ um/arch/um/include/sysdep-ia64/sigcontext.h 2002-10-23 21:08:04.000000000 -0400
15843 @@ -0,0 +1,20 @@
15844 +/* 
15845 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15846 + * Licensed under the GPL
15847 + */
15848 +
15849 +#ifndef __SYSDEP_IA64_SIGCONTEXT_H
15850 +#define __SYSDEP_IA64_SIGCONTEXT_H
15851 +
15852 +#endif
15853 +
15854 +/*
15855 + * Overrides for Emacs so that we follow Linus's tabbing style.
15856 + * Emacs will notice this stuff at the end of the file and automatically
15857 + * adjust the settings for this buffer only.  This must remain at the end
15858 + * of the file.
15859 + * ---------------------------------------------------------------------------
15860 + * Local variables:
15861 + * c-file-style: "linux"
15862 + * End:
15863 + */
15864 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/syscalls.h um/arch/um/include/sysdep-ia64/syscalls.h
15865 --- orig/arch/um/include/sysdep-ia64/syscalls.h 1969-12-31 19:00:00.000000000 -0500
15866 +++ um/arch/um/include/sysdep-ia64/syscalls.h   2002-10-23 21:08:04.000000000 -0400
15867 @@ -0,0 +1,20 @@
15868 +/* 
15869 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15870 + * Licensed under the GPL
15871 + */
15872 +
15873 +#ifndef __SYSDEP_IA64_SYSCALLS_H
15874 +#define __SYSDEP_IA64_SYSCALLS_H
15875 +
15876 +#endif
15877 +
15878 +/*
15879 + * Overrides for Emacs so that we follow Linus's tabbing style.
15880 + * Emacs will notice this stuff at the end of the file and automatically
15881 + * adjust the settings for this buffer only.  This must remain at the end
15882 + * of the file.
15883 + * ---------------------------------------------------------------------------
15884 + * Local variables:
15885 + * c-file-style: "linux"
15886 + * End:
15887 + */
15888 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/ptrace.h um/arch/um/include/sysdep-ppc/ptrace.h
15889 --- orig/arch/um/include/sysdep-ppc/ptrace.h    1969-12-31 19:00:00.000000000 -0500
15890 +++ um/arch/um/include/sysdep-ppc/ptrace.h      2002-10-23 21:08:04.000000000 -0400
15891 @@ -0,0 +1,104 @@
15892 +/* 
15893 + * Licensed under the GPL
15894 + */
15895 +
15896 +#ifndef __SYS_PTRACE_PPC_H
15897 +#define __SYS_PTRACE_PPC_H
15898 +
15899 +#include "linux/config.h"
15900 +#include "linux/types.h"
15901 +
15902 +/* the following taken from <asm-ppc/ptrace.h> */
15903 +
15904 +#ifdef CONFIG_PPC64
15905 +#define PPC_REG unsigned long /*long*/
15906 +#else
15907 +#define PPC_REG unsigned long
15908 +#endif
15909 +struct sys_pt_regs_s {
15910 +       PPC_REG gpr[32];
15911 +       PPC_REG nip;
15912 +       PPC_REG msr;
15913 +       PPC_REG orig_gpr3;      /* Used for restarting system calls */
15914 +       PPC_REG ctr;
15915 +       PPC_REG link;
15916 +       PPC_REG xer;
15917 +       PPC_REG ccr;
15918 +       PPC_REG mq;             /* 601 only (not used at present) */
15919 +                               /* Used on APUS to hold IPL value. */
15920 +       PPC_REG trap;           /* Reason for being here */
15921 +       PPC_REG dar;            /* Fault registers */
15922 +       PPC_REG dsisr;
15923 +       PPC_REG result;         /* Result of a system call */
15924 +};
15925 +
15926 +#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
15927 +
15928 +struct sys_pt_regs {
15929 +    PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
15930 +};
15931 +
15932 +#define UM_MAX_REG (PT_FPR0)
15933 +#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
15934 +
15935 +#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
15936 +
15937 +#define UM_REG(r, n) ((r)->regs[n])
15938 +
15939 +#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3)
15940 +#define UM_SP(r) UM_REG(r, PT_R1)
15941 +#define UM_IP(r) UM_REG(r, PT_NIP)
15942 +#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR)
15943 +#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0)
15944 +#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3)
15945 +#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4)
15946 +#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5)
15947 +#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6)
15948 +#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7)
15949 +#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8)
15950 +
15951 +#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG))
15952 +#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG))
15953 +#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG))
15954 +#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG))
15955 +#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG))
15956 +#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG))
15957 +#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG))
15958 +#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG))
15959 +#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG))
15960 +#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG))
15961 +#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG))
15962 +
15963 +#define UM_SET_SYSCALL_RETURN(_regs, result)           \
15964 +do {                                                    \
15965 +        if (result < 0) {                              \
15966 +               (_regs)->regs[PT_CCR] |= 0x10000000;    \
15967 +               UM_SYSCALL_RET((_regs)) = -result;      \
15968 +        } else {                                       \
15969 +               UM_SYSCALL_RET((_regs)) = result;       \
15970 +        }                                               \
15971 +} while(0)
15972 +
15973 +extern void shove_aux_table(unsigned long sp);
15974 +#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
15975 +
15976 +/* These aren't actually defined.  The undefs are just to make sure
15977 + * everyone's clear on the concept.
15978 + */
15979 +#undef UML_HAVE_GETREGS
15980 +#undef UML_HAVE_GETFPREGS
15981 +#undef UML_HAVE_SETREGS
15982 +#undef UML_HAVE_SETFPREGS
15983 +
15984 +#endif
15985 +
15986 +/*
15987 + * Overrides for Emacs so that we follow Linus's tabbing style.
15988 + * Emacs will notice this stuff at the end of the file and automatically
15989 + * adjust the settings for this buffer only.  This must remain at the end
15990 + * of the file.
15991 + * ---------------------------------------------------------------------------
15992 + * Local variables:
15993 + * c-file-style: "linux"
15994 + * End:
15995 + */
15996 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/sigcontext.h um/arch/um/include/sysdep-ppc/sigcontext.h
15997 --- orig/arch/um/include/sysdep-ppc/sigcontext.h        1969-12-31 19:00:00.000000000 -0500
15998 +++ um/arch/um/include/sysdep-ppc/sigcontext.h  2002-11-23 22:02:19.000000000 -0500
15999 @@ -0,0 +1,62 @@
16000 +/* 
16001 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16002 + * Licensed under the GPL
16003 + */
16004 +
16005 +#ifndef __SYS_SIGCONTEXT_PPC_H
16006 +#define __SYS_SIGCONTEXT_PPC_H
16007 +
16008 +#define DSISR_WRITE 0x02000000
16009 +
16010 +#define SC_FAULT_ADDR(sc) ({ \
16011 +               struct sigcontext *_sc = (sc); \
16012 +               long retval = -1; \
16013 +               switch (_sc->regs->trap) { \
16014 +               case 0x300: \
16015 +                       /* data exception */ \
16016 +                       retval = _sc->regs->dar; \
16017 +                       break; \
16018 +               case 0x400: \
16019 +                       /* instruction exception */ \
16020 +                       retval = _sc->regs->nip; \
16021 +                       break; \
16022 +               default: \
16023 +                       panic("SC_FAULT_ADDR: unhandled trap type\n"); \
16024 +               } \
16025 +               retval; \
16026 +       })
16027 +
16028 +#define SC_FAULT_WRITE(sc) ({ \
16029 +               struct sigcontext *_sc = (sc); \
16030 +               long retval = -1; \
16031 +               switch (_sc->regs->trap) { \
16032 +               case 0x300: \
16033 +                       /* data exception */ \
16034 +                       retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
16035 +                       break; \
16036 +               case 0x400: \
16037 +                       /* instruction exception: not a write */ \
16038 +                       retval = 0; \
16039 +                       break; \
16040 +               default: \
16041 +                       panic("SC_FAULT_ADDR: unhandled trap type\n"); \
16042 +               } \
16043 +               retval; \
16044 +       })
16045 +
16046 +#define SC_IP(sc) ((sc)->regs->nip)
16047 +#define SC_SP(sc) ((sc)->regs->gpr[1])
16048 +#define SEGV_IS_FIXABLE(sc) (1)
16049 +
16050 +#endif
16051 +
16052 +/*
16053 + * Overrides for Emacs so that we follow Linus's tabbing style.
16054 + * Emacs will notice this stuff at the end of the file and automatically
16055 + * adjust the settings for this buffer only.  This must remain at the end
16056 + * of the file.
16057 + * ---------------------------------------------------------------------------
16058 + * Local variables:
16059 + * c-file-style: "linux"
16060 + * End:
16061 + */
16062 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/syscalls.h um/arch/um/include/sysdep-ppc/syscalls.h
16063 --- orig/arch/um/include/sysdep-ppc/syscalls.h  1969-12-31 19:00:00.000000000 -0500
16064 +++ um/arch/um/include/sysdep-ppc/syscalls.h    2002-10-23 21:08:04.000000000 -0400
16065 @@ -0,0 +1,50 @@
16066 +/* 
16067 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16068 + * Licensed under the GPL
16069 + */
16070 +
16071 +typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2,
16072 +                              unsigned long arg3, unsigned long arg4,
16073 +                              unsigned long arg5, unsigned long arg6);
16074 +
16075 +#define EXECUTE_SYSCALL(syscall, regs) \
16076 +        (*sys_call_table[syscall])(UM_SYSCALL_ARG1(&regs), \
16077 +                                  UM_SYSCALL_ARG2(&regs), \
16078 +                                  UM_SYSCALL_ARG3(&regs), \
16079 +                                  UM_SYSCALL_ARG4(&regs), \
16080 +                                  UM_SYSCALL_ARG5(&regs), \
16081 +                                  UM_SYSCALL_ARG6(&regs))
16082 +
16083 +extern syscall_handler_t sys_mincore;
16084 +extern syscall_handler_t sys_madvise;
16085 +
16086 +/* old_mmap needs the correct prototype since syscall_kern.c includes
16087 + * this file.
16088 + */
16089 +int old_mmap(unsigned long addr, unsigned long len,
16090 +            unsigned long prot, unsigned long flags,
16091 +            unsigned long fd, unsigned long offset);
16092 +
16093 +#define ARCH_SYSCALLS \
16094 +       [ __NR_modify_ldt ] = sys_ni_syscall, \
16095 +       [ __NR_pciconfig_read ] = sys_ni_syscall, \
16096 +       [ __NR_pciconfig_write ] = sys_ni_syscall, \
16097 +       [ __NR_pciconfig_iobase ] = sys_ni_syscall, \
16098 +       [ __NR_pivot_root ] = sys_ni_syscall, \
16099 +       [ __NR_multiplexer ] = sys_ni_syscall, \
16100 +       [ __NR_mmap ] = old_mmap, \
16101 +       [ __NR_madvise ] = sys_madvise, \
16102 +       [ __NR_mincore ] = sys_mincore, 
16103 +
16104 +#define LAST_ARCH_SYSCALL __NR_mincore
16105 +
16106 +/*
16107 + * Overrides for Emacs so that we follow Linus's tabbing style.
16108 + * Emacs will notice this stuff at the end of the file and automatically
16109 + * adjust the settings for this buffer only.  This must remain at the end
16110 + * of the file.
16111 + * ---------------------------------------------------------------------------
16112 + * Local variables:
16113 + * c-file-style: "linux"
16114 + * End:
16115 + */
16116 diff -Naur -X ../exclude-files orig/arch/um/include/sysrq.h um/arch/um/include/sysrq.h
16117 --- orig/arch/um/include/sysrq.h        1969-12-31 19:00:00.000000000 -0500
16118 +++ um/arch/um/include/sysrq.h  2002-10-23 21:08:04.000000000 -0400
16119 @@ -0,0 +1,6 @@
16120 +#ifndef __UM_SYSRQ_H
16121 +#define __UM_SYSRQ_H
16122 +
16123 +extern void show_trace(unsigned long *stack);
16124 +
16125 +#endif
16126 diff -Naur -X ../exclude-files orig/arch/um/include/tempfile.h um/arch/um/include/tempfile.h
16127 --- orig/arch/um/include/tempfile.h     1969-12-31 19:00:00.000000000 -0500
16128 +++ um/arch/um/include/tempfile.h       2002-10-23 21:08:04.000000000 -0400
16129 @@ -0,0 +1,21 @@
16130 +/* 
16131 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16132 + * Licensed under the GPL
16133 + */
16134 +
16135 +#ifndef __TEMPFILE_H__
16136 +#define __TEMPFILE_H__
16137 +
16138 +extern int make_tempfile(const char *template, char **tempname, int do_unlink);
16139 +
16140 +#endif
16141 +/*
16142 + * Overrides for Emacs so that we follow Linus's tabbing style.
16143 + * Emacs will notice this stuff at the end of the file and automatically
16144 + * adjust the settings for this buffer only.  This must remain at the end
16145 + * of the file.
16146 + * ---------------------------------------------------------------------------
16147 + * Local variables:
16148 + * c-file-style: "linux"
16149 + * End:
16150 + */
16151 diff -Naur -X ../exclude-files orig/arch/um/include/time_user.h um/arch/um/include/time_user.h
16152 --- orig/arch/um/include/time_user.h    1969-12-31 19:00:00.000000000 -0500
16153 +++ um/arch/um/include/time_user.h      2003-01-08 12:55:47.000000000 -0500
16154 @@ -0,0 +1,17 @@
16155 +/* 
16156 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16157 + * Licensed under the GPL
16158 + */
16159 +
16160 +#ifndef __TIME_USER_H__
16161 +#define __TIME_USER_H__
16162 +
16163 +extern void timer(void);
16164 +extern void switch_timers(int to_real);
16165 +extern void set_interval(int timer_type);
16166 +extern void idle_sleep(int secs);
16167 +extern void enable_timer(void);
16168 +extern unsigned long time_lock(void);
16169 +extern void time_unlock(unsigned long);
16170 +
16171 +#endif
16172 diff -Naur -X ../exclude-files orig/arch/um/include/tlb.h um/arch/um/include/tlb.h
16173 --- orig/arch/um/include/tlb.h  1969-12-31 19:00:00.000000000 -0500
16174 +++ um/arch/um/include/tlb.h    2002-10-23 21:08:04.000000000 -0400
16175 @@ -0,0 +1,23 @@
16176 +/* 
16177 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16178 + * Licensed under the GPL
16179 + */
16180 +
16181 +#ifndef __TLB_H__
16182 +#define __TLB_H__
16183 +
16184 +extern void mprotect_kernel_vm(int w);
16185 +extern void force_flush_all(void);
16186 +
16187 +#endif
16188 +
16189 +/*
16190 + * Overrides for Emacs so that we follow Linus's tabbing style.
16191 + * Emacs will notice this stuff at the end of the file and automatically
16192 + * adjust the settings for this buffer only.  This must remain at the end
16193 + * of the file.
16194 + * ---------------------------------------------------------------------------
16195 + * Local variables:
16196 + * c-file-style: "linux"
16197 + * End:
16198 + */
16199 diff -Naur -X ../exclude-files orig/arch/um/include/ubd_user.h um/arch/um/include/ubd_user.h
16200 --- orig/arch/um/include/ubd_user.h     1969-12-31 19:00:00.000000000 -0500
16201 +++ um/arch/um/include/ubd_user.h       2003-03-06 18:09:14.000000000 -0500
16202 @@ -0,0 +1,77 @@
16203 +/* 
16204 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16205 + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
16206 + * Licensed under the GPL
16207 + */
16208 +
16209 +#ifndef __UM_UBD_USER_H
16210 +#define __UM_UBD_USER_H
16211 +
16212 +#include "os.h"
16213 +
16214 +enum ubd_req { UBD_READ, UBD_WRITE };
16215 +
16216 +struct io_thread_req {
16217 +       enum ubd_req op;
16218 +       int fds[2];
16219 +       unsigned long offsets[2];
16220 +       unsigned long long offset;
16221 +       unsigned long length;
16222 +       char *buffer;
16223 +       int sectorsize;
16224 +       unsigned long sector_mask;
16225 +       unsigned long cow_offset;
16226 +       unsigned long bitmap_words[2];
16227 +       int error;
16228 +};
16229 +
16230 +extern int open_ubd_file(char *file, struct openflags *openflags, 
16231 +                        char **backing_file_out, int *bitmap_offset_out, 
16232 +                        unsigned long *bitmap_len_out, int *data_offset_out,
16233 +                        int *create_cow_out);
16234 +extern int create_cow_file(char *cow_file, char *backing_file, 
16235 +                          struct openflags flags, int sectorsize, 
16236 +                          int *bitmap_offset_out, 
16237 +                          unsigned long *bitmap_len_out,
16238 +                          int *data_offset_out);
16239 +extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
16240 +extern int read_ubd_fs(int fd, void *buffer, int len);
16241 +extern int write_ubd_fs(int fd, char *buffer, int len);
16242 +extern int start_io_thread(unsigned long sp, int *fds_out);
16243 +extern void do_io(struct io_thread_req *req);
16244 +
16245 +static inline int ubd_test_bit(__u64 bit, unsigned char *data)
16246 +{
16247 +       __u64 n;
16248 +       int bits, off;
16249 +
16250 +       bits = sizeof(data[0]) * 8;
16251 +       n = bit / bits;
16252 +       off = bit % bits;
16253 +       return((data[n] & (1 << off)) != 0);
16254 +}
16255 +
16256 +static inline void ubd_set_bit(__u64 bit, unsigned char *data)
16257 +{
16258 +       __u64 n;
16259 +       int bits, off;
16260 +
16261 +       bits = sizeof(data[0]) * 8;
16262 +       n = bit / bits;
16263 +       off = bit % bits;
16264 +       data[n] |= (1 << off);
16265 +}
16266 +
16267 +
16268 +#endif
16269 +
16270 +/*
16271 + * Overrides for Emacs so that we follow Linus's tabbing style.
16272 + * Emacs will notice this stuff at the end of the file and automatically
16273 + * adjust the settings for this buffer only.  This must remain at the end
16274 + * of the file.
16275 + * ---------------------------------------------------------------------------
16276 + * Local variables:
16277 + * c-file-style: "linux"
16278 + * End:
16279 + */
16280 diff -Naur -X ../exclude-files orig/arch/um/include/umid.h um/arch/um/include/umid.h
16281 --- orig/arch/um/include/umid.h 1969-12-31 19:00:00.000000000 -0500
16282 +++ um/arch/um/include/umid.h   2002-12-16 20:52:19.000000000 -0500
16283 @@ -0,0 +1,22 @@
16284 +/*
16285 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16286 + * Licensed under the GPL
16287 + */
16288 +
16289 +#ifndef __UMID_H__
16290 +#define __UMID_H__
16291 +
16292 +extern int umid_file_name(char *name, char *buf, int len);
16293 +
16294 +#endif
16295 +
16296 +/*
16297 + * Overrides for Emacs so that we follow Linus's tabbing style.
16298 + * Emacs will notice this stuff at the end of the file and automatically
16299 + * adjust the settings for this buffer only.  This must remain at the end
16300 + * of the file.
16301 + * ---------------------------------------------------------------------------
16302 + * Local variables:
16303 + * c-file-style: "linux"
16304 + * End:
16305 + */
16306 diff -Naur -X ../exclude-files orig/arch/um/include/uml_uaccess.h um/arch/um/include/uml_uaccess.h
16307 --- orig/arch/um/include/uml_uaccess.h  1969-12-31 19:00:00.000000000 -0500
16308 +++ um/arch/um/include/uml_uaccess.h    2002-12-19 13:15:22.000000000 -0500
16309 @@ -0,0 +1,28 @@
16310 +/*
16311 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16312 + * Licensed under the GPL
16313 + */
16314 +
16315 +#ifndef __UML_UACCESS_H__
16316 +#define __UML_UACCESS_H__
16317 +
16318 +extern int __do_copy_to_user(void *to, const void *from, int n,
16319 +                                 void **fault_addr, void **fault_catcher);
16320 +extern unsigned long __do_user_copy(void *to, const void *from, int n,
16321 +                                   void **fault_addr, void **fault_catcher,
16322 +                                   void (*op)(void *to, const void *from,
16323 +                                              int n), int *faulted_out);
16324 +void __do_copy(void *to, const void *from, int n);
16325 +
16326 +#endif
16327 +
16328 +/*
16329 + * Overrides for Emacs so that we follow Linus's tabbing style.
16330 + * Emacs will notice this stuff at the end of the file and automatically
16331 + * adjust the settings for this buffer only.  This must remain at the end
16332 + * of the file.
16333 + * ---------------------------------------------------------------------------
16334 + * Local variables:
16335 + * c-file-style: "linux"
16336 + * End:
16337 + */
16338 diff -Naur -X ../exclude-files orig/arch/um/include/um_mmu.h um/arch/um/include/um_mmu.h
16339 --- orig/arch/um/include/um_mmu.h       1969-12-31 19:00:00.000000000 -0500
16340 +++ um/arch/um/include/um_mmu.h 2002-11-09 12:51:43.000000000 -0500
16341 @@ -0,0 +1,40 @@
16342 +/* 
16343 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16344 + * Licensed under the GPL
16345 + */
16346 +
16347 +#ifndef __ARCH_UM_MMU_H
16348 +#define __ARCH_UM_MMU_H
16349 +
16350 +#include "linux/config.h"
16351 +#include "choose-mode.h"
16352 +
16353 +#ifdef CONFIG_MODE_TT
16354 +#include "../kernel/tt/include/mmu.h"
16355 +#endif
16356 +
16357 +#ifdef CONFIG_MODE_SKAS
16358 +#include "../kernel/skas/include/mmu.h"
16359 +#endif
16360 +
16361 +typedef union {
16362 +#ifdef CONFIG_MODE_TT
16363 +       struct mmu_context_tt tt;
16364 +#endif
16365 +#ifdef CONFIG_MODE_SKAS
16366 +       struct mmu_context_skas skas;
16367 +#endif
16368 +} mm_context_t;
16369 +
16370 +#endif
16371 +
16372 +/*
16373 + * Overrides for Emacs so that we follow Linus's tabbing style.
16374 + * Emacs will notice this stuff at the end of the file and automatically
16375 + * adjust the settings for this buffer only.  This must remain at the end
16376 + * of the file.
16377 + * ---------------------------------------------------------------------------
16378 + * Local variables:
16379 + * c-file-style: "linux"
16380 + * End:
16381 + */
16382 diff -Naur -X ../exclude-files orig/arch/um/include/umn.h um/arch/um/include/umn.h
16383 --- orig/arch/um/include/umn.h  1969-12-31 19:00:00.000000000 -0500
16384 +++ um/arch/um/include/umn.h    2002-10-23 21:08:04.000000000 -0400
16385 @@ -0,0 +1,27 @@
16386 +/* 
16387 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16388 + * Licensed under the GPL
16389 + */
16390 +
16391 +#ifndef __UMN_H
16392 +#define __UMN_H
16393 +
16394 +extern int open_umn_tty(int *slave_out, int *slipno_out);
16395 +extern void close_umn_tty(int master, int slave);
16396 +extern int umn_send_packet(int fd, void *data, int len);
16397 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
16398 +extern void slip_unesc(unsigned char s);
16399 +extern void umn_read(int fd);
16400 +
16401 +#endif
16402 +
16403 +/*
16404 + * Overrides for Emacs so that we follow Linus's tabbing style.
16405 + * Emacs will notice this stuff at the end of the file and automatically
16406 + * adjust the settings for this buffer only.  This must remain at the end
16407 + * of the file.
16408 + * ---------------------------------------------------------------------------
16409 + * Local variables:
16410 + * c-file-style: "linux"
16411 + * End:
16412 + */
16413 diff -Naur -X ../exclude-files orig/arch/um/include/um_uaccess.h um/arch/um/include/um_uaccess.h
16414 --- orig/arch/um/include/um_uaccess.h   1969-12-31 19:00:00.000000000 -0500
16415 +++ um/arch/um/include/um_uaccess.h     2002-11-23 22:03:02.000000000 -0500
16416 @@ -0,0 +1,73 @@
16417 +/* 
16418 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16419 + * Licensed under the GPL
16420 + */
16421 +
16422 +#ifndef __ARCH_UM_UACCESS_H
16423 +#define __ARCH_UM_UACCESS_H
16424 +
16425 +#include "linux/config.h"
16426 +#include "choose-mode.h"
16427 +
16428 +#ifdef CONFIG_MODE_TT
16429 +#include "../kernel/tt/include/uaccess.h"
16430 +#endif
16431 +
16432 +#ifdef CONFIG_MODE_SKAS
16433 +#include "../kernel/skas/include/uaccess.h"
16434 +#endif
16435 +
16436 +#define access_ok(type, addr, size) \
16437 +       CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
16438 +
16439 +static inline int verify_area(int type, const void * addr, unsigned long size)
16440 +{
16441 +       return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
16442 +                               size));
16443 +}
16444 +
16445 +static inline int copy_from_user(void *to, const void *from, int n)
16446 +{
16447 +       return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
16448 +                               from, n));
16449 +}
16450 +
16451 +static inline int copy_to_user(void *to, const void *from, int n)
16452 +{
16453 +       return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to, 
16454 +                               from, n));
16455 +}
16456 +
16457 +static inline int strncpy_from_user(char *dst, const char *src, int count)
16458 +{
16459 +       return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
16460 +                               dst, src, count));
16461 +}
16462 +
16463 +static inline int __clear_user(void *mem, int len)
16464 +{
16465 +       return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
16466 +}
16467 +
16468 +static inline int clear_user(void *mem, int len)
16469 +{
16470 +       return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
16471 +}
16472 +
16473 +static inline int strnlen_user(const void *str, int len)
16474 +{
16475 +       return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
16476 +}
16477 +
16478 +#endif
16479 +
16480 +/*
16481 + * Overrides for Emacs so that we follow Linus's tabbing style.
16482 + * Emacs will notice this stuff at the end of the file and automatically
16483 + * adjust the settings for this buffer only.  This must remain at the end
16484 + * of the file.
16485 + * ---------------------------------------------------------------------------
16486 + * Local variables:
16487 + * c-file-style: "linux"
16488 + * End:
16489 + */
16490 diff -Naur -X ../exclude-files orig/arch/um/include/user.h um/arch/um/include/user.h
16491 --- orig/arch/um/include/user.h 1969-12-31 19:00:00.000000000 -0500
16492 +++ um/arch/um/include/user.h   2002-10-23 21:08:04.000000000 -0400
16493 @@ -0,0 +1,29 @@
16494 +/* 
16495 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16496 + * Licensed under the GPL
16497 + */
16498 +
16499 +#ifndef __USER_H__
16500 +#define __USER_H__
16501 +
16502 +extern void panic(const char *fmt, ...);
16503 +extern int printk(const char *fmt, ...);
16504 +extern void schedule(void);
16505 +extern void *um_kmalloc(int size);
16506 +extern void *um_kmalloc_atomic(int size);
16507 +extern void kfree(void *ptr);
16508 +extern int in_aton(char *str);
16509 +extern int open_gdb_chan(void);
16510 +
16511 +#endif
16512 +
16513 +/*
16514 + * Overrides for Emacs so that we follow Linus's tabbing style.
16515 + * Emacs will notice this stuff at the end of the file and automatically
16516 + * adjust the settings for this buffer only.  This must remain at the end
16517 + * of the file.
16518 + * ---------------------------------------------------------------------------
16519 + * Local variables:
16520 + * c-file-style: "linux"
16521 + * End:
16522 + */
16523 diff -Naur -X ../exclude-files orig/arch/um/include/user_util.h um/arch/um/include/user_util.h
16524 --- orig/arch/um/include/user_util.h    1969-12-31 19:00:00.000000000 -0500
16525 +++ um/arch/um/include/user_util.h      2003-05-15 13:53:40.000000000 -0400
16526 @@ -0,0 +1,104 @@
16527 +/* 
16528 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16529 + * Licensed under the GPL
16530 + */
16531 +
16532 +#ifndef __USER_UTIL_H__
16533 +#define __USER_UTIL_H__
16534 +
16535 +#include "sysdep/ptrace.h"
16536 +
16537 +extern int mode_tt;
16538 +
16539 +extern int grantpt(int __fd);
16540 +extern int unlockpt(int __fd);
16541 +extern char *ptsname(int __fd);
16542 +
16543 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
16544 +
16545 +struct cpu_task {
16546 +       int pid;
16547 +       void *task;
16548 +};
16549 +
16550 +extern struct cpu_task cpu_tasks[];
16551 +
16552 +struct signal_info {
16553 +       void (*handler)(int, union uml_pt_regs *);
16554 +       int is_irq;
16555 +};
16556 +
16557 +extern struct signal_info sig_info[];
16558 +
16559 +extern unsigned long low_physmem;
16560 +extern unsigned long high_physmem;
16561 +extern unsigned long uml_physmem;
16562 +extern unsigned long uml_reserved;
16563 +extern unsigned long end_vm;
16564 +extern unsigned long start_vm;
16565 +extern unsigned long highmem;
16566 +
16567 +extern char host_info[];
16568 +
16569 +extern char saved_command_line[];
16570 +extern char command_line[];
16571 +
16572 +extern char *tempdir;
16573 +
16574 +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
16575 +extern unsigned long _unprotected_end;
16576 +extern unsigned long brk_start;
16577 +
16578 +extern int pty_output_sigio;
16579 +extern int pty_close_sigio;
16580 +
16581 +extern void stop(void);
16582 +extern void stack_protections(unsigned long address);
16583 +extern void task_protections(unsigned long address);
16584 +extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
16585 +extern void *add_signal_handler(int sig, void (*handler)(int));
16586 +extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
16587 +                           int clone_flags, int (*tramp)(void *));
16588 +extern int linux_main(int argc, char **argv);
16589 +extern void set_cmdline(char *cmd);
16590 +extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
16591 +extern int get_pty(void);
16592 +extern void *um_kmalloc(int size);
16593 +extern int raw(int fd, int complain);
16594 +extern int switcheroo(int fd, int prot, void *from, void *to, int size);
16595 +extern void setup_machinename(char *machine_out);
16596 +extern void setup_hostinfo(void);
16597 +extern void add_arg(char *cmd_line, char *arg);
16598 +extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
16599 +extern void init_new_thread_signals(int altstack);
16600 +extern void do_exec(int old_pid, int new_pid);
16601 +extern void tracer_panic(char *msg, ...);
16602 +extern char *get_umid(int only_if_set);
16603 +extern void do_longjmp(void *p, int val);
16604 +extern void suspend_new_thread(int fd);
16605 +extern int detach(int pid, int sig);
16606 +extern int attach(int pid);
16607 +extern void kill_child_dead(int pid);
16608 +extern int cont(int pid);
16609 +extern void check_ptrace(void);
16610 +extern void check_sigio(void);
16611 +extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
16612 +extern void write_sigio_workaround(void);
16613 +extern void arch_check_bugs(void);
16614 +extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
16615 +extern int arch_fixup(unsigned long address, void *sc_ptr);
16616 +extern int can_do_skas(void);
16617 +extern void arch_init_thread(void);
16618 +
16619 +#endif
16620 +
16621 +/*
16622 + * Overrides for Emacs so that we follow Linus's tabbing style.
16623 + * Emacs will notice this stuff at the end of the file and automatically
16624 + * adjust the settings for this buffer only.  This must remain at the end
16625 + * of the file.
16626 + * ---------------------------------------------------------------------------
16627 + * Local variables:
16628 + * c-file-style: "linux"
16629 + * End:
16630 + */
16631 diff -Naur -X ../exclude-files orig/arch/um/kernel/checksum.c um/arch/um/kernel/checksum.c
16632 --- orig/arch/um/kernel/checksum.c      1969-12-31 19:00:00.000000000 -0500
16633 +++ um/arch/um/kernel/checksum.c        2002-10-31 22:39:58.000000000 -0500
16634 @@ -0,0 +1,42 @@
16635 +#include "asm/uaccess.h"
16636 +#include "linux/errno.h"
16637 +
16638 +extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
16639 +
16640 +extern unsigned int csum_partial(char *buff, int len, int sum)
16641 +{
16642 +       return(arch_csum_partial(buff, len, sum));
16643 +}
16644 +
16645 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
16646 +                                 int sum, int *err_ptr)
16647 +{
16648 +       if(copy_to_user(dst, src, len)){
16649 +               *err_ptr = -EFAULT;
16650 +               return(-1);
16651 +       }
16652 +
16653 +       return(arch_csum_partial(src, len, sum));
16654 +}
16655 +
16656 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
16657 +                                   int sum, int *err_ptr)
16658 +{
16659 +       if(copy_from_user(dst, src, len)){
16660 +               *err_ptr = -EFAULT;
16661 +               return(-1);
16662 +       }
16663 +
16664 +       return(arch_csum_partial(dst, len, sum));
16665 +}
16666 +
16667 +/*
16668 + * Overrides for Emacs so that we follow Linus's tabbing style.
16669 + * Emacs will notice this stuff at the end of the file and automatically
16670 + * adjust the settings for this buffer only.  This must remain at the end
16671 + * of the file.
16672 + * ---------------------------------------------------------------------------
16673 + * Local variables:
16674 + * c-file-style: "linux"
16675 + * End:
16676 + */
16677 diff -Naur -X ../exclude-files orig/arch/um/kernel/config.c.in um/arch/um/kernel/config.c.in
16678 --- orig/arch/um/kernel/config.c.in     1969-12-31 19:00:00.000000000 -0500
16679 +++ um/arch/um/kernel/config.c.in       2003-04-10 11:17:55.000000000 -0400
16680 @@ -0,0 +1,32 @@
16681 +/* 
16682 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16683 + * Licensed under the GPL
16684 + */
16685 +
16686 +#include <stdio.h>
16687 +#include <stdlib.h>
16688 +#include "init.h"
16689 +
16690 +static __initdata char *config = "CONFIG";
16691 +
16692 +static int __init print_config(char *line, int *add)
16693 +{
16694 +       printf("%s", config);
16695 +       exit(0);
16696 +}
16697 +
16698 +__uml_setup("--showconfig", print_config,
16699 +"--showconfig\n"
16700 +"    Prints the config file that this UML binary was generated from.\n\n"
16701 +);
16702 +
16703 +/*
16704 + * Overrides for Emacs so that we follow Linus's tabbing style.
16705 + * Emacs will notice this stuff at the end of the file and automatically
16706 + * adjust the settings for this buffer only.  This must remain at the end
16707 + * of the file.
16708 + * ---------------------------------------------------------------------------
16709 + * Local variables:
16710 + * c-file-style: "linux"
16711 + * End:
16712 + */
16713 diff -Naur -X ../exclude-files orig/arch/um/kernel/exec_kern.c um/arch/um/kernel/exec_kern.c
16714 --- orig/arch/um/kernel/exec_kern.c     1969-12-31 19:00:00.000000000 -0500
16715 +++ um/arch/um/kernel/exec_kern.c       2003-04-16 16:35:05.000000000 -0400
16716 @@ -0,0 +1,86 @@
16717 +/* 
16718 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
16719 + * Licensed under the GPL
16720 + */
16721 +
16722 +#include "linux/slab.h"
16723 +#include "linux/smp_lock.h"
16724 +#include "asm/ptrace.h"
16725 +#include "asm/pgtable.h"
16726 +#include "asm/pgalloc.h"
16727 +#include "asm/uaccess.h"
16728 +#include "user_util.h"
16729 +#include "kern_util.h"
16730 +#include "mem_user.h"
16731 +#include "kern.h"
16732 +#include "irq_user.h"
16733 +#include "tlb.h"
16734 +#include "2_5compat.h"
16735 +#include "os.h"
16736 +#include "time_user.h"
16737 +#include "choose-mode.h"
16738 +#include "mode_kern.h"
16739 +
16740 +void flush_thread(void)
16741 +{
16742 +       CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
16743 +}
16744 +
16745 +void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
16746 +{
16747 +       CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
16748 +}
16749 +
16750 +extern void log_exec(char **argv, void *tty);
16751 +
16752 +static int execve1(char *file, char **argv, char **env)
16753 +{
16754 +        int error;
16755 +
16756 +#ifdef CONFIG_TTY_LOG
16757 +       log_exec(argv, current->tty);
16758 +#endif
16759 +        error = do_execve(file, argv, env, &current->thread.regs);
16760 +        if (error == 0){
16761 +                current->ptrace &= ~PT_DTRACE;
16762 +                set_cmdline(current_cmd());
16763 +        }
16764 +        return(error);
16765 +}
16766 +
16767 +int um_execve(char *file, char **argv, char **env)
16768 +{
16769 +       int err;
16770 +
16771 +       err = execve1(file, argv, env);
16772 +       if(!err) 
16773 +               do_longjmp(current->thread.exec_buf, 1);
16774 +       return(err);
16775 +}
16776 +
16777 +int sys_execve(char *file, char **argv, char **env)
16778 +{
16779 +       int error;
16780 +       char *filename;
16781 +
16782 +       lock_kernel();
16783 +       filename = getname((char *) file);
16784 +       error = PTR_ERR(filename);
16785 +       if (IS_ERR(filename)) goto out;
16786 +       error = execve1(filename, argv, env);
16787 +       putname(filename);
16788 + out:
16789 +       unlock_kernel();
16790 +       return(error);
16791 +}
16792 +
16793 +/*
16794 + * Overrides for Emacs so that we follow Linus's tabbing style.
16795 + * Emacs will notice this stuff at the end of the file and automatically
16796 + * adjust the settings for this buffer only.  This must remain at the end
16797 + * of the file.
16798 + * ---------------------------------------------------------------------------
16799 + * Local variables:
16800 + * c-file-style: "linux"
16801 + * End:
16802 + */
16803 diff -Naur -X ../exclude-files orig/arch/um/kernel/exitcode.c um/arch/um/kernel/exitcode.c
16804 --- orig/arch/um/kernel/exitcode.c      1969-12-31 19:00:00.000000000 -0500
16805 +++ um/arch/um/kernel/exitcode.c        2002-11-07 18:22:04.000000000 -0500
16806 @@ -0,0 +1,73 @@
16807 +/* 
16808 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16809 + * Licensed under the GPL
16810 + */
16811 +
16812 +#include "linux/init.h"
16813 +#include "linux/ctype.h"
16814 +#include "linux/proc_fs.h"
16815 +#include "asm/uaccess.h"
16816 +
16817 +/* If read and write race, the read will still atomically read a valid
16818 + * value.
16819 + */
16820 +int uml_exitcode = 0;
16821 +
16822 +static int read_proc_exitcode(char *page, char **start, off_t off,
16823 +                             int count, int *eof, void *data)
16824 +{
16825 +       int len;
16826 +
16827 +       len = sprintf(page, "%d\n", uml_exitcode);
16828 +       len -= off;
16829 +       if(len <= off+count) *eof = 1;
16830 +       *start = page + off;
16831 +       if(len > count) len = count;
16832 +       if(len < 0) len = 0;
16833 +       return(len);
16834 +}
16835 +
16836 +static int write_proc_exitcode(struct file *file, const char *buffer,
16837 +                              unsigned long count, void *data)
16838 +{
16839 +       char *end, buf[sizeof("nnnnn\0")];
16840 +       int tmp;
16841 +
16842 +       if(copy_from_user(buf, buffer, count))
16843 +               return(-EFAULT);
16844 +       tmp = simple_strtol(buf, &end, 0);
16845 +       if((*end != '\0') && !isspace(*end))
16846 +               return(-EINVAL);
16847 +       uml_exitcode = tmp;
16848 +       return(count);
16849 +}
16850 +
16851 +static int make_proc_exitcode(void)
16852 +{
16853 +       struct proc_dir_entry *ent;
16854 +
16855 +       ent = create_proc_entry("exitcode", 0600, &proc_root);
16856 +       if(ent == NULL){
16857 +               printk("make_proc_exitcode : Failed to register "
16858 +                      "/proc/exitcode\n");
16859 +               return(0);
16860 +       }
16861 +
16862 +       ent->read_proc = read_proc_exitcode;
16863 +       ent->write_proc = write_proc_exitcode;
16864 +       
16865 +       return(0);
16866 +}
16867 +
16868 +__initcall(make_proc_exitcode);
16869 +
16870 +/*
16871 + * Overrides for Emacs so that we follow Linus's tabbing style.
16872 + * Emacs will notice this stuff at the end of the file and automatically
16873 + * adjust the settings for this buffer only.  This must remain at the end
16874 + * of the file.
16875 + * ---------------------------------------------------------------------------
16876 + * Local variables:
16877 + * c-file-style: "linux"
16878 + * End:
16879 + */
16880 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame.c um/arch/um/kernel/frame.c
16881 --- orig/arch/um/kernel/frame.c 1969-12-31 19:00:00.000000000 -0500
16882 +++ um/arch/um/kernel/frame.c   2002-12-11 11:12:41.000000000 -0500
16883 @@ -0,0 +1,342 @@
16884 +/* 
16885 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16886 + * Licensed under the GPL
16887 + */
16888 +
16889 +#include <stdio.h>
16890 +#include <stdlib.h>
16891 +#include <unistd.h>
16892 +#include <string.h>
16893 +#include <signal.h>
16894 +#include <wait.h>
16895 +#include <sched.h>
16896 +#include <errno.h>
16897 +#include <sys/ptrace.h>
16898 +#include <sys/syscall.h>
16899 +#include <sys/mman.h>
16900 +#include <asm/page.h>
16901 +#include <asm/ptrace.h>
16902 +#include <asm/sigcontext.h>
16903 +#include "sysdep/ptrace.h"
16904 +#include "sysdep/sigcontext.h"
16905 +#include "frame_user.h"
16906 +#include "kern_util.h"
16907 +#include "ptrace_user.h"
16908 +#include "os.h"
16909 +
16910 +static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
16911 +                        unsigned long top, void **data_out)
16912 +{
16913 +       unsigned long regs[FRAME_SIZE];
16914 +       int pid, status, n, len;
16915 +
16916 +       /* Start the child as a thread */
16917 +       pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
16918 +       if(pid < 0){
16919 +               printf("capture_stack : clone failed - errno = %d\n", errno);
16920 +               exit(1);
16921 +       }
16922 +
16923 +       /* Wait for it to stop itself and continue it with a SIGUSR1 to force 
16924 +        * it into the signal handler.
16925 +        */
16926 +       n = waitpid(pid, &status, WUNTRACED);
16927 +       if(n < 0){
16928 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
16929 +               exit(1);
16930 +       }
16931 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
16932 +               fprintf(stderr, "capture_stack : Expected SIGSTOP, "
16933 +                       "got status = 0x%x\n", status);
16934 +               exit(1);
16935 +       }
16936 +       if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
16937 +               printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
16938 +                      errno);
16939 +               exit(1);
16940 +       }
16941 +
16942 +       /* Wait for it to stop itself again and grab its registers again.  
16943 +        * At this point, the handler has stuffed the addresses of
16944 +        * sig, sc, and SA_RESTORER in raw.
16945 +        */
16946 +       n = waitpid(pid, &status, WUNTRACED);
16947 +       if(n < 0){
16948 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
16949 +               exit(1);
16950 +       }
16951 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
16952 +               fprintf(stderr, "capture_stack : Expected SIGSTOP, "
16953 +                       "got status = 0x%x\n", status);
16954 +               exit(1);
16955 +       }
16956 +       if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
16957 +               printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n", 
16958 +                      errno);
16959 +               exit(1);
16960 +       }
16961 +
16962 +       /* It has outlived its usefulness, so continue it so it can exit */
16963 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
16964 +               printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
16965 +                      errno);
16966 +               exit(1);
16967 +       }
16968 +       if(waitpid(pid, &status, 0) < 0){
16969 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
16970 +               exit(1);
16971 +       }
16972 +       if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
16973 +               printf("capture_stack : Expected exit signal 9, "
16974 +                      "got status = 0x%x\n", status);
16975 +               exit(1);
16976 +       }
16977 +
16978 +       /* The frame that we want is the top of the signal stack */
16979 +
16980 +       len = top - PT_SP(regs);
16981 +       *data_out = malloc(len);
16982 +       if(*data_out == NULL){
16983 +               printf("capture_stack : malloc failed - errno = %d\n", errno);
16984 +               exit(1);
16985 +       }
16986 +       memcpy(*data_out, (void *) PT_SP(regs), len);
16987 +
16988 +       return(len);
16989 +}
16990 +
16991 +struct common_raw {
16992 +       void *stack;
16993 +       int size;
16994 +       unsigned long sig;
16995 +       unsigned long sr;
16996 +       unsigned long sp;       
16997 +       struct arch_frame_data_raw arch;
16998 +};
16999 +
17000 +#define SA_RESTORER (0x04000000)
17001 +
17002 +typedef unsigned long old_sigset_t;
17003 +
17004 +struct old_sigaction {
17005 +       __sighandler_t handler;
17006 +       old_sigset_t sa_mask;
17007 +       unsigned long sa_flags;
17008 +       void (*sa_restorer)(void);
17009 +};
17010 +
17011 +static void child_common(struct common_raw *common, sighandler_t handler,
17012 +                        int restorer, int flags)
17013 +{
17014 +       stack_t ss = ((stack_t) { .ss_sp        = common->stack,
17015 +                                 .ss_flags     = 0,
17016 +                                 .ss_size      = common->size });
17017 +       int err;
17018 +
17019 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
17020 +               printf("PTRACE_TRACEME failed, errno = %d\n", errno);
17021 +       }
17022 +       if(sigaltstack(&ss, NULL) < 0){
17023 +               printf("sigaltstack failed - errno = %d\n", errno);
17024 +               kill(getpid(), SIGKILL);
17025 +       }
17026 +
17027 +       if(restorer){
17028 +               struct sigaction sa;
17029 +
17030 +               sa.sa_handler = handler;
17031 +               sigemptyset(&sa.sa_mask);
17032 +               sa.sa_flags = SA_ONSTACK | flags;
17033 +               err = sigaction(SIGUSR1, &sa, NULL);
17034 +       }
17035 +       else {
17036 +               struct old_sigaction sa;
17037 +
17038 +               sa.handler = handler;
17039 +               sa.sa_mask = 0;
17040 +               sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
17041 +               err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
17042 +       }
17043 +       
17044 +       if(err < 0){
17045 +               printf("sigaction failed - errno = %d\n", errno);
17046 +               kill(getpid(), SIGKILL);
17047 +       }
17048 +
17049 +       os_stop_process(os_getpid());
17050 +}
17051 +
17052 +/* Changed only during early boot */
17053 +struct sc_frame signal_frame_sc;
17054 +
17055 +struct sc_frame signal_frame_sc_sr;
17056 +
17057 +struct sc_frame_raw {
17058 +       struct common_raw common;
17059 +       unsigned long sc;
17060 +       int restorer;
17061 +};
17062 +
17063 +/* Changed only during early boot */
17064 +static struct sc_frame_raw *raw_sc = NULL;
17065 +
17066 +static void sc_handler(int sig, struct sigcontext sc)
17067 +{
17068 +       raw_sc->common.sig = (unsigned long) &sig;
17069 +       raw_sc->common.sr = frame_restorer();
17070 +       raw_sc->common.sp = frame_sp();
17071 +       raw_sc->sc = (unsigned long) &sc;
17072 +       setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
17073 +
17074 +       os_stop_process(os_getpid());
17075 +       kill(getpid(), SIGKILL);
17076 +}
17077 +
17078 +static int sc_child(void *arg)
17079 +{
17080 +       raw_sc = arg;
17081 +       child_common(&raw_sc->common, (sighandler_t) sc_handler, 
17082 +                    raw_sc->restorer, 0);
17083 +       return(-1);
17084 +}
17085 +
17086 +/* Changed only during early boot */
17087 +struct si_frame signal_frame_si;
17088 +
17089 +struct si_frame_raw {
17090 +       struct common_raw common;
17091 +       unsigned long sip;
17092 +       unsigned long si;
17093 +       unsigned long ucp;
17094 +       unsigned long uc;
17095 +};
17096 +
17097 +/* Changed only during early boot */
17098 +static struct si_frame_raw *raw_si = NULL;
17099 +
17100 +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
17101 +{
17102 +       raw_si->common.sig = (unsigned long) &sig;
17103 +       raw_si->common.sr = frame_restorer();
17104 +       raw_si->common.sp = frame_sp();
17105 +       raw_si->sip = (unsigned long) &si;
17106 +       raw_si->si = (unsigned long) si;
17107 +       raw_si->ucp = (unsigned long) &ucontext;
17108 +       raw_si->uc = (unsigned long) ucontext;
17109 +       setup_arch_frame_raw(&raw_si->common.arch, 
17110 +                            ucontext->uc_mcontext.fpregs, raw_si->common.sr);
17111 +       
17112 +       os_stop_process(os_getpid());
17113 +       kill(getpid(), SIGKILL);
17114 +}
17115 +
17116 +static int si_child(void *arg)
17117 +{
17118 +       raw_si = arg;
17119 +       child_common(&raw_si->common, (sighandler_t) si_handler, 1, 
17120 +                    SA_SIGINFO);
17121 +       return(-1);
17122 +}
17123 +
17124 +static int relative_sr(unsigned long sr, int sr_index, void *stack, 
17125 +                      void *framep)
17126 +{
17127 +       unsigned long *srp = (unsigned long *) sr;
17128 +       unsigned long frame = (unsigned long) framep;
17129 +
17130 +       if((*srp & PAGE_MASK) == (unsigned long) stack){
17131 +               *srp -= sr;
17132 +               *((unsigned long *) (frame + sr_index)) = *srp;
17133 +               return(1);
17134 +       }
17135 +       else return(0);
17136 +}
17137 +
17138 +static unsigned long capture_stack_common(int (*proc)(void *), void *arg, 
17139 +                                         struct common_raw *common_in, 
17140 +                                         void *top, void *sigstack, 
17141 +                                         int stack_len, 
17142 +                                         struct frame_common *common_out)
17143 +{
17144 +       unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
17145 +
17146 +       common_in->stack = (void *) sigstack;
17147 +       common_in->size = stack_len;
17148 +       common_out->len = capture_stack(proc, arg, top, sig_top, 
17149 +                                       &common_out->data);
17150 +       base = sig_top - common_out->len;
17151 +       common_out->sig_index = common_in->sig - base;
17152 +       common_out->sp_index = common_in->sp - base;
17153 +       common_out->sr_index = common_in->sr - base;
17154 +       common_out->sr_relative = relative_sr(common_in->sr, 
17155 +                                             common_out->sr_index, sigstack, 
17156 +                                             common_out->data);
17157 +       return(base);
17158 +}
17159 +
17160 +void capture_signal_stack(void)
17161 +{
17162 +       struct sc_frame_raw raw_sc;
17163 +       struct si_frame_raw raw_si;
17164 +       void *stack, *sigstack;
17165 +       unsigned long top, sig_top, base;
17166 +
17167 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
17168 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
17169 +       sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
17170 +                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
17171 +       if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){
17172 +               printf("capture_signal_stack : mmap failed - errno = %d\n", 
17173 +                      errno);
17174 +               exit(1);
17175 +       }
17176 +
17177 +       top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
17178 +       sig_top = (unsigned long) sigstack + PAGE_SIZE;
17179 +
17180 +       /* Get the sigcontext, no sigrestorer layout */
17181 +       raw_sc.restorer = 0;
17182 +       base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
17183 +                                   (void *) top, sigstack, PAGE_SIZE, 
17184 +                                   &signal_frame_sc.common);
17185 +
17186 +       signal_frame_sc.sc_index = raw_sc.sc - base;
17187 +       setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
17188 +
17189 +       /* Ditto for the sigcontext, sigrestorer layout */
17190 +       raw_sc.restorer = 1;
17191 +       base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
17192 +                                   (void *) top, sigstack, PAGE_SIZE, 
17193 +                                   &signal_frame_sc_sr.common);
17194 +       signal_frame_sc_sr.sc_index = raw_sc.sc - base;
17195 +       setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
17196 +
17197 +       /* And the siginfo layout */
17198 +
17199 +       base = capture_stack_common(si_child, &raw_si, &raw_si.common, 
17200 +                                   (void *) top, sigstack, PAGE_SIZE, 
17201 +                                   &signal_frame_si.common);
17202 +       signal_frame_si.sip_index = raw_si.sip - base;
17203 +       signal_frame_si.si_index = raw_si.si - base;
17204 +       signal_frame_si.ucp_index = raw_si.ucp - base;
17205 +       signal_frame_si.uc_index = raw_si.uc - base;
17206 +       setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
17207 +
17208 +       if((munmap(stack, PAGE_SIZE) < 0) || 
17209 +          (munmap(sigstack, PAGE_SIZE) < 0)){
17210 +               printf("capture_signal_stack : munmap failed - errno = %d\n", 
17211 +                      errno);
17212 +               exit(1);
17213 +       }
17214 +}
17215 +
17216 +/*
17217 + * Overrides for Emacs so that we follow Linus's tabbing style.
17218 + * Emacs will notice this stuff at the end of the file and automatically
17219 + * adjust the settings for this buffer only.  This must remain at the end
17220 + * of the file.
17221 + * ---------------------------------------------------------------------------
17222 + * Local variables:
17223 + * c-file-style: "linux"
17224 + * End:
17225 + */
17226 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame_kern.c um/arch/um/kernel/frame_kern.c
17227 --- orig/arch/um/kernel/frame_kern.c    1969-12-31 19:00:00.000000000 -0500
17228 +++ um/arch/um/kernel/frame_kern.c      2002-12-08 19:44:13.000000000 -0500
17229 @@ -0,0 +1,171 @@
17230 +/* 
17231 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17232 + * Licensed under the GPL
17233 + */
17234 +
17235 +#include "asm/ptrace.h"
17236 +#include "asm/uaccess.h"
17237 +#include "asm/signal.h"
17238 +#include "asm/uaccess.h"
17239 +#include "asm/ucontext.h"
17240 +#include "frame_kern.h"
17241 +#include "sigcontext.h"
17242 +#include "sysdep/ptrace.h"
17243 +#include "choose-mode.h"
17244 +#include "mode.h"
17245 +
17246 +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
17247 +{
17248 +       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
17249 +               return -EFAULT;
17250 +       if (from->si_code < 0)
17251 +               return __copy_to_user(to, from, sizeof(siginfo_t));
17252 +       else {
17253 +               int err;
17254 +
17255 +               /* If you change siginfo_t structure, please be sure
17256 +                  this code is fixed accordingly.
17257 +                  It should never copy any pad contained in the structure
17258 +                  to avoid security leaks, but must copy the generic
17259 +                  3 ints plus the relevant union member.  */
17260 +               err = __put_user(from->si_signo, &to->si_signo);
17261 +               err |= __put_user(from->si_errno, &to->si_errno);
17262 +               err |= __put_user((short)from->si_code, &to->si_code);
17263 +               /* First 32bits of unions are always present.  */
17264 +               err |= __put_user(from->si_pid, &to->si_pid);
17265 +               switch (from->si_code >> 16) {
17266 +               case __SI_FAULT >> 16:
17267 +                       break;
17268 +               case __SI_CHLD >> 16:
17269 +                       err |= __put_user(from->si_utime, &to->si_utime);
17270 +                       err |= __put_user(from->si_stime, &to->si_stime);
17271 +                       err |= __put_user(from->si_status, &to->si_status);
17272 +               default:
17273 +                       err |= __put_user(from->si_uid, &to->si_uid);
17274 +                       break;
17275 +               }
17276 +               return err;
17277 +       }
17278 +}
17279 +
17280 +static int copy_restorer(void (*restorer)(void), unsigned long start, 
17281 +                        unsigned long sr_index, int sr_relative)
17282 +{
17283 +       unsigned long sr;
17284 +
17285 +       if(sr_relative){
17286 +               sr = (unsigned long) restorer;
17287 +               sr += start + sr_index;
17288 +               restorer = (void (*)(void)) sr;
17289 +       }
17290 +
17291 +       return(copy_to_user((void *) (start + sr_index), &restorer, 
17292 +                           sizeof(restorer)));
17293 +}
17294 +
17295 +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
17296 +                          struct arch_frame_data *arch)
17297 +{
17298 +       return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
17299 +                                             arch),
17300 +                          copy_sc_to_user_skas(to, fp, &from->regs,
17301 +                                               current->thread.cr2,
17302 +                                               current->thread.err)));
17303 +}
17304 +
17305 +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
17306 +                                unsigned long sp)
17307 +{
17308 +       int err = 0;
17309 +
17310 +       err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
17311 +       err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
17312 +       err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
17313 +       err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs,
17314 +                              &signal_frame_si.common.arch);
17315 +       err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
17316 +       return(err);
17317 +}
17318 +
17319 +int setup_signal_stack_si(unsigned long stack_top, int sig, 
17320 +                         unsigned long handler, void (*restorer)(void), 
17321 +                         struct pt_regs *regs, siginfo_t *info, 
17322 +                         sigset_t *mask)
17323 +{
17324 +       unsigned long start;
17325 +       void *sip, *ucp, *fp;
17326 +
17327 +       start = stack_top - signal_frame_si.common.len;
17328 +       sip = (void *) (start + signal_frame_si.si_index);
17329 +       ucp = (void *) (start + signal_frame_si.uc_index);
17330 +       fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
17331 +
17332 +       if(restorer == NULL)
17333 +               panic("setup_signal_stack_si - no restorer");
17334 +
17335 +       if(copy_to_user((void *) start, signal_frame_si.common.data,
17336 +                       signal_frame_si.common.len) ||
17337 +          copy_to_user((void *) (start + signal_frame_si.common.sig_index), 
17338 +                       &sig, sizeof(sig)) ||
17339 +          copy_siginfo_to_user(sip, info) ||
17340 +          copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
17341 +                       sizeof(sip)) ||
17342 +          copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
17343 +          copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
17344 +                       sizeof(ucp)) ||
17345 +          copy_restorer(restorer, start, signal_frame_si.common.sr_index,
17346 +                        signal_frame_si.common.sr_relative))
17347 +               return(1);
17348 +       
17349 +       PT_REGS_IP(regs) = handler;
17350 +       PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
17351 +       return(0);
17352 +}
17353 +
17354 +int setup_signal_stack_sc(unsigned long stack_top, int sig, 
17355 +                         unsigned long handler, void (*restorer)(void), 
17356 +                         struct pt_regs *regs, sigset_t *mask)
17357 +{
17358 +       struct frame_common *frame = &signal_frame_sc_sr.common;
17359 +       void *user_sc;
17360 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
17361 +       unsigned long sigs, sr;
17362 +       unsigned long start = stack_top - frame->len - sig_size;
17363 +
17364 +       user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
17365 +       if(restorer == NULL){
17366 +               frame = &signal_frame_sc.common;
17367 +               user_sc = (void *) (start + signal_frame_sc.sc_index);
17368 +               sr = (unsigned long) frame->data;
17369 +               sr += frame->sr_index;
17370 +               sr = *((unsigned long *) sr);
17371 +               restorer = ((void (*)(void)) sr);
17372 +       }
17373 +
17374 +       sigs = start + frame->len;
17375 +       if(copy_to_user((void *) start, frame->data, frame->len) ||
17376 +          copy_to_user((void *) (start + frame->sig_index), &sig, 
17377 +                       sizeof(sig)) ||
17378 +          copy_sc_to_user(user_sc, NULL, regs, 
17379 +                          &signal_frame_sc.common.arch) ||
17380 +          copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
17381 +          copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
17382 +          copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
17383 +               return(1);
17384 +
17385 +       PT_REGS_IP(regs) = handler;
17386 +       PT_REGS_SP(regs) = start + frame->sp_index;
17387 +
17388 +       return(0);
17389 +}
17390 +
17391 +/*
17392 + * Overrides for Emacs so that we follow Linus's tabbing style.
17393 + * Emacs will notice this stuff at the end of the file and automatically
17394 + * adjust the settings for this buffer only.  This must remain at the end
17395 + * of the file.
17396 + * ---------------------------------------------------------------------------
17397 + * Local variables:
17398 + * c-file-style: "linux"
17399 + * End:
17400 + */
17401 diff -Naur -X ../exclude-files orig/arch/um/kernel/gmon_syms.c um/arch/um/kernel/gmon_syms.c
17402 --- orig/arch/um/kernel/gmon_syms.c     1969-12-31 19:00:00.000000000 -0500
17403 +++ um/arch/um/kernel/gmon_syms.c       2002-10-23 21:08:04.000000000 -0400
17404 @@ -0,0 +1,20 @@
17405 +/* 
17406 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17407 + * Licensed under the GPL
17408 + */
17409 +
17410 +#include "linux/module.h"
17411 +
17412 +extern void __bb_init_func(void *);
17413 +EXPORT_SYMBOL(__bb_init_func);
17414 +
17415 +/*
17416 + * Overrides for Emacs so that we follow Linus's tabbing style.
17417 + * Emacs will notice this stuff at the end of the file and automatically
17418 + * adjust the settings for this buffer only.  This must remain at the end
17419 + * of the file.
17420 + * ---------------------------------------------------------------------------
17421 + * Local variables:
17422 + * c-file-style: "linux"
17423 + * End:
17424 + */
17425 diff -Naur -X ../exclude-files orig/arch/um/kernel/gprof_syms.c um/arch/um/kernel/gprof_syms.c
17426 --- orig/arch/um/kernel/gprof_syms.c    1969-12-31 19:00:00.000000000 -0500
17427 +++ um/arch/um/kernel/gprof_syms.c      2002-10-23 21:08:04.000000000 -0400
17428 @@ -0,0 +1,20 @@
17429 +/* 
17430 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
17431 + * Licensed under the GPL
17432 + */
17433 +
17434 +#include "linux/module.h"
17435 +
17436 +extern void mcount(void);
17437 +EXPORT_SYMBOL(mcount);
17438 +
17439 +/*
17440 + * Overrides for Emacs so that we follow Linus's tabbing style.
17441 + * Emacs will notice this stuff at the end of the file and automatically
17442 + * adjust the settings for this buffer only.  This must remain at the end
17443 + * of the file.
17444 + * ---------------------------------------------------------------------------
17445 + * Local variables:
17446 + * c-file-style: "linux"
17447 + * End:
17448 + */
17449 diff -Naur -X ../exclude-files orig/arch/um/kernel/helper.c um/arch/um/kernel/helper.c
17450 --- orig/arch/um/kernel/helper.c        1969-12-31 19:00:00.000000000 -0500
17451 +++ um/arch/um/kernel/helper.c  2002-10-31 10:34:23.000000000 -0500
17452 @@ -0,0 +1,153 @@
17453 +/* 
17454 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17455 + * Licensed under the GPL
17456 + */
17457 +
17458 +#include <stdio.h>
17459 +#include <stdlib.h>
17460 +#include <unistd.h>
17461 +#include <errno.h>
17462 +#include <fcntl.h>
17463 +#include <sched.h>
17464 +#include <sys/signal.h>
17465 +#include <sys/wait.h>
17466 +#include "user.h"
17467 +#include "kern_util.h"
17468 +#include "os.h"
17469 +
17470 +struct helper_data {
17471 +       void (*pre_exec)(void*);
17472 +       void *pre_data;
17473 +       char **argv;
17474 +       int fd;
17475 +};
17476 +
17477 +/* Debugging aid, changed only from gdb */
17478 +int helper_pause = 0;
17479 +
17480 +static void helper_hup(int sig)
17481 +{
17482 +}
17483 +
17484 +static int helper_child(void *arg)
17485 +{
17486 +       struct helper_data *data = arg;
17487 +       char **argv = data->argv;
17488 +
17489 +       if(helper_pause){
17490 +               signal(SIGHUP, helper_hup);
17491 +               pause();
17492 +       }
17493 +       if(data->pre_exec != NULL)
17494 +               (*data->pre_exec)(data->pre_data);
17495 +       execvp(argv[0], argv);
17496 +       printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
17497 +       write(data->fd, &errno, sizeof(errno));
17498 +       os_kill_process(os_getpid(), 0);
17499 +       return(0);
17500 +}
17501 +
17502 +/* XXX The alloc_stack here breaks if this is called in the tracing thread */
17503 +
17504 +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
17505 +              unsigned long *stack_out)
17506 +{
17507 +       struct helper_data data;
17508 +       unsigned long stack, sp;
17509 +       int pid, fds[2], err, n;
17510 +
17511 +       if((stack_out != NULL) && (*stack_out != 0))
17512 +               stack = *stack_out;
17513 +       else stack = alloc_stack(0, um_in_interrupt());
17514 +       if(stack == 0) return(-ENOMEM);
17515 +
17516 +       err = os_pipe(fds, 1, 0);
17517 +       if(err){
17518 +               printk("run_helper : pipe failed, errno = %d\n", -err);
17519 +               return(err);
17520 +       }
17521 +       if(fcntl(fds[1], F_SETFD, 1) != 0){
17522 +               printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
17523 +                      errno);
17524 +               return(-errno);
17525 +       }
17526 +
17527 +       sp = stack + page_size() - sizeof(void *);
17528 +       data.pre_exec = pre_exec;
17529 +       data.pre_data = pre_data;
17530 +       data.argv = argv;
17531 +       data.fd = fds[1];
17532 +       pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
17533 +       if(pid < 0){
17534 +               printk("run_helper : clone failed, errno = %d\n", errno);
17535 +               return(-errno);
17536 +       }
17537 +       close(fds[1]);
17538 +       n = read(fds[0], &err, sizeof(err));
17539 +       if(n < 0){
17540 +               printk("run_helper : read on pipe failed, errno = %d\n", 
17541 +                      errno);
17542 +               return(-errno);
17543 +       }
17544 +       else if(n != 0){
17545 +               waitpid(pid, NULL, 0);
17546 +               pid = -err;
17547 +       }
17548 +
17549 +       if(stack_out == NULL) free_stack(stack, 0);
17550 +        else *stack_out = stack;
17551 +       return(pid);
17552 +}
17553 +
17554 +int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
17555 +                     unsigned long *stack_out, int stack_order)
17556 +{
17557 +       unsigned long stack, sp;
17558 +       int pid, status;
17559 +
17560 +       stack = alloc_stack(stack_order, um_in_interrupt());
17561 +       if(stack == 0) return(-ENOMEM);
17562 +
17563 +       sp = stack + (page_size() << stack_order) - sizeof(void *);
17564 +       pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
17565 +       if(pid < 0){
17566 +               printk("run_helper_thread : clone failed, errno = %d\n", 
17567 +                      errno);
17568 +               return(-errno);
17569 +       }
17570 +       if(stack_out == NULL){
17571 +               pid = waitpid(pid, &status, 0);
17572 +               if(pid < 0)
17573 +                       printk("run_helper_thread - wait failed, errno = %d\n",
17574 +                              pid);
17575 +               if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
17576 +                       printk("run_helper_thread - thread returned status "
17577 +                              "0x%x\n", status);
17578 +               free_stack(stack, stack_order);
17579 +       }
17580 +        else *stack_out = stack;
17581 +       return(pid);
17582 +}
17583 +
17584 +int helper_wait(int pid, int block)
17585 +{
17586 +       int ret;
17587 +
17588 +       ret = waitpid(pid, NULL, WNOHANG);
17589 +       if(ret < 0){
17590 +               printk("helper_wait : waitpid failed, errno = %d\n", errno);
17591 +               return(-errno);
17592 +       }
17593 +       return(ret);
17594 +}
17595 +
17596 +/*
17597 + * Overrides for Emacs so that we follow Linus's tabbing style.
17598 + * Emacs will notice this stuff at the end of the file and automatically
17599 + * adjust the settings for this buffer only.  This must remain at the end
17600 + * of the file.
17601 + * ---------------------------------------------------------------------------
17602 + * Local variables:
17603 + * c-file-style: "linux"
17604 + * End:
17605 + */
17606 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_kern.c um/arch/um/kernel/initrd_kern.c
17607 --- orig/arch/um/kernel/initrd_kern.c   1969-12-31 19:00:00.000000000 -0500
17608 +++ um/arch/um/kernel/initrd_kern.c     2002-10-23 21:08:04.000000000 -0400
17609 @@ -0,0 +1,59 @@
17610 +/*
17611 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17612 + * Licensed under the GPL
17613 + */
17614 +
17615 +#include "linux/init.h"
17616 +#include "linux/bootmem.h"
17617 +#include "linux/blk.h"
17618 +#include "asm/types.h"
17619 +#include "user_util.h"
17620 +#include "kern_util.h"
17621 +#include "initrd.h"
17622 +#include "init.h"
17623 +#include "os.h"
17624 +
17625 +/* Changed by uml_initrd_setup, which is a setup */
17626 +static char *initrd __initdata = NULL;
17627 +
17628 +static int __init read_initrd(void)
17629 +{
17630 +       void *area;
17631 +       long long size;
17632 +       int err;
17633 +
17634 +       if(initrd == NULL) return 0;
17635 +       err = os_file_size(initrd, &size);
17636 +       if(err) return 0;
17637 +       area = alloc_bootmem(size);
17638 +       if(area == NULL) return 0;
17639 +       if(load_initrd(initrd, area, size) == -1) return 0;
17640 +       initrd_start = (unsigned long) area;
17641 +       initrd_end = initrd_start + size;
17642 +       return 0;
17643 +}
17644 +
17645 +__uml_postsetup(read_initrd);
17646 +
17647 +static int __init uml_initrd_setup(char *line, int *add)
17648 +{
17649 +       initrd = line;
17650 +       return 0;
17651 +}
17652 +
17653 +__uml_setup("initrd=", uml_initrd_setup, 
17654 +"initrd=<initrd image>\n"
17655 +"    This is used to boot UML from an initrd image.  The argument is the\n"
17656 +"    name of the file containing the image.\n\n"
17657 +);
17658 +
17659 +/*
17660 + * Overrides for Emacs so that we follow Linus's tabbing style.
17661 + * Emacs will notice this stuff at the end of the file and automatically
17662 + * adjust the settings for this buffer only.  This must remain at the end
17663 + * of the file.
17664 + * ---------------------------------------------------------------------------
17665 + * Local variables:
17666 + * c-file-style: "linux"
17667 + * End:
17668 + */
17669 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_user.c um/arch/um/kernel/initrd_user.c
17670 --- orig/arch/um/kernel/initrd_user.c   1969-12-31 19:00:00.000000000 -0500
17671 +++ um/arch/um/kernel/initrd_user.c     2002-10-23 21:08:04.000000000 -0400
17672 @@ -0,0 +1,43 @@
17673 +/*
17674 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17675 + * Licensed under the GPL
17676 + */
17677 +
17678 +#include <unistd.h>
17679 +#include <sys/types.h>
17680 +#include <sys/stat.h>
17681 +#include <fcntl.h>
17682 +#include <errno.h>
17683 +
17684 +#include "user_util.h"
17685 +#include "kern_util.h"
17686 +#include "user.h"
17687 +#include "initrd.h"
17688 +#include "os.h"
17689 +
17690 +int load_initrd(char *filename, void *buf, int size)
17691 +{
17692 +       int fd, n;
17693 +
17694 +       if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){
17695 +               printk("Opening '%s' failed - errno = %d\n", filename, errno);
17696 +               return(-1);
17697 +       }
17698 +       if((n = read(fd, buf, size)) != size){
17699 +               printk("Read of %d bytes from '%s' returned %d, errno = %d\n",
17700 +                      size, filename, n, errno);
17701 +               return(-1);
17702 +       }
17703 +       return(0);
17704 +}
17705 +
17706 +/*
17707 + * Overrides for Emacs so that we follow Linus's tabbing style.
17708 + * Emacs will notice this stuff at the end of the file and automatically
17709 + * adjust the settings for this buffer only.  This must remain at the end
17710 + * of the file.
17711 + * ---------------------------------------------------------------------------
17712 + * Local variables:
17713 + * c-file-style: "linux"
17714 + * End:
17715 + */
17716 diff -Naur -X ../exclude-files orig/arch/um/kernel/init_task.c um/arch/um/kernel/init_task.c
17717 --- orig/arch/um/kernel/init_task.c     1969-12-31 19:00:00.000000000 -0500
17718 +++ um/arch/um/kernel/init_task.c       2002-12-28 19:58:44.000000000 -0500
17719 @@ -0,0 +1,61 @@
17720 +/* 
17721 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17722 + * Licensed under the GPL
17723 + */
17724 +
17725 +#include "linux/config.h"
17726 +#include "linux/mm.h"
17727 +#include "linux/sched.h"
17728 +#include "linux/version.h"
17729 +#include "asm/uaccess.h"
17730 +#include "asm/pgtable.h"
17731 +#include "user_util.h"
17732 +#include "mem_user.h"
17733 +
17734 +static struct fs_struct init_fs = INIT_FS;
17735 +static struct files_struct init_files = INIT_FILES;
17736 +static struct signal_struct init_signals = INIT_SIGNALS;
17737 +struct mm_struct init_mm = INIT_MM(init_mm);
17738 +
17739 +/*
17740 + * Initial task structure.
17741 + *
17742 + * We need to make sure that this is 16384-byte aligned due to the
17743 + * way process stacks are handled. This is done by having a special
17744 + * "init_task" linker map entry..
17745 + */
17746 +
17747 +union task_union init_task_union 
17748 +__attribute__((__section__(".data.init_task"))) = 
17749 +{ INIT_TASK(init_task_union.task) };
17750 +
17751 +struct task_struct *alloc_task_struct(void)
17752 +{
17753 +       return((struct task_struct *) 
17754 +              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
17755 +}
17756 +
17757 +void unprotect_stack(unsigned long stack)
17758 +{
17759 +       protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
17760 +                      1, 1, 0, 1);
17761 +}
17762 +
17763 +void free_task_struct(struct task_struct *task)
17764 +{
17765 +       /* free_pages decrements the page counter and only actually frees
17766 +        * the pages if they are now not accessed by anything.
17767 +        */
17768 +       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
17769 +}
17770 +
17771 +/*
17772 + * Overrides for Emacs so that we follow Linus's tabbing style.
17773 + * Emacs will notice this stuff at the end of the file and automatically
17774 + * adjust the settings for this buffer only.  This must remain at the end
17775 + * of the file.
17776 + * ---------------------------------------------------------------------------
17777 + * Local variables:
17778 + * c-file-style: "linux"
17779 + * End:
17780 + */
17781 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq.c um/arch/um/kernel/irq.c
17782 --- orig/arch/um/kernel/irq.c   1969-12-31 19:00:00.000000000 -0500
17783 +++ um/arch/um/kernel/irq.c     2003-03-26 14:45:29.000000000 -0500
17784 @@ -0,0 +1,842 @@
17785 +/* 
17786 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17787 + * Licensed under the GPL
17788 + * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
17789 + *     Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
17790 + */
17791 +
17792 +#include "linux/config.h"
17793 +#include "linux/kernel.h"
17794 +#include "linux/smp.h"
17795 +#include "linux/irq.h"
17796 +#include "linux/kernel_stat.h"
17797 +#include "linux/interrupt.h"
17798 +#include "linux/random.h"
17799 +#include "linux/slab.h"
17800 +#include "linux/file.h"
17801 +#include "linux/proc_fs.h"
17802 +#include "linux/init.h"
17803 +#include "linux/seq_file.h"
17804 +#include "asm/irq.h"
17805 +#include "asm/hw_irq.h"
17806 +#include "asm/hardirq.h"
17807 +#include "asm/atomic.h"
17808 +#include "asm/signal.h"
17809 +#include "asm/system.h"
17810 +#include "asm/errno.h"
17811 +#include "asm/uaccess.h"
17812 +#include "user_util.h"
17813 +#include "kern_util.h"
17814 +#include "irq_user.h"
17815 +
17816 +static void register_irq_proc (unsigned int irq);
17817 +
17818 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
17819 +        { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
17820 +
17821 +/*
17822 + * Generic no controller code
17823 + */
17824 +
17825 +static void enable_none(unsigned int irq) { }
17826 +static unsigned int startup_none(unsigned int irq) { return 0; }
17827 +static void disable_none(unsigned int irq) { }
17828 +static void ack_none(unsigned int irq)
17829 +{
17830 +/*
17831 + * 'what should we do if we get a hw irq event on an illegal vector'.
17832 + * each architecture has to answer this themselves, it doesnt deserve
17833 + * a generic callback i think.
17834 + */
17835 +#if CONFIG_X86
17836 +       printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
17837 +#ifdef CONFIG_X86_LOCAL_APIC
17838 +       /*
17839 +        * Currently unexpected vectors happen only on SMP and APIC.
17840 +        * We _must_ ack these because every local APIC has only N
17841 +        * irq slots per priority level, and a 'hanging, unacked' IRQ
17842 +        * holds up an irq slot - in excessive cases (when multiple
17843 +        * unexpected vectors occur) that might lock up the APIC
17844 +        * completely.
17845 +        */
17846 +       ack_APIC_irq();
17847 +#endif
17848 +#endif
17849 +}
17850 +
17851 +/* startup is the same as "enable", shutdown is same as "disable" */
17852 +#define shutdown_none  disable_none
17853 +#define end_none       enable_none
17854 +
17855 +struct hw_interrupt_type no_irq_type = {
17856 +       "none",
17857 +       startup_none,
17858 +       shutdown_none,
17859 +       enable_none,
17860 +       disable_none,
17861 +       ack_none,
17862 +       end_none
17863 +};
17864 +
17865 +/* Not changed */
17866 +volatile unsigned long irq_err_count;
17867 +
17868 +/*
17869 + * Generic, controller-independent functions:
17870 + */
17871 +
17872 +int get_irq_list(char *buf)
17873 +{
17874 +       int i, j;
17875 +       unsigned long flags;
17876 +       struct irqaction * action;
17877 +       char *p = buf;
17878 +
17879 +       p += sprintf(p, "           ");
17880 +       for (j=0; j<smp_num_cpus; j++)
17881 +               p += sprintf(p, "CPU%d       ",j);
17882 +       *p++ = '\n';
17883 +
17884 +       for (i = 0 ; i < NR_IRQS ; i++) {
17885 +               spin_lock_irqsave(&irq_desc[i].lock, flags);
17886 +               action = irq_desc[i].action;
17887 +               if (!action) 
17888 +                       goto end;
17889 +               p += sprintf(p, "%3d: ",i);
17890 +#ifndef CONFIG_SMP
17891 +               p += sprintf(p, "%10u ", kstat_irqs(i));
17892 +#else
17893 +               for (j = 0; j < smp_num_cpus; j++)
17894 +                       p += sprintf(p, "%10u ",
17895 +                               kstat.irqs[cpu_logical_map(j)][i]);
17896 +#endif
17897 +               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
17898 +               p += sprintf(p, "  %s", action->name);
17899 +
17900 +               for (action=action->next; action; action = action->next)
17901 +                       p += sprintf(p, ", %s", action->name);
17902 +               *p++ = '\n';
17903 +       end:
17904 +               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
17905 +       }
17906 +       p += sprintf(p, "\n");
17907 +#ifdef notdef
17908 +#if CONFIG_SMP
17909 +       p += sprintf(p, "LOC: ");
17910 +       for (j = 0; j < smp_num_cpus; j++)
17911 +               p += sprintf(p, "%10u ",
17912 +                       apic_timer_irqs[cpu_logical_map(j)]);
17913 +       p += sprintf(p, "\n");
17914 +#endif
17915 +#endif
17916 +       p += sprintf(p, "ERR: %10lu\n", irq_err_count);
17917 +       return p - buf;
17918 +}
17919 +
17920 +
17921 +/*
17922 + * This should really return information about whether
17923 + * we should do bottom half handling etc. Right now we
17924 + * end up _always_ checking the bottom half, which is a
17925 + * waste of time and is not what some drivers would
17926 + * prefer.
17927 + */
17928 +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, 
17929 +                    struct irqaction * action)
17930 +{
17931 +       int status;
17932 +       int cpu = smp_processor_id();
17933 +
17934 +       irq_enter(cpu, irq);
17935 +
17936 +       status = 1;     /* Force the "do bottom halves" bit */
17937 +
17938 +       if (!(action->flags & SA_INTERRUPT))
17939 +               __sti();
17940 +
17941 +       do {
17942 +               status |= action->flags;
17943 +               action->handler(irq, action->dev_id, regs);
17944 +               action = action->next;
17945 +       } while (action);
17946 +       if (status & SA_SAMPLE_RANDOM)
17947 +               add_interrupt_randomness(irq);
17948 +       __cli();
17949 +
17950 +       irq_exit(cpu, irq);
17951 +
17952 +       return status;
17953 +}
17954 +
17955 +/*
17956 + * Generic enable/disable code: this just calls
17957 + * down into the PIC-specific version for the actual
17958 + * hardware disable after having gotten the irq
17959 + * controller lock. 
17960 + */
17961
17962 +/**
17963 + *     disable_irq_nosync - disable an irq without waiting
17964 + *     @irq: Interrupt to disable
17965 + *
17966 + *     Disable the selected interrupt line. Disables of an interrupt
17967 + *     stack. Unlike disable_irq(), this function does not ensure existing
17968 + *     instances of the IRQ handler have completed before returning.
17969 + *
17970 + *     This function may be called from IRQ context.
17971 + */
17972
17973 +void inline disable_irq_nosync(unsigned int irq)
17974 +{
17975 +       irq_desc_t *desc = irq_desc + irq;
17976 +       unsigned long flags;
17977 +
17978 +       spin_lock_irqsave(&desc->lock, flags);
17979 +       if (!desc->depth++) {
17980 +               desc->status |= IRQ_DISABLED;
17981 +               desc->handler->disable(irq);
17982 +       }
17983 +       spin_unlock_irqrestore(&desc->lock, flags);
17984 +}
17985 +
17986 +/**
17987 + *     disable_irq - disable an irq and wait for completion
17988 + *     @irq: Interrupt to disable
17989 + *
17990 + *     Disable the selected interrupt line. Disables of an interrupt
17991 + *     stack. That is for two disables you need two enables. This
17992 + *     function waits for any pending IRQ handlers for this interrupt
17993 + *     to complete before returning. If you use this function while
17994 + *     holding a resource the IRQ handler may need you will deadlock.
17995 + *
17996 + *     This function may be called - with care - from IRQ context.
17997 + */
17998
17999 +void disable_irq(unsigned int irq)
18000 +{
18001 +       disable_irq_nosync(irq);
18002 +
18003 +       if (!local_irq_count(smp_processor_id())) {
18004 +               do {
18005 +                       barrier();
18006 +               } while (irq_desc[irq].status & IRQ_INPROGRESS);
18007 +       }
18008 +}
18009 +
18010 +/**
18011 + *     enable_irq - enable interrupt handling on an irq
18012 + *     @irq: Interrupt to enable
18013 + *
18014 + *     Re-enables the processing of interrupts on this IRQ line
18015 + *     providing no disable_irq calls are now in effect.
18016 + *
18017 + *     This function may be called from IRQ context.
18018 + */
18019
18020 +void enable_irq(unsigned int irq)
18021 +{
18022 +       irq_desc_t *desc = irq_desc + irq;
18023 +       unsigned long flags;
18024 +
18025 +       spin_lock_irqsave(&desc->lock, flags);
18026 +       switch (desc->depth) {
18027 +       case 1: {
18028 +               unsigned int status = desc->status & ~IRQ_DISABLED;
18029 +               desc->status = status;
18030 +               if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
18031 +                       desc->status = status | IRQ_REPLAY;
18032 +                       hw_resend_irq(desc->handler,irq);
18033 +               }
18034 +               desc->handler->enable(irq);
18035 +               /* fall-through */
18036 +       }
18037 +       default:
18038 +               desc->depth--;
18039 +               break;
18040 +       case 0:
18041 +               printk(KERN_ERR "enable_irq() unbalanced from %p\n",
18042 +                      __builtin_return_address(0));
18043 +       }
18044 +       spin_unlock_irqrestore(&desc->lock, flags);
18045 +}
18046 +
18047 +/*
18048 + * do_IRQ handles all normal device IRQ's (the special
18049 + * SMP cross-CPU interrupts have their own specific
18050 + * handlers).
18051 + */
18052 +unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
18053 +{      
18054 +       /* 
18055 +        * 0 return value means that this irq is already being
18056 +        * handled by some other CPU. (or is disabled)
18057 +        */
18058 +       int cpu = smp_processor_id();
18059 +       irq_desc_t *desc = irq_desc + irq;
18060 +       struct irqaction * action;
18061 +       unsigned int status;
18062 +
18063 +       kstat.irqs[cpu][irq]++;
18064 +       spin_lock(&desc->lock);
18065 +       desc->handler->ack(irq);
18066 +       /*
18067 +          REPLAY is when Linux resends an IRQ that was dropped earlier
18068 +          WAITING is used by probe to mark irqs that are being tested
18069 +          */
18070 +       status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
18071 +       status |= IRQ_PENDING; /* we _want_ to handle it */
18072 +
18073 +       /*
18074 +        * If the IRQ is disabled for whatever reason, we cannot
18075 +        * use the action we have.
18076 +        */
18077 +       action = NULL;
18078 +       if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
18079 +               action = desc->action;
18080 +               status &= ~IRQ_PENDING; /* we commit to handling */
18081 +               status |= IRQ_INPROGRESS; /* we are handling it */
18082 +       }
18083 +       desc->status = status;
18084 +
18085 +       /*
18086 +        * If there is no IRQ handler or it was disabled, exit early.
18087 +          Since we set PENDING, if another processor is handling
18088 +          a different instance of this same irq, the other processor
18089 +          will take care of it.
18090 +        */
18091 +       if (!action)
18092 +               goto out;
18093 +
18094 +       /*
18095 +        * Edge triggered interrupts need to remember
18096 +        * pending events.
18097 +        * This applies to any hw interrupts that allow a second
18098 +        * instance of the same irq to arrive while we are in do_IRQ
18099 +        * or in the handler. But the code here only handles the _second_
18100 +        * instance of the irq, not the third or fourth. So it is mostly
18101 +        * useful for irq hardware that does not mask cleanly in an
18102 +        * SMP environment.
18103 +        */
18104 +       for (;;) {
18105 +               spin_unlock(&desc->lock);
18106 +               handle_IRQ_event(irq, (struct pt_regs *) regs, action);
18107 +               spin_lock(&desc->lock);
18108 +               
18109 +               if (!(desc->status & IRQ_PENDING))
18110 +                       break;
18111 +               desc->status &= ~IRQ_PENDING;
18112 +       }
18113 +       desc->status &= ~IRQ_INPROGRESS;
18114 +out:
18115 +       /*
18116 +        * The ->end() handler has to deal with interrupts which got
18117 +        * disabled while the handler was running.
18118 +        */
18119 +       desc->handler->end(irq);
18120 +       spin_unlock(&desc->lock);
18121 +
18122 +       if (softirq_pending(cpu))
18123 +               do_softirq();
18124 +       return 1;
18125 +}
18126 +
18127 +/**
18128 + *     request_irq - allocate an interrupt line
18129 + *     @irq: Interrupt line to allocate
18130 + *     @handler: Function to be called when the IRQ occurs
18131 + *     @irqflags: Interrupt type flags
18132 + *     @devname: An ascii name for the claiming device
18133 + *     @dev_id: A cookie passed back to the handler function
18134 + *
18135 + *     This call allocates interrupt resources and enables the
18136 + *     interrupt line and IRQ handling. From the point this
18137 + *     call is made your handler function may be invoked. Since
18138 + *     your handler function must clear any interrupt the board 
18139 + *     raises, you must take care both to initialise your hardware
18140 + *     and to set up the interrupt handler in the right order.
18141 + *
18142 + *     Dev_id must be globally unique. Normally the address of the
18143 + *     device data structure is used as the cookie. Since the handler
18144 + *     receives this value it makes sense to use it.
18145 + *
18146 + *     If your interrupt is shared you must pass a non NULL dev_id
18147 + *     as this is required when freeing the interrupt.
18148 + *
18149 + *     Flags:
18150 + *
18151 + *     SA_SHIRQ                Interrupt is shared
18152 + *
18153 + *     SA_INTERRUPT            Disable local interrupts while processing
18154 + *
18155 + *     SA_SAMPLE_RANDOM        The interrupt can be used for entropy
18156 + *
18157 + */
18158
18159 +int request_irq(unsigned int irq,
18160 +               void (*handler)(int, void *, struct pt_regs *),
18161 +               unsigned long irqflags, 
18162 +               const char * devname,
18163 +               void *dev_id)
18164 +{
18165 +       int retval;
18166 +       struct irqaction * action;
18167 +
18168 +#if 1
18169 +       /*
18170 +        * Sanity-check: shared interrupts should REALLY pass in
18171 +        * a real dev-ID, otherwise we'll have trouble later trying
18172 +        * to figure out which interrupt is which (messes up the
18173 +        * interrupt freeing logic etc).
18174 +        */
18175 +       if (irqflags & SA_SHIRQ) {
18176 +               if (!dev_id)
18177 +                       printk(KERN_ERR "Bad boy: %s (at 0x%x) called us "
18178 +                              "without a dev_id!\n", devname, (&irq)[-1]);
18179 +       }
18180 +#endif
18181 +
18182 +       if (irq >= NR_IRQS)
18183 +               return -EINVAL;
18184 +       if (!handler)
18185 +               return -EINVAL;
18186 +
18187 +       action = (struct irqaction *)
18188 +                       kmalloc(sizeof(struct irqaction), GFP_KERNEL);
18189 +       if (!action)
18190 +               return -ENOMEM;
18191 +
18192 +       action->handler = handler;
18193 +       action->flags = irqflags;
18194 +       action->mask = 0;
18195 +       action->name = devname;
18196 +       action->next = NULL;
18197 +       action->dev_id = dev_id;
18198 +
18199 +       retval = setup_irq(irq, action);
18200 +       if (retval)
18201 +               kfree(action);
18202 +       return retval;
18203 +}
18204 +
18205 +int um_request_irq(unsigned int irq, int fd, int type,
18206 +                  void (*handler)(int, void *, struct pt_regs *),
18207 +                  unsigned long irqflags, const char * devname,
18208 +                  void *dev_id)
18209 +{
18210 +       int err;
18211 +
18212 +       err = request_irq(irq, handler, irqflags, devname, dev_id);
18213 +       if(err) 
18214 +               return(err);
18215 +
18216 +       if(fd != -1)
18217 +               err = activate_fd(irq, fd, type, dev_id);
18218 +       return(err);
18219 +}
18220 +
18221 +/* this was setup_x86_irq but it seems pretty generic */
18222 +int setup_irq(unsigned int irq, struct irqaction * new)
18223 +{
18224 +       int shared = 0;
18225 +       unsigned long flags;
18226 +       struct irqaction *old, **p;
18227 +       irq_desc_t *desc = irq_desc + irq;
18228 +
18229 +       /*
18230 +        * Some drivers like serial.c use request_irq() heavily,
18231 +        * so we have to be careful not to interfere with a
18232 +        * running system.
18233 +        */
18234 +       if (new->flags & SA_SAMPLE_RANDOM) {
18235 +               /*
18236 +                * This function might sleep, we want to call it first,
18237 +                * outside of the atomic block.
18238 +                * Yes, this might clear the entropy pool if the wrong
18239 +                * driver is attempted to be loaded, without actually
18240 +                * installing a new handler, but is this really a problem,
18241 +                * only the sysadmin is able to do this.
18242 +                */
18243 +               rand_initialize_irq(irq);
18244 +       }
18245 +
18246 +       /*
18247 +        * The following block of code has to be executed atomically
18248 +        */
18249 +       spin_lock_irqsave(&desc->lock,flags);
18250 +       p = &desc->action;
18251 +       if ((old = *p) != NULL) {
18252 +               /* Can't share interrupts unless both agree to */
18253 +               if (!(old->flags & new->flags & SA_SHIRQ)) {
18254 +                       spin_unlock_irqrestore(&desc->lock,flags);
18255 +                       return -EBUSY;
18256 +               }
18257 +
18258 +               /* add new interrupt at end of irq queue */
18259 +               do {
18260 +                       p = &old->next;
18261 +                       old = *p;
18262 +               } while (old);
18263 +               shared = 1;
18264 +       }
18265 +
18266 +       *p = new;
18267 +
18268 +       if (!shared) {
18269 +               desc->depth = 0;
18270 +               desc->status &= ~IRQ_DISABLED;
18271 +               desc->handler->startup(irq);
18272 +       }
18273 +       spin_unlock_irqrestore(&desc->lock,flags);
18274 +
18275 +       register_irq_proc(irq);
18276 +       return 0;
18277 +}
18278 +
18279 +/**
18280 + *     free_irq - free an interrupt
18281 + *     @irq: Interrupt line to free
18282 + *     @dev_id: Device identity to free
18283 + *
18284 + *     Remove an interrupt handler. The handler is removed and if the
18285 + *     interrupt line is no longer in use by any driver it is disabled.
18286 + *     On a shared IRQ the caller must ensure the interrupt is disabled
18287 + *     on the card it drives before calling this function. The function
18288 + *     does not return until any executing interrupts for this IRQ
18289 + *     have completed.
18290 + *
18291 + *     This function may be called from interrupt context. 
18292 + *
18293 + *     Bugs: Attempting to free an irq in a handler for the same irq hangs
18294 + *           the machine.
18295 + */
18296
18297 +void free_irq(unsigned int irq, void *dev_id)
18298 +{
18299 +       irq_desc_t *desc;
18300 +       struct irqaction **p;
18301 +       unsigned long flags;
18302 +
18303 +       if (irq >= NR_IRQS)
18304 +               return;
18305 +
18306 +       desc = irq_desc + irq;
18307 +       spin_lock_irqsave(&desc->lock,flags);
18308 +       p = &desc->action;
18309 +       for (;;) {
18310 +               struct irqaction * action = *p;
18311 +               if (action) {
18312 +                       struct irqaction **pp = p;
18313 +                       p = &action->next;
18314 +                       if (action->dev_id != dev_id)
18315 +                               continue;
18316 +
18317 +                       /* Found it - now remove it from the list of entries */
18318 +                       *pp = action->next;
18319 +                       if (!desc->action) {
18320 +                               desc->status |= IRQ_DISABLED;
18321 +                               desc->handler->shutdown(irq);
18322 +                       }
18323 +                       free_irq_by_irq_and_dev(irq, dev_id);
18324 +                       spin_unlock_irqrestore(&desc->lock,flags);
18325 +
18326 +#ifdef CONFIG_SMP
18327 +                       /* Wait to make sure it's not being used on another CPU */
18328 +                       while (desc->status & IRQ_INPROGRESS)
18329 +                               barrier();
18330 +#endif
18331 +                       kfree(action);
18332 +                       return;
18333 +               }
18334 +               printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
18335 +               spin_unlock_irqrestore(&desc->lock,flags);
18336 +               return;
18337 +       }
18338 +}
18339 +
18340 +/* These are initialized by sysctl_init, which is called from init/main.c */
18341 +static struct proc_dir_entry * root_irq_dir;
18342 +static struct proc_dir_entry * irq_dir [NR_IRQS];
18343 +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
18344 +
18345 +/* These are read and written as longs, so a read won't see a partial write
18346 + * even during a race.
18347 + */
18348 +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
18349 +
18350 +#define HEX_DIGITS 8
18351 +
18352 +static int irq_affinity_read_proc (char *page, char **start, off_t off,
18353 +                       int count, int *eof, void *data)
18354 +{
18355 +       if (count < HEX_DIGITS+1)
18356 +               return -EINVAL;
18357 +       return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
18358 +}
18359 +
18360 +static unsigned int parse_hex_value (const char *buffer,
18361 +               unsigned long count, unsigned long *ret)
18362 +{
18363 +       unsigned char hexnum [HEX_DIGITS];
18364 +       unsigned long value;
18365 +       int i;
18366 +
18367 +       if (!count)
18368 +               return -EINVAL;
18369 +       if (count > HEX_DIGITS)
18370 +               count = HEX_DIGITS;
18371 +       if (copy_from_user(hexnum, buffer, count))
18372 +               return -EFAULT;
18373 +
18374 +       /*
18375 +        * Parse the first 8 characters as a hex string, any non-hex char
18376 +        * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
18377 +        */
18378 +       value = 0;
18379 +
18380 +       for (i = 0; i < count; i++) {
18381 +               unsigned int c = hexnum[i];
18382 +
18383 +               switch (c) {
18384 +                       case '0' ... '9': c -= '0'; break;
18385 +                       case 'a' ... 'f': c -= 'a'-10; break;
18386 +                       case 'A' ... 'F': c -= 'A'-10; break;
18387 +               default:
18388 +                       goto out;
18389 +               }
18390 +               value = (value << 4) | c;
18391 +       }
18392 +out:
18393 +       *ret = value;
18394 +       return 0;
18395 +}
18396 +
18397 +static int irq_affinity_write_proc (struct file *file, const char *buffer,
18398 +                                       unsigned long count, void *data)
18399 +{
18400 +       int irq = (long) data, full_count = count, err;
18401 +       unsigned long new_value;
18402 +
18403 +       if (!irq_desc[irq].handler->set_affinity)
18404 +               return -EIO;
18405 +
18406 +       err = parse_hex_value(buffer, count, &new_value);
18407 +
18408 +#if CONFIG_SMP
18409 +       /*
18410 +        * Do not allow disabling IRQs completely - it's a too easy
18411 +        * way to make the system unusable accidentally :-) At least
18412 +        * one online CPU still has to be targeted.
18413 +        */
18414 +       if (!(new_value & cpu_online_map))
18415 +               return -EINVAL;
18416 +#endif
18417 +
18418 +       irq_affinity[irq] = new_value;
18419 +       irq_desc[irq].handler->set_affinity(irq, new_value);
18420 +
18421 +       return full_count;
18422 +}
18423 +
18424 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
18425 +                       int count, int *eof, void *data)
18426 +{
18427 +       unsigned long *mask = (unsigned long *) data;
18428 +       if (count < HEX_DIGITS+1)
18429 +               return -EINVAL;
18430 +       return sprintf (page, "%08lx\n", *mask);
18431 +}
18432 +
18433 +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
18434 +                                       unsigned long count, void *data)
18435 +{
18436 +       unsigned long *mask = (unsigned long *) data, full_count = count, err;
18437 +       unsigned long new_value;
18438 +
18439 +       err = parse_hex_value(buffer, count, &new_value);
18440 +       if (err)
18441 +               return err;
18442 +
18443 +       *mask = new_value;
18444 +       return full_count;
18445 +}
18446 +
18447 +#define MAX_NAMELEN 10
18448 +
18449 +static void register_irq_proc (unsigned int irq)
18450 +{
18451 +       struct proc_dir_entry *entry;
18452 +       char name [MAX_NAMELEN];
18453 +
18454 +       if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
18455 +           irq_dir[irq])
18456 +               return;
18457 +
18458 +       memset(name, 0, MAX_NAMELEN);
18459 +       sprintf(name, "%d", irq);
18460 +
18461 +       /* create /proc/irq/1234 */
18462 +       irq_dir[irq] = proc_mkdir(name, root_irq_dir);
18463 +
18464 +       /* create /proc/irq/1234/smp_affinity */
18465 +       entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
18466 +
18467 +       entry->nlink = 1;
18468 +       entry->data = (void *)(long)irq;
18469 +       entry->read_proc = irq_affinity_read_proc;
18470 +       entry->write_proc = irq_affinity_write_proc;
18471 +
18472 +       smp_affinity_entry[irq] = entry;
18473 +}
18474 +
18475 +/* Read and written as a long */
18476 +unsigned long prof_cpu_mask = -1;
18477 +
18478 +void __init init_irq_proc (void)
18479 +{
18480 +       struct proc_dir_entry *entry;
18481 +       int i;
18482 +
18483 +       /* create /proc/irq */
18484 +       root_irq_dir = proc_mkdir("irq", 0);
18485 +
18486 +       /* create /proc/irq/prof_cpu_mask */
18487 +       entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
18488 +
18489 +       entry->nlink = 1;
18490 +       entry->data = (void *)&prof_cpu_mask;
18491 +       entry->read_proc = prof_cpu_mask_read_proc;
18492 +       entry->write_proc = prof_cpu_mask_write_proc;
18493 +
18494 +       /*
18495 +        * Create entries for all existing IRQs.
18496 +        */
18497 +       for (i = 0; i < NR_IRQS; i++)
18498 +               register_irq_proc(i);
18499 +}
18500 +
18501 +static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
18502 +
18503 +unsigned long irq_lock(void)
18504 +{
18505 +       unsigned long flags;
18506 +
18507 +       spin_lock_irqsave(&irq_spinlock, flags);
18508 +       return(flags);
18509 +}
18510 +
18511 +void irq_unlock(unsigned long flags)
18512 +{
18513 +       spin_unlock_irqrestore(&irq_spinlock, flags);
18514 +}
18515 +
18516 +unsigned long probe_irq_on(void)
18517 +{
18518 +       return(0);
18519 +}
18520 +
18521 +int probe_irq_off(unsigned long val)
18522 +{
18523 +       return(0);
18524 +}
18525 +
18526 +static unsigned int startup_SIGIO_irq(unsigned int irq)
18527 +{
18528 +       return(0);
18529 +}
18530 +
18531 +static void shutdown_SIGIO_irq(unsigned int irq)
18532 +{
18533 +}
18534 +
18535 +static void enable_SIGIO_irq(unsigned int irq)
18536 +{
18537 +}
18538 +
18539 +static void disable_SIGIO_irq(unsigned int irq)
18540 +{
18541 +}
18542 +
18543 +static void mask_and_ack_SIGIO(unsigned int irq)
18544 +{
18545 +}
18546 +
18547 +static void end_SIGIO_irq(unsigned int irq)
18548 +{
18549 +}
18550 +
18551 +static unsigned int startup_SIGVTALRM_irq(unsigned int irq)
18552 +{
18553 +       return(0);
18554 +}
18555 +
18556 +static void shutdown_SIGVTALRM_irq(unsigned int irq)
18557 +{
18558 +}
18559 +
18560 +static void enable_SIGVTALRM_irq(unsigned int irq)
18561 +{
18562 +}
18563 +
18564 +static void disable_SIGVTALRM_irq(unsigned int irq)
18565 +{
18566 +}
18567 +
18568 +static void mask_and_ack_SIGVTALRM(unsigned int irq)
18569 +{
18570 +}
18571 +
18572 +static void end_SIGVTALRM_irq(unsigned int irq)
18573 +{
18574 +}
18575 +
18576 +static struct hw_interrupt_type SIGIO_irq_type = {
18577 +       "SIGIO",
18578 +       startup_SIGIO_irq,
18579 +       shutdown_SIGIO_irq,
18580 +       enable_SIGIO_irq,
18581 +       disable_SIGIO_irq,
18582 +       mask_and_ack_SIGIO,
18583 +       end_SIGIO_irq,
18584 +       NULL
18585 +};
18586 +
18587 +static struct hw_interrupt_type SIGVTALRM_irq_type = {
18588 +       "SIGVTALRM",
18589 +       startup_SIGVTALRM_irq,
18590 +       shutdown_SIGVTALRM_irq,
18591 +       enable_SIGVTALRM_irq,
18592 +       disable_SIGVTALRM_irq,
18593 +       mask_and_ack_SIGVTALRM,
18594 +       end_SIGVTALRM_irq,
18595 +       NULL
18596 +};
18597 +
18598 +void __init init_IRQ(void)
18599 +{
18600 +       int i;
18601 +
18602 +       irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
18603 +       irq_desc[TIMER_IRQ].action = 0;
18604 +       irq_desc[TIMER_IRQ].depth = 1;
18605 +       irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
18606 +       enable_irq(TIMER_IRQ);
18607 +       for(i=1;i<NR_IRQS;i++){
18608 +               irq_desc[i].status = IRQ_DISABLED;
18609 +               irq_desc[i].action = 0;
18610 +               irq_desc[i].depth = 1;
18611 +               irq_desc[i].handler = &SIGIO_irq_type;
18612 +               enable_irq(i);
18613 +       }
18614 +       init_irq_signals(0);
18615 +}
18616 +
18617 +/*
18618 + * Overrides for Emacs so that we follow Linus's tabbing style.
18619 + * Emacs will notice this stuff at the end of the file and automatically
18620 + * adjust the settings for this buffer only.  This must remain at the end
18621 + * of the file.
18622 + * ---------------------------------------------------------------------------
18623 + * Local variables:
18624 + * c-file-style: "linux"
18625 + * End:
18626 + */
18627 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq_user.c um/arch/um/kernel/irq_user.c
18628 --- orig/arch/um/kernel/irq_user.c      1969-12-31 19:00:00.000000000 -0500
18629 +++ um/arch/um/kernel/irq_user.c        2002-12-22 15:49:46.000000000 -0500
18630 @@ -0,0 +1,427 @@
18631 +/* 
18632 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
18633 + * Licensed under the GPL
18634 + */
18635 +
18636 +#include <stdlib.h>
18637 +#include <unistd.h>
18638 +#include <errno.h>
18639 +#include <fcntl.h>
18640 +#include <signal.h>
18641 +#include <string.h>
18642 +#include <sys/poll.h>
18643 +#include <sys/types.h>
18644 +#include <sys/time.h>
18645 +#include "user_util.h"
18646 +#include "kern_util.h"
18647 +#include "user.h"
18648 +#include "process.h"
18649 +#include "signal_user.h"
18650 +#include "sigio.h"
18651 +#include "irq_user.h"
18652 +#include "os.h"
18653 +
18654 +struct irq_fd {
18655 +       struct irq_fd *next;
18656 +       void *id;
18657 +       int fd;
18658 +       int type;
18659 +       int irq;
18660 +       int pid;
18661 +       int events;
18662 +       int current_events;
18663 +       int freed;
18664 +};
18665 +
18666 +static struct irq_fd *active_fds = NULL;
18667 +static struct irq_fd **last_irq_ptr = &active_fds;
18668 +
18669 +static struct pollfd *pollfds = NULL;
18670 +static int pollfds_num = 0;
18671 +static int pollfds_size = 0;
18672 +
18673 +extern int io_count, intr_count;
18674 +
18675 +void sigio_handler(int sig, union uml_pt_regs *regs)
18676 +{
18677 +       struct irq_fd *irq_fd, *next;
18678 +       int i, n;
18679 +
18680 +       if(smp_sigio_handler()) return;
18681 +       while(1){
18682 +               if((n = poll(pollfds, pollfds_num, 0)) < 0){
18683 +                       if(errno == EINTR) continue;
18684 +                       printk("sigio_handler : poll returned %d, "
18685 +                              "errno = %d\n", n, errno);
18686 +                       break;
18687 +               }
18688 +               if(n == 0) break;
18689 +
18690 +               irq_fd = active_fds;
18691 +               for(i = 0; i < pollfds_num; i++){
18692 +                       if(pollfds[i].revents != 0){
18693 +                               irq_fd->current_events = pollfds[i].revents;
18694 +                               pollfds[i].fd = -1;
18695 +                       }
18696 +                       irq_fd = irq_fd->next;
18697 +               }
18698 +
18699 +               for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
18700 +                       next = irq_fd->next;
18701 +                       if(irq_fd->current_events != 0){
18702 +                               irq_fd->current_events = 0;
18703 +                               do_IRQ(irq_fd->irq, regs);
18704 +
18705 +                               /* This is here because the next irq may be
18706 +                                * freed in the handler.  If a console goes
18707 +                                * away, both the read and write irqs will be
18708 +                                * freed.  After do_IRQ, ->next will point to
18709 +                                * a good IRQ.
18710 +                                * Irqs can't be freed inside their handlers,
18711 +                                * so the next best thing is to have them
18712 +                                * marked as needing freeing, so that they
18713 +                                * can be freed here.
18714 +                                */
18715 +                               next = irq_fd->next;
18716 +                               if(irq_fd->freed)
18717 +                                       free_irq(irq_fd->irq, irq_fd->id);
18718 +                       }
18719 +               }
18720 +       }
18721 +}
18722 +
18723 +int activate_ipi(int fd, int pid)
18724 +{
18725 +       return(os_set_fd_async(fd, pid));
18726 +}
18727 +
18728 +static void maybe_sigio_broken(int fd, int type)
18729 +{
18730 +       if(isatty(fd)){
18731 +               if((type == IRQ_WRITE) && !pty_output_sigio){
18732 +                       write_sigio_workaround();
18733 +                       add_sigio_fd(fd, 0);
18734 +               }
18735 +               else if((type == IRQ_READ) && !pty_close_sigio){
18736 +                       write_sigio_workaround();
18737 +                       add_sigio_fd(fd, 1);                    
18738 +               }
18739 +       }
18740 +}
18741 +
18742 +int activate_fd(int irq, int fd, int type, void *dev_id)
18743 +{
18744 +       struct pollfd *tmp_pfd;
18745 +       struct irq_fd *new_fd, *irq_fd;
18746 +       unsigned long flags;
18747 +       int pid, events, err, n, size;
18748 +
18749 +       pid = os_getpid();
18750 +       err = os_set_fd_async(fd, pid);
18751 +       if(err < 0)
18752 +               goto out;
18753 +
18754 +       new_fd = um_kmalloc(sizeof(*new_fd));
18755 +       err = -ENOMEM;
18756 +       if(new_fd == NULL)
18757 +               goto out;
18758 +
18759 +       if(type == IRQ_READ) events = POLLIN | POLLPRI;
18760 +       else events = POLLOUT;
18761 +       *new_fd = ((struct irq_fd) { .next              = NULL,
18762 +                                    .id                = dev_id,
18763 +                                    .fd                = fd,
18764 +                                    .type              = type,
18765 +                                    .irq               = irq,
18766 +                                    .pid               = pid,
18767 +                                    .events            = events,
18768 +                                    .current_events    = 0,
18769 +                                    .freed             = 0  } );
18770 +
18771 +       /* Critical section - locked by a spinlock because this stuff can
18772 +        * be changed from interrupt handlers.  The stuff above is done 
18773 +        * outside the lock because it allocates memory.
18774 +        */
18775 +
18776 +       /* Actually, it only looks like it can be called from interrupt
18777 +        * context.  The culprit is reactivate_fd, which calls 
18778 +        * maybe_sigio_broken, which calls write_sigio_workaround,
18779 +        * which calls activate_fd.  However, write_sigio_workaround should
18780 +        * only be called once, at boot time.  That would make it clear that
18781 +        * this is called only from process context, and can be locked with
18782 +        * a semaphore.
18783 +        */
18784 +       flags = irq_lock();
18785 +       for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
18786 +               if((irq_fd->fd == fd) && (irq_fd->type == type)){
18787 +                       printk("Registering fd %d twice\n", fd);
18788 +                       printk("Irqs : %d, %d\n", irq_fd->irq, irq);
18789 +                       printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
18790 +                       goto out_unlock;
18791 +               }
18792 +       }
18793 +
18794 +       n = pollfds_num;
18795 +       if(n == pollfds_size){
18796 +               while(1){
18797 +                       /* Here we have to drop the lock in order to call 
18798 +                        * kmalloc, which might sleep.  If something else
18799 +                        * came in and changed the pollfds array, we free
18800 +                        * the buffer and try again.
18801 +                        */
18802 +                       irq_unlock(flags);
18803 +                       size = (pollfds_num + 1) * sizeof(pollfds[0]);
18804 +                       tmp_pfd = um_kmalloc(size);
18805 +                       flags = irq_lock();
18806 +                       if(tmp_pfd == NULL)
18807 +                               goto out_unlock;
18808 +                       if(n == pollfds_size)
18809 +                               break;
18810 +                       kfree(tmp_pfd);
18811 +               }
18812 +               if(pollfds != NULL){
18813 +                       memcpy(tmp_pfd, pollfds,
18814 +                              sizeof(pollfds[0]) * pollfds_size);
18815 +                       kfree(pollfds);
18816 +               }
18817 +               pollfds = tmp_pfd;
18818 +               pollfds_size++;
18819 +       }
18820 +
18821 +       if(type == IRQ_WRITE) 
18822 +               fd = -1;
18823 +
18824 +       pollfds[pollfds_num] = ((struct pollfd) { .fd   = fd,
18825 +                                                 .events       = events,
18826 +                                                 .revents      = 0 });
18827 +       pollfds_num++;
18828 +
18829 +       *last_irq_ptr = new_fd;
18830 +       last_irq_ptr = &new_fd->next;
18831 +
18832 +       irq_unlock(flags);
18833 +
18834 +       /* This calls activate_fd, so it has to be outside the critical
18835 +        * section.
18836 +        */
18837 +       maybe_sigio_broken(fd, type);
18838 +
18839 +       return(0);
18840 +
18841 + out_unlock:
18842 +       irq_unlock(flags);
18843 +       kfree(new_fd);
18844 + out:
18845 +       return(err);
18846 +}
18847 +
18848 +static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
18849 +{
18850 +       struct irq_fd **prev;
18851 +       unsigned long flags;
18852 +       int i = 0;
18853 +
18854 +       flags = irq_lock();
18855 +       prev = &active_fds;
18856 +       while(*prev != NULL){
18857 +               if((*test)(*prev, arg)){
18858 +                       struct irq_fd *old_fd = *prev;
18859 +                       if((pollfds[i].fd != -1) && 
18860 +                          (pollfds[i].fd != (*prev)->fd)){
18861 +                               printk("free_irq_by_cb - mismatch between "
18862 +                                      "active_fds and pollfds, fd %d vs %d\n",
18863 +                                      (*prev)->fd, pollfds[i].fd);
18864 +                               goto out;
18865 +                       }
18866 +                       memcpy(&pollfds[i], &pollfds[i + 1],
18867 +                              (pollfds_num - i - 1) * sizeof(pollfds[0]));
18868 +                       pollfds_num--;
18869 +                       if(last_irq_ptr == &old_fd->next) 
18870 +                               last_irq_ptr = prev;
18871 +                       *prev = (*prev)->next;
18872 +                       if(old_fd->type == IRQ_WRITE) 
18873 +                               ignore_sigio_fd(old_fd->fd);
18874 +                       kfree(old_fd);
18875 +                       continue;
18876 +               }
18877 +               prev = &(*prev)->next;
18878 +               i++;
18879 +       }
18880 + out:
18881 +       irq_unlock(flags);
18882 +}
18883 +
18884 +struct irq_and_dev {
18885 +       int irq;
18886 +       void *dev;
18887 +};
18888 +
18889 +static int same_irq_and_dev(struct irq_fd *irq, void *d)
18890 +{
18891 +       struct irq_and_dev *data = d;
18892 +
18893 +       return((irq->irq == data->irq) && (irq->id == data->dev));
18894 +}
18895 +
18896 +void free_irq_by_irq_and_dev(int irq, void *dev)
18897 +{
18898 +       struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
18899 +                                                         .dev  = dev });
18900 +
18901 +       free_irq_by_cb(same_irq_and_dev, &data);
18902 +}
18903 +
18904 +static int same_fd(struct irq_fd *irq, void *fd)
18905 +{
18906 +       return(irq->fd == *((int *) fd));
18907 +}
18908 +
18909 +void free_irq_by_fd(int fd)
18910 +{
18911 +       free_irq_by_cb(same_fd, &fd);
18912 +}
18913 +
18914 +static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
18915 +{
18916 +       struct irq_fd *irq;
18917 +       int i = 0;
18918 +
18919 +       for(irq=active_fds; irq != NULL; irq = irq->next){
18920 +               if((irq->fd == fd) && (irq->irq == irqnum)) break;
18921 +               i++;
18922 +       }
18923 +       if(irq == NULL){
18924 +               printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
18925 +               goto out;
18926 +       }
18927 +       if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
18928 +               printk("find_irq_by_fd - mismatch between active_fds and "
18929 +                      "pollfds, fd %d vs %d, need %d\n", irq->fd, 
18930 +                      pollfds[i].fd, fd);
18931 +               irq = NULL;
18932 +               goto out;
18933 +       }
18934 +       *index_out = i;
18935 + out:
18936 +       return(irq);
18937 +}
18938 +
18939 +void free_irq_later(int irq, void *dev_id)
18940 +{
18941 +       struct irq_fd *irq_fd;
18942 +       unsigned long flags;
18943 +
18944 +       flags = irq_lock();
18945 +       for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
18946 +               if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
18947 +                       break;
18948 +       }
18949 +       if(irq_fd == NULL){
18950 +               printk("free_irq_later found no irq, irq = %d, "
18951 +                      "dev_id = 0x%p\n", irq, dev_id);
18952 +               goto out;
18953 +       }
18954 +       irq_fd->freed = 1;
18955 + out:
18956 +       irq_unlock(flags);
18957 +}
18958 +
18959 +void reactivate_fd(int fd, int irqnum)
18960 +{
18961 +       struct irq_fd *irq;
18962 +       unsigned long flags;
18963 +       int i;
18964 +
18965 +       flags = irq_lock();
18966 +       irq = find_irq_by_fd(fd, irqnum, &i);
18967 +       if(irq == NULL){
18968 +               irq_unlock(flags);
18969 +               return;
18970 +       }
18971 +
18972 +       pollfds[i].fd = irq->fd;
18973 +
18974 +       irq_unlock(flags);
18975 +
18976 +       /* This calls activate_fd, so it has to be outside the critical
18977 +        * section.
18978 +        */
18979 +       maybe_sigio_broken(fd, irq->type);
18980 +}
18981 +
18982 +void deactivate_fd(int fd, int irqnum)
18983 +{
18984 +       struct irq_fd *irq;
18985 +       unsigned long flags;
18986 +       int i;
18987 +
18988 +       flags = irq_lock();
18989 +       irq = find_irq_by_fd(fd, irqnum, &i);
18990 +       if(irq == NULL)
18991 +               goto out;
18992 +       pollfds[i].fd = -1;
18993 + out:
18994 +       irq_unlock(flags);
18995 +}
18996 +
18997 +void forward_ipi(int fd, int pid)
18998 +{
18999 +       if(fcntl(fd, F_SETOWN, pid) < 0){
19000 +               int save_errno = errno;
19001 +               if(fcntl(fd, F_GETOWN, 0) != pid){
19002 +                       printk("forward_ipi: F_SETOWN failed, fd = %d, "
19003 +                              "me = %d, target = %d, errno = %d\n", fd, 
19004 +                              os_getpid(), pid, save_errno);
19005 +               }
19006 +       }
19007 +}
19008 +
19009 +void forward_interrupts(int pid)
19010 +{
19011 +       struct irq_fd *irq;
19012 +       unsigned long flags;
19013 +
19014 +       flags = irq_lock();
19015 +       for(irq=active_fds;irq != NULL;irq = irq->next){
19016 +               if(fcntl(irq->fd, F_SETOWN, pid) < 0){
19017 +                       int save_errno = errno;
19018 +                       if(fcntl(irq->fd, F_GETOWN, 0) != pid){
19019 +                               /* XXX Just remove the irq rather than
19020 +                                * print out an infinite stream of these
19021 +                                */
19022 +                               printk("Failed to forward %d to pid %d, "
19023 +                                      "errno = %d\n", irq->fd, pid, 
19024 +                                      save_errno);
19025 +                       }
19026 +               }
19027 +               irq->pid = pid;
19028 +       }
19029 +       irq_unlock(flags);
19030 +}
19031 +
19032 +void init_irq_signals(int on_sigstack)
19033 +{
19034 +       __sighandler_t h;
19035 +       int flags;
19036 +
19037 +       flags = on_sigstack ? SA_ONSTACK : 0;
19038 +       if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
19039 +       else h = boot_timer_handler;
19040 +
19041 +       set_handler(SIGVTALRM, h, flags | SA_RESTART, 
19042 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
19043 +       set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
19044 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
19045 +       signal(SIGWINCH, SIG_IGN);
19046 +}
19047 +
19048 +/*
19049 + * Overrides for Emacs so that we follow Linus's tabbing style.
19050 + * Emacs will notice this stuff at the end of the file and automatically
19051 + * adjust the settings for this buffer only.  This must remain at the end
19052 + * of the file.
19053 + * ---------------------------------------------------------------------------
19054 + * Local variables:
19055 + * c-file-style: "linux"
19056 + * End:
19057 + */
19058 diff -Naur -X ../exclude-files orig/arch/um/kernel/ksyms.c um/arch/um/kernel/ksyms.c
19059 --- orig/arch/um/kernel/ksyms.c 1969-12-31 19:00:00.000000000 -0500
19060 +++ um/arch/um/kernel/ksyms.c   2002-12-17 13:29:43.000000000 -0500
19061 @@ -0,0 +1,94 @@
19062 +/* 
19063 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
19064 + * Licensed under the GPL
19065 + */
19066 +
19067 +#include "linux/config.h"
19068 +#include "linux/module.h"
19069 +#include "linux/string.h"
19070 +#include "linux/smp_lock.h"
19071 +#include "linux/spinlock.h"
19072 +#include "asm/current.h"
19073 +#include "asm/delay.h"
19074 +#include "asm/processor.h"
19075 +#include "asm/unistd.h"
19076 +#include "asm/pgalloc.h"
19077 +#include "asm/pgtable.h"
19078 +#include "asm/page.h"
19079 +#include "kern_util.h"
19080 +#include "user_util.h"
19081 +#include "os.h"
19082 +#include "helper.h"
19083 +
19084 +EXPORT_SYMBOL(stop);
19085 +EXPORT_SYMBOL(strtok);
19086 +EXPORT_SYMBOL(uml_physmem);
19087 +EXPORT_SYMBOL(set_signals);
19088 +EXPORT_SYMBOL(get_signals);
19089 +EXPORT_SYMBOL(kernel_thread);
19090 +EXPORT_SYMBOL(__const_udelay);
19091 +EXPORT_SYMBOL(__udelay);
19092 +EXPORT_SYMBOL(sys_waitpid);
19093 +EXPORT_SYMBOL(task_size);
19094 +EXPORT_SYMBOL(flush_tlb_range);
19095 +EXPORT_SYMBOL(host_task_size);
19096 +EXPORT_SYMBOL(arch_validate);
19097 +
19098 +EXPORT_SYMBOL(region_pa);
19099 +EXPORT_SYMBOL(region_va);
19100 +EXPORT_SYMBOL(phys_mem_map);
19101 +EXPORT_SYMBOL(page_mem_map);
19102 +EXPORT_SYMBOL(high_physmem);
19103 +EXPORT_SYMBOL(empty_zero_page);
19104 +EXPORT_SYMBOL(um_virt_to_phys);
19105 +EXPORT_SYMBOL(mode_tt);
19106 +EXPORT_SYMBOL(handle_page_fault);
19107 +
19108 +EXPORT_SYMBOL(os_getpid);
19109 +EXPORT_SYMBOL(os_open_file);
19110 +EXPORT_SYMBOL(os_read_file);
19111 +EXPORT_SYMBOL(os_write_file);
19112 +EXPORT_SYMBOL(os_seek_file);
19113 +EXPORT_SYMBOL(os_pipe);
19114 +EXPORT_SYMBOL(os_file_type);
19115 +EXPORT_SYMBOL(os_close_file);
19116 +EXPORT_SYMBOL(helper_wait);
19117 +EXPORT_SYMBOL(os_shutdown_socket);
19118 +EXPORT_SYMBOL(os_connect_socket);
19119 +EXPORT_SYMBOL(run_helper);
19120 +EXPORT_SYMBOL(start_thread);
19121 +EXPORT_SYMBOL(dump_thread);
19122 +
19123 +/* This is here because UML expands open to sys_open, not to a system
19124 + * call instruction.
19125 + */
19126 +EXPORT_SYMBOL(sys_open);
19127 +EXPORT_SYMBOL(sys_lseek);
19128 +EXPORT_SYMBOL(sys_read);
19129 +EXPORT_SYMBOL(sys_wait4);
19130 +
19131 +#ifdef CONFIG_SMP
19132 +
19133 +/* required for SMP */
19134 +
19135 +extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
19136 +EXPORT_SYMBOL_NOVERS(__write_lock_failed);
19137 +
19138 +extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
19139 +EXPORT_SYMBOL_NOVERS(__read_lock_failed);
19140 +
19141 +EXPORT_SYMBOL(kernel_flag_cacheline);
19142 +EXPORT_SYMBOL(smp_num_cpus);
19143 +
19144 +#endif
19145 +
19146 +/*
19147 + * Overrides for Emacs so that we follow Linus's tabbing style.
19148 + * Emacs will notice this stuff at the end of the file and automatically
19149 + * adjust the settings for this buffer only.  This must remain at the end
19150 + * of the file.
19151 + * ---------------------------------------------------------------------------
19152 + * Local variables:
19153 + * c-file-style: "linux"
19154 + * End:
19155 + */
19156 diff -Naur -X ../exclude-files orig/arch/um/kernel/Makefile um/arch/um/kernel/Makefile
19157 --- orig/arch/um/kernel/Makefile        1969-12-31 19:00:00.000000000 -0500
19158 +++ um/arch/um/kernel/Makefile  2003-04-10 11:14:55.000000000 -0400
19159 @@ -0,0 +1,73 @@
19160 +# 
19161 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
19162 +# Licensed under the GPL
19163 +#
19164 +
19165 +O_TARGET = built-in.o
19166 +
19167 +obj-y = config.o checksum.o exec_kern.o exitcode.o frame_kern.o frame.o \
19168 +       helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
19169 +       process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
19170 +       sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \
19171 +       syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
19172 +       time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
19173 +       umid.o user_syms.o user_util.o
19174 +
19175 +obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
19176 +obj-$(CONFIG_GPROF) += gprof_syms.o
19177 +obj-$(CONFIG_GCOV) += gmon_syms.o
19178 +obj-$(CONFIG_TTY_LOG) += tty_log.o
19179 +
19180 +subdir-$(CONFIG_MODE_TT) += tt
19181 +subdir-$(CONFIG_MODE_SKAS) += skas
19182 +
19183 +user-objs-$(CONFIG_TTY_LOG) += tty_log.o
19184 +
19185 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
19186 +
19187 +# user_syms.o not included here because Rules.make has its own ideas about
19188 +# building anything in export-objs
19189 +
19190 +USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
19191 +       process.o tempfile.o time.o umid.o user_util.o 
19192 +
19193 +DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
19194 +DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
19195 +
19196 +export-objs-$(CONFIG_GPROF) += gprof_syms.o
19197 +export-objs-$(CONFIG_GCOV) += gmon_syms.o
19198 +
19199 +export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
19200 +
19201 +CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
19202 +       -I/usr/include -I../include
19203 +
19204 +CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
19205 +
19206 +include $(TOPDIR)/Rules.make
19207 +
19208 +$(USER_OBJS) : %.o: %.c
19209 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
19210 +
19211 +# This has to be separate because it needs be compiled with frame pointers
19212 +# regardless of how the rest of the kernel is built.
19213 +
19214 +frame.o: frame.c
19215 +       $(CC) $(CFLAGS_$@) -c -o $@ $<
19216 +
19217 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
19218 +
19219 +config.c : config.c.in $(TOPDIR)/.config
19220 +       $(PERL) -e $(QUOTE) < config.c.in > $@
19221 +
19222 +clean:
19223 +       $(RM) config.c
19224 +       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
19225 +
19226 +modules:
19227 +
19228 +fastdep:
19229 +
19230 +dep:
19231 +
19232 +archmrproper: clean
19233 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem.c um/arch/um/kernel/mem.c
19234 --- orig/arch/um/kernel/mem.c   1969-12-31 19:00:00.000000000 -0500
19235 +++ um/arch/um/kernel/mem.c     2003-03-30 14:30:26.000000000 -0500
19236 @@ -0,0 +1,852 @@
19237 +/* 
19238 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19239 + * Licensed under the GPL
19240 + */
19241 +
19242 +#include "linux/config.h"
19243 +#include "linux/types.h"
19244 +#include "linux/mm.h"
19245 +#include "linux/fs.h"
19246 +#include "linux/init.h"
19247 +#include "linux/bootmem.h"
19248 +#include "linux/swap.h"
19249 +#include "linux/slab.h"
19250 +#include "linux/vmalloc.h"
19251 +#include "linux/highmem.h"
19252 +#include "asm/page.h"
19253 +#include "asm/pgtable.h"
19254 +#include "asm/pgalloc.h"
19255 +#include "asm/bitops.h"
19256 +#include "asm/uaccess.h"
19257 +#include "asm/tlb.h"
19258 +#include "user_util.h"
19259 +#include "kern_util.h"
19260 +#include "mem_user.h"
19261 +#include "mem.h"
19262 +#include "kern.h"
19263 +#include "init.h"
19264 +#include "os.h"
19265 +#include "mode_kern.h"
19266 +#include "uml_uaccess.h"
19267 +
19268 +/* Changed during early boot */
19269 +pgd_t swapper_pg_dir[1024];
19270 +unsigned long high_physmem;
19271 +unsigned long vm_start;
19272 +unsigned long vm_end;
19273 +unsigned long highmem;
19274 +unsigned long *empty_zero_page = NULL;
19275 +unsigned long *empty_bad_page = NULL;
19276 +
19277 +/* Not modified */
19278 +const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
19279 +
19280 +/* Changed during early boot */
19281 +static unsigned long totalram_pages = 0;
19282 +
19283 +extern char __init_begin, __init_end;
19284 +extern long physmem_size;
19285 +
19286 +#ifdef CONFIG_SMP
19287 +/* Not changed by UML */
19288 +mmu_gather_t mmu_gathers[NR_CPUS];
19289 +#endif
19290 +
19291 +/* Changed during early boot */
19292 +int kmalloc_ok = 0;
19293 +
19294 +#define NREGIONS (phys_region_index(0xffffffff) - phys_region_index(0x0) + 1)
19295 +struct mem_region *regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = NULL };
19296 +#define REGION_SIZE ((0xffffffff & ~REGION_MASK) + 1)
19297 +
19298 +/* Changed during early boot */
19299 +static unsigned long brk_end;
19300 +
19301 +static void map_cb(void *unused)
19302 +{
19303 +       map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
19304 +}
19305 +
19306 +void unmap_physmem(void)
19307 +{
19308 +       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
19309 +}
19310 +
19311 +extern char __binary_start;
19312 +
19313 +void mem_init(void)
19314 +{
19315 +       unsigned long start;
19316 +
19317 +#ifdef CONFIG_HIGHMEM
19318 +       highmem_start_page = phys_page(__pa(high_physmem));
19319 +#endif
19320 +
19321 +        /* clear the zero-page */
19322 +        memset((void *) empty_zero_page, 0, PAGE_SIZE);
19323 +
19324 +       /* Map in the area just after the brk now that kmalloc is about
19325 +        * to be turned on.
19326 +        */
19327 +       brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
19328 +       map_cb(NULL);
19329 +       initial_thread_cb(map_cb, NULL);
19330 +       free_bootmem(__pa(brk_end), uml_reserved - brk_end);
19331 +       uml_reserved = brk_end;
19332 +
19333 +       /* Fill in any hole at the start of the binary */
19334 +       start = (unsigned long) &__binary_start;
19335 +       if(uml_physmem != start){
19336 +               map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
19337 +                   1, 1, 0);
19338 +       }
19339 +
19340 +       /* this will put all low memory onto the freelists */
19341 +       totalram_pages = free_all_bootmem();
19342 +       totalram_pages += highmem >> PAGE_SHIFT;
19343 +       max_mapnr = totalram_pages;
19344 +       num_physpages = totalram_pages;
19345 +       printk(KERN_INFO "Memory: %luk available\n", 
19346 +              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
19347 +       kmalloc_ok = 1;
19348 +}
19349 +
19350 +/* Changed during early boot */
19351 +static unsigned long kmem_top = 0;
19352 +
19353 +unsigned long get_kmem_end(void)
19354 +{
19355 +       if(kmem_top == 0) 
19356 +               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
19357 +       return(kmem_top);
19358 +}
19359 +
19360 +void set_kmem_end(unsigned long new)
19361 +{
19362 +       kmem_top = new;
19363 +}
19364 +
19365 +#if CONFIG_HIGHMEM
19366 +/* Changed during early boot */
19367 +pte_t *kmap_pte;
19368 +pgprot_t kmap_prot;
19369 +
19370 +#define kmap_get_fixmap_pte(vaddr)                                     \
19371 +       pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
19372 +
19373 +void __init kmap_init(void)
19374 +{
19375 +       unsigned long kmap_vstart;
19376 +
19377 +       /* cache the first kmap pte */
19378 +       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
19379 +       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
19380 +
19381 +       kmap_prot = PAGE_KERNEL;
19382 +}
19383 +#endif /* CONFIG_HIGHMEM */
19384 +
19385 +static void __init fixrange_init(unsigned long start, unsigned long end, 
19386 +                                pgd_t *pgd_base)
19387 +{
19388 +       pgd_t *pgd;
19389 +       pmd_t *pmd;
19390 +       pte_t *pte;
19391 +       int i, j;
19392 +       unsigned long vaddr;
19393 +
19394 +       vaddr = start;
19395 +       i = __pgd_offset(vaddr);
19396 +       j = __pmd_offset(vaddr);
19397 +       pgd = pgd_base + i;
19398 +
19399 +       for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
19400 +               pmd = (pmd_t *)pgd;
19401 +               for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
19402 +                       if (pmd_none(*pmd)) {
19403 +                               pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
19404 +                               set_pmd(pmd, __pmd(_KERNPG_TABLE + 
19405 +                                                  (unsigned long) __pa(pte)));
19406 +                               if (pte != pte_offset(pmd, 0))
19407 +                                       BUG();
19408 +                       }
19409 +                       vaddr += PMD_SIZE;
19410 +               }
19411 +               j = 0;
19412 +       }
19413 +}
19414 +
19415 +int init_maps(struct mem_region *region)
19416 +{
19417 +       struct page *p, *map;
19418 +       int i, n, len;
19419 +
19420 +       if(region == &physmem_region){
19421 +               region->mem_map = mem_map;
19422 +               return(0);
19423 +       }
19424 +       else if(region->mem_map != NULL) return(0);
19425 +
19426 +       n = region->len >> PAGE_SHIFT;
19427 +       len = n * sizeof(struct page);
19428 +       if(kmalloc_ok){
19429 +               map = kmalloc(len, GFP_KERNEL);
19430 +               if(map == NULL) map = vmalloc(len);
19431 +       }
19432 +       else map = alloc_bootmem_low_pages(len);
19433 +
19434 +       if(map == NULL)
19435 +               return(-ENOMEM);
19436 +       for(i = 0; i < n; i++){
19437 +               p = &map[i];
19438 +               set_page_count(p, 0);
19439 +               SetPageReserved(p);
19440 +               INIT_LIST_HEAD(&p->list);
19441 +       }
19442 +       region->mem_map = map;
19443 +       return(0);
19444 +}
19445 +
19446 +DECLARE_MUTEX(regions_sem);
19447 +
19448 +static int setup_one_range(int fd, char *driver, unsigned long start, 
19449 +                          unsigned long pfn, int len, 
19450 +                          struct mem_region *region)
19451 +{
19452 +       int i;
19453 +
19454 +       down(&regions_sem);
19455 +       for(i = 0; i < NREGIONS; i++){
19456 +               if(regions[i] == NULL) break;           
19457 +       }
19458 +       if(i == NREGIONS){
19459 +               printk("setup_one_range : no free regions\n");
19460 +               i = -1;
19461 +               goto out;
19462 +       }
19463 +
19464 +       if(fd == -1)
19465 +               fd = create_mem_file(len);
19466 +
19467 +       if(region == NULL){
19468 +               if(kmalloc_ok)
19469 +                       region = kmalloc(sizeof(*region), GFP_KERNEL);
19470 +               else region = alloc_bootmem_low_pages(sizeof(*region));
19471 +               if(region == NULL)
19472 +                       panic("Failed to allocating mem_region");
19473 +       }
19474 +
19475 +       *region = ((struct mem_region) { .driver        = driver,
19476 +                                        .start_pfn     = pfn,
19477 +                                        .start         = start, 
19478 +                                        .len           = len, 
19479 +                                        .fd            = fd } );
19480 +       regions[i] = region;
19481 + out:
19482 +       up(&regions_sem);
19483 +       return(i);
19484 +}
19485 +
19486 +#ifdef CONFIG_HIGHMEM
19487 +static void init_highmem(void)
19488 +{
19489 +       pgd_t *pgd;
19490 +       pmd_t *pmd;
19491 +       pte_t *pte;
19492 +       unsigned long vaddr;
19493 +
19494 +       /*
19495 +        * Permanent kmaps:
19496 +        */
19497 +       vaddr = PKMAP_BASE;
19498 +       fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
19499 +
19500 +       pgd = swapper_pg_dir + __pgd_offset(vaddr);
19501 +       pmd = pmd_offset(pgd, vaddr);
19502 +       pte = pte_offset(pmd, vaddr);
19503 +       pkmap_page_table = pte;
19504 +
19505 +       kmap_init();
19506 +}
19507 +
19508 +void setup_highmem(unsigned long len)
19509 +{
19510 +       struct mem_region *region;
19511 +       struct page *page, *map;
19512 +       unsigned long phys;
19513 +       int i, cur, index;
19514 +
19515 +       phys = physmem_size;
19516 +       do {
19517 +               cur = min(len, (unsigned long) REGION_SIZE);
19518 +               i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur,
19519 +                                   NULL);
19520 +               if(i == -1){
19521 +                       printk("setup_highmem - setup_one_range failed\n");
19522 +                       return;
19523 +               }
19524 +               region = regions[i];
19525 +               index = phys / PAGE_SIZE;
19526 +               region->mem_map = &mem_map[index];
19527 +
19528 +               map = region->mem_map;
19529 +               for(i = 0; i < (cur >> PAGE_SHIFT); i++){
19530 +                       page = &map[i];
19531 +                       ClearPageReserved(page);
19532 +                       set_bit(PG_highmem, &page->flags);
19533 +                       atomic_set(&page->count, 1);
19534 +                       __free_page(page);
19535 +               }
19536 +               phys += cur;
19537 +               len -= cur;
19538 +       } while(len > 0);
19539 +}
19540 +#endif
19541 +
19542 +void paging_init(void)
19543 +{
19544 +       struct mem_region *region;
19545 +       unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
19546 +       int i, index;
19547 +
19548 +       empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
19549 +       empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
19550 +       for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 
19551 +               zones_size[i] = 0;
19552 +       zones_size[0] = (high_physmem >> PAGE_SHIFT) - 
19553 +               (uml_physmem >> PAGE_SHIFT);
19554 +       zones_size[2] = highmem >> PAGE_SHIFT;
19555 +       free_area_init(zones_size);
19556 +       start = phys_region_index(__pa(uml_physmem));
19557 +       end = phys_region_index(__pa(high_physmem - 1));
19558 +       for(i = start; i <= end; i++){
19559 +               region = regions[i];
19560 +               index = (region->start - uml_physmem) / PAGE_SIZE;
19561 +               region->mem_map = &mem_map[index];
19562 +               if(i > start) free_bootmem(__pa(region->start), region->len);
19563 +       }
19564 +
19565 +       /*
19566 +        * Fixed mappings, only the page table structure has to be
19567 +        * created - mappings will be set by set_fixmap():
19568 +        */
19569 +       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
19570 +       fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
19571 +
19572 +#if CONFIG_HIGHMEM
19573 +       init_highmem();
19574 +       setup_highmem(highmem);
19575 +#endif
19576 +}
19577 +
19578 +/* Changed by meminfo_compat, which is a setup */
19579 +static int meminfo_22 = 0;
19580 +
19581 +static int meminfo_compat(char *str)
19582 +{
19583 +       meminfo_22 = 1;
19584 +       return(1);
19585 +}
19586 +
19587 +__setup("22_meminfo", meminfo_compat);
19588 +
19589 +void si_meminfo(struct sysinfo *val)
19590 +{
19591 +       val->totalram = totalram_pages;
19592 +       val->sharedram = 0;
19593 +       val->freeram = nr_free_pages();
19594 +       val->bufferram = atomic_read(&buffermem_pages);
19595 +       val->totalhigh = highmem >> PAGE_SHIFT;
19596 +       val->freehigh = nr_free_highpages();
19597 +       val->mem_unit = PAGE_SIZE;
19598 +       if(meminfo_22){
19599 +               val->freeram <<= PAGE_SHIFT;
19600 +               val->bufferram <<= PAGE_SHIFT;
19601 +               val->totalram <<= PAGE_SHIFT;
19602 +               val->sharedram <<= PAGE_SHIFT;
19603 +       }
19604 +}
19605 +
19606 +pte_t __bad_page(void)
19607 +{
19608 +       clear_page(empty_bad_page);
19609 +        return pte_mkdirty(mk_pte((struct page *) empty_bad_page, 
19610 +                                 PAGE_SHARED));
19611 +}
19612 +
19613 +/* This can't do anything because nothing in the kernel image can be freed
19614 + * since it's not in kernel physical memory.
19615 + */
19616 +
19617 +void free_initmem(void)
19618 +{
19619 +}
19620 +
19621 +#ifdef CONFIG_BLK_DEV_INITRD
19622 +
19623 +void free_initrd_mem(unsigned long start, unsigned long end)
19624 +{
19625 +       if (start < end)
19626 +               printk ("Freeing initrd memory: %ldk freed\n", 
19627 +                       (end - start) >> 10);
19628 +       for (; start < end; start += PAGE_SIZE) {
19629 +               ClearPageReserved(virt_to_page(start));
19630 +               set_page_count(virt_to_page(start), 1);
19631 +               free_page(start);
19632 +               totalram_pages++;
19633 +       }
19634 +}
19635 +       
19636 +#endif
19637 +
19638 +int do_check_pgt_cache(int low, int high)
19639 +{
19640 +        int freed = 0;
19641 +        if(pgtable_cache_size > high) {
19642 +                do {
19643 +                        if (pgd_quicklist) {
19644 +                                free_pgd_slow(get_pgd_fast());
19645 +                                freed++;
19646 +                        }
19647 +                        if (pmd_quicklist) {
19648 +                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
19649 +                                freed++;
19650 +                        }
19651 +                        if (pte_quicklist) {
19652 +                                pte_free_slow(pte_alloc_one_fast(NULL, 0));
19653 +                                freed++;
19654 +                        }
19655 +                } while(pgtable_cache_size > low);
19656 +        }
19657 +        return freed;
19658 +}
19659 +
19660 +void show_mem(void)
19661 +{
19662 +        int i, total = 0, reserved = 0;
19663 +        int shared = 0, cached = 0;
19664 +        int highmem = 0;
19665 +
19666 +        printk("Mem-info:\n");
19667 +        show_free_areas();
19668 +        printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
19669 +        i = max_mapnr;
19670 +        while(i-- > 0) {
19671 +                total++;
19672 +                if(PageHighMem(mem_map + i))
19673 +                        highmem++;
19674 +                if(PageReserved(mem_map + i))
19675 +                        reserved++;
19676 +                else if(PageSwapCache(mem_map + i))
19677 +                        cached++;
19678 +                else if(page_count(mem_map + i))
19679 +                        shared += page_count(mem_map + i) - 1;
19680 +        }
19681 +        printk("%d pages of RAM\n", total);
19682 +        printk("%d pages of HIGHMEM\n", highmem);
19683 +        printk("%d reserved pages\n", reserved);
19684 +        printk("%d pages shared\n", shared);
19685 +        printk("%d pages swap cached\n", cached);
19686 +        printk("%ld pages in page table cache\n", pgtable_cache_size);
19687 +        show_buffers();
19688 +}
19689 +
19690 +static int __init uml_mem_setup(char *line, int *add)
19691 +{
19692 +       char *retptr;
19693 +       physmem_size = memparse(line,&retptr);
19694 +       return 0;
19695 +}
19696 +__uml_setup("mem=", uml_mem_setup,
19697 +"mem=<Amount of desired ram>\n"
19698 +"    This controls how much \"physical\" memory the kernel allocates\n"
19699 +"    for the system. The size is specified as a number followed by\n"
19700 +"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
19701 +"    This is not related to the amount of memory in the physical\n"
19702 +"    machine. It can be more, and the excess, if it's ever used, will\n"
19703 +"    just be swapped out.\n        Example: mem=64M\n\n"
19704 +);
19705 +
19706 +struct page *arch_validate(struct page *page, int mask, int order)
19707 +{
19708 +       unsigned long addr, zero = 0;
19709 +       int i;
19710 +
19711 + again:
19712 +       if(page == NULL) return(page);
19713 +       if(PageHighMem(page)) return(page);
19714 +
19715 +       addr = (unsigned long) page_address(page);
19716 +       for(i = 0; i < (1 << order); i++){
19717 +               current->thread.fault_addr = (void *) addr;
19718 +               if(__do_copy_to_user((void *) addr, &zero, 
19719 +                                    sizeof(zero),
19720 +                                    &current->thread.fault_addr,
19721 +                                    &current->thread.fault_catcher)){
19722 +                       if(!(mask & __GFP_WAIT)) return(NULL);
19723 +                       else break;
19724 +               }
19725 +               addr += PAGE_SIZE;
19726 +       }
19727 +       if(i == (1 << order)) return(page);
19728 +       page = _alloc_pages(mask, order);
19729 +       goto again;
19730 +}
19731 +
19732 +DECLARE_MUTEX(vm_reserved_sem);
19733 +static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
19734 +
19735 +/* Static structures, linked in to the list in early boot */
19736 +static struct vm_reserved head = {
19737 +       .list           = LIST_HEAD_INIT(head.list),
19738 +       .start          = 0,
19739 +       .end            = 0xffffffff
19740 +};
19741 +
19742 +static struct vm_reserved tail = {
19743 +       .list           = LIST_HEAD_INIT(tail.list),
19744 +       .start          = 0,
19745 +       .end            = 0xffffffff
19746 +};
19747 +
19748 +void set_usable_vm(unsigned long start, unsigned long end)
19749 +{
19750 +       list_add(&head.list, &vm_reserved);
19751 +       list_add(&tail.list, &head.list);
19752 +       head.end = start;
19753 +       tail.start = end;
19754 +}
19755 +
19756 +int reserve_vm(unsigned long start, unsigned long end, void *e)
19757 +              
19758 +{
19759 +       struct vm_reserved *entry = e, *reserved, *prev;
19760 +       struct list_head *ele;
19761 +       int err;
19762 +
19763 +       down(&vm_reserved_sem);
19764 +       list_for_each(ele, &vm_reserved){
19765 +               reserved = list_entry(ele, struct vm_reserved, list);
19766 +               if(reserved->start >= end) goto found;
19767 +       }
19768 +       panic("Reserved vm out of range");
19769 + found:
19770 +       prev = list_entry(ele->prev, struct vm_reserved, list);
19771 +       if(prev->end > start)
19772 +               panic("Can't reserve vm");
19773 +       if(entry == NULL)
19774 +               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
19775 +       if(entry == NULL){
19776 +               printk("reserve_vm : Failed to allocate entry\n");
19777 +               err = -ENOMEM;
19778 +               goto out;
19779 +       }
19780 +       *entry = ((struct vm_reserved) 
19781 +               { .list         = LIST_HEAD_INIT(entry->list),
19782 +                 .start        = start,
19783 +                 .end          = end });
19784 +       list_add(&entry->list, &prev->list);
19785 +       err = 0;
19786 + out:
19787 +       up(&vm_reserved_sem);
19788 +       return(0);
19789 +}
19790 +
19791 +unsigned long get_vm(unsigned long len)
19792 +{
19793 +       struct vm_reserved *this, *next;
19794 +       struct list_head *ele;
19795 +       unsigned long start;
19796 +       int err;
19797 +       
19798 +       down(&vm_reserved_sem);
19799 +       list_for_each(ele, &vm_reserved){
19800 +               this = list_entry(ele, struct vm_reserved, list);
19801 +               next = list_entry(ele->next, struct vm_reserved, list);
19802 +               if((this->start < next->start) && 
19803 +                  (this->end + len + PAGE_SIZE <= next->start))
19804 +                       goto found;
19805 +       }
19806 +       up(&vm_reserved_sem);
19807 +       return(0);
19808 + found:
19809 +       up(&vm_reserved_sem);
19810 +       start = (unsigned long) UML_ROUND_UP(this->end) + PAGE_SIZE;
19811 +       err = reserve_vm(start, start + len, NULL);
19812 +       if(err) return(0);
19813 +       return(start);
19814 +}
19815 +
19816 +int nregions(void)
19817 +{
19818 +       return(NREGIONS);
19819 +}
19820 +
19821 +void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
19822 +                unsigned long len, int need_vm, struct mem_region *region, 
19823 +                void *reserved)
19824 +{
19825 +       int i, cur;
19826 +
19827 +       do {
19828 +               cur = min(len, (unsigned long) REGION_SIZE);
19829 +               i = setup_one_range(fd, driver, start, pfn, cur, region);
19830 +               region = regions[i];
19831 +               if(need_vm && setup_region(region, reserved)){
19832 +                       kfree(region);
19833 +                       regions[i] = NULL;
19834 +                       return;
19835 +               }
19836 +               start += cur;
19837 +               if(pfn != -1) pfn += cur;
19838 +               len -= cur;
19839 +       } while(len > 0);
19840 +}
19841 +
19842 +struct iomem {
19843 +       char *name;
19844 +       int fd;
19845 +       unsigned long size;
19846 +};
19847 +
19848 +/* iomem regions can only be added on the command line at the moment.  
19849 + * Locking will be needed when they can be added via mconsole.
19850 + */
19851 +
19852 +struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
19853 +                                        { .name        = NULL,
19854 +                                          .fd          = -1,
19855 +                                          .size        = 0 } };
19856 +
19857 +int num_iomem_regions = 0;
19858 +
19859 +void add_iomem(char *name, int fd, unsigned long size)
19860 +{
19861 +       if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
19862 +               return;
19863 +       size = (size + PAGE_SIZE - 1) & PAGE_MASK;
19864 +       iomem_regions[num_iomem_regions++] = 
19865 +               ((struct iomem) { .name         = name,
19866 +                                 .fd           = fd,
19867 +                                 .size         = size } );
19868 +}
19869 +
19870 +int setup_iomem(void)
19871 +{
19872 +       struct iomem *iomem;
19873 +       int i;
19874 +
19875 +       for(i = 0; i < num_iomem_regions; i++){
19876 +               iomem = &iomem_regions[i];
19877 +               setup_range(iomem->fd, iomem->name, -1, -1, iomem->size, 1, 
19878 +                           NULL, NULL);
19879 +       }
19880 +       return(0);
19881 +}
19882 +
19883 +__initcall(setup_iomem);
19884 +
19885 +#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
19886 +#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
19887 +
19888 +/* Changed during early boot */
19889 +static struct mem_region physmem_region;
19890 +static struct vm_reserved physmem_reserved;
19891 +
19892 +void setup_physmem(unsigned long start, unsigned long reserve_end,
19893 +                  unsigned long len)
19894 +{
19895 +       struct mem_region *region = &physmem_region;
19896 +       struct vm_reserved *reserved = &physmem_reserved;
19897 +       unsigned long cur, pfn = 0;
19898 +       int do_free = 1, bootmap_size;
19899 +
19900 +       do {
19901 +               cur = min(len, (unsigned long) REGION_SIZE);
19902 +               if(region == NULL) 
19903 +                       region = alloc_bootmem_low_pages(sizeof(*region));
19904 +               if(reserved == NULL) 
19905 +                       reserved = alloc_bootmem_low_pages(sizeof(*reserved));
19906 +               if((region == NULL) || (reserved == NULL))
19907 +                       panic("Couldn't allocate physmem region or vm "
19908 +                             "reservation\n");
19909 +               setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
19910 +
19911 +               if(do_free){
19912 +                       unsigned long reserve = reserve_end - start;
19913 +                       int pfn = PFN_UP(__pa(reserve_end));
19914 +                       int delta = (len - reserve) >> PAGE_SHIFT;
19915 +
19916 +                       bootmap_size = init_bootmem(pfn, pfn + delta);
19917 +                       free_bootmem(__pa(reserve_end) + bootmap_size,
19918 +                                    cur - bootmap_size - reserve);
19919 +                       do_free = 0;
19920 +               }
19921 +               start += cur;
19922 +               pfn += cur >> PAGE_SHIFT;
19923 +               len -= cur;
19924 +               region = NULL;
19925 +               reserved = NULL;
19926 +       } while(len > 0);
19927 +}
19928 +
19929 +struct mem_region *phys_region(unsigned long phys)
19930 +{
19931 +       unsigned int n = phys_region_index(phys);
19932 +
19933 +       if(regions[n] == NULL) 
19934 +               panic("Physical address in uninitialized region");
19935 +       return(regions[n]);
19936 +}
19937 +
19938 +unsigned long phys_offset(unsigned long phys)
19939 +{
19940 +       return(phys_addr(phys));
19941 +}
19942 +
19943 +struct page *phys_mem_map(unsigned long phys)
19944 +{
19945 +       return((struct page *) phys_region(phys)->mem_map);
19946 +}
19947 +
19948 +struct page *pte_mem_map(pte_t pte)
19949 +{
19950 +       return(phys_mem_map(pte_val(pte)));
19951 +}
19952 +
19953 +struct mem_region *page_region(struct page *page, int *index_out)
19954 +{
19955 +       int i;
19956 +       struct mem_region *region;
19957 +       struct page *map;
19958 +
19959 +       for(i = 0; i < NREGIONS; i++){
19960 +               region = regions[i];
19961 +               if(region == NULL) continue;
19962 +               map = region->mem_map;
19963 +               if((page >= map) && (page < &map[region->len >> PAGE_SHIFT])){
19964 +                       if(index_out != NULL) *index_out = i;
19965 +                       return(region);
19966 +               }
19967 +       }
19968 +       panic("No region found for page");
19969 +       return(NULL);
19970 +}
19971 +
19972 +unsigned long page_to_pfn(struct page *page)
19973 +{
19974 +       struct mem_region *region = page_region(page, NULL);
19975 +
19976 +       return(region->start_pfn + (page - (struct page *) region->mem_map));
19977 +}
19978 +
19979 +struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
19980 +{
19981 +       struct mem_region *region;
19982 +       int i;
19983 +
19984 +       for(i = 0; i < NREGIONS; i++){
19985 +               region = regions[i];
19986 +               if(region == NULL)
19987 +                       continue;
19988 +
19989 +               if((region->start_pfn <= pfn) &&
19990 +                  (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
19991 +                       if(index_out != NULL) 
19992 +                               *index_out = i;
19993 +                       return(region);
19994 +               }
19995 +       }
19996 +       return(NULL);
19997 +}
19998 +
19999 +struct page *pfn_to_page(unsigned long pfn)
20000 +{
20001 +       struct mem_region *region = pfn_to_region(pfn, NULL);
20002 +       struct page *mem_map = (struct page *) region->mem_map;
20003 +
20004 +       return(&mem_map[pfn - region->start_pfn]);
20005 +}
20006 +
20007 +unsigned long phys_to_pfn(unsigned long p)
20008 +{
20009 +       struct mem_region *region = regions[phys_region_index(p)];
20010 +
20011 +       return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
20012 +}
20013 +
20014 +unsigned long pfn_to_phys(unsigned long pfn)
20015 +{
20016 +       int n;
20017 +       struct mem_region *region = pfn_to_region(pfn, &n);
20018 +
20019 +       return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
20020 +}
20021 +
20022 +struct page *page_mem_map(struct page *page)
20023 +{
20024 +       return((struct page *) page_region(page, NULL)->mem_map);
20025 +}
20026 +
20027 +extern unsigned long region_pa(void *virt)
20028 +{
20029 +       struct mem_region *region;
20030 +       unsigned long addr = (unsigned long) virt;
20031 +       int i;
20032 +
20033 +       for(i = 0; i < NREGIONS; i++){
20034 +               region = regions[i];
20035 +               if(region == NULL) continue;
20036 +               if((region->start <= addr) && 
20037 +                  (addr <= region->start + region->len))
20038 +                       return(mk_phys(addr - region->start, i));
20039 +       }
20040 +       panic("region_pa : no region for virtual address");
20041 +       return(0);
20042 +}
20043 +
20044 +extern void *region_va(unsigned long phys)
20045 +{
20046 +       return((void *) (phys_region(phys)->start + phys_addr(phys)));
20047 +}
20048 +
20049 +unsigned long page_to_phys(struct page *page)
20050 +{
20051 +       int n;
20052 +       struct mem_region *region = page_region(page, &n);
20053 +       struct page *map = region->mem_map;
20054 +       return(mk_phys((page - map) << PAGE_SHIFT, n));
20055 +}
20056 +
20057 +struct page *phys_to_page(unsigned long phys)
20058 +{
20059 +       struct page *mem_map;
20060 +
20061 +       mem_map = phys_mem_map(phys);
20062 +       return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
20063 +}
20064 +
20065 +static int setup_mem_maps(void)
20066 +{
20067 +       struct mem_region *region;
20068 +       int i;
20069 +
20070 +       for(i = 0; i < NREGIONS; i++){
20071 +               region = regions[i];
20072 +               if((region != NULL) && (region->fd > 0)) init_maps(region);
20073 +       }
20074 +       return(0);
20075 +}
20076 +
20077 +__initcall(setup_mem_maps);
20078 +
20079 +/*
20080 + * Overrides for Emacs so that we follow Linus's tabbing style.
20081 + * Emacs will notice this stuff at the end of the file and automatically
20082 + * adjust the settings for this buffer only.  This must remain at the end
20083 + * of the file.
20084 + * ---------------------------------------------------------------------------
20085 + * Local variables:
20086 + * c-file-style: "linux"
20087 + * End:
20088 + */
20089 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem_user.c um/arch/um/kernel/mem_user.c
20090 --- orig/arch/um/kernel/mem_user.c      1969-12-31 19:00:00.000000000 -0500
20091 +++ um/arch/um/kernel/mem_user.c        2003-03-06 16:05:21.000000000 -0500
20092 @@ -0,0 +1,232 @@
20093 +/*
20094 + * arch/um/kernel/mem_user.c
20095 + *
20096 + * BRIEF MODULE DESCRIPTION
20097 + * user side memory routines for supporting IO memory inside user mode linux
20098 + *
20099 + * Copyright (C) 2001 RidgeRun, Inc.
20100 + * Author: RidgeRun, Inc.
20101 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
20102 + *
20103 + *  This program is free software; you can redistribute  it and/or modify it
20104 + *  under  the terms of  the GNU General  Public License as published by the
20105 + *  Free Software Foundation;  either version 2 of the  License, or (at your
20106 + *  option) any later version.
20107 + *
20108 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
20109 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
20110 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
20111 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
20112 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20113 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
20114 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20115 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
20116 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20117 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20118 + *
20119 + *  You should have received a copy of the  GNU General Public License along
20120 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
20121 + *  675 Mass Ave, Cambridge, MA 02139, USA.
20122 + */
20123 +
20124 +#include <stdio.h>
20125 +#include <stdlib.h>
20126 +#include <stddef.h>
20127 +#include <stdarg.h>
20128 +#include <unistd.h>
20129 +#include <fcntl.h>
20130 +#include <errno.h>
20131 +#include <string.h>
20132 +#include <sys/stat.h>
20133 +#include <sys/types.h>
20134 +#include <sys/mman.h>
20135 +#include "kern_util.h"
20136 +#include "user.h"
20137 +#include "user_util.h"
20138 +#include "mem_user.h"
20139 +#include "init.h"
20140 +#include "os.h"
20141 +#include "tempfile.h"
20142 +
20143 +extern struct mem_region physmem_region;
20144 +
20145 +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
20146 +
20147 +int create_mem_file(unsigned long len)
20148 +{
20149 +       int fd;
20150 +       char zero;
20151 +
20152 +       fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
20153 +       if (fchmod(fd, 0777) < 0){
20154 +               perror("fchmod");
20155 +               exit(1);
20156 +       }
20157 +       if(os_seek_file(fd, len) < 0){
20158 +               perror("lseek");
20159 +               exit(1);
20160 +       }
20161 +       zero = 0;
20162 +       if(write(fd, &zero, 1) != 1){
20163 +               perror("write");
20164 +               exit(1);
20165 +       }
20166 +       if(fcntl(fd, F_SETFD, 1) != 0)
20167 +               perror("Setting FD_CLOEXEC failed");
20168 +       return(fd);
20169 +}
20170 +
20171 +int setup_region(struct mem_region *region, void *entry)
20172 +{
20173 +       void *loc, *start;
20174 +       char *driver;
20175 +       int err, offset;
20176 +
20177 +       if(region->start != -1){
20178 +               err = reserve_vm(region->start, 
20179 +                                region->start + region->len, entry);
20180 +               if(err){
20181 +                       printk("setup_region : failed to reserve "
20182 +                              "0x%x - 0x%x for driver '%s'\n",
20183 +                              region->start, 
20184 +                              region->start + region->len,
20185 +                              region->driver);
20186 +                       return(-1);
20187 +               }
20188 +       }
20189 +       else region->start = get_vm(region->len);
20190 +       if(region->start == 0){
20191 +               if(region->driver == NULL) driver = "physmem";
20192 +               else driver = region->driver;
20193 +               printk("setup_region : failed to find vm for "
20194 +                      "driver '%s' (length %d)\n", driver, region->len);
20195 +               return(-1);
20196 +       }
20197 +       if(region->start == uml_physmem){
20198 +               start = (void *) uml_reserved;
20199 +               offset = uml_reserved - uml_physmem;
20200 +       }
20201 +       else {
20202 +               start = (void *) region->start;
20203 +               offset = 0;
20204 +       }
20205 +
20206 +       loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
20207 +                  MAP_SHARED | MAP_FIXED, region->fd, offset);
20208 +       if(loc != start){
20209 +               perror("Mapping memory");
20210 +               exit(1);
20211 +       }
20212 +       return(0);
20213 +}
20214 +
20215 +static int __init parse_iomem(char *str, int *add)
20216 +{
20217 +       struct stat64 buf;
20218 +       char *file, *driver;
20219 +       int fd;
20220 +
20221 +       driver = str;
20222 +       file = strchr(str,',');
20223 +       if(file == NULL){
20224 +               printf("parse_iomem : failed to parse iomem\n");
20225 +               return(1);
20226 +       }
20227 +       *file = '\0';
20228 +       file++;
20229 +       fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
20230 +       if(fd < 0){
20231 +               printf("parse_iomem - Couldn't open io file, errno = %d\n", 
20232 +                      errno);
20233 +               return(1);
20234 +       }
20235 +       if(fstat64(fd, &buf) < 0) {
20236 +               printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
20237 +               return(1);
20238 +       }
20239 +       add_iomem(driver, fd, buf.st_size);
20240 +       return(0);
20241 +}
20242 +
20243 +__uml_setup("iomem=", parse_iomem,
20244 +"iomem=<name>,<file>\n"
20245 +"    Configure <file> as an IO memory region named <name>.\n\n"
20246 +);
20247 +
20248 +#ifdef notdef
20249 +int logging = 0;
20250 +int logging_fd = -1;
20251 +
20252 +int logging_line = 0;
20253 +char logging_buf[256];
20254 +
20255 +void log(char *fmt, ...)
20256 +{
20257 +       va_list ap;
20258 +       struct timeval tv;
20259 +       struct openflags flags;
20260 +
20261 +       if(logging == 0) return;
20262 +       if(logging_fd < 0){
20263 +               flags = of_create(of_trunc(of_rdrw(OPENFLAGS())));
20264 +               logging_fd = os_open_file("log", flags, 0644);
20265 +       }
20266 +       gettimeofday(&tv, NULL);
20267 +       sprintf(logging_buf, "%d\t %u.%u  ", logging_line++, tv.tv_sec, 
20268 +               tv.tv_usec);
20269 +       va_start(ap, fmt);
20270 +       vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
20271 +       va_end(ap);
20272 +       write(logging_fd, logging_buf, strlen(logging_buf));
20273 +}
20274 +#endif
20275 +
20276 +int map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
20277 +              int r, int w, int x)
20278 +{
20279 +       struct mem_region *region = phys_region(phys);
20280 +
20281 +       return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
20282 +                            r, w, x));
20283 +}
20284 +
20285 +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
20286 +                  int must_succeed)
20287 +{
20288 +       if(os_protect_memory((void *) addr, len, r, w, x) < 0){
20289 +                if(must_succeed)
20290 +                        panic("protect failed, errno = %d", errno);
20291 +                else return(-errno);
20292 +       }
20293 +       return(0);
20294 +}
20295 +
20296 +unsigned long find_iomem(char *driver, unsigned long *len_out)
20297 +{
20298 +       struct mem_region *region;
20299 +       int i, n;
20300 +
20301 +       n = nregions();
20302 +       for(i = 0; i < n; i++){
20303 +               region = regions[i];
20304 +               if(region == NULL) continue;
20305 +               if((region->driver != NULL) &&
20306 +                  !strcmp(region->driver, driver)){
20307 +                       *len_out = region->len;
20308 +                       return(region->start);
20309 +               }
20310 +       }
20311 +       *len_out = 0;
20312 +       return 0;
20313 +}
20314 +
20315 +/*
20316 + * Overrides for Emacs so that we follow Linus's tabbing style.
20317 + * Emacs will notice this stuff at the end of the file and automatically
20318 + * adjust the settings for this buffer only.  This must remain at the end
20319 + * of the file.
20320 + * ---------------------------------------------------------------------------
20321 + * Local variables:
20322 + * c-file-style: "linux"
20323 + * End:
20324 + */
20325 diff -Naur -X ../exclude-files orig/arch/um/kernel/mprot.h um/arch/um/kernel/mprot.h
20326 --- orig/arch/um/kernel/mprot.h 1969-12-31 19:00:00.000000000 -0500
20327 +++ um/arch/um/kernel/mprot.h   2002-10-23 21:08:04.000000000 -0400
20328 @@ -0,0 +1,6 @@
20329 +#ifndef __MPROT_H__
20330 +#define __MPROT_H__
20331 +
20332 +extern void no_access(unsigned long addr, unsigned int len);
20333 +
20334 +#endif
20335 diff -Naur -X ../exclude-files orig/arch/um/kernel/process.c um/arch/um/kernel/process.c
20336 --- orig/arch/um/kernel/process.c       1969-12-31 19:00:00.000000000 -0500
20337 +++ um/arch/um/kernel/process.c 2003-04-23 20:36:15.000000000 -0400
20338 @@ -0,0 +1,286 @@
20339 +/* 
20340 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20341 + * Licensed under the GPL
20342 + */
20343 +
20344 +#include <stdio.h>
20345 +#include <unistd.h>
20346 +#include <signal.h>
20347 +#include <sched.h>
20348 +#include <errno.h>
20349 +#include <stdarg.h>
20350 +#include <fcntl.h>
20351 +#include <stdlib.h>
20352 +#include <setjmp.h>
20353 +#include <sys/time.h>
20354 +#include <sys/ptrace.h>
20355 +#include <sys/ioctl.h>
20356 +#include <sys/wait.h>
20357 +#include <sys/mman.h>
20358 +#include <asm/ptrace.h>
20359 +#include <asm/sigcontext.h>
20360 +#include <asm/unistd.h>
20361 +#include <asm/page.h>
20362 +#include "user_util.h"
20363 +#include "kern_util.h"
20364 +#include "user.h"
20365 +#include "process.h"
20366 +#include "signal_kern.h"
20367 +#include "signal_user.h"
20368 +#include "sysdep/ptrace.h"
20369 +#include "sysdep/sigcontext.h"
20370 +#include "irq_user.h"
20371 +#include "ptrace_user.h"
20372 +#include "time_user.h"
20373 +#include "init.h"
20374 +#include "os.h"
20375 +#include "uml-config.h"
20376 +#include "choose-mode.h"
20377 +#include "mode.h"
20378 +#ifdef UML_CONFIG_MODE_SKAS
20379 +#include "skas.h"
20380 +#include "skas_ptrace.h"
20381 +#endif
20382 +
20383 +void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
20384 +{
20385 +       int flags = 0, pages;
20386 +
20387 +       if(sig_stack != NULL){
20388 +               pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
20389 +               set_sigstack(sig_stack, pages * page_size());
20390 +               flags = SA_ONSTACK;
20391 +       }
20392 +       if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
20393 +}
20394 +
20395 +void init_new_thread_signals(int altstack)
20396 +{
20397 +       int flags = altstack ? SA_ONSTACK : 0;
20398 +
20399 +       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
20400 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20401 +       set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, 
20402 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20403 +       set_handler(SIGFPE, (__sighandler_t) sig_handler, flags, 
20404 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20405 +       set_handler(SIGILL, (__sighandler_t) sig_handler, flags, 
20406 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20407 +       set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 
20408 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20409 +       set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, 
20410 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20411 +       set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
20412 +                   SA_NOMASK | flags, -1);
20413 +       signal(SIGHUP, SIG_IGN);
20414 +
20415 +       init_irq_signals(altstack);
20416 +}
20417 +
20418 +struct tramp {
20419 +       int (*tramp)(void *);
20420 +       void *tramp_data;
20421 +       unsigned long temp_stack;
20422 +       int flags;
20423 +       int pid;
20424 +};
20425 +
20426 +/* See above for why sigkill is here */
20427 +
20428 +int sigkill = SIGKILL;
20429 +
20430 +int outer_tramp(void *arg)
20431 +{
20432 +       struct tramp *t;
20433 +       int sig = sigkill;
20434 +
20435 +       t = arg;
20436 +       t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
20437 +                      t->flags, t->tramp_data);
20438 +       if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
20439 +       kill(os_getpid(), sig);
20440 +       _exit(0);
20441 +}
20442 +
20443 +int start_fork_tramp(void *thread_arg, unsigned long temp_stack, 
20444 +                    int clone_flags, int (*tramp)(void *))
20445 +{
20446 +       struct tramp arg;
20447 +       unsigned long sp;
20448 +       int new_pid, status, err;
20449 +
20450 +       /* The trampoline will run on the temporary stack */
20451 +       sp = stack_sp(temp_stack);
20452 +
20453 +       clone_flags |= CLONE_FILES | SIGCHLD;
20454 +
20455 +       arg.tramp = tramp;
20456 +       arg.tramp_data = thread_arg;
20457 +       arg.temp_stack = temp_stack;
20458 +       arg.flags = clone_flags;
20459 +
20460 +       /* Start the process and wait for it to kill itself */
20461 +       new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
20462 +       if(new_pid < 0) return(-errno);
20463 +       while((err = waitpid(new_pid, &status, 0) < 0) && (errno == EINTR)) ;
20464 +       if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
20465 +                         errno);
20466 +       if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
20467 +               panic("outer trampoline didn't exit with SIGKILL");
20468 +
20469 +       return(arg.pid);
20470 +}
20471 +
20472 +void suspend_new_thread(int fd)
20473 +{
20474 +       char c;
20475 +
20476 +       os_stop_process(os_getpid());
20477 +
20478 +       if(read(fd, &c, sizeof(c)) != sizeof(c))
20479 +               panic("read failed in suspend_new_thread");
20480 +}
20481 +
20482 +static int ptrace_child(void *arg)
20483 +{
20484 +       int pid = os_getpid();
20485 +
20486 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
20487 +               perror("ptrace");
20488 +               os_kill_process(pid, 0);
20489 +       }
20490 +       os_stop_process(pid);
20491 +       _exit(os_getpid() == pid);
20492 +}
20493 +
20494 +static int start_ptraced_child(void **stack_out)
20495 +{
20496 +       void *stack;
20497 +       unsigned long sp;
20498 +       int pid, n, status;
20499 +       
20500 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
20501 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
20502 +       if(stack == MAP_FAILED)
20503 +               panic("check_ptrace : mmap failed, errno = %d", errno);
20504 +       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
20505 +       pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
20506 +       if(pid < 0)
20507 +               panic("check_ptrace : clone failed, errno = %d", errno);
20508 +       n = waitpid(pid, &status, WUNTRACED);
20509 +       if(n < 0)
20510 +               panic("check_ptrace : wait failed, errno = %d", errno);
20511 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
20512 +               panic("check_ptrace : expected SIGSTOP, got status = %d",
20513 +                     status);
20514 +
20515 +       *stack_out = stack;
20516 +       return(pid);
20517 +}
20518 +
20519 +static void stop_ptraced_child(int pid, void *stack, int exitcode)
20520 +{
20521 +       int status, n;
20522 +
20523 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
20524 +               panic("check_ptrace : ptrace failed, errno = %d", errno);
20525 +       n = waitpid(pid, &status, 0);
20526 +       if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
20527 +               panic("check_ptrace : child exited with status 0x%x", status);
20528 +
20529 +       if(munmap(stack, PAGE_SIZE) < 0)
20530 +               panic("check_ptrace : munmap failed, errno = %d", errno);
20531 +}
20532 +
20533 +void __init check_ptrace(void)
20534 +{
20535 +       void *stack;
20536 +       int pid, syscall, n, status;
20537 +
20538 +       printk("Checking that ptrace can change system call numbers...");
20539 +       pid = start_ptraced_child(&stack);
20540 +
20541 +       while(1){
20542 +               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
20543 +                       panic("check_ptrace : ptrace failed, errno = %d", 
20544 +                             errno);
20545 +               n = waitpid(pid, &status, WUNTRACED);
20546 +               if(n < 0)
20547 +                       panic("check_ptrace : wait failed, errno = %d", errno);
20548 +               if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
20549 +                       panic("check_ptrace : expected SIGTRAP, "
20550 +                             "got status = %d", status);
20551 +               
20552 +               syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
20553 +                                0);
20554 +               if(syscall == __NR_getpid){
20555 +                       n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
20556 +                                  __NR_getppid);
20557 +                       if(n < 0)
20558 +                               panic("check_ptrace : failed to modify system "
20559 +                                     "call, errno = %d", errno);
20560 +                       break;
20561 +               }
20562 +       }
20563 +       stop_ptraced_child(pid, stack, 0);
20564 +       printk("OK\n");
20565 +}
20566 +
20567 +int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
20568 +{
20569 +       jmp_buf buf;
20570 +       int n;
20571 +
20572 +       *jmp_ptr = &buf;
20573 +       n = setjmp(buf);
20574 +       if(n != 0)
20575 +               return(n);
20576 +       (*fn)(arg);
20577 +       return(0);
20578 +}
20579 +
20580 +int can_do_skas(void)
20581 +{
20582 +#ifdef UML_CONFIG_MODE_SKAS
20583 +       struct ptrace_faultinfo fi;
20584 +       void *stack;
20585 +       int pid, n, ret = 1;
20586 +
20587 +       printf("Checking for the skas3 patch in the host...");
20588 +       pid = start_ptraced_child(&stack);
20589 +
20590 +       n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
20591 +       if(n < 0){
20592 +               if(errno == EIO)
20593 +                       printf("not found\n");
20594 +               else printf("No (unexpected errno - %d)\n", errno);
20595 +               ret = 0;
20596 +       }
20597 +       else printf("found\n");
20598 +
20599 +       init_registers(pid);
20600 +       stop_ptraced_child(pid, stack, 1);
20601 +
20602 +       printf("Checking for /proc/mm...");
20603 +       if(access("/proc/mm", W_OK)){
20604 +               printf("not found\n");
20605 +               ret = 0;
20606 +       }
20607 +       else printf("found\n");
20608 +
20609 +       return(ret);
20610 +#else
20611 +       return(0);
20612 +#endif
20613 +}
20614 +
20615 +/*
20616 + * Overrides for Emacs so that we follow Linus's tabbing style.
20617 + * Emacs will notice this stuff at the end of the file and automatically
20618 + * adjust the settings for this buffer only.  This must remain at the end
20619 + * of the file.
20620 + * ---------------------------------------------------------------------------
20621 + * Local variables:
20622 + * c-file-style: "linux"
20623 + * End:
20624 + */
20625 diff -Naur -X ../exclude-files orig/arch/um/kernel/process_kern.c um/arch/um/kernel/process_kern.c
20626 --- orig/arch/um/kernel/process_kern.c  1969-12-31 19:00:00.000000000 -0500
20627 +++ um/arch/um/kernel/process_kern.c    2003-04-16 16:02:09.000000000 -0400
20628 @@ -0,0 +1,391 @@
20629 +/* 
20630 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
20631 + * Licensed under the GPL
20632 + */
20633 +
20634 +#include "linux/config.h"
20635 +#include "linux/kernel.h"
20636 +#include "linux/sched.h"
20637 +#include "linux/interrupt.h"
20638 +#include "linux/mm.h"
20639 +#include "linux/slab.h"
20640 +#include "linux/utsname.h"
20641 +#include "linux/fs.h"
20642 +#include "linux/utime.h"
20643 +#include "linux/smp_lock.h"
20644 +#include "linux/module.h"
20645 +#include "linux/init.h"
20646 +#include "linux/capability.h"
20647 +#include "asm/unistd.h"
20648 +#include "asm/mman.h"
20649 +#include "asm/segment.h"
20650 +#include "asm/stat.h"
20651 +#include "asm/pgtable.h"
20652 +#include "asm/processor.h"
20653 +#include "asm/pgalloc.h"
20654 +#include "asm/spinlock.h"
20655 +#include "asm/uaccess.h"
20656 +#include "asm/user.h"
20657 +#include "user_util.h"
20658 +#include "kern_util.h"
20659 +#include "kern.h"
20660 +#include "signal_kern.h"
20661 +#include "signal_user.h"
20662 +#include "init.h"
20663 +#include "irq_user.h"
20664 +#include "mem_user.h"
20665 +#include "time_user.h"
20666 +#include "tlb.h"
20667 +#include "frame_kern.h"
20668 +#include "sigcontext.h"
20669 +#include "2_5compat.h"
20670 +#include "os.h"
20671 +#include "mode.h"
20672 +#include "mode_kern.h"
20673 +#include "choose-mode.h"
20674 +
20675 +/* This is a per-cpu array.  A processor only modifies its entry and it only
20676 + * cares about its entry, so it's OK if another processor is modifying its
20677 + * entry.
20678 + */
20679 +struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
20680 +
20681 +struct task_struct *get_task(int pid, int require)
20682 +{
20683 +        struct task_struct *ret;
20684 +
20685 +        read_lock(&tasklist_lock);
20686 +       ret = find_task_by_pid(pid);
20687 +        read_unlock(&tasklist_lock);
20688 +
20689 +        if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
20690 +        return(ret);
20691 +}
20692 +
20693 +int external_pid(void *t)
20694 +{
20695 +       struct task_struct *task = t ? t : current;
20696 +
20697 +       return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
20698 +}
20699 +
20700 +int pid_to_processor_id(int pid)
20701 +{
20702 +       int i;
20703 +
20704 +       for(i = 0; i < smp_num_cpus; i++){
20705 +               if(cpu_tasks[i].pid == pid) return(i);
20706 +       }
20707 +       return(-1);
20708 +}
20709 +
20710 +void free_stack(unsigned long stack, int order)
20711 +{
20712 +       free_pages(stack, order);
20713 +}
20714 +
20715 +unsigned long alloc_stack(int order, int atomic)
20716 +{
20717 +       unsigned long page;
20718 +       int flags = GFP_KERNEL;
20719 +
20720 +       if(atomic) flags |= GFP_ATOMIC;
20721 +       if((page = __get_free_pages(flags, order)) == 0)
20722 +               return(0);
20723 +       stack_protections(page);
20724 +       return(page);
20725 +}
20726 +
20727 +int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
20728 +{
20729 +       int pid;
20730 +
20731 +       current->thread.request.u.thread.proc = fn;
20732 +       current->thread.request.u.thread.arg = arg;
20733 +       pid = do_fork(CLONE_VM | flags, 0, NULL, 0);
20734 +       if(pid < 0) panic("do_fork failed in kernel_thread");
20735 +       return(pid);
20736 +}
20737 +
20738 +void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
20739 +              struct task_struct *tsk, unsigned cpu)
20740 +{
20741 +       if (prev != next) 
20742 +               clear_bit(cpu, &prev->cpu_vm_mask);
20743 +       set_bit(cpu, &next->cpu_vm_mask);
20744 +}
20745 +
20746 +void set_current(void *t)
20747 +{
20748 +       struct task_struct *task = t;
20749 +
20750 +       cpu_tasks[task->processor] = ((struct cpu_task) 
20751 +               { external_pid(task), task });
20752 +}
20753 +
20754 +void *_switch_to(void *prev, void *next)
20755 +{
20756 +       return(CHOOSE_MODE(_switch_to_tt(prev, next), 
20757 +                          _switch_to_skas(prev, next)));
20758 +}
20759 +
20760 +void interrupt_end(void)
20761 +{
20762 +       if(current->need_resched) schedule();
20763 +       if(current->sigpending != 0) do_signal(0);
20764 +}
20765 +
20766 +void release_thread(struct task_struct *task)
20767 +{
20768 +       CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
20769 +}
20770 +
20771 +void exit_thread(void)
20772 +{
20773 +       CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
20774 +       unprotect_stack((unsigned long) current);
20775 +}
20776 +
20777 +void *get_current(void)
20778 +{
20779 +       return(current);
20780 +}
20781 +
20782 +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
20783 +               unsigned long stack_top, struct task_struct * p, 
20784 +               struct pt_regs *regs)
20785 +{
20786 +       p->thread = (struct thread_struct) INIT_THREAD;
20787 +       p->thread.kernel_stack = (unsigned long) p + 2 * PAGE_SIZE;
20788 +
20789 +       return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, 
20790 +                               clone_flags, sp, stack_top, p, regs));
20791 +}
20792 +
20793 +void initial_thread_cb(void (*proc)(void *), void *arg)
20794 +{
20795 +       int save_kmalloc_ok = kmalloc_ok;
20796 +
20797 +       kmalloc_ok = 0;
20798 +       CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, 
20799 +                        arg);
20800 +       kmalloc_ok = save_kmalloc_ok;
20801 +}
20802 +
20803 +unsigned long stack_sp(unsigned long page)
20804 +{
20805 +       return(page + PAGE_SIZE - sizeof(void *));
20806 +}
20807 +
20808 +int current_pid(void)
20809 +{
20810 +       return(current->pid);
20811 +}
20812 +
20813 +void cpu_idle(void)
20814 +{
20815 +       CHOOSE_MODE(init_idle_tt(), init_idle_skas());
20816 +
20817 +       atomic_inc(&init_mm.mm_count);
20818 +       current->mm = &init_mm;
20819 +       current->active_mm = &init_mm;
20820 +
20821 +       while(1){
20822 +               /* endless idle loop with no priority at all */
20823 +               SET_PRI(current);
20824 +
20825 +               /*
20826 +                * although we are an idle CPU, we do not want to
20827 +                * get into the scheduler unnecessarily.
20828 +                */
20829 +               if (current->need_resched) {
20830 +                       schedule();
20831 +                       check_pgt_cache();
20832 +               }
20833 +               idle_sleep(10);
20834 +       }
20835 +}
20836 +
20837 +int page_size(void)
20838 +{
20839 +       return(PAGE_SIZE);
20840 +}
20841 +
20842 +int page_mask(void)
20843 +{
20844 +       return(PAGE_MASK);
20845 +}
20846 +
20847 +void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
20848 +                     pte_t *pte_out)
20849 +{
20850 +       pgd_t *pgd;
20851 +       pmd_t *pmd;
20852 +       pte_t *pte;
20853 +
20854 +       if(task->mm == NULL) 
20855 +               return(ERR_PTR(-EINVAL));
20856 +       pgd = pgd_offset(task->mm, addr);
20857 +       pmd = pmd_offset(pgd, addr);
20858 +       if(!pmd_present(*pmd)) 
20859 +               return(ERR_PTR(-EINVAL));
20860 +       pte = pte_offset(pmd, addr);
20861 +       if(!pte_present(*pte)) 
20862 +               return(ERR_PTR(-EINVAL));
20863 +       if(pte_out != NULL)
20864 +               *pte_out = *pte;
20865 +       return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
20866 +}
20867 +
20868 +char *current_cmd(void)
20869 +{
20870 +#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
20871 +       return("(Unknown)");
20872 +#else
20873 +       void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
20874 +       return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
20875 +#endif
20876 +}
20877 +
20878 +void force_sigbus(void)
20879 +{
20880 +       printk(KERN_ERR "Killing pid %d because of a lack of memory\n", 
20881 +              current->pid);
20882 +       lock_kernel();
20883 +       sigaddset(&current->pending.signal, SIGBUS);
20884 +       recalc_sigpending(current);
20885 +       current->flags |= PF_SIGNALED;
20886 +       do_exit(SIGBUS | 0x80);
20887 +}
20888 +
20889 +void dump_thread(struct pt_regs *regs, struct user *u)
20890 +{
20891 +}
20892 +
20893 +void enable_hlt(void)
20894 +{
20895 +       panic("enable_hlt");
20896 +}
20897 +
20898 +void disable_hlt(void)
20899 +{
20900 +       panic("disable_hlt");
20901 +}
20902 +
20903 +extern int signal_frame_size;
20904 +
20905 +void *um_kmalloc(int size)
20906 +{
20907 +       return(kmalloc(size, GFP_KERNEL));
20908 +}
20909 +
20910 +void *um_kmalloc_atomic(int size)
20911 +{
20912 +       return(kmalloc(size, GFP_ATOMIC));
20913 +}
20914 +
20915 +unsigned long get_fault_addr(void)
20916 +{
20917 +       return((unsigned long) current->thread.fault_addr);
20918 +}
20919 +
20920 +EXPORT_SYMBOL(get_fault_addr);
20921 +
20922 +void not_implemented(void)
20923 +{
20924 +       printk(KERN_DEBUG "Something isn't implemented in here\n");
20925 +}
20926 +
20927 +EXPORT_SYMBOL(not_implemented);
20928 +
20929 +int user_context(unsigned long sp)
20930 +{
20931 +       unsigned long stack;
20932 +
20933 +       stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
20934 +       stack += 2 * PAGE_SIZE;
20935 +       return(stack != current->thread.kernel_stack);
20936 +}
20937 +
20938 +extern void remove_umid_dir(void);
20939 +
20940 +__uml_exitcall(remove_umid_dir);
20941 +
20942 +extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
20943 +
20944 +void do_uml_exitcalls(void)
20945 +{
20946 +       exitcall_t *call;
20947 +
20948 +       call = &__uml_exitcall_end;
20949 +       while (--call >= &__uml_exitcall_begin)
20950 +               (*call)();
20951 +}
20952 +
20953 +char *uml_strdup(char *string)
20954 +{
20955 +       char *new;
20956 +
20957 +       new = kmalloc(strlen(string) + 1, GFP_KERNEL);
20958 +       if(new == NULL) return(NULL);
20959 +       strcpy(new, string);
20960 +       return(new);
20961 +}
20962 +
20963 +void *get_init_task(void)
20964 +{
20965 +       return(&init_task_union.task);
20966 +}
20967 +
20968 +int copy_to_user_proc(void *to, void *from, int size)
20969 +{
20970 +       return(copy_to_user(to, from, size));
20971 +}
20972 +
20973 +int copy_from_user_proc(void *to, void *from, int size)
20974 +{
20975 +       return(copy_from_user(to, from, size));
20976 +}
20977 +
20978 +int clear_user_proc(void *buf, int size)
20979 +{
20980 +       return(clear_user(buf, size));
20981 +}
20982 +
20983 +int strlen_user_proc(char *str)
20984 +{
20985 +       return(strlen_user(str));
20986 +}
20987 +
20988 +int smp_sigio_handler(void)
20989 +{
20990 +#ifdef CONFIG_SMP
20991 +       int cpu = current->processor;
20992 +
20993 +       IPI_handler(cpu);
20994 +       if(cpu != 0)
20995 +               return(1);
20996 +#endif
20997 +       return(0);
20998 +}
20999 +
21000 +int um_in_interrupt(void)
21001 +{
21002 +       return(in_interrupt());
21003 +}
21004 +
21005 +int cpu(void)
21006 +{
21007 +        return(current->processor);
21008 +}
21009 +
21010 +/*
21011 + * Overrides for Emacs so that we follow Linus's tabbing style.
21012 + * Emacs will notice this stuff at the end of the file and automatically
21013 + * adjust the settings for this buffer only.  This must remain at the end
21014 + * of the file.
21015 + * ---------------------------------------------------------------------------
21016 + * Local variables:
21017 + * c-file-style: "linux"
21018 + * End:
21019 + */
21020 diff -Naur -X ../exclude-files orig/arch/um/kernel/ptrace.c um/arch/um/kernel/ptrace.c
21021 --- orig/arch/um/kernel/ptrace.c        1969-12-31 19:00:00.000000000 -0500
21022 +++ um/arch/um/kernel/ptrace.c  2002-12-28 22:50:21.000000000 -0500
21023 @@ -0,0 +1,325 @@
21024 +/* 
21025 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
21026 + * Licensed under the GPL
21027 + */
21028 +
21029 +#include "linux/sched.h"
21030 +#include "linux/mm.h"
21031 +#include "linux/errno.h"
21032 +#include "linux/smp_lock.h"
21033 +#ifdef CONFIG_PROC_MM
21034 +#include "linux/proc_mm.h"
21035 +#endif
21036 +#include "asm/ptrace.h"
21037 +#include "asm/uaccess.h"
21038 +#include "kern_util.h"
21039 +#include "ptrace_user.h"
21040 +
21041 +/*
21042 + * Called by kernel/ptrace.c when detaching..
21043 + */
21044 +void ptrace_disable(struct task_struct *child)
21045 +{ 
21046 +}
21047 +
21048 +extern long do_mmap2(struct task_struct *task, unsigned long addr, 
21049 +                    unsigned long len, unsigned long prot, 
21050 +                    unsigned long flags, unsigned long fd,
21051 +                    unsigned long pgoff);
21052 +
21053 +int sys_ptrace(long request, long pid, long addr, long data)
21054 +{
21055 +       struct task_struct *child;
21056 +       int i, ret;
21057 +
21058 +       lock_kernel();
21059 +       ret = -EPERM;
21060 +       if (request == PTRACE_TRACEME) {
21061 +               /* are we already being traced? */
21062 +               if (current->ptrace & PT_PTRACED)
21063 +                       goto out;
21064 +               /* set the ptrace bit in the process flags. */
21065 +               current->ptrace |= PT_PTRACED;
21066 +               ret = 0;
21067 +               goto out;
21068 +       }
21069 +       ret = -ESRCH;
21070 +       read_lock(&tasklist_lock);
21071 +       child = find_task_by_pid(pid);
21072 +       if (child)
21073 +               get_task_struct(child);
21074 +       read_unlock(&tasklist_lock);
21075 +       if (!child)
21076 +               goto out;
21077 +
21078 +       ret = -EPERM;
21079 +       if (pid == 1)           /* you may not mess with init */
21080 +               goto out_tsk;
21081 +
21082 +       if (request == PTRACE_ATTACH) {
21083 +               ret = ptrace_attach(child);
21084 +               goto out_tsk;
21085 +       }
21086 +
21087 +       ret = ptrace_check_attach(child, request == PTRACE_KILL);
21088 +       if (ret < 0)
21089 +               goto out_tsk;
21090 +
21091 +       switch (request) {
21092 +               /* when I and D space are separate, these will need to be fixed. */
21093 +       case PTRACE_PEEKTEXT: /* read word at location addr. */ 
21094 +       case PTRACE_PEEKDATA: {
21095 +               unsigned long tmp;
21096 +               int copied;
21097 +
21098 +               ret = -EIO;
21099 +               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
21100 +               if (copied != sizeof(tmp))
21101 +                       break;
21102 +               ret = put_user(tmp,(unsigned long *) data);
21103 +               break;
21104 +       }
21105 +
21106 +       /* read the word at location addr in the USER area. */
21107 +       case PTRACE_PEEKUSR: {
21108 +               unsigned long tmp;
21109 +
21110 +               ret = -EIO;
21111 +               if ((addr & 3) || addr < 0) 
21112 +                       break;
21113 +
21114 +               tmp = 0;  /* Default return condition */
21115 +               if(addr < FRAME_SIZE_OFFSET){
21116 +                       tmp = getreg(child, addr);
21117 +               }
21118 +               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
21119 +                       (addr <= offsetof(struct user, u_debugreg[7]))){
21120 +                       addr -= offsetof(struct user, u_debugreg[0]);
21121 +                       addr = addr >> 2;
21122 +                       tmp = child->thread.arch.debugregs[addr];
21123 +               }
21124 +               ret = put_user(tmp, (unsigned long *) data);
21125 +               break;
21126 +       }
21127 +
21128 +       /* when I and D space are separate, this will have to be fixed. */
21129 +       case PTRACE_POKETEXT: /* write the word at location addr. */
21130 +       case PTRACE_POKEDATA:
21131 +               ret = -EIO;
21132 +               if (access_process_vm(child, addr, &data, sizeof(data), 
21133 +                                     1) != sizeof(data))
21134 +                       break;
21135 +               ret = 0;
21136 +               break;
21137 +
21138 +       case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
21139 +               ret = -EIO;
21140 +               if ((addr & 3) || addr < 0)
21141 +                       break;
21142 +
21143 +               if (addr < FRAME_SIZE_OFFSET) {
21144 +                       ret = putreg(child, addr, data);
21145 +                       break;
21146 +               }
21147 +               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
21148 +                       (addr <= offsetof(struct user, u_debugreg[7]))){
21149 +                         addr -= offsetof(struct user, u_debugreg[0]);
21150 +                         addr = addr >> 2;
21151 +                         if((addr == 4) || (addr == 5)) break;
21152 +                         child->thread.arch.debugregs[addr] = data;
21153 +                         ret = 0;
21154 +               }
21155 +
21156 +               break;
21157 +
21158 +       case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
21159 +       case PTRACE_CONT: { /* restart after signal. */
21160 +               ret = -EIO;
21161 +               if ((unsigned long) data > _NSIG)
21162 +                       break;
21163 +               if (request == PTRACE_SYSCALL)
21164 +                       child->ptrace |= PT_TRACESYS;
21165 +               else
21166 +                       child->ptrace &= ~PT_TRACESYS;
21167 +               child->exit_code = data;
21168 +               wake_up_process(child);
21169 +               ret = 0;
21170 +               break;
21171 +       }
21172 +
21173 +/*
21174 + * make the child exit.  Best I can do is send it a sigkill. 
21175 + * perhaps it should be put in the status that it wants to 
21176 + * exit.
21177 + */
21178 +       case PTRACE_KILL: {
21179 +               ret = 0;
21180 +               if (child->state == TASK_ZOMBIE)        /* already dead */
21181 +                       break;
21182 +               child->exit_code = SIGKILL;
21183 +               wake_up_process(child);
21184 +               break;
21185 +       }
21186 +
21187 +       case PTRACE_SINGLESTEP: {  /* set the trap flag. */
21188 +               ret = -EIO;
21189 +               if ((unsigned long) data > _NSIG)
21190 +                       break;
21191 +               child->ptrace &= ~PT_TRACESYS;
21192 +               child->ptrace |= PT_DTRACE;
21193 +               child->exit_code = data;
21194 +               /* give it a chance to run. */
21195 +               wake_up_process(child);
21196 +               ret = 0;
21197 +               break;
21198 +       }
21199 +
21200 +       case PTRACE_DETACH:
21201 +               /* detach a process that was attached. */
21202 +               ret = ptrace_detach(child, data);
21203 +               break;
21204 +
21205 +#ifdef PTRACE_GETREGS
21206 +       case PTRACE_GETREGS: { /* Get all gp regs from the child. */
21207 +               if (!access_ok(VERIFY_WRITE, (unsigned long *)data, 
21208 +                              FRAME_SIZE_OFFSET)) {
21209 +                       ret = -EIO;
21210 +                       break;
21211 +               }
21212 +               for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
21213 +                       __put_user(getreg(child, i), (unsigned long *) data);
21214 +                       data += sizeof(long);
21215 +               }
21216 +               ret = 0;
21217 +               break;
21218 +       }
21219 +#endif
21220 +#ifdef PTRACE_SETREGS
21221 +       case PTRACE_SETREGS: { /* Set all gp regs in the child. */
21222 +               unsigned long tmp = 0;
21223 +               if (!access_ok(VERIFY_READ, (unsigned *)data, 
21224 +                              FRAME_SIZE_OFFSET)) {
21225 +                       ret = -EIO;
21226 +                       break;
21227 +               }
21228 +               for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
21229 +                       __get_user(tmp, (unsigned long *) data);
21230 +                       putreg(child, i, tmp);
21231 +                       data += sizeof(long);
21232 +               }
21233 +               ret = 0;
21234 +               break;
21235 +       }
21236 +#endif
21237 +#ifdef PTRACE_GETFPREGS
21238 +       case PTRACE_GETFPREGS: /* Get the child FPU state. */
21239 +               ret = get_fpregs(data, child);
21240 +               break;
21241 +#endif
21242 +#ifdef PTRACE_SETFPREGS
21243 +       case PTRACE_SETFPREGS: /* Set the child FPU state. */
21244 +               ret = set_fpregs(data, child);
21245 +               break;
21246 +#endif
21247 +#ifdef PTRACE_GETFPXREGS
21248 +       case PTRACE_GETFPXREGS: /* Get the child FPU state. */
21249 +               ret = get_fpxregs(data, child);
21250 +               break;
21251 +#endif
21252 +#ifdef PTRACE_SETFPXREGS
21253 +       case PTRACE_SETFPXREGS: /* Set the child FPU state. */
21254 +               ret = set_fpxregs(data, child);
21255 +               break;
21256 +#endif
21257 +       case PTRACE_FAULTINFO: {
21258 +               struct ptrace_faultinfo fault;
21259 +
21260 +               fault = ((struct ptrace_faultinfo) 
21261 +                       { .is_write     = child->thread.err,
21262 +                         .addr         = child->thread.cr2 });
21263 +               ret = copy_to_user((unsigned long *) data, &fault, 
21264 +                                  sizeof(fault));
21265 +               if(ret)
21266 +                       break;
21267 +               break;
21268 +       }
21269 +       case PTRACE_SIGPENDING:
21270 +               ret = copy_to_user((unsigned long *) data, 
21271 +                                  &child->pending.signal,
21272 +                                  sizeof(child->pending.signal));
21273 +               break;
21274 +
21275 +       case PTRACE_LDT: {
21276 +               struct ptrace_ldt ldt;
21277 +
21278 +               if(copy_from_user(&ldt, (unsigned long *) data, 
21279 +                                 sizeof(ldt))){
21280 +                       ret = -EIO;
21281 +                       break;
21282 +               }
21283 +
21284 +               /* This one is confusing, so just punt and return -EIO for 
21285 +                * now
21286 +                */
21287 +               ret = -EIO;
21288 +               break;
21289 +       }
21290 +#ifdef CONFIG_PROC_MM
21291 +       case PTRACE_SWITCH_MM: {
21292 +               struct mm_struct *old = child->mm;
21293 +               struct mm_struct *new = proc_mm_get_mm(data);
21294 +
21295 +               if(IS_ERR(new)){
21296 +                       ret = PTR_ERR(new);
21297 +                       break;
21298 +               }
21299 +
21300 +               atomic_inc(&new->mm_users);
21301 +               child->mm = new;
21302 +               child->active_mm = new;
21303 +               mmput(old);
21304 +               ret = 0;
21305 +               break;
21306 +       }
21307 +#endif
21308 +       default:
21309 +               ret = -EIO;
21310 +               break;
21311 +       }
21312 + out_tsk:
21313 +       free_task_struct(child);
21314 + out:
21315 +       unlock_kernel();
21316 +       return ret;
21317 +}
21318 +
21319 +void syscall_trace(void)
21320 +{
21321 +       if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
21322 +           != (PT_PTRACED|PT_TRACESYS))
21323 +               return;
21324 +       current->exit_code = SIGTRAP;
21325 +       current->state = TASK_STOPPED;
21326 +       notify_parent(current, SIGCHLD);
21327 +       schedule();
21328 +       /*
21329 +        * this isn't the same as continuing with a signal, but it will do
21330 +        * for normal use.  strace only continues with a signal if the
21331 +        * stopping signal is not SIGTRAP.  -brl
21332 +        */
21333 +       if (current->exit_code) {
21334 +               send_sig(current->exit_code, current, 1);
21335 +               current->exit_code = 0;
21336 +       }
21337 +}
21338 +
21339 +/*
21340 + * Overrides for Emacs so that we follow Linus's tabbing style.
21341 + * Emacs will notice this stuff at the end of the file and automatically
21342 + * adjust the settings for this buffer only.  This must remain at the end
21343 + * of the file.
21344 + * ---------------------------------------------------------------------------
21345 + * Local variables:
21346 + * c-file-style: "linux"
21347 + * End:
21348 + */
21349 diff -Naur -X ../exclude-files orig/arch/um/kernel/reboot.c um/arch/um/kernel/reboot.c
21350 --- orig/arch/um/kernel/reboot.c        1969-12-31 19:00:00.000000000 -0500
21351 +++ um/arch/um/kernel/reboot.c  2002-12-30 20:57:42.000000000 -0500
21352 @@ -0,0 +1,71 @@
21353 +/* 
21354 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
21355 + * Licensed under the GPL
21356 + */
21357 +
21358 +#include "linux/sched.h"
21359 +#include "user_util.h"
21360 +#include "kern_util.h"
21361 +#include "kern.h"
21362 +#include "os.h"
21363 +#include "mode.h"
21364 +#include "choose-mode.h"
21365 +
21366 +#ifdef CONFIG_SMP
21367 +static void kill_idlers(int me)
21368 +{
21369 +       struct task_struct *p;
21370 +       int i;
21371 +
21372 +       for(i = 0; i < sizeof(init_tasks)/sizeof(init_tasks[0]); i++){
21373 +               p = init_tasks[i];
21374 +               if((p != NULL) && (p->thread.mode.tt.extern_pid != me) &&
21375 +                  (p->thread.mode.tt.extern_pid != -1))
21376 +                       os_kill_process(p->thread.mode.tt.extern_pid, 0);
21377 +       }
21378 +}
21379 +#endif
21380 +
21381 +static void kill_off_processes(void)
21382 +{
21383 +       CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
21384 +#ifdef CONFIG_SMP
21385 +       kill_idlers(os_getpid());
21386 +#endif
21387 +}
21388 +
21389 +void uml_cleanup(void)
21390 +{
21391 +       kill_off_processes();
21392 +       do_uml_exitcalls();
21393 +}
21394 +
21395 +void machine_restart(char * __unused)
21396 +{
21397 +       do_uml_exitcalls();
21398 +       kill_off_processes();
21399 +       CHOOSE_MODE(reboot_tt(), reboot_skas());
21400 +}
21401 +
21402 +void machine_power_off(void)
21403 +{
21404 +       do_uml_exitcalls();
21405 +       kill_off_processes();
21406 +       CHOOSE_MODE(halt_tt(), halt_skas());
21407 +}
21408 +
21409 +void machine_halt(void)
21410 +{
21411 +       machine_power_off();
21412 +}
21413 +
21414 +/*
21415 + * Overrides for Emacs so that we follow Linus's tabbing style.
21416 + * Emacs will notice this stuff at the end of the file and automatically
21417 + * adjust the settings for this buffer only.  This must remain at the end
21418 + * of the file.
21419 + * ---------------------------------------------------------------------------
21420 + * Local variables:
21421 + * c-file-style: "linux"
21422 + * End:
21423 + */
21424 diff -Naur -X ../exclude-files orig/arch/um/kernel/resource.c um/arch/um/kernel/resource.c
21425 --- orig/arch/um/kernel/resource.c      1969-12-31 19:00:00.000000000 -0500
21426 +++ um/arch/um/kernel/resource.c        2002-10-23 21:08:04.000000000 -0400
21427 @@ -0,0 +1,23 @@
21428 +/* 
21429 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
21430 + * Licensed under the GPL
21431 + */
21432 +
21433 +#include "linux/pci.h"
21434 +
21435 +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
21436 +                            unsigned long start, unsigned long size)
21437 +{
21438 +       return start;
21439 +}
21440 +
21441 +/*
21442 + * Overrides for Emacs so that we follow Linus's tabbing style.
21443 + * Emacs will notice this stuff at the end of the file and automatically
21444 + * adjust the settings for this buffer only.  This must remain at the end
21445 + * of the file.
21446 + * ---------------------------------------------------------------------------
21447 + * Local variables:
21448 + * c-file-style: "linux"
21449 + * End:
21450 + */
21451 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_kern.c um/arch/um/kernel/sigio_kern.c
21452 --- orig/arch/um/kernel/sigio_kern.c    1969-12-31 19:00:00.000000000 -0500
21453 +++ um/arch/um/kernel/sigio_kern.c      2003-05-11 18:34:01.000000000 -0400
21454 @@ -0,0 +1,57 @@
21455 +/* 
21456 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21457 + * Licensed under the GPL
21458 + */
21459 +
21460 +#include "linux/kernel.h"
21461 +#include "linux/list.h"
21462 +#include "linux/slab.h"
21463 +#include "asm/irq.h"
21464 +#include "init.h"
21465 +#include "sigio.h"
21466 +#include "irq_user.h"
21467 +#include "irq_kern.h"
21468 +
21469 +/* Protected by sigio_lock() called from write_sigio_workaround */
21470 +static int sigio_irq_fd = -1;
21471 +
21472 +void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
21473 +{
21474 +       read_sigio_fd(sigio_irq_fd);
21475 +       reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
21476 +}
21477 +
21478 +int write_sigio_irq(int fd)
21479 +{
21480 +       if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
21481 +                         SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", 
21482 +                         NULL)){
21483 +               printk("write_sigio_irq : um_request_irq failed\n");
21484 +               return(-1);
21485 +       }
21486 +       sigio_irq_fd = fd;
21487 +       return(0);
21488 +}
21489 +
21490 +static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
21491 +
21492 +void sigio_lock(void)
21493 +{
21494 +       spin_lock(&sigio_spinlock);
21495 +}
21496 +
21497 +void sigio_unlock(void)
21498 +{
21499 +       spin_unlock(&sigio_spinlock);
21500 +}
21501 +
21502 +/*
21503 + * Overrides for Emacs so that we follow Linus's tabbing style.
21504 + * Emacs will notice this stuff at the end of the file and automatically
21505 + * adjust the settings for this buffer only.  This must remain at the end
21506 + * of the file.
21507 + * ---------------------------------------------------------------------------
21508 + * Local variables:
21509 + * c-file-style: "linux"
21510 + * End:
21511 + */
21512 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_user.c um/arch/um/kernel/sigio_user.c
21513 --- orig/arch/um/kernel/sigio_user.c    1969-12-31 19:00:00.000000000 -0500
21514 +++ um/arch/um/kernel/sigio_user.c      2002-12-29 23:36:35.000000000 -0500
21515 @@ -0,0 +1,440 @@
21516 +/* 
21517 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
21518 + * Licensed under the GPL
21519 + */
21520 +
21521 +#include <unistd.h>
21522 +#include <stdlib.h>
21523 +#include <termios.h>
21524 +#include <pty.h>
21525 +#include <fcntl.h>
21526 +#include <signal.h>
21527 +#include <errno.h>
21528 +#include <string.h>
21529 +#include <sched.h>
21530 +#include <sys/socket.h>
21531 +#include <sys/poll.h>
21532 +#include "init.h"
21533 +#include "user.h"
21534 +#include "kern_util.h"
21535 +#include "sigio.h"
21536 +#include "helper.h"
21537 +#include "os.h"
21538 +
21539 +/* Changed during early boot */
21540 +int pty_output_sigio = 0;
21541 +int pty_close_sigio = 0;
21542 +
21543 +/* Used as a flag during SIGIO testing early in boot */
21544 +static int got_sigio = 0;
21545 +
21546 +void __init handler(int sig)
21547 +{
21548 +       got_sigio = 1;
21549 +}
21550 +
21551 +struct openpty_arg {
21552 +       int master;
21553 +       int slave;
21554 +       int err;
21555 +};
21556 +
21557 +static void openpty_cb(void *arg)
21558 +{
21559 +       struct openpty_arg *info = arg;
21560 +
21561 +       info->err = 0;
21562 +       if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
21563 +               info->err = errno;
21564 +}
21565 +
21566 +void __init check_one_sigio(void (*proc)(int, int))
21567 +{
21568 +       struct sigaction old, new;
21569 +       struct termios tt;
21570 +       struct openpty_arg pty = { .master = -1, .slave = -1 };
21571 +       int master, slave, flags;
21572 +
21573 +       initial_thread_cb(openpty_cb, &pty);
21574 +       if(pty.err){
21575 +               printk("openpty failed, errno = %d\n", pty.err);
21576 +               return;
21577 +       }
21578 +
21579 +       master = pty.master;
21580 +       slave = pty.slave;
21581 +
21582 +       if((master == -1) || (slave == -1)){
21583 +               printk("openpty failed to allocate a pty\n");
21584 +               return;
21585 +       }
21586 +
21587 +       if(tcgetattr(master, &tt) < 0)
21588 +               panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
21589 +       cfmakeraw(&tt);
21590 +       if(tcsetattr(master, TCSADRAIN, &tt) < 0)
21591 +               panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
21592 +
21593 +       if((flags = fcntl(master, F_GETFL)) < 0)
21594 +               panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
21595 +
21596 +       if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
21597 +          (fcntl(master, F_SETOWN, os_getpid()) < 0))
21598 +               panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, "
21599 +                     "errno = %d\n", errno);
21600 +
21601 +       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
21602 +               panic("check_sigio : fcntl F_SETFL failed, errno = %d\n", 
21603 +                     errno);
21604 +
21605 +       if(sigaction(SIGIO, NULL, &old) < 0)
21606 +               panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
21607 +       new = old;
21608 +       new.sa_handler = handler;
21609 +       if(sigaction(SIGIO, &new, NULL) < 0)
21610 +               panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
21611 +
21612 +       got_sigio = 0;
21613 +       (*proc)(master, slave);
21614 +               
21615 +       close(master);
21616 +       close(slave);
21617 +
21618 +       if(sigaction(SIGIO, &old, NULL) < 0)
21619 +               panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
21620 +}
21621 +
21622 +static void tty_output(int master, int slave)
21623 +{
21624 +       int n;
21625 +       char buf[512];
21626 +
21627 +       printk("Checking that host ptys support output SIGIO...");
21628 +
21629 +       memset(buf, 0, sizeof(buf));
21630 +       while(write(master, buf, sizeof(buf)) > 0) ;
21631 +       if(errno != EAGAIN)
21632 +               panic("check_sigio : write failed, errno = %d\n", errno);
21633 +
21634 +       while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
21635 +
21636 +       if(got_sigio){
21637 +               printk("Yes\n");
21638 +               pty_output_sigio = 1;
21639 +       }
21640 +       else if(errno == EAGAIN) printk("No, enabling workaround\n");
21641 +       else panic("check_sigio : read failed, errno = %d\n", errno);
21642 +}
21643 +
21644 +static void tty_close(int master, int slave)
21645 +{
21646 +       printk("Checking that host ptys support SIGIO on close...");
21647 +
21648 +       close(slave);
21649 +       if(got_sigio){
21650 +               printk("Yes\n");
21651 +               pty_close_sigio = 1;
21652 +       }
21653 +       else printk("No, enabling workaround\n");
21654 +}
21655 +
21656 +void __init check_sigio(void)
21657 +{
21658 +       if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){
21659 +               printk("No pseudo-terminals available - skipping pty SIGIO "
21660 +                      "check\n");
21661 +               return;
21662 +       }
21663 +       check_one_sigio(tty_output);
21664 +       check_one_sigio(tty_close);
21665 +}
21666 +
21667 +/* Protected by sigio_lock(), also used by sigio_cleanup, which is an 
21668 + * exitcall.
21669 + */
21670 +static int write_sigio_pid = -1;
21671 +
21672 +/* These arrays are initialized before the sigio thread is started, and
21673 + * the descriptors closed after it is killed.  So, it can't see them change.
21674 + * On the UML side, they are changed under the sigio_lock.
21675 + */
21676 +static int write_sigio_fds[2] = { -1, -1 };
21677 +static int sigio_private[2] = { -1, -1 };
21678 +
21679 +struct pollfds {
21680 +       struct pollfd *poll;
21681 +       int size;
21682 +       int used;
21683 +};
21684 +
21685 +/* Protected by sigio_lock().  Used by the sigio thread, but the UML thread
21686 + * synchronizes with it.
21687 + */
21688 +struct pollfds current_poll = {
21689 +       .poll           = NULL,
21690 +       .size           = 0,
21691 +       .used           = 0
21692 +};
21693 +
21694 +struct pollfds next_poll = {
21695 +       .poll           = NULL,
21696 +       .size           = 0,
21697 +       .used           = 0
21698 +};
21699 +
21700 +static int write_sigio_thread(void *unused)
21701 +{
21702 +       struct pollfds *fds, tmp;
21703 +       struct pollfd *p;
21704 +       int i, n, respond_fd;
21705 +       char c;
21706 +
21707 +       fds = &current_poll;
21708 +       while(1){
21709 +               n = poll(fds->poll, fds->used, -1);
21710 +               if(n < 0){
21711 +                       if(errno == EINTR) continue;
21712 +                       printk("write_sigio_thread : poll returned %d, "
21713 +                              "errno = %d\n", n, errno);
21714 +               }
21715 +               for(i = 0; i < fds->used; i++){
21716 +                       p = &fds->poll[i];
21717 +                       if(p->revents == 0) continue;
21718 +                       if(p->fd == sigio_private[1]){
21719 +                               n = read(sigio_private[1], &c, sizeof(c));
21720 +                               if(n != sizeof(c))
21721 +                                       printk("write_sigio_thread : "
21722 +                                              "read failed, errno = %d\n",
21723 +                                              errno);
21724 +                               tmp = current_poll;
21725 +                               current_poll = next_poll;
21726 +                               next_poll = tmp;
21727 +                               respond_fd = sigio_private[1];
21728 +                       }
21729 +                       else {
21730 +                               respond_fd = write_sigio_fds[1];
21731 +                               fds->used--;
21732 +                               memmove(&fds->poll[i], &fds->poll[i + 1],
21733 +                                       (fds->used - i) * sizeof(*fds->poll));
21734 +                       }
21735 +
21736 +                       n = write(respond_fd, &c, sizeof(c));
21737 +                       if(n != sizeof(c))
21738 +                               printk("write_sigio_thread : write failed, "
21739 +                                      "errno = %d\n", errno);
21740 +               }
21741 +       }
21742 +}
21743 +
21744 +static int need_poll(int n)
21745 +{
21746 +       if(n <= next_poll.size){
21747 +               next_poll.used = n;
21748 +               return(0);
21749 +       }
21750 +       if(next_poll.poll != NULL) kfree(next_poll.poll);
21751 +       next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
21752 +       if(next_poll.poll == NULL){
21753 +               printk("need_poll : failed to allocate new pollfds\n");
21754 +               next_poll.size = 0;
21755 +               next_poll.used = 0;
21756 +               return(-1);
21757 +       }
21758 +       next_poll.size = n;
21759 +       next_poll.used = n;
21760 +       return(0);
21761 +}
21762 +
21763 +static void update_thread(void)
21764 +{
21765 +       unsigned long flags;
21766 +       int n;
21767 +       char c;
21768 +
21769 +       flags = set_signals(0);
21770 +       n = write(sigio_private[0], &c, sizeof(c));
21771 +       if(n != sizeof(c)){
21772 +               printk("update_thread : write failed, errno = %d\n", errno);
21773 +               goto fail;
21774 +       }
21775 +
21776 +       n = read(sigio_private[0], &c, sizeof(c));
21777 +       if(n != sizeof(c)){
21778 +               printk("update_thread : read failed, errno = %d\n", errno);
21779 +               goto fail;
21780 +       }
21781 +
21782 +       set_signals(flags);
21783 +       return;
21784 + fail:
21785 +       sigio_lock();
21786 +       if(write_sigio_pid != -1) 
21787 +               os_kill_process(write_sigio_pid, 1);
21788 +       write_sigio_pid = -1;
21789 +       close(sigio_private[0]);
21790 +       close(sigio_private[1]);        
21791 +       close(write_sigio_fds[0]);
21792 +       close(write_sigio_fds[1]);
21793 +       sigio_unlock();
21794 +       set_signals(flags);
21795 +}
21796 +
21797 +int add_sigio_fd(int fd, int read)
21798 +{
21799 +       int err = 0, i, n, events;
21800 +
21801 +       sigio_lock();
21802 +       for(i = 0; i < current_poll.used; i++){
21803 +               if(current_poll.poll[i].fd == fd) 
21804 +                       goto out;
21805 +       }
21806 +
21807 +       n = current_poll.used + 1;
21808 +       err = need_poll(n);
21809 +       if(err) 
21810 +               goto out;
21811 +
21812 +       for(i = 0; i < current_poll.used; i++)
21813 +               next_poll.poll[i] = current_poll.poll[i];
21814 +
21815 +       if(read) events = POLLIN;
21816 +       else events = POLLOUT;
21817 +
21818 +       next_poll.poll[n - 1] = ((struct pollfd) { .fd          = fd,
21819 +                                                  .events      = events,
21820 +                                                  .revents     = 0 });
21821 +       update_thread();
21822 + out:
21823 +       sigio_unlock();
21824 +       return(err);
21825 +}
21826 +
21827 +int ignore_sigio_fd(int fd)
21828 +{
21829 +       struct pollfd *p;
21830 +       int err = 0, i, n = 0;
21831 +
21832 +       sigio_lock();
21833 +       for(i = 0; i < current_poll.used; i++){
21834 +               if(current_poll.poll[i].fd == fd) break;
21835 +       }
21836 +       if(i == current_poll.used)
21837 +               goto out;
21838 +       
21839 +       err = need_poll(current_poll.used - 1);
21840 +       if(err)
21841 +               goto out;
21842 +
21843 +       for(i = 0; i < current_poll.used; i++){
21844 +               p = &current_poll.poll[i];
21845 +               if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i];
21846 +       }
21847 +       if(n == i){
21848 +               printk("ignore_sigio_fd : fd %d not found\n", fd);
21849 +               err = -1;
21850 +               goto out;
21851 +       }
21852 +
21853 +       update_thread();
21854 + out:
21855 +       sigio_unlock();
21856 +       return(err);
21857 +}
21858 +
21859 +static int setup_initial_poll(int fd)
21860 +{
21861 +       struct pollfd *p;
21862 +
21863 +       p = um_kmalloc(sizeof(struct pollfd));
21864 +       if(p == NULL){
21865 +               printk("setup_initial_poll : failed to allocate poll\n");
21866 +               return(-1);
21867 +       }
21868 +       *p = ((struct pollfd) { .fd     = fd,
21869 +                               .events         = POLLIN,
21870 +                               .revents        = 0 });
21871 +       current_poll = ((struct pollfds) { .poll        = p,
21872 +                                          .used        = 1,
21873 +                                          .size        = 1 });
21874 +       return(0);
21875 +}
21876 +
21877 +void write_sigio_workaround(void)
21878 +{
21879 +       unsigned long stack;
21880 +       int err;
21881 +
21882 +       sigio_lock();
21883 +       if(write_sigio_pid != -1)
21884 +               goto out;
21885 +
21886 +       err = os_pipe(write_sigio_fds, 1, 1);
21887 +       if(err){
21888 +               printk("write_sigio_workaround - os_pipe 1 failed, "
21889 +                      "errno = %d\n", -err);
21890 +               goto out;
21891 +       }
21892 +       err = os_pipe(sigio_private, 1, 1);
21893 +       if(err){
21894 +               printk("write_sigio_workaround - os_pipe 2 failed, "
21895 +                      "errno = %d\n", -err);
21896 +               goto out_close1;
21897 +       }
21898 +       if(setup_initial_poll(sigio_private[1]))
21899 +               goto out_close2;
21900 +
21901 +       write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 
21902 +                                           CLONE_FILES | CLONE_VM, &stack, 0);
21903 +
21904 +       if(write_sigio_pid < 0) goto out_close2;
21905 +
21906 +       if(write_sigio_irq(write_sigio_fds[0])) 
21907 +               goto out_kill;
21908 +
21909 + out:
21910 +       sigio_unlock();
21911 +       return;
21912 +
21913 + out_kill:
21914 +       os_kill_process(write_sigio_pid, 1);
21915 +       write_sigio_pid = -1;
21916 + out_close2:
21917 +       close(sigio_private[0]);
21918 +       close(sigio_private[1]);        
21919 + out_close1:
21920 +       close(write_sigio_fds[0]);
21921 +       close(write_sigio_fds[1]);
21922 +       sigio_unlock();
21923 +}
21924 +
21925 +int read_sigio_fd(int fd)
21926 +{
21927 +       int n;
21928 +       char c;
21929 +
21930 +       n = read(fd, &c, sizeof(c));
21931 +       if(n != sizeof(c)){
21932 +               printk("read_sigio_fd - read failed, errno = %d\n", errno);
21933 +               return(-errno);
21934 +       }
21935 +       return(n);
21936 +}
21937 +
21938 +static void sigio_cleanup(void)
21939 +{
21940 +       if(write_sigio_pid != -1)
21941 +               os_kill_process(write_sigio_pid, 1);
21942 +}
21943 +
21944 +__uml_exitcall(sigio_cleanup);
21945 +
21946 +/*
21947 + * Overrides for Emacs so that we follow Linus's tabbing style.
21948 + * Emacs will notice this stuff at the end of the file and automatically
21949 + * adjust the settings for this buffer only.  This must remain at the end
21950 + * of the file.
21951 + * ---------------------------------------------------------------------------
21952 + * Local variables:
21953 + * c-file-style: "linux"
21954 + * End:
21955 + */
21956 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_kern.c um/arch/um/kernel/signal_kern.c
21957 --- orig/arch/um/kernel/signal_kern.c   1969-12-31 19:00:00.000000000 -0500
21958 +++ um/arch/um/kernel/signal_kern.c     2002-12-08 19:44:13.000000000 -0500
21959 @@ -0,0 +1,367 @@
21960 +/* 
21961 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
21962 + * Licensed under the GPL
21963 + */
21964 +
21965 +#include "linux/config.h"
21966 +#include "linux/stddef.h"
21967 +#include "linux/sys.h"
21968 +#include "linux/sched.h"
21969 +#include "linux/wait.h"
21970 +#include "linux/kernel.h"
21971 +#include "linux/smp_lock.h"
21972 +#include "linux/module.h"
21973 +#include "linux/slab.h"
21974 +#include "asm/signal.h"
21975 +#include "asm/uaccess.h"
21976 +#include "asm/ucontext.h"
21977 +#include "user_util.h"
21978 +#include "kern_util.h"
21979 +#include "signal_kern.h"
21980 +#include "signal_user.h"
21981 +#include "kern.h"
21982 +#include "frame_kern.h"
21983 +#include "sigcontext.h"
21984 +#include "mode.h"
21985 +
21986 +EXPORT_SYMBOL(block_signals);
21987 +EXPORT_SYMBOL(unblock_signals);
21988 +
21989 +static void force_segv(int sig)
21990 +{
21991 +       if(sig == SIGSEGV){
21992 +               struct k_sigaction *ka;
21993 +
21994 +               ka = &current->sig->action[SIGSEGV - 1];
21995 +               ka->sa.sa_handler = SIG_DFL;
21996 +       }
21997 +       force_sig(SIGSEGV, current);
21998 +}
21999 +
22000 +#define _S(nr) (1<<((nr)-1))
22001 +
22002 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
22003 +
22004 +/*
22005 + * OK, we're invoking a handler
22006 + */    
22007 +static int handle_signal(struct pt_regs *regs, unsigned long signr, 
22008 +                        struct k_sigaction *ka, siginfo_t *info, 
22009 +                        sigset_t *oldset, int error)
22010 +{
22011 +        __sighandler_t handler;
22012 +       void (*restorer)(void);
22013 +       unsigned long sp;
22014 +       sigset_t save;
22015 +       int err, ret;
22016 +
22017 +       ret = 0;
22018 +       switch(error){
22019 +       case -ERESTARTNOHAND:
22020 +               ret = -EINTR;
22021 +               break;
22022 +
22023 +       case -ERESTARTSYS:
22024 +               if (!(ka->sa.sa_flags & SA_RESTART)) {
22025 +                       ret = -EINTR;
22026 +                       break;
22027 +               }
22028 +               /* fallthrough */
22029 +       case -ERESTARTNOINTR:
22030 +               PT_REGS_RESTART_SYSCALL(regs);
22031 +               PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
22032 +
22033 +               /* This is because of the UM_SET_SYSCALL_RETURN and the fact
22034 +                * that on i386 the system call number and return value are
22035 +                * in the same register.  When the system call restarts, %eax
22036 +                * had better have the system call number in it.  Since the
22037 +                * return value doesn't matter (except that it shouldn't be
22038 +                * -ERESTART*), we'll stick the system call number there.
22039 +                */
22040 +               ret = PT_REGS_SYSCALL_NR(regs);
22041 +               break;
22042 +       }
22043 +
22044 +       handler = ka->sa.sa_handler;
22045 +       save = *oldset;
22046 +
22047 +       if (ka->sa.sa_flags & SA_ONESHOT)
22048 +               ka->sa.sa_handler = SIG_DFL;
22049 +
22050 +       if (!(ka->sa.sa_flags & SA_NODEFER)) {
22051 +               spin_lock_irq(&current->sigmask_lock);
22052 +               sigorsets(&current->blocked, &current->blocked, 
22053 +                         &ka->sa.sa_mask);
22054 +               sigaddset(&current->blocked, signr);
22055 +               recalc_sigpending(current);
22056 +               spin_unlock_irq(&current->sigmask_lock);
22057 +       }
22058 +
22059 +       sp = PT_REGS_SP(regs);
22060 +
22061 +       if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
22062 +               sp = current->sas_ss_sp + current->sas_ss_size;
22063 +       
22064 +       if(error != 0) PT_REGS_SET_SYSCALL_RETURN(regs, ret);
22065 +
22066 +       if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer;
22067 +       else restorer = NULL;
22068 +
22069 +       if(ka->sa.sa_flags & SA_SIGINFO)
22070 +               err = setup_signal_stack_si(sp, signr, (unsigned long) handler,
22071 +                                           restorer, regs, info, &save);
22072 +       else
22073 +               err = setup_signal_stack_sc(sp, signr, (unsigned long) handler,
22074 +                                           restorer, regs, &save);
22075 +       if(err) goto segv;
22076 +
22077 +       return(0);
22078 + segv:
22079 +       force_segv(signr);
22080 +       return(1);
22081 +}
22082 +
22083 +/*
22084 + * Note that 'init' is a special process: it doesn't get signals it doesn't
22085 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
22086 + * mistake.
22087 + */
22088 +
22089 +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
22090 +{
22091 +       siginfo_t info;
22092 +       struct k_sigaction *ka;
22093 +       int err;
22094 +
22095 +       if (!oldset)
22096 +               oldset = &current->blocked;
22097 +
22098 +       for (;;) {
22099 +               unsigned long signr;
22100 +
22101 +               spin_lock_irq(&current->sigmask_lock);
22102 +               signr = dequeue_signal(&current->blocked, &info);
22103 +               spin_unlock_irq(&current->sigmask_lock);
22104 +
22105 +               if (!signr)
22106 +                       break;
22107 +
22108 +               if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
22109 +                       /* Let the debugger run.  */
22110 +                       current->exit_code = signr;
22111 +                       current->state = TASK_STOPPED;
22112 +                       notify_parent(current, SIGCHLD);
22113 +                       schedule();
22114 +
22115 +                       /* We're back.  Did the debugger cancel the sig?  */
22116 +                       if (!(signr = current->exit_code))
22117 +                               continue;
22118 +                       current->exit_code = 0;
22119 +
22120 +                       /* The debugger continued.  Ignore SIGSTOP.  */
22121 +                       if (signr == SIGSTOP)
22122 +                               continue;
22123 +
22124 +                       /* Update the siginfo structure.  Is this good?  */
22125 +                       if (signr != info.si_signo) {
22126 +                               info.si_signo = signr;
22127 +                               info.si_errno = 0;
22128 +                               info.si_code = SI_USER;
22129 +                               info.si_pid = current->p_pptr->pid;
22130 +                               info.si_uid = current->p_pptr->uid;
22131 +                       }
22132 +
22133 +                       /* If the (new) signal is now blocked, requeue it.  */
22134 +                       if (sigismember(&current->blocked, signr)) {
22135 +                               send_sig_info(signr, &info, current);
22136 +                               continue;
22137 +                       }
22138 +               }
22139 +
22140 +               ka = &current->sig->action[signr-1];
22141 +               if (ka->sa.sa_handler == SIG_IGN) {
22142 +                       if (signr != SIGCHLD)
22143 +                               continue;
22144 +                       /* Check for SIGCHLD: it's special.  */
22145 +                       while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
22146 +                               /* nothing */;
22147 +                       continue;
22148 +               }
22149 +
22150 +               if (ka->sa.sa_handler == SIG_DFL) {
22151 +                       int exit_code = signr;
22152 +
22153 +                       /* Init gets no signals it doesn't want.  */
22154 +                       if (current->pid == 1)
22155 +                               continue;
22156 +
22157 +                       switch (signr) {
22158 +                       case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
22159 +                               continue;
22160 +
22161 +                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
22162 +                               if (is_orphaned_pgrp(current->pgrp))
22163 +                                       continue;
22164 +                               /* FALLTHRU */
22165 +
22166 +                        case SIGSTOP: {
22167 +                                struct signal_struct *sig;
22168 +                               current->state = TASK_STOPPED;
22169 +                               current->exit_code = signr;
22170 +                                sig = current->p_pptr->sig;
22171 +                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
22172 +                                       notify_parent(current, SIGCHLD);
22173 +                               schedule();
22174 +                               continue;
22175 +                       }
22176 +                       case SIGQUIT: case SIGILL: case SIGTRAP:
22177 +                       case SIGABRT: case SIGFPE: case SIGSEGV:
22178 +                       case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
22179 +                               if (do_coredump(signr, &current->thread.regs))
22180 +                                       exit_code |= 0x80;
22181 +                               /* FALLTHRU */
22182 +
22183 +                       default:
22184 +                               sig_exit(signr, exit_code, &info);
22185 +                               /* NOTREACHED */
22186 +                       }
22187 +               }
22188 +
22189 +               /* Whee!  Actually deliver the signal.  */
22190 +               err = handle_signal(regs, signr, ka, &info, oldset, error);
22191 +               if(!err) return(1);
22192 +       }
22193 +
22194 +       /* Did we come from a system call? */
22195 +       if(PT_REGS_SYSCALL_NR(regs) >= 0){
22196 +               /* Restart the system call - no handlers present */
22197 +               if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND ||
22198 +                  PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS ||
22199 +                  PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){
22200 +                       PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
22201 +                       PT_REGS_RESTART_SYSCALL(regs);
22202 +               }
22203 +       }
22204 +
22205 +       /* This closes a way to execute a system call on the host.  If
22206 +        * you set a breakpoint on a system call instruction and singlestep
22207 +        * from it, the tracing thread used to PTRACE_SINGLESTEP the process
22208 +        * rather than PTRACE_SYSCALL it, allowing the system call to execute
22209 +        * on the host.  The tracing thread will check this flag and 
22210 +        * PTRACE_SYSCALL if necessary.
22211 +        */
22212 +       if((current->ptrace & PT_DTRACE) && 
22213 +          is_syscall(PT_REGS_IP(&current->thread.regs)))
22214 +               (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0);
22215 +
22216 +       return(0);
22217 +}
22218 +
22219 +int do_signal(int error)
22220 +{
22221 +       return(kern_do_signal(&current->thread.regs, NULL, error));
22222 +}
22223 +
22224 +/*
22225 + * Atomically swap in the new signal mask, and wait for a signal.
22226 + */
22227 +int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
22228 +{
22229 +       sigset_t saveset;
22230 +
22231 +       mask &= _BLOCKABLE;
22232 +       spin_lock_irq(&current->sigmask_lock);
22233 +       saveset = current->blocked;
22234 +       siginitset(&current->blocked, mask);
22235 +       recalc_sigpending(current);
22236 +       spin_unlock_irq(&current->sigmask_lock);
22237 +
22238 +       while (1) {
22239 +               current->state = TASK_INTERRUPTIBLE;
22240 +               schedule();
22241 +               if(kern_do_signal(&current->thread.regs, &saveset, -EINTR))
22242 +                       return(-EINTR);
22243 +       }
22244 +}
22245 +
22246 +int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
22247 +{
22248 +       sigset_t saveset, newset;
22249 +
22250 +       /* XXX: Don't preclude handling different sized sigset_t's.  */
22251 +       if (sigsetsize != sizeof(sigset_t))
22252 +               return -EINVAL;
22253 +
22254 +       if (copy_from_user(&newset, unewset, sizeof(newset)))
22255 +               return -EFAULT;
22256 +       sigdelsetmask(&newset, ~_BLOCKABLE);
22257 +
22258 +       spin_lock_irq(&current->sigmask_lock);
22259 +       saveset = current->blocked;
22260 +       current->blocked = newset;
22261 +       recalc_sigpending(current);
22262 +       spin_unlock_irq(&current->sigmask_lock);
22263 +
22264 +       while (1) {
22265 +               current->state = TASK_INTERRUPTIBLE;
22266 +               schedule();
22267 +               if (kern_do_signal(&current->thread.regs, &saveset, -EINTR))
22268 +                       return(-EINTR);
22269 +       }
22270 +}
22271 +
22272 +static int copy_sc_from_user(struct pt_regs *to, void *from, 
22273 +                            struct arch_frame_data *arch)
22274 +{
22275 +       int ret;
22276 +
22277 +       ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
22278 +                         copy_sc_from_user_skas(&to->regs, from));
22279 +       return(ret);
22280 +}
22281 +
22282 +int sys_sigreturn(struct pt_regs regs)
22283 +{
22284 +       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
22285 +       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
22286 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
22287 +
22288 +       spin_lock_irq(&current->sigmask_lock);
22289 +       copy_from_user(&current->blocked.sig[0], sc_sigmask(sc), 
22290 +                      sizeof(current->blocked.sig[0]));
22291 +       copy_from_user(&current->blocked.sig[1], mask, sig_size);
22292 +       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
22293 +       recalc_sigpending(current);
22294 +       spin_unlock_irq(&current->sigmask_lock);
22295 +       copy_sc_from_user(&current->thread.regs, sc, 
22296 +                         &signal_frame_sc.common.arch);
22297 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
22298 +}
22299 +
22300 +int sys_rt_sigreturn(struct pt_regs regs)
22301 +{
22302 +       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
22303 +       void *fp;
22304 +       int sig_size = _NSIG_WORDS * sizeof(unsigned long);
22305 +
22306 +       spin_lock_irq(&current->sigmask_lock);
22307 +       copy_from_user(&current->blocked, &uc->uc_sigmask, sig_size);
22308 +       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
22309 +       recalc_sigpending(current);
22310 +       spin_unlock_irq(&current->sigmask_lock);
22311 +       fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
22312 +       copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
22313 +                         &signal_frame_si.common.arch);
22314 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
22315 +}
22316 +
22317 +/*
22318 + * Overrides for Emacs so that we follow Linus's tabbing style.
22319 + * Emacs will notice this stuff at the end of the file and automatically
22320 + * adjust the settings for this buffer only.  This must remain at the end
22321 + * of the file.
22322 + * ---------------------------------------------------------------------------
22323 + * Local variables:
22324 + * c-file-style: "linux"
22325 + * End:
22326 + */
22327 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_user.c um/arch/um/kernel/signal_user.c
22328 --- orig/arch/um/kernel/signal_user.c   1969-12-31 19:00:00.000000000 -0500
22329 +++ um/arch/um/kernel/signal_user.c     2002-10-23 21:08:04.000000000 -0400
22330 @@ -0,0 +1,142 @@
22331 +/* 
22332 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22333 + * Licensed under the GPL
22334 + */
22335 +
22336 +#include <stdio.h>
22337 +#include <unistd.h>
22338 +#include <stdlib.h>
22339 +#include <signal.h>
22340 +#include <errno.h>
22341 +#include <stdarg.h>
22342 +#include <string.h>
22343 +#include <sys/mman.h>
22344 +#include "user_util.h"
22345 +#include "kern_util.h"
22346 +#include "user.h"
22347 +#include "signal_user.h"
22348 +#include "signal_kern.h"
22349 +#include "sysdep/sigcontext.h"
22350 +#include "sigcontext.h"
22351 +
22352 +void set_sigstack(void *sig_stack, int size)
22353 +{
22354 +       stack_t stack = ((stack_t) { .ss_flags  = 0,
22355 +                                    .ss_sp     = (__ptr_t) sig_stack,
22356 +                                    .ss_size   = size - sizeof(void *) });
22357 +
22358 +       if(sigaltstack(&stack, NULL) != 0)
22359 +               panic("enabling signal stack failed, errno = %d\n", errno);
22360 +}
22361 +
22362 +void set_handler(int sig, void (*handler)(int), int flags, ...)
22363 +{
22364 +       struct sigaction action;
22365 +       va_list ap;
22366 +       int mask;
22367 +
22368 +       va_start(ap, flags);
22369 +       action.sa_handler = handler;
22370 +       sigemptyset(&action.sa_mask);
22371 +       while((mask = va_arg(ap, int)) != -1){
22372 +               sigaddset(&action.sa_mask, mask);
22373 +       }
22374 +       action.sa_flags = flags;
22375 +       action.sa_restorer = NULL;
22376 +       if(sigaction(sig, &action, NULL) < 0)
22377 +               panic("sigaction failed");
22378 +}
22379 +
22380 +int change_sig(int signal, int on)
22381 +{
22382 +       sigset_t sigset, old;
22383 +
22384 +       sigemptyset(&sigset);
22385 +       sigaddset(&sigset, signal);
22386 +       sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
22387 +       return(!sigismember(&old, signal));
22388 +}
22389 +
22390 +static void change_signals(int type)
22391 +{
22392 +       sigset_t mask;
22393 +
22394 +       sigemptyset(&mask);
22395 +       sigaddset(&mask, SIGVTALRM);
22396 +       sigaddset(&mask, SIGALRM);
22397 +       sigaddset(&mask, SIGIO);
22398 +       sigaddset(&mask, SIGPROF);
22399 +       if(sigprocmask(type, &mask, NULL) < 0)
22400 +               panic("Failed to change signal mask - errno = %d", errno);
22401 +}
22402 +
22403 +void block_signals(void)
22404 +{
22405 +       change_signals(SIG_BLOCK);
22406 +}
22407 +
22408 +void unblock_signals(void)
22409 +{
22410 +       change_signals(SIG_UNBLOCK);
22411 +}
22412 +
22413 +#define SIGIO_BIT 0
22414 +#define SIGVTALRM_BIT 1
22415 +
22416 +static int enable_mask(sigset_t *mask)
22417 +{
22418 +       int sigs;
22419 +
22420 +       sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
22421 +       sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
22422 +       sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
22423 +       return(sigs);
22424 +}
22425 +
22426 +int get_signals(void)
22427 +{
22428 +       sigset_t mask;
22429 +       
22430 +       if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
22431 +               panic("Failed to get signal mask");
22432 +       return(enable_mask(&mask));
22433 +}
22434 +
22435 +int set_signals(int enable)
22436 +{
22437 +       sigset_t mask;
22438 +       int ret;
22439 +
22440 +       sigemptyset(&mask);
22441 +       if(enable & (1 << SIGIO_BIT)) 
22442 +               sigaddset(&mask, SIGIO);
22443 +       if(enable & (1 << SIGVTALRM_BIT)){
22444 +               sigaddset(&mask, SIGVTALRM);
22445 +               sigaddset(&mask, SIGALRM);
22446 +       }
22447 +       if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
22448 +               panic("Failed to enable signals");
22449 +       ret = enable_mask(&mask);
22450 +       sigemptyset(&mask);
22451 +       if((enable & (1 << SIGIO_BIT)) == 0) 
22452 +               sigaddset(&mask, SIGIO);
22453 +       if((enable & (1 << SIGVTALRM_BIT)) == 0){
22454 +               sigaddset(&mask, SIGVTALRM);
22455 +               sigaddset(&mask, SIGALRM);
22456 +       }
22457 +       if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
22458 +               panic("Failed to block signals");
22459 +
22460 +       return(ret);
22461 +}
22462 +
22463 +/*
22464 + * Overrides for Emacs so that we follow Linus's tabbing style.
22465 + * Emacs will notice this stuff at the end of the file and automatically
22466 + * adjust the settings for this buffer only.  This must remain at the end
22467 + * of the file.
22468 + * ---------------------------------------------------------------------------
22469 + * Local variables:
22470 + * c-file-style: "linux"
22471 + * End:
22472 + */
22473 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_kern.c um/arch/um/kernel/skas/exec_kern.c
22474 --- orig/arch/um/kernel/skas/exec_kern.c        1969-12-31 19:00:00.000000000 -0500
22475 +++ um/arch/um/kernel/skas/exec_kern.c  2002-11-11 18:57:19.000000000 -0500
22476 @@ -0,0 +1,41 @@
22477 +/* 
22478 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22479 + * Licensed under the GPL
22480 + */
22481 +
22482 +#include "linux/kernel.h"
22483 +#include "asm/current.h"
22484 +#include "asm/page.h"
22485 +#include "asm/signal.h"
22486 +#include "asm/ptrace.h"
22487 +#include "asm/uaccess.h"
22488 +#include "asm/mmu_context.h"
22489 +#include "tlb.h"
22490 +#include "skas.h"
22491 +#include "mmu.h"
22492 +#include "os.h"
22493 +
22494 +void flush_thread_skas(void)
22495 +{
22496 +       force_flush_all();
22497 +       switch_mm_skas(current->mm->context.skas.mm_fd);
22498 +}
22499 +
22500 +void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
22501 +                      unsigned long esp)
22502 +{
22503 +       set_fs(USER_DS);
22504 +        PT_REGS_IP(regs) = eip;
22505 +       PT_REGS_SP(regs) = esp;
22506 +}
22507 +
22508 +/*
22509 + * Overrides for Emacs so that we follow Linus's tabbing style.
22510 + * Emacs will notice this stuff at the end of the file and automatically
22511 + * adjust the settings for this buffer only.  This must remain at the end
22512 + * of the file.
22513 + * ---------------------------------------------------------------------------
22514 + * Local variables:
22515 + * c-file-style: "linux"
22516 + * End:
22517 + */
22518 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_user.c um/arch/um/kernel/skas/exec_user.c
22519 --- orig/arch/um/kernel/skas/exec_user.c        1969-12-31 19:00:00.000000000 -0500
22520 +++ um/arch/um/kernel/skas/exec_user.c  2002-11-03 19:23:01.000000000 -0500
22521 @@ -0,0 +1,61 @@
22522 +/* 
22523 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22524 + * Licensed under the GPL
22525 + */
22526 +
22527 +#include <stdlib.h>
22528 +#include <errno.h>
22529 +#include <signal.h>
22530 +#include <sched.h>
22531 +#include <sys/wait.h>
22532 +#include <sys/ptrace.h>
22533 +#include "user.h"
22534 +#include "kern_util.h"
22535 +#include "os.h"
22536 +#include "time_user.h"
22537 +
22538 +static int user_thread_tramp(void *arg)
22539 +{
22540 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
22541 +               panic("user_thread_tramp - PTRACE_TRACEME failed, "
22542 +                     "errno = %d\n", errno);
22543 +       enable_timer();
22544 +       os_stop_process(os_getpid());
22545 +       return(0);
22546 +}
22547 +
22548 +int user_thread(unsigned long stack, int flags)
22549 +{
22550 +       int pid, status;
22551 +
22552 +       pid = clone(user_thread_tramp, (void *) stack_sp(stack), 
22553 +                   flags | CLONE_FILES | SIGCHLD, NULL);
22554 +       if(pid < 0){
22555 +               printk("user_thread - clone failed, errno = %d\n", errno);
22556 +               return(pid);
22557 +       }
22558 +
22559 +       if(waitpid(pid, &status, WUNTRACED) < 0){
22560 +               printk("user_thread - waitpid failed, errno = %d\n", errno);
22561 +               return(-errno);
22562 +       }
22563 +
22564 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
22565 +               printk("user_thread - trampoline didn't stop, status = %d\n", 
22566 +                      status);
22567 +               return(-EINVAL);
22568 +       }
22569 +
22570 +       return(pid);
22571 +}
22572 +
22573 +/*
22574 + * Overrides for Emacs so that we follow Linus's tabbing style.
22575 + * Emacs will notice this stuff at the end of the file and automatically
22576 + * adjust the settings for this buffer only.  This must remain at the end
22577 + * of the file.
22578 + * ---------------------------------------------------------------------------
22579 + * Local variables:
22580 + * c-file-style: "linux"
22581 + * End:
22582 + */
22583 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mmu.h um/arch/um/kernel/skas/include/mmu.h
22584 --- orig/arch/um/kernel/skas/include/mmu.h      1969-12-31 19:00:00.000000000 -0500
22585 +++ um/arch/um/kernel/skas/include/mmu.h        2002-11-10 21:21:50.000000000 -0500
22586 @@ -0,0 +1,27 @@
22587 +/* 
22588 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22589 + * Licensed under the GPL
22590 + */
22591 +
22592 +#ifndef __SKAS_MMU_H
22593 +#define __SKAS_MMU_H
22594 +
22595 +#include "linux/list.h"
22596 +#include "linux/spinlock.h"
22597 +
22598 +struct mmu_context_skas {
22599 +       int mm_fd;
22600 +};
22601 +
22602 +#endif
22603 +
22604 +/*
22605 + * Overrides for Emacs so that we follow Linus's tabbing style.
22606 + * Emacs will notice this stuff at the end of the file and automatically
22607 + * adjust the settings for this buffer only.  This must remain at the end
22608 + * of the file.
22609 + * ---------------------------------------------------------------------------
22610 + * Local variables:
22611 + * c-file-style: "linux"
22612 + * End:
22613 + */
22614 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode.h um/arch/um/kernel/skas/include/mode.h
22615 --- orig/arch/um/kernel/skas/include/mode.h     1969-12-31 19:00:00.000000000 -0500
22616 +++ um/arch/um/kernel/skas/include/mode.h       2003-03-26 13:27:46.000000000 -0500
22617 @@ -0,0 +1,36 @@
22618 +/* 
22619 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22620 + * Licensed under the GPL
22621 + */
22622 +
22623 +#ifndef __MODE_SKAS_H__
22624 +#define __MODE_SKAS_H__
22625 +
22626 +extern unsigned long exec_regs[];
22627 +extern unsigned long exec_fp_regs[];
22628 +extern unsigned long exec_fpx_regs[];
22629 +extern int have_fpx_regs;
22630 +
22631 +extern void user_time_init_skas(void);
22632 +extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
22633 +extern int copy_sc_to_user_skas(void *to_ptr, void *fp, 
22634 +                               union uml_pt_regs *regs, 
22635 +                               unsigned long fault_addr, int fault_type);
22636 +extern void sig_handler_common_skas(int sig, void *sc_ptr);
22637 +extern void halt_skas(void);
22638 +extern void reboot_skas(void);
22639 +extern void kill_off_processes_skas(void);
22640 +extern int is_skas_winch(int pid, int fd, void *data);
22641 +
22642 +#endif
22643 +
22644 +/*
22645 + * Overrides for Emacs so that we follow Linus's tabbing style.
22646 + * Emacs will notice this stuff at the end of the file and automatically
22647 + * adjust the settings for this buffer only.  This must remain at the end
22648 + * of the file.
22649 + * ---------------------------------------------------------------------------
22650 + * Local variables:
22651 + * c-file-style: "linux"
22652 + * End:
22653 + */
22654 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode_kern.h um/arch/um/kernel/skas/include/mode_kern.h
22655 --- orig/arch/um/kernel/skas/include/mode_kern.h        1969-12-31 19:00:00.000000000 -0500
22656 +++ um/arch/um/kernel/skas/include/mode_kern.h  2002-12-16 21:49:11.000000000 -0500
22657 @@ -0,0 +1,51 @@
22658 +/* 
22659 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22660 + * Licensed under the GPL
22661 + */
22662 +
22663 +#ifndef __SKAS_MODE_KERN_H__
22664 +#define __SKAS_MODE_KERN_H__
22665 +
22666 +#include "linux/sched.h"
22667 +#include "asm/page.h"
22668 +#include "asm/ptrace.h"
22669 +
22670 +extern void flush_thread_skas(void);
22671 +extern void *_switch_to_skas(void *prev, void *next);
22672 +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
22673 +                             unsigned long esp);
22674 +extern int copy_thread_skas(int nr, unsigned long clone_flags, 
22675 +                           unsigned long sp, unsigned long stack_top, 
22676 +                           struct task_struct *p, struct pt_regs *regs);
22677 +extern void release_thread_skas(struct task_struct *task);
22678 +extern void exit_thread_skas(void);
22679 +extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
22680 +extern void init_idle_skas(void);
22681 +extern void flush_tlb_kernel_vm_skas(void);
22682 +extern void __flush_tlb_one_skas(unsigned long addr);
22683 +extern void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, 
22684 +                                unsigned long end);
22685 +extern void flush_tlb_mm_skas(struct mm_struct *mm);
22686 +extern void force_flush_all_skas(void);
22687 +extern long execute_syscall_skas(void *r);
22688 +extern void before_mem_skas(unsigned long unused);
22689 +extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
22690 +                                        unsigned long *task_size_out);
22691 +extern int start_uml_skas(void);
22692 +extern int external_pid_skas(struct task_struct *task);
22693 +extern int thread_pid_skas(struct thread_struct *thread);
22694 +
22695 +#define kmem_end_skas (host_task_size - 1024 * 1024)
22696 +
22697 +#endif
22698 +
22699 +/*
22700 + * Overrides for Emacs so that we follow Linus's tabbing style.
22701 + * Emacs will notice this stuff at the end of the file and automatically
22702 + * adjust the settings for this buffer only.  This must remain at the end
22703 + * of the file.
22704 + * ---------------------------------------------------------------------------
22705 + * Local variables:
22706 + * c-file-style: "linux"
22707 + * End:
22708 + */
22709 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/proc_mm.h um/arch/um/kernel/skas/include/proc_mm.h
22710 --- orig/arch/um/kernel/skas/include/proc_mm.h  1969-12-31 19:00:00.000000000 -0500
22711 +++ um/arch/um/kernel/skas/include/proc_mm.h    2002-11-13 11:57:23.000000000 -0500
22712 @@ -0,0 +1,55 @@
22713 +/* 
22714 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22715 + * Licensed under the GPL
22716 + */
22717 +
22718 +#ifndef __SKAS_PROC_MM_H
22719 +#define __SKAS_PROC_MM_H
22720 +
22721 +#define MM_MMAP 54
22722 +#define MM_MUNMAP 55
22723 +#define MM_MPROTECT 56
22724 +#define MM_COPY_SEGMENTS 57
22725 +
22726 +struct mm_mmap {
22727 +       unsigned long addr;
22728 +       unsigned long len;
22729 +       unsigned long prot;
22730 +       unsigned long flags;
22731 +       unsigned long fd;
22732 +       unsigned long offset;
22733 +};
22734 +
22735 +struct mm_munmap {
22736 +       unsigned long addr;
22737 +       unsigned long len;      
22738 +};
22739 +
22740 +struct mm_mprotect {
22741 +       unsigned long addr;
22742 +       unsigned long len;
22743 +        unsigned int prot;
22744 +};
22745 +
22746 +struct proc_mm_op {
22747 +       int op;
22748 +       union {
22749 +               struct mm_mmap mmap;
22750 +               struct mm_munmap munmap;
22751 +               struct mm_mprotect mprotect;
22752 +               int copy_segments;
22753 +       } u;
22754 +};
22755 +
22756 +#endif
22757 +
22758 +/*
22759 + * Overrides for Emacs so that we follow Linus's tabbing style.
22760 + * Emacs will notice this stuff at the end of the file and automatically
22761 + * adjust the settings for this buffer only.  This must remain at the end
22762 + * of the file.
22763 + * ---------------------------------------------------------------------------
22764 + * Local variables:
22765 + * c-file-style: "linux"
22766 + * End:
22767 + */
22768 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/ptrace-skas.h um/arch/um/kernel/skas/include/ptrace-skas.h
22769 --- orig/arch/um/kernel/skas/include/ptrace-skas.h      1969-12-31 19:00:00.000000000 -0500
22770 +++ um/arch/um/kernel/skas/include/ptrace-skas.h        2003-01-17 13:22:09.000000000 -0500
22771 @@ -0,0 +1,57 @@
22772 +/* 
22773 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22774 + * Licensed under the GPL
22775 + */
22776 +
22777 +#ifndef __PTRACE_SKAS_H
22778 +#define __PTRACE_SKAS_H
22779 +
22780 +#include "uml-config.h"
22781 +
22782 +#ifdef UML_CONFIG_MODE_SKAS
22783 +
22784 +#include "skas_ptregs.h"
22785 +
22786 +#define HOST_FRAME_SIZE 17
22787 +
22788 +#define REGS_IP(r) ((r)[HOST_IP])
22789 +#define REGS_SP(r) ((r)[HOST_SP])
22790 +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
22791 +#define REGS_EAX(r) ((r)[HOST_EAX])
22792 +#define REGS_EBX(r) ((r)[HOST_EBX])
22793 +#define REGS_ECX(r) ((r)[HOST_ECX])
22794 +#define REGS_EDX(r) ((r)[HOST_EDX])
22795 +#define REGS_ESI(r) ((r)[HOST_ESI])
22796 +#define REGS_EDI(r) ((r)[HOST_EDI])
22797 +#define REGS_EBP(r) ((r)[HOST_EBP])
22798 +#define REGS_CS(r) ((r)[HOST_CS])
22799 +#define REGS_SS(r) ((r)[HOST_SS])
22800 +#define REGS_DS(r) ((r)[HOST_DS])
22801 +#define REGS_ES(r) ((r)[HOST_ES])
22802 +#define REGS_FS(r) ((r)[HOST_FS])
22803 +#define REGS_GS(r) ((r)[HOST_GS])
22804 +
22805 +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
22806 +
22807 +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
22808 +
22809 +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
22810 +
22811 +#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
22812 +
22813 +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
22814 +
22815 +#endif
22816 +
22817 +#endif
22818 +
22819 +/*
22820 + * Overrides for Emacs so that we follow Linus's tabbing style.
22821 + * Emacs will notice this stuff at the end of the file and automatically
22822 + * adjust the settings for this buffer only.  This must remain at the end
22823 + * of the file.
22824 + * ---------------------------------------------------------------------------
22825 + * Local variables:
22826 + * c-file-style: "linux"
22827 + * End:
22828 + */
22829 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/skas.h um/arch/um/kernel/skas/include/skas.h
22830 --- orig/arch/um/kernel/skas/include/skas.h     1969-12-31 19:00:00.000000000 -0500
22831 +++ um/arch/um/kernel/skas/include/skas.h       2002-12-08 21:00:12.000000000 -0500
22832 @@ -0,0 +1,49 @@
22833 +/* 
22834 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22835 + * Licensed under the GPL
22836 + */
22837 +
22838 +#ifndef __SKAS_H
22839 +#define __SKAS_H
22840 +
22841 +#include "sysdep/ptrace.h"
22842 +
22843 +extern int userspace_pid;
22844 +
22845 +extern void switch_threads(void *me, void *next);
22846 +extern void thread_wait(void *sw, void *fb);
22847 +extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
22848 +                       void (*handler)(int));
22849 +extern int start_idle_thread(void *stack, void *switch_buf_ptr, 
22850 +                            void **fork_buf_ptr);
22851 +extern int user_thread(unsigned long stack, int flags);
22852 +extern void userspace(union uml_pt_regs *regs);
22853 +extern void new_thread_proc(void *stack, void (*handler)(int sig));
22854 +extern void remove_sigstack(void);
22855 +extern void new_thread_handler(int sig);
22856 +extern void handle_syscall(union uml_pt_regs *regs);
22857 +extern void map(int fd, unsigned long virt, unsigned long phys, 
22858 +               unsigned long len, int r, int w, int x);
22859 +extern int unmap(int fd, void *addr, int len);
22860 +extern int protect(int fd, unsigned long addr, unsigned long len, 
22861 +                  int r, int w, int x, int must_succeed);
22862 +extern void user_signal(int sig, union uml_pt_regs *regs);
22863 +extern int singlestepping_skas(void);
22864 +extern int new_mm(int from);
22865 +extern void save_registers(union uml_pt_regs *regs);
22866 +extern void restore_registers(union uml_pt_regs *regs);
22867 +extern void start_userspace(void);
22868 +extern void init_registers(int pid);
22869 +
22870 +#endif
22871 +
22872 +/*
22873 + * Overrides for Emacs so that we follow Linus's tabbing style.
22874 + * Emacs will notice this stuff at the end of the file and automatically
22875 + * adjust the settings for this buffer only.  This must remain at the end
22876 + * of the file.
22877 + * ---------------------------------------------------------------------------
22878 + * Local variables:
22879 + * c-file-style: "linux"
22880 + * End:
22881 + */
22882 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/uaccess.h um/arch/um/kernel/skas/include/uaccess.h
22883 --- orig/arch/um/kernel/skas/include/uaccess.h  1969-12-31 19:00:00.000000000 -0500
22884 +++ um/arch/um/kernel/skas/include/uaccess.h    2003-01-31 23:05:56.000000000 -0500
22885 @@ -0,0 +1,232 @@
22886 +/* 
22887 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22888 + * Licensed under the GPL
22889 + */
22890 +
22891 +#ifndef __SKAS_UACCESS_H
22892 +#define __SKAS_UACCESS_H
22893 +
22894 +#include "linux/string.h"
22895 +#include "linux/sched.h"
22896 +#include "asm/processor.h"
22897 +#include "asm/pgtable.h"
22898 +#include "asm/errno.h"
22899 +#include "asm/current.h"
22900 +#include "asm/a.out.h"
22901 +#include "kern_util.h"
22902 +
22903 +#define access_ok_skas(type, addr, size) \
22904 +       ((segment_eq(get_fs(), KERNEL_DS)) || \
22905 +        (((unsigned long) (addr) < TASK_SIZE) && \
22906 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)))
22907 +
22908 +static inline int verify_area_skas(int type, const void * addr, 
22909 +                                  unsigned long size)
22910 +{
22911 +       return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
22912 +}
22913 +
22914 +static inline unsigned long maybe_map(unsigned long virt, int is_write)
22915 +{
22916 +       pte_t pte;
22917 +
22918 +       void *phys = um_virt_to_phys(current, virt, &pte);
22919 +       int dummy_code;
22920 +
22921 +       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
22922 +               if(!handle_page_fault(virt, 0, is_write, 0, &dummy_code))
22923 +                       return(0);
22924 +               phys = um_virt_to_phys(current, virt, NULL);
22925 +       }
22926 +       return((unsigned long) __va((unsigned long) phys));
22927 +}
22928 +
22929 +static inline int buffer_op(unsigned long addr, int len, 
22930 +                           int (*op)(unsigned long addr, int len, void *arg),
22931 +                           void *arg)
22932 +{
22933 +       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
22934 +       int remain = len, n;
22935 +
22936 +       n = (*op)(addr, size, arg);
22937 +       if(n != 0)
22938 +               return(n < 0 ? remain : 0);
22939 +
22940 +       addr += size;
22941 +       remain -= size;
22942 +       if(remain == 0) 
22943 +               return(0);
22944 +
22945 +       while(addr < ((addr + remain) & PAGE_MASK)){
22946 +               n = (*op)(addr, PAGE_SIZE, arg);
22947 +               if(n != 0)
22948 +                       return(n < 0 ? remain : 0);
22949 +
22950 +               addr += PAGE_SIZE;
22951 +               remain -= PAGE_SIZE;
22952 +       }
22953 +       if(remain == 0)
22954 +               return(0);
22955 +
22956 +       n = (*op)(addr, remain, arg);
22957 +       if(n != 0)
22958 +               return(n < 0 ? remain : 0);
22959 +       return(0);
22960 +}
22961 +
22962 +static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
22963 +{
22964 +       unsigned long *to_ptr = arg, to = *to_ptr;
22965 +
22966 +       from = maybe_map(from, 0);
22967 +       if(from == 0)
22968 +               return(-1);
22969 +
22970 +       memcpy((void *) to, (void *) from, len);
22971 +       *to_ptr += len;
22972 +       return(0);
22973 +}
22974 +
22975 +static inline int copy_from_user_skas(void *to, const void *from, int n)
22976 +{
22977 +       if(segment_eq(get_fs(), KERNEL_DS)){
22978 +               memcpy(to, from, n);
22979 +               return(0);
22980 +       }
22981 +
22982 +       return(access_ok_skas(VERIFY_READ, from, n) ?
22983 +              buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
22984 +              n);
22985 +}
22986 +
22987 +static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
22988 +{
22989 +       unsigned long *from_ptr = arg, from = *from_ptr;
22990 +
22991 +       to = maybe_map(to, 1);
22992 +       if(to == 0)
22993 +               return(-1);
22994 +
22995 +       memcpy((void *) to, (void *) from, len);
22996 +       *from_ptr += len;
22997 +       return(0);
22998 +}
22999 +
23000 +static inline int copy_to_user_skas(void *to, const void *from, int n)
23001 +{
23002 +       if(segment_eq(get_fs(), KERNEL_DS)){
23003 +               memcpy(to, from, n);
23004 +               return(0);
23005 +       }
23006 +
23007 +       return(access_ok_skas(VERIFY_WRITE, to, n) ?
23008 +              buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
23009 +              n);
23010 +}
23011 +
23012 +static inline int strncpy_chunk_from_user(unsigned long from, int len, 
23013 +                                         void *arg)
23014 +{
23015 +        char **to_ptr = arg, *to = *to_ptr;
23016 +       int n;
23017 +
23018 +       from = maybe_map(from, 0);
23019 +       if(from == 0)
23020 +               return(-1);
23021 +
23022 +       strncpy(to, (void *) from, len);
23023 +       n = strnlen(to, len);
23024 +       *to_ptr += n;
23025 +
23026 +       if(n < len) 
23027 +               return(1);
23028 +       return(0);
23029 +}
23030 +
23031 +static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
23032 +{
23033 +       int n;
23034 +       char *ptr = dst;
23035 +
23036 +       if(segment_eq(get_fs(), KERNEL_DS)){
23037 +               strncpy(dst, src, count);
23038 +               return(strnlen(dst, count));
23039 +       }
23040 +
23041 +       if(!access_ok_skas(VERIFY_READ, src, 1))
23042 +               return(-EFAULT);
23043 +
23044 +       n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user, 
23045 +                     &ptr);
23046 +       if(n != 0)
23047 +               return(-EFAULT);
23048 +       return(strnlen(dst, count));
23049 +}
23050 +
23051 +static inline int clear_chunk(unsigned long addr, int len, void *unused)
23052 +{
23053 +       addr = maybe_map(addr, 1);
23054 +       if(addr == 0) 
23055 +               return(-1);
23056 +
23057 +       memset((void *) addr, 0, len);
23058 +       return(0);
23059 +}
23060 +
23061 +static inline int __clear_user_skas(void *mem, int len)
23062 +{
23063 +       return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
23064 +}
23065 +
23066 +static inline int clear_user_skas(void *mem, int len)
23067 +{
23068 +       if(segment_eq(get_fs(), KERNEL_DS)){
23069 +               memset(mem, 0, len);
23070 +               return(0);
23071 +       }
23072 +
23073 +       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
23074 +              buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
23075 +}
23076 +
23077 +static inline int strnlen_chunk(unsigned long str, int len, void *arg)
23078 +{
23079 +       int *len_ptr = arg, n;
23080 +
23081 +       str = maybe_map(str, 0);
23082 +       if(str == 0) 
23083 +               return(-1);
23084 +
23085 +       n = strnlen((void *) str, len);
23086 +       *len_ptr += n;
23087 +
23088 +       if(n < len)
23089 +               return(1);
23090 +       return(0);
23091 +}
23092 +
23093 +static inline int strnlen_user_skas(const void *str, int len)
23094 +{
23095 +       int count = 0, n;
23096 +
23097 +       if(segment_eq(get_fs(), KERNEL_DS))
23098 +               return(strnlen(str, len) + 1);
23099 +
23100 +       n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
23101 +       if(n == 0)
23102 +               return(count + 1);
23103 +       return(-EFAULT);
23104 +}
23105 +
23106 +#endif
23107 +
23108 +/*
23109 + * Overrides for Emacs so that we follow Linus's tabbing style.
23110 + * Emacs will notice this stuff at the end of the file and automatically
23111 + * adjust the settings for this buffer only.  This must remain at the end
23112 + * of the file.
23113 + * ---------------------------------------------------------------------------
23114 + * Local variables:
23115 + * c-file-style: "linux"
23116 + * End:
23117 + */
23118 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/Makefile um/arch/um/kernel/skas/Makefile
23119 --- orig/arch/um/kernel/skas/Makefile   1969-12-31 19:00:00.000000000 -0500
23120 +++ um/arch/um/kernel/skas/Makefile     2002-11-01 16:05:44.000000000 -0500
23121 @@ -0,0 +1,30 @@
23122 +# 
23123 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23124 +# Licensed under the GPL
23125 +#
23126 +
23127 +O_TARGET = skas.o
23128 +
23129 +obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
23130 +       process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o
23131 +
23132 +subdir-y = sys-$(SUBARCH)
23133 +
23134 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
23135 +
23136 +USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
23137 +
23138 +include $(TOPDIR)/Rules.make
23139 +
23140 +include/skas_ptregs.h : util/mk_ptregs
23141 +       util/mk_ptregs > $@
23142 +
23143 +util/mk_ptregs :
23144 +       $(MAKE) -C util
23145 +
23146 +$(USER_OBJS) : %.o: %.c
23147 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
23148 +
23149 +clean :
23150 +       $(MAKE) -C util clean
23151 +       $(RM) -f include/skas_ptregs.h
23152 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem.c um/arch/um/kernel/skas/mem.c
23153 --- orig/arch/um/kernel/skas/mem.c      1969-12-31 19:00:00.000000000 -0500
23154 +++ um/arch/um/kernel/skas/mem.c        2002-12-16 21:49:39.000000000 -0500
23155 @@ -0,0 +1,30 @@
23156 +/* 
23157 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23158 + * Licensed under the GPL
23159 + */
23160 +
23161 +#include "linux/config.h"
23162 +#include "linux/mm.h"
23163 +#include "mem_user.h"
23164 +
23165 +unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, 
23166 +                                 unsigned long *task_size_out)
23167 +{
23168 +       /* Round up to the nearest 4M */
23169 +       unsigned long top = ROUND_4M((unsigned long) &arg);
23170 +
23171 +       *host_size_out = top;
23172 +       *task_size_out = top;
23173 +       return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
23174 +}
23175 +
23176 +/*
23177 + * Overrides for Emacs so that we follow Linus's tabbing style.
23178 + * Emacs will notice this stuff at the end of the file and automatically
23179 + * adjust the settings for this buffer only.  This must remain at the end
23180 + * of the file.
23181 + * ---------------------------------------------------------------------------
23182 + * Local variables:
23183 + * c-file-style: "linux"
23184 + * End:
23185 + */
23186 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem_user.c um/arch/um/kernel/skas/mem_user.c
23187 --- orig/arch/um/kernel/skas/mem_user.c 1969-12-31 19:00:00.000000000 -0500
23188 +++ um/arch/um/kernel/skas/mem_user.c   2002-12-31 00:13:18.000000000 -0500
23189 @@ -0,0 +1,95 @@
23190 +/* 
23191 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23192 + * Licensed under the GPL
23193 + */
23194 +
23195 +#include <errno.h>
23196 +#include <sys/mman.h>
23197 +#include <sys/ptrace.h>
23198 +#include "mem_user.h"
23199 +#include "user.h"
23200 +#include "os.h"
23201 +#include "proc_mm.h"
23202 +
23203 +void map(int fd, unsigned long virt, unsigned long phys, unsigned long len, 
23204 +        int r, int w, int x)
23205 +{
23206 +       struct proc_mm_op map;
23207 +       struct mem_region *region;
23208 +       int prot, n;
23209 +
23210 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
23211 +               (x ? PROT_EXEC : 0);
23212 +       region = phys_region(phys);
23213 +
23214 +       map = ((struct proc_mm_op) { .op        = MM_MMAP,
23215 +                                    .u         = 
23216 +                                    { .mmap    = 
23217 +                                      { .addr          = virt,
23218 +                                        .len           = len,
23219 +                                        .prot          = prot,
23220 +                                        .flags         = MAP_SHARED | 
23221 +                                                         MAP_FIXED,
23222 +                                        .fd            = region->fd,
23223 +                                        .offset        = phys_offset(phys)
23224 +                                      } } } );
23225 +       n = os_write_file(fd, &map, sizeof(map));
23226 +       if(n != sizeof(map)) 
23227 +               printk("map : /proc/mm map failed, errno = %d\n", errno);
23228 +}
23229 +
23230 +int unmap(int fd, void *addr, int len)
23231 +{
23232 +       struct proc_mm_op unmap;
23233 +       int n;
23234 +
23235 +       unmap = ((struct proc_mm_op) { .op      = MM_MUNMAP,
23236 +                                      .u       = 
23237 +                                      { .munmap        = 
23238 +                                        { .addr        = (unsigned long) addr,
23239 +                                          .len         = len } } } );
23240 +       n = os_write_file(fd, &unmap, sizeof(unmap));
23241 +       if((n != 0) && (n != sizeof(unmap)))
23242 +               return(-errno);
23243 +       return(0);
23244 +}
23245 +
23246 +int protect(int fd, unsigned long addr, unsigned long len, int r, int w, 
23247 +           int x, int must_succeed)
23248 +{
23249 +       struct proc_mm_op protect;
23250 +       int prot, n;
23251 +
23252 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
23253 +               (x ? PROT_EXEC : 0);
23254 +
23255 +       protect = ((struct proc_mm_op) { .op    = MM_MPROTECT,
23256 +                                      .u       = 
23257 +                                      { .mprotect      = 
23258 +                                        { .addr        = (unsigned long) addr,
23259 +                                          .len         = len,
23260 +                                          .prot        = prot } } } );
23261 +
23262 +       n = os_write_file(fd, &protect, sizeof(protect));
23263 +       if((n != 0) && (n != sizeof(protect))){
23264 +               if(must_succeed)
23265 +                       panic("protect failed, errno = %d", errno);
23266 +               return(-errno);
23267 +       }
23268 +       return(0);
23269 +}
23270 +
23271 +void before_mem_skas(unsigned long unused)
23272 +{
23273 +}
23274 +
23275 +/*
23276 + * Overrides for Emacs so that we follow Linus's tabbing style.
23277 + * Emacs will notice this stuff at the end of the file and automatically
23278 + * adjust the settings for this buffer only.  This must remain at the end
23279 + * of the file.
23280 + * ---------------------------------------------------------------------------
23281 + * Local variables:
23282 + * c-file-style: "linux"
23283 + * End:
23284 + */
23285 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mmu.c um/arch/um/kernel/skas/mmu.c
23286 --- orig/arch/um/kernel/skas/mmu.c      1969-12-31 19:00:00.000000000 -0500
23287 +++ um/arch/um/kernel/skas/mmu.c        2002-11-13 13:09:57.000000000 -0500
23288 @@ -0,0 +1,44 @@
23289 +/* 
23290 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23291 + * Licensed under the GPL
23292 + */
23293 +
23294 +#include "linux/list.h"
23295 +#include "linux/spinlock.h"
23296 +#include "linux/slab.h"
23297 +#include "asm/segment.h"
23298 +#include "asm/mmu.h"
23299 +#include "os.h"
23300 +#include "skas.h"
23301 +
23302 +int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
23303 +{
23304 +       int from;
23305 +
23306 +       if((current->mm != NULL) && (current->mm != &init_mm))
23307 +               from = current->mm->context.skas.mm_fd;
23308 +       else from = -1;
23309 +
23310 +       mm->context.skas.mm_fd = new_mm(from);
23311 +       if(mm->context.skas.mm_fd < 0)
23312 +               panic("init_new_context_skas - new_mm failed, errno = %d\n",
23313 +                     mm->context.skas.mm_fd);
23314 +
23315 +       return(0);
23316 +}
23317 +
23318 +void destroy_context_skas(struct mm_struct *mm)
23319 +{
23320 +       os_close_file(mm->context.skas.mm_fd);
23321 +}
23322 +
23323 +/*
23324 + * Overrides for Emacs so that we follow Linus's tabbing style.
23325 + * Emacs will notice this stuff at the end of the file and automatically
23326 + * adjust the settings for this buffer only.  This must remain at the end
23327 + * of the file.
23328 + * ---------------------------------------------------------------------------
23329 + * Local variables:
23330 + * c-file-style: "linux"
23331 + * End:
23332 + */
23333 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process.c um/arch/um/kernel/skas/process.c
23334 --- orig/arch/um/kernel/skas/process.c  1969-12-31 19:00:00.000000000 -0500
23335 +++ um/arch/um/kernel/skas/process.c    2003-05-15 15:21:48.000000000 -0400
23336 @@ -0,0 +1,409 @@
23337 +/* 
23338 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23339 + * Licensed under the GPL
23340 + */
23341 +
23342 +#include <stdlib.h>
23343 +#include <unistd.h>
23344 +#include <errno.h>
23345 +#include <signal.h>
23346 +#include <setjmp.h>
23347 +#include <sched.h>
23348 +#include <sys/wait.h>
23349 +#include <sys/ptrace.h>
23350 +#include <sys/mman.h>
23351 +#include <sys/user.h>
23352 +#include <asm/unistd.h>
23353 +#include "user.h"
23354 +#include "ptrace_user.h"
23355 +#include "time_user.h"
23356 +#include "sysdep/ptrace.h"
23357 +#include "user_util.h"
23358 +#include "kern_util.h"
23359 +#include "skas.h"
23360 +#include "sysdep/sigcontext.h"
23361 +#include "os.h"
23362 +#include "proc_mm.h"
23363 +#include "skas_ptrace.h"
23364 +#include "chan_user.h"
23365 +
23366 +int is_skas_winch(int pid, int fd, void *data)
23367 +{
23368 +       if(pid != getpid())
23369 +               return(0);
23370 +
23371 +       register_winch_irq(-1, fd, -1, data);
23372 +       return(1);
23373 +}
23374 +
23375 +unsigned long exec_regs[FRAME_SIZE];
23376 +unsigned long exec_fp_regs[HOST_FP_SIZE];
23377 +unsigned long exec_fpx_regs[HOST_XFP_SIZE];
23378 +int have_fpx_regs = 1;
23379 +
23380 +static void handle_segv(int pid)
23381 +{
23382 +       struct ptrace_faultinfo fault;
23383 +       int err;
23384 +
23385 +       err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
23386 +       if(err)
23387 +               panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
23388 +                     errno);
23389 +
23390 +       segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
23391 +}
23392 +
23393 +static void handle_trap(int pid, union uml_pt_regs *regs)
23394 +{
23395 +       int err, syscall_nr, status;
23396 +
23397 +       syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
23398 +       if(syscall_nr < 1){
23399 +               relay_signal(SIGTRAP, regs);
23400 +               return;
23401 +       }
23402 +       UPT_SYSCALL_NR(regs) = syscall_nr;
23403 +
23404 +       err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
23405 +       if(err < 0)
23406 +               panic("handle_trap - nullifying syscall failed errno = %d\n", 
23407 +                     errno);
23408 +
23409 +       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
23410 +       if(err < 0)
23411 +               panic("handle_trap - continuing to end of syscall failed, "
23412 +                     "errno = %d\n", errno);
23413 +
23414 +       err = waitpid(pid, &status, WUNTRACED);
23415 +       if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
23416 +               panic("handle_trap - failed to wait at end of syscall, "
23417 +                     "errno = %d, status = %d\n", errno, status);
23418 +
23419 +       handle_syscall(regs);
23420 +}
23421 +
23422 +static int userspace_tramp(void *arg)
23423 +{
23424 +       init_new_thread_signals(0);
23425 +       enable_timer();
23426 +       ptrace(PTRACE_TRACEME, 0, 0, 0);
23427 +       os_stop_process(os_getpid());
23428 +       return(0);
23429 +}
23430 +
23431 +int userspace_pid;
23432 +
23433 +void start_userspace(void)
23434 +{
23435 +       void *stack;
23436 +       unsigned long sp;
23437 +       int pid, status, n;
23438 +
23439 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
23440 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
23441 +       if(stack == MAP_FAILED)
23442 +               panic("start_userspace : mmap failed, errno = %d", errno);
23443 +       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
23444 +
23445 +       pid = clone(userspace_tramp, (void *) sp, 
23446 +                   CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
23447 +       if(pid < 0)
23448 +               panic("start_userspace : clone failed, errno = %d", errno);
23449 +
23450 +       do {
23451 +               n = waitpid(pid, &status, WUNTRACED);
23452 +               if(n < 0)
23453 +                       panic("start_userspace : wait failed, errno = %d", 
23454 +                             errno);
23455 +       } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
23456 +
23457 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
23458 +               panic("start_userspace : expected SIGSTOP, got status = %d",
23459 +                     status);
23460 +
23461 +       if(munmap(stack, PAGE_SIZE) < 0)
23462 +               panic("start_userspace : munmap failed, errno = %d\n", errno);
23463 +
23464 +       userspace_pid = pid;
23465 +}
23466 +
23467 +void userspace(union uml_pt_regs *regs)
23468 +{
23469 +       int err, status, op;
23470 +
23471 +       restore_registers(regs);
23472 +               
23473 +       err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
23474 +       if(err)
23475 +               panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
23476 +                      errno);
23477 +       while(1){
23478 +               err = waitpid(userspace_pid, &status, WUNTRACED);
23479 +               if(err < 0)
23480 +                       panic("userspace - waitpid failed, errno = %d\n", 
23481 +                             errno);
23482 +
23483 +               regs->skas.is_user = 1;
23484 +               save_registers(regs);
23485 +
23486 +               if(WIFSTOPPED(status)){
23487 +                       switch(WSTOPSIG(status)){
23488 +                       case SIGSEGV:
23489 +                               handle_segv(userspace_pid);
23490 +                               break;
23491 +                       case SIGTRAP:
23492 +                               handle_trap(userspace_pid, regs);
23493 +                               break;
23494 +                       case SIGIO:
23495 +                       case SIGVTALRM:
23496 +                       case SIGILL:
23497 +                       case SIGBUS:
23498 +                       case SIGFPE:
23499 +                       case SIGWINCH:
23500 +                               user_signal(WSTOPSIG(status), regs);
23501 +                               break;
23502 +                       default:
23503 +                               printk("userspace - child stopped with signal "
23504 +                                      "%d\n", WSTOPSIG(status));
23505 +                       }
23506 +                       interrupt_end();
23507 +               }
23508 +
23509 +               restore_registers(regs);
23510 +
23511 +               op = singlestepping_skas() ? PTRACE_SINGLESTEP : 
23512 +                       PTRACE_SYSCALL;
23513 +               err = ptrace(op, userspace_pid, 0, 0);
23514 +               if(err)
23515 +                       panic("userspace - PTRACE_SYSCALL failed, "
23516 +                             "errno = %d\n", errno);
23517 +       }
23518 +}
23519 +
23520 +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
23521 +               void (*handler)(int))
23522 +{
23523 +       jmp_buf switch_buf, fork_buf;
23524 +
23525 +       *switch_buf_ptr = &switch_buf;
23526 +       *fork_buf_ptr = &fork_buf;
23527 +
23528 +       if(setjmp(fork_buf) == 0)
23529 +               new_thread_proc(stack, handler);
23530 +
23531 +       remove_sigstack();
23532 +}
23533 +
23534 +void thread_wait(void *sw, void *fb)
23535 +{
23536 +       jmp_buf buf, **switch_buf = sw, *fork_buf;
23537 +
23538 +       *switch_buf = &buf;
23539 +       fork_buf = fb;
23540 +       if(setjmp(buf) == 0)
23541 +               longjmp(*fork_buf, 1);
23542 +}
23543 +
23544 +static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
23545 +                         unsigned long *fp_regs)
23546 +{
23547 +       if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
23548 +               return(-errno);
23549 +       if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
23550 +               return(-errno);
23551 +       return(0);
23552 +}
23553 +
23554 +void save_registers(union uml_pt_regs *regs)
23555 +{
23556 +       unsigned long *fp_regs;
23557 +       int err, fp_op;
23558 +
23559 +       if(have_fpx_regs){
23560 +               fp_op = PTRACE_GETFPXREGS;
23561 +               fp_regs = regs->skas.xfp;
23562 +       }
23563 +       else {
23564 +               fp_op = PTRACE_GETFPREGS;
23565 +               fp_regs = regs->skas.fp;
23566 +       }
23567 +
23568 +       err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
23569 +       if(err)
23570 +               panic("save_registers - saving registers failed, errno = %d\n",
23571 +                     err);
23572 +}
23573 +
23574 +void restore_registers(union uml_pt_regs *regs)
23575 +{
23576 +       unsigned long *fp_regs;
23577 +       int err, fp_op;
23578 +
23579 +       if(have_fpx_regs){
23580 +               fp_op = PTRACE_SETFPXREGS;
23581 +               fp_regs = regs->skas.xfp;
23582 +       }
23583 +       else {
23584 +               fp_op = PTRACE_SETFPREGS;
23585 +               fp_regs = regs->skas.fp;
23586 +       }
23587 +
23588 +       err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
23589 +       if(err)
23590 +               panic("restore_registers - saving registers failed, "
23591 +                     "errno = %d\n", err);
23592 +}
23593 +
23594 +void switch_threads(void *me, void *next)
23595 +{
23596 +       jmp_buf my_buf, **me_ptr = me, *next_buf = next;
23597 +       
23598 +       *me_ptr = &my_buf;
23599 +       if(setjmp(my_buf) == 0)
23600 +               longjmp(*next_buf, 1);
23601 +}
23602 +
23603 +static jmp_buf initial_jmpbuf;
23604 +
23605 +/* XXX Make these percpu */
23606 +static void (*cb_proc)(void *arg);
23607 +static void *cb_arg;
23608 +static jmp_buf *cb_back;
23609 +
23610 +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
23611 +{
23612 +       jmp_buf **switch_buf = switch_buf_ptr;
23613 +       int n;
23614 +
23615 +       *fork_buf_ptr = &initial_jmpbuf;
23616 +       n = setjmp(initial_jmpbuf);
23617 +       if(n == 0)
23618 +               new_thread_proc((void *) stack, new_thread_handler);
23619 +       else if(n == 1)
23620 +               remove_sigstack();
23621 +       else if(n == 2){
23622 +               (*cb_proc)(cb_arg);
23623 +               longjmp(*cb_back, 1);
23624 +       }
23625 +       else if(n == 3){
23626 +               kmalloc_ok = 0;
23627 +               return(0);
23628 +       }
23629 +       else if(n == 4){
23630 +               kmalloc_ok = 0;
23631 +               return(1);
23632 +       }
23633 +       longjmp(**switch_buf, 1);
23634 +}
23635 +
23636 +void remove_sigstack(void)
23637 +{
23638 +       stack_t stack = ((stack_t) { .ss_flags  = SS_DISABLE,
23639 +                                    .ss_sp     = NULL,
23640 +                                    .ss_size   = 0 });
23641 +
23642 +       if(sigaltstack(&stack, NULL) != 0)
23643 +               panic("disabling signal stack failed, errno = %d\n", errno);
23644 +}
23645 +
23646 +void initial_thread_cb_skas(void (*proc)(void *), void *arg)
23647 +{
23648 +       jmp_buf here;
23649 +
23650 +       cb_proc = proc;
23651 +       cb_arg = arg;
23652 +       cb_back = &here;
23653 +
23654 +       block_signals();
23655 +       if(setjmp(here) == 0)
23656 +               longjmp(initial_jmpbuf, 2);
23657 +       unblock_signals();
23658 +
23659 +       cb_proc = NULL;
23660 +       cb_arg = NULL;
23661 +       cb_back = NULL;
23662 +}
23663 +
23664 +void halt_skas(void)
23665 +{
23666 +       block_signals();
23667 +       longjmp(initial_jmpbuf, 3);
23668 +}
23669 +
23670 +void reboot_skas(void)
23671 +{
23672 +       block_signals();
23673 +       longjmp(initial_jmpbuf, 4);
23674 +}
23675 +
23676 +int new_mm(int from)
23677 +{
23678 +       struct proc_mm_op copy;
23679 +       int n, fd = os_open_file("/proc/mm", 
23680 +                                of_cloexec(of_write(OPENFLAGS())), 0);
23681 +
23682 +       if(fd < 0)
23683 +               return(-errno);
23684 +
23685 +       if(from != -1){
23686 +               copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
23687 +                                             .u        = 
23688 +                                             { .copy_segments  = from } } );
23689 +               n = os_write_file(fd, &copy, sizeof(copy));
23690 +               if(n != sizeof(copy)) 
23691 +                       printk("new_mm : /proc/mm copy_segments failed, "
23692 +                              "errno = %d\n", errno);
23693 +       }
23694 +
23695 +       return(fd);
23696 +}
23697 +
23698 +void switch_mm_skas(int mm_fd)
23699 +{
23700 +       int err;
23701 +
23702 +       err = ptrace(PTRACE_SWITCH_MM, userspace_pid, 0, mm_fd);
23703 +       if(err)
23704 +               panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
23705 +                     errno);
23706 +}
23707 +
23708 +void kill_off_processes_skas(void)
23709 +{
23710 +       os_kill_process(userspace_pid, 1);
23711 +}
23712 +
23713 +void init_registers(int pid)
23714 +{
23715 +       int err;
23716 +
23717 +       if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
23718 +               panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 
23719 +                     errno);
23720 +
23721 +       err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
23722 +       if(!err)
23723 +               return;
23724 +
23725 +       have_fpx_regs = 0;
23726 +       if(errno != EIO)
23727 +               panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", 
23728 +                     errno);
23729 +
23730 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
23731 +       if(err)
23732 +               panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", 
23733 +                     errno);
23734 +}
23735 +
23736 +/*
23737 + * Overrides for Emacs so that we follow Linus's tabbing style.
23738 + * Emacs will notice this stuff at the end of the file and automatically
23739 + * adjust the settings for this buffer only.  This must remain at the end
23740 + * of the file.
23741 + * ---------------------------------------------------------------------------
23742 + * Local variables:
23743 + * c-file-style: "linux"
23744 + * End:
23745 + */
23746 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process_kern.c um/arch/um/kernel/skas/process_kern.c
23747 --- orig/arch/um/kernel/skas/process_kern.c     1969-12-31 19:00:00.000000000 -0500
23748 +++ um/arch/um/kernel/skas/process_kern.c       2002-12-22 20:37:39.000000000 -0500
23749 @@ -0,0 +1,191 @@
23750 +/* 
23751 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23752 + * Licensed under the GPL
23753 + */
23754 +
23755 +#include "linux/sched.h"
23756 +#include "linux/slab.h"
23757 +#include "kern_util.h"
23758 +#include "time_user.h"
23759 +#include "signal_user.h"
23760 +#include "skas.h"
23761 +#include "os.h"
23762 +#include "user_util.h"
23763 +#include "tlb.h"
23764 +#include "frame.h"
23765 +#include "kern.h"
23766 +#include "mode.h"
23767 +
23768 +int singlestepping_skas(void)
23769 +{
23770 +       int ret = current->ptrace & PT_DTRACE;
23771 +
23772 +       current->ptrace &= ~PT_DTRACE;
23773 +       return(ret);
23774 +}
23775 +
23776 +void *_switch_to_skas(void *prev, void *next)
23777 +{
23778 +       struct task_struct *from, *to;
23779 +
23780 +       from = prev;
23781 +       to = next;
23782 +
23783 +       /* XXX need to check runqueues[cpu].idle */
23784 +       if(current->pid == 0)
23785 +               switch_timers(0);
23786 +
23787 +       to->thread.prev_sched = from;
23788 +       set_current(to);
23789 +
23790 +       switch_threads(&from->thread.mode.skas.switch_buf, 
23791 +                      to->thread.mode.skas.switch_buf);
23792 +
23793 +       if(current->pid == 0)
23794 +               switch_timers(1);
23795 +
23796 +       return(current->thread.prev_sched);
23797 +}
23798 +
23799 +extern void schedule_tail(struct task_struct *prev);
23800 +
23801 +void new_thread_handler(int sig)
23802 +{
23803 +       int (*fn)(void *), n;
23804 +       void *arg;
23805 +
23806 +       fn = current->thread.request.u.thread.proc;
23807 +       arg = current->thread.request.u.thread.arg;
23808 +       change_sig(SIGUSR1, 1);
23809 +       thread_wait(&current->thread.mode.skas.switch_buf, 
23810 +                   current->thread.mode.skas.fork_buf);
23811 +
23812 +       if(current->thread.prev_sched != NULL)
23813 +               schedule_tail(current->thread.prev_sched);
23814 +       current->thread.prev_sched = NULL;
23815 +
23816 +       n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
23817 +       if(n == 1)
23818 +               userspace(&current->thread.regs.regs);
23819 +       else do_exit(0);
23820 +}
23821 +
23822 +void new_thread_proc(void *stack, void (*handler)(int sig))
23823 +{
23824 +       init_new_thread_stack(stack, handler);
23825 +       os_usr1_process(os_getpid());
23826 +}
23827 +
23828 +void release_thread_skas(struct task_struct *task)
23829 +{
23830 +}
23831 +
23832 +void exit_thread_skas(void)
23833 +{
23834 +}
23835 +
23836 +void fork_handler(int sig)
23837 +{
23838 +        change_sig(SIGUSR1, 1);
23839 +       thread_wait(&current->thread.mode.skas.switch_buf, 
23840 +                   current->thread.mode.skas.fork_buf);
23841 +       
23842 +       force_flush_all();
23843 +       if(current->thread.prev_sched != NULL)
23844 +               schedule_tail(current->thread.prev_sched);
23845 +       current->thread.prev_sched = NULL;
23846 +       unblock_signals();
23847 +
23848 +       userspace(&current->thread.regs.regs);
23849 +}
23850 +
23851 +int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
23852 +                    unsigned long stack_top, struct task_struct * p, 
23853 +                    struct pt_regs *regs)
23854 +{
23855 +       void (*handler)(int);
23856 +
23857 +       if(current->thread.forking){
23858 +               memcpy(&p->thread.regs.regs.skas, 
23859 +                      &current->thread.regs.regs.skas, 
23860 +                      sizeof(p->thread.regs.regs.skas));
23861 +               REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
23862 +               if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
23863 +
23864 +               handler = fork_handler;
23865 +       }
23866 +       else {
23867 +               memcpy(p->thread.regs.regs.skas.regs, exec_regs, 
23868 +                      sizeof(p->thread.regs.regs.skas.regs));
23869 +               memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, 
23870 +                      sizeof(p->thread.regs.regs.skas.fp));
23871 +               memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, 
23872 +                      sizeof(p->thread.regs.regs.skas.xfp));
23873 +                p->thread.request.u.thread = current->thread.request.u.thread;
23874 +               handler = new_thread_handler;
23875 +       }
23876 +
23877 +       new_thread((void *) p->thread.kernel_stack, 
23878 +                  &p->thread.mode.skas.switch_buf, 
23879 +                  &p->thread.mode.skas.fork_buf, handler);
23880 +       return(0);
23881 +}
23882 +
23883 +void init_idle_skas(void)
23884 +{
23885 +       cpu_tasks[current->processor].pid = os_getpid();
23886 +}
23887 +
23888 +extern void start_kernel(void);
23889 +
23890 +static int start_kernel_proc(void *unused)
23891 +{
23892 +       int pid;
23893 +
23894 +       block_signals();
23895 +       pid = os_getpid();
23896 +
23897 +       cpu_tasks[0].pid = pid;
23898 +       cpu_tasks[0].task = current;
23899 +#ifdef CONFIG_SMP
23900 +       cpu_online_map = 1;
23901 +#endif
23902 +       start_kernel();
23903 +       return(0);
23904 +}
23905 +
23906 +int start_uml_skas(void)
23907 +{
23908 +       start_userspace();
23909 +       capture_signal_stack();
23910 +
23911 +       init_new_thread_signals(1);
23912 +       idle_timer();
23913 +
23914 +       init_task.thread.request.u.thread.proc = start_kernel_proc;
23915 +       init_task.thread.request.u.thread.arg = NULL;
23916 +       return(start_idle_thread((void *) init_task.thread.kernel_stack,
23917 +                                &init_task.thread.mode.skas.switch_buf,
23918 +                                &init_task.thread.mode.skas.fork_buf));
23919 +}
23920 +
23921 +int external_pid_skas(struct task_struct *task)
23922 +{
23923 +       return(userspace_pid);
23924 +}
23925 +
23926 +int thread_pid_skas(struct thread_struct *thread)
23927 +{
23928 +       return(userspace_pid);
23929 +}
23930 +
23931 +/*
23932 + * Overrides for Emacs so that we follow Linus's tabbing style.
23933 + * Emacs will notice this stuff at the end of the file and automatically
23934 + * adjust the settings for this buffer only.  This must remain at the end
23935 + * of the file.
23936 + * ---------------------------------------------------------------------------
23937 + * Local variables:
23938 + * c-file-style: "linux"
23939 + * End:
23940 + */
23941 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_kern.c um/arch/um/kernel/skas/syscall_kern.c
23942 --- orig/arch/um/kernel/skas/syscall_kern.c     1969-12-31 19:00:00.000000000 -0500
23943 +++ um/arch/um/kernel/skas/syscall_kern.c       2002-12-08 21:01:44.000000000 -0500
23944 @@ -0,0 +1,42 @@
23945 +/* 
23946 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23947 + * Licensed under the GPL
23948 + */
23949 +
23950 +#include "linux/sys.h"
23951 +#include "asm/errno.h"
23952 +#include "asm/unistd.h"
23953 +#include "asm/ptrace.h"
23954 +#include "asm/current.h"
23955 +#include "sysdep/syscalls.h"
23956 +#include "kern_util.h"
23957 +
23958 +extern syscall_handler_t *sys_call_table[];
23959 +
23960 +long execute_syscall_skas(void *r)
23961 +{
23962 +       struct pt_regs *regs = r;
23963 +       long res;
23964 +       int syscall;
23965 +
23966 +       current->thread.nsyscalls++;
23967 +       nsyscalls++;
23968 +       syscall = UPT_SYSCALL_NR(&regs->regs);
23969 +
23970 +       if((syscall >= NR_syscalls) || (syscall < 0))
23971 +               res = -ENOSYS;
23972 +       else res = EXECUTE_SYSCALL(syscall, regs);
23973 +
23974 +       return(res);
23975 +}
23976 +
23977 +/*
23978 + * Overrides for Emacs so that we follow Linus's tabbing style.
23979 + * Emacs will notice this stuff at the end of the file and automatically
23980 + * adjust the settings for this buffer only.  This must remain at the end
23981 + * of the file.
23982 + * ---------------------------------------------------------------------------
23983 + * Local variables:
23984 + * c-file-style: "linux"
23985 + * End:
23986 + */
23987 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_user.c um/arch/um/kernel/skas/syscall_user.c
23988 --- orig/arch/um/kernel/skas/syscall_user.c     1969-12-31 19:00:00.000000000 -0500
23989 +++ um/arch/um/kernel/skas/syscall_user.c       2002-12-08 21:00:12.000000000 -0500
23990 @@ -0,0 +1,46 @@
23991 +/* 
23992 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23993 + * Licensed under the GPL
23994 + */
23995 +
23996 +#include <stdlib.h>
23997 +#include <signal.h>
23998 +#include "kern_util.h"
23999 +#include "syscall_user.h"
24000 +#include "sysdep/ptrace.h"
24001 +#include "sysdep/sigcontext.h"
24002 +
24003 +/* XXX Bogus */
24004 +#define ERESTARTSYS    512
24005 +#define ERESTARTNOINTR 513
24006 +#define ERESTARTNOHAND 514
24007 +
24008 +void handle_syscall(union uml_pt_regs *regs)
24009 +{
24010 +       long result;
24011 +       int index;
24012 +
24013 +       index = record_syscall_start(UPT_SYSCALL_NR(regs));
24014 +
24015 +       syscall_trace();
24016 +       result = execute_syscall(regs);
24017 +
24018 +       REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
24019 +       if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
24020 +          (result == -ERESTARTNOINTR))
24021 +               do_signal(result);
24022 +
24023 +       syscall_trace();
24024 +       record_syscall_end(index, result);
24025 +}
24026 +
24027 +/*
24028 + * Overrides for Emacs so that we follow Linus's tabbing style.
24029 + * Emacs will notice this stuff at the end of the file and automatically
24030 + * adjust the settings for this buffer only.  This must remain at the end
24031 + * of the file.
24032 + * ---------------------------------------------------------------------------
24033 + * Local variables:
24034 + * c-file-style: "linux"
24035 + * End:
24036 + */
24037 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/Makefile um/arch/um/kernel/skas/sys-i386/Makefile
24038 --- orig/arch/um/kernel/skas/sys-i386/Makefile  1969-12-31 19:00:00.000000000 -0500
24039 +++ um/arch/um/kernel/skas/sys-i386/Makefile    2002-10-23 21:08:04.000000000 -0400
24040 @@ -0,0 +1,17 @@
24041 +# 
24042 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24043 +# Licensed under the GPL
24044 +#
24045 +
24046 +O_TARGET = sys-i386.o
24047 +
24048 +obj-y = sigcontext.o
24049 +
24050 +USER_OBJS = sigcontext.o
24051 +
24052 +include $(TOPDIR)/Rules.make
24053 +
24054 +$(USER_OBJS) : %.o: %.c
24055 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
24056 +
24057 +clean :
24058 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/sigcontext.c um/arch/um/kernel/skas/sys-i386/sigcontext.c
24059 --- orig/arch/um/kernel/skas/sys-i386/sigcontext.c      1969-12-31 19:00:00.000000000 -0500
24060 +++ um/arch/um/kernel/skas/sys-i386/sigcontext.c        2002-12-08 20:38:46.000000000 -0500
24061 @@ -0,0 +1,115 @@
24062 +/* 
24063 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24064 + * Licensed under the GPL
24065 + */
24066 +
24067 +#include <errno.h>
24068 +#include <asm/sigcontext.h>
24069 +#include <sys/ptrace.h>
24070 +#include <linux/ptrace.h>
24071 +#include "sysdep/ptrace.h"
24072 +#include "sysdep/ptrace_user.h"
24073 +#include "kern_util.h"
24074 +#include "user.h"
24075 +#include "sigcontext.h"
24076 +
24077 +extern int userspace_pid;
24078 +
24079 +int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
24080 +{
24081 +       struct sigcontext sc, *from = from_ptr;
24082 +       unsigned long fpregs[FP_FRAME_SIZE];
24083 +       int err;
24084 +
24085 +       err = copy_from_user_proc(&sc, from, sizeof(sc));
24086 +       err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
24087 +       if(err)
24088 +               return(err);
24089 +
24090 +       regs->skas.regs[GS] = sc.gs;
24091 +       regs->skas.regs[FS] = sc.fs;
24092 +       regs->skas.regs[ES] = sc.es;
24093 +       regs->skas.regs[DS] = sc.ds;
24094 +       regs->skas.regs[EDI] = sc.edi;
24095 +       regs->skas.regs[ESI] = sc.esi;
24096 +       regs->skas.regs[EBP] = sc.ebp;
24097 +       regs->skas.regs[UESP] = sc.esp;
24098 +       regs->skas.regs[EBX] = sc.ebx;
24099 +       regs->skas.regs[EDX] = sc.edx;
24100 +       regs->skas.regs[ECX] = sc.ecx;
24101 +       regs->skas.regs[EAX] = sc.eax;
24102 +       regs->skas.regs[EIP] = sc.eip;
24103 +       regs->skas.regs[CS] = sc.cs;
24104 +       regs->skas.regs[EFL] = sc.eflags;
24105 +       regs->skas.regs[UESP] = sc.esp_at_signal;
24106 +       regs->skas.regs[SS] = sc.ss;
24107 +       regs->skas.fault_addr = sc.cr2;
24108 +       regs->skas.fault_type = FAULT_WRITE(sc.err);
24109 +       regs->skas.trap_type = sc.trapno;
24110 +
24111 +       err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
24112 +       if(err < 0){
24113 +               printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
24114 +                      "errno = %d\n", errno);
24115 +               return(1);
24116 +       }
24117 +
24118 +       return(0);
24119 +}
24120 +
24121 +int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs, 
24122 +                        unsigned long fault_addr, int fault_type)
24123 +{
24124 +       struct sigcontext sc, *to = to_ptr;
24125 +       struct _fpstate *to_fp;
24126 +       unsigned long fpregs[FP_FRAME_SIZE];
24127 +       int err;
24128 +
24129 +       sc.gs = regs->skas.regs[GS];
24130 +       sc.fs = regs->skas.regs[FS];
24131 +       sc.es = regs->skas.regs[ES];
24132 +       sc.ds = regs->skas.regs[DS];
24133 +       sc.edi = regs->skas.regs[EDI];
24134 +       sc.esi = regs->skas.regs[ESI];
24135 +       sc.ebp = regs->skas.regs[EBP];
24136 +       sc.esp = regs->skas.regs[UESP];
24137 +       sc.ebx = regs->skas.regs[EBX];
24138 +       sc.edx = regs->skas.regs[EDX];
24139 +       sc.ecx = regs->skas.regs[ECX];
24140 +       sc.eax = regs->skas.regs[EAX];
24141 +       sc.eip = regs->skas.regs[EIP];
24142 +       sc.cs = regs->skas.regs[CS];
24143 +       sc.eflags = regs->skas.regs[EFL];
24144 +       sc.esp_at_signal = regs->skas.regs[UESP];
24145 +       sc.ss = regs->skas.regs[SS];
24146 +       sc.cr2 = fault_addr;
24147 +       sc.err = TO_SC_ERR(fault_type);
24148 +       sc.trapno = regs->skas.trap_type;
24149 +
24150 +       err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
24151 +       if(err < 0){
24152 +               printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
24153 +                      "errno = %d\n", errno);
24154 +               return(1);
24155 +       }
24156 +       to_fp = (struct _fpstate *) 
24157 +               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
24158 +       sc.fpstate = to_fp;
24159 +
24160 +       if(err)
24161 +               return(err);
24162 +
24163 +       return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
24164 +              copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
24165 +}
24166 +
24167 +/*
24168 + * Overrides for Emacs so that we follow Linus's tabbing style.
24169 + * Emacs will notice this stuff at the end of the file and automatically
24170 + * adjust the settings for this buffer only.  This must remain at the end
24171 + * of the file.
24172 + * ---------------------------------------------------------------------------
24173 + * Local variables:
24174 + * c-file-style: "linux"
24175 + * End:
24176 + */
24177 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/time.c um/arch/um/kernel/skas/time.c
24178 --- orig/arch/um/kernel/skas/time.c     1969-12-31 19:00:00.000000000 -0500
24179 +++ um/arch/um/kernel/skas/time.c       2002-10-23 21:08:04.000000000 -0400
24180 @@ -0,0 +1,30 @@
24181 +/* 
24182 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24183 + * Licensed under the GPL
24184 + */
24185 +
24186 +#include <sys/signal.h>
24187 +#include <sys/time.h>
24188 +#include "time_user.h"
24189 +#include "process.h"
24190 +#include "user.h"
24191 +
24192 +void user_time_init_skas(void)
24193 +{
24194 +        if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
24195 +                panic("Couldn't set SIGALRM handler");
24196 +       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
24197 +               panic("Couldn't set SIGVTALRM handler");
24198 +       set_interval(ITIMER_VIRTUAL);
24199 +}
24200 +
24201 +/*
24202 + * Overrides for Emacs so that we follow Linus's tabbing style.
24203 + * Emacs will notice this stuff at the end of the file and automatically
24204 + * adjust the settings for this buffer only.  This must remain at the end
24205 + * of the file.
24206 + * ---------------------------------------------------------------------------
24207 + * Local variables:
24208 + * c-file-style: "linux"
24209 + * End:
24210 + */
24211 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/tlb.c um/arch/um/kernel/skas/tlb.c
24212 --- orig/arch/um/kernel/skas/tlb.c      1969-12-31 19:00:00.000000000 -0500
24213 +++ um/arch/um/kernel/skas/tlb.c        2002-12-22 18:30:35.000000000 -0500
24214 @@ -0,0 +1,153 @@
24215 +/* 
24216 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24217 + * Licensed under the GPL
24218 + */
24219 +
24220 +#include "linux/stddef.h"
24221 +#include "linux/sched.h"
24222 +#include "asm/page.h"
24223 +#include "asm/pgtable.h"
24224 +#include "asm/mmu.h"
24225 +#include "user_util.h"
24226 +#include "mem_user.h"
24227 +#include "skas.h"
24228 +#include "os.h"
24229 +
24230 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
24231 +                     unsigned long end_addr, int force)
24232 +{
24233 +       pgd_t *npgd;
24234 +       pmd_t *npmd;
24235 +       pte_t *npte;
24236 +       unsigned long addr;
24237 +       int r, w, x, err, fd;
24238 +
24239 +       if(mm == NULL) return;
24240 +       fd = mm->context.skas.mm_fd;
24241 +       for(addr = start_addr; addr < end_addr;){
24242 +               npgd = pgd_offset(mm, addr);
24243 +               npmd = pmd_offset(npgd, addr);
24244 +               if(pmd_present(*npmd)){
24245 +                       npte = pte_offset(npmd, addr);
24246 +                       r = pte_read(*npte);
24247 +                       w = pte_write(*npte);
24248 +                       x = pte_exec(*npte);
24249 +                       if(!pte_dirty(*npte)) w = 0;
24250 +                       if(!pte_young(*npte)){
24251 +                               r = 0;
24252 +                               w = 0;
24253 +                       }
24254 +                       if(force || pte_newpage(*npte)){
24255 +                               err = unmap(fd, (void *) addr, PAGE_SIZE);
24256 +                               if(err < 0)
24257 +                                       panic("munmap failed, errno = %d\n",
24258 +                                             -err);
24259 +                               if(pte_present(*npte))
24260 +                                       map(fd, addr, 
24261 +                                           pte_val(*npte) & PAGE_MASK,
24262 +                                           PAGE_SIZE, r, w, x);
24263 +                       }
24264 +                       else if(pte_newprot(*npte)){
24265 +                               protect(fd, addr, PAGE_SIZE, r, w, x, 1);
24266 +                       }
24267 +                       *npte = pte_mkuptodate(*npte);
24268 +                       addr += PAGE_SIZE;
24269 +               }
24270 +               else {
24271 +                       if(force || pmd_newpage(*npmd)){
24272 +                               err = unmap(fd, (void *) addr, PMD_SIZE);
24273 +                               if(err < 0)
24274 +                                       panic("munmap failed, errno = %d\n",
24275 +                                             -err);
24276 +                               pmd_mkuptodate(*npmd);
24277 +                       }
24278 +                       addr += PMD_SIZE;
24279 +               }
24280 +       }
24281 +}
24282 +
24283 +static void flush_kernel_vm_range(unsigned long start, unsigned long end)
24284 +{
24285 +       struct mm_struct *mm;
24286 +       pgd_t *pgd;
24287 +       pmd_t *pmd;
24288 +       pte_t *pte;
24289 +       unsigned long addr;
24290 +       int updated = 0, err;
24291 +
24292 +       mm = &init_mm;
24293 +       for(addr = start_vm; addr < end_vm;){
24294 +               pgd = pgd_offset(mm, addr);
24295 +               pmd = pmd_offset(pgd, addr);
24296 +               if(pmd_present(*pmd)){
24297 +                       pte = pte_offset(pmd, addr);
24298 +                       if(!pte_present(*pte) || pte_newpage(*pte)){
24299 +                               updated = 1;
24300 +                               err = os_unmap_memory((void *) addr, 
24301 +                                                     PAGE_SIZE);
24302 +                               if(err < 0)
24303 +                                       panic("munmap failed, errno = %d\n",
24304 +                                             -err);
24305 +                               if(pte_present(*pte))
24306 +                                       map_memory(addr, 
24307 +                                                  pte_val(*pte) & PAGE_MASK,
24308 +                                                  PAGE_SIZE, 1, 1, 1);
24309 +                       }
24310 +                       else if(pte_newprot(*pte)){
24311 +                               updated = 1;
24312 +                               protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
24313 +                       }
24314 +                       addr += PAGE_SIZE;
24315 +               }
24316 +               else {
24317 +                       if(pmd_newpage(*pmd)){
24318 +                               updated = 1;
24319 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
24320 +                               if(err < 0)
24321 +                                       panic("munmap failed, errno = %d\n",
24322 +                                             -err);
24323 +                       }
24324 +                       addr += PMD_SIZE;
24325 +               }
24326 +       }
24327 +}
24328 +
24329 +void flush_tlb_kernel_vm_skas(void)
24330 +{
24331 +       flush_kernel_vm_range(start_vm, end_vm);
24332 +}
24333 +
24334 +void __flush_tlb_one_skas(unsigned long addr)
24335 +{
24336 +       flush_kernel_vm_range(addr, addr + PAGE_SIZE);
24337 +}
24338 +
24339 +void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, 
24340 +                    unsigned long end)
24341 +{
24342 +       if(mm == NULL)
24343 +               flush_kernel_vm_range(start, end);
24344 +       else fix_range(mm, start, end, 0);
24345 +}
24346 +
24347 +void flush_tlb_mm_skas(struct mm_struct *mm)
24348 +{
24349 +       flush_tlb_kernel_vm_skas();
24350 +       fix_range(mm, 0, host_task_size, 0);
24351 +}
24352 +
24353 +void force_flush_all_skas(void)
24354 +{
24355 +       fix_range(current->mm, 0, host_task_size, 1);
24356 +}
24357 +
24358 +/*
24359 + * Overrides for Emacs so that we follow Linus's tabbing style.
24360 + * Emacs will notice this stuff at the end of the file and automatically
24361 + * adjust the settings for this buffer only.  This must remain at the end
24362 + * of the file.
24363 + * ---------------------------------------------------------------------------
24364 + * Local variables:
24365 + * c-file-style: "linux"
24366 + * End:
24367 + */
24368 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/trap_user.c um/arch/um/kernel/skas/trap_user.c
24369 --- orig/arch/um/kernel/skas/trap_user.c        1969-12-31 19:00:00.000000000 -0500
24370 +++ um/arch/um/kernel/skas/trap_user.c  2002-12-15 13:28:41.000000000 -0500
24371 @@ -0,0 +1,65 @@
24372 +/* 
24373 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24374 + * Licensed under the GPL
24375 + */
24376 +
24377 +#include <signal.h>
24378 +#include <errno.h>
24379 +#include <asm/sigcontext.h>
24380 +#include "sysdep/ptrace.h"
24381 +#include "signal_user.h"
24382 +#include "user_util.h"
24383 +#include "kern_util.h"
24384 +#include "task.h"
24385 +#include "sigcontext.h"
24386 +
24387 +void sig_handler_common_skas(int sig, void *sc_ptr)
24388 +{
24389 +       struct sigcontext *sc = sc_ptr;
24390 +       struct skas_regs *r;
24391 +       struct signal_info *info;
24392 +       int save_errno = errno;
24393 +
24394 +       r = &TASK_REGS(get_current())->skas;
24395 +       r->is_user = 0;
24396 +       r->fault_addr = SC_FAULT_ADDR(sc);
24397 +       r->fault_type = SC_FAULT_TYPE(sc);
24398 +       r->trap_type = SC_TRAP_TYPE(sc);
24399 +
24400 +       change_sig(SIGUSR1, 1);
24401 +       info = &sig_info[sig];
24402 +       if(!info->is_irq) unblock_signals();
24403 +
24404 +       (*info->handler)(sig, (union uml_pt_regs *) r);
24405 +
24406 +       errno = save_errno;
24407 +}
24408 +
24409 +extern int missed_ticks[];
24410 +
24411 +void user_signal(int sig, union uml_pt_regs *regs)
24412 +{
24413 +       struct signal_info *info;
24414 +
24415 +       if(sig == SIGVTALRM)
24416 +               missed_ticks[cpu()]++;
24417 +       regs->skas.is_user = 1;
24418 +       regs->skas.fault_addr = 0;
24419 +       regs->skas.fault_type = 0;
24420 +       regs->skas.trap_type = 0;
24421 +       info = &sig_info[sig];
24422 +       (*info->handler)(sig, regs);
24423 +
24424 +       unblock_signals();
24425 +}
24426 +
24427 +/*
24428 + * Overrides for Emacs so that we follow Linus's tabbing style.
24429 + * Emacs will notice this stuff at the end of the file and automatically
24430 + * adjust the settings for this buffer only.  This must remain at the end
24431 + * of the file.
24432 + * ---------------------------------------------------------------------------
24433 + * Local variables:
24434 + * c-file-style: "linux"
24435 + * End:
24436 + */
24437 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/Makefile um/arch/um/kernel/skas/util/Makefile
24438 --- orig/arch/um/kernel/skas/util/Makefile      1969-12-31 19:00:00.000000000 -0500
24439 +++ um/arch/um/kernel/skas/util/Makefile        2002-10-23 21:08:04.000000000 -0400
24440 @@ -0,0 +1,10 @@
24441 +all: mk_ptregs
24442 +
24443 +mk_ptregs : mk_ptregs.o
24444 +       $(CC) -o mk_ptregs mk_ptregs.o
24445 +
24446 +mk_ptregs.o : mk_ptregs.c
24447 +       $(CC) -c $< 
24448 +
24449 +clean : 
24450 +       $(RM) -f mk_ptregs *.o *~
24451 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/mk_ptregs.c um/arch/um/kernel/skas/util/mk_ptregs.c
24452 --- orig/arch/um/kernel/skas/util/mk_ptregs.c   1969-12-31 19:00:00.000000000 -0500
24453 +++ um/arch/um/kernel/skas/util/mk_ptregs.c     2002-11-11 12:10:06.000000000 -0500
24454 @@ -0,0 +1,50 @@
24455 +#include <asm/ptrace.h>
24456 +#include <asm/user.h>
24457 +
24458 +#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
24459 +
24460 +int main(int argc, char **argv)
24461 +{
24462 +       printf("/* Automatically generated by "
24463 +              "arch/um/kernel/skas/util/mk_ptregs */\n");
24464 +       printf("\n");
24465 +       printf("#ifndef __SKAS_PT_REGS_\n");
24466 +       printf("#define __SKAS_PT_REGS_\n");
24467 +       printf("\n");
24468 +       printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
24469 +       printf("#define HOST_FP_SIZE %d\n", 
24470 +              sizeof(struct user_i387_struct) / sizeof(unsigned long));
24471 +       printf("#define HOST_XFP_SIZE %d\n", 
24472 +              sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
24473 +
24474 +       PRINT_REG("IP", EIP);
24475 +       PRINT_REG("SP", UESP);
24476 +       PRINT_REG("EFLAGS", EFL);
24477 +       PRINT_REG("EAX", EAX);
24478 +       PRINT_REG("EBX", EBX);
24479 +       PRINT_REG("ECX", ECX);
24480 +       PRINT_REG("EDX", EDX);
24481 +       PRINT_REG("ESI", ESI);
24482 +       PRINT_REG("EDI", EDI);
24483 +       PRINT_REG("EBP", EBP);
24484 +       PRINT_REG("CS", CS);
24485 +       PRINT_REG("SS", SS);
24486 +       PRINT_REG("DS", DS);
24487 +       PRINT_REG("FS", FS);
24488 +       PRINT_REG("ES", ES);
24489 +       PRINT_REG("GS", GS);
24490 +       printf("\n");
24491 +       printf("#endif\n");
24492 +       return(0);
24493 +}
24494 +
24495 +/*
24496 + * Overrides for Emacs so that we follow Linus's tabbing style.
24497 + * Emacs will notice this stuff at the end of the file and automatically
24498 + * adjust the settings for this buffer only.  This must remain at the end
24499 + * of the file.
24500 + * ---------------------------------------------------------------------------
24501 + * Local variables:
24502 + * c-file-style: "linux"
24503 + * End:
24504 + */
24505 diff -Naur -X ../exclude-files orig/arch/um/kernel/smp.c um/arch/um/kernel/smp.c
24506 --- orig/arch/um/kernel/smp.c   1969-12-31 19:00:00.000000000 -0500
24507 +++ um/arch/um/kernel/smp.c     2003-02-22 14:28:45.000000000 -0500
24508 @@ -0,0 +1,324 @@
24509 +/* 
24510 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
24511 + * Licensed under the GPL
24512 + */
24513 +
24514 +#include "linux/config.h"
24515 +
24516 +
24517 +#ifdef CONFIG_SMP
24518 +
24519 +#include "linux/sched.h"
24520 +#include "linux/threads.h"
24521 +#include "linux/interrupt.h"
24522 +#include "asm/smp.h"
24523 +#include "asm/processor.h"
24524 +#include "asm/spinlock.h"
24525 +#include "asm/softirq.h"
24526 +#include "asm/hardirq.h"
24527 +#include "user_util.h"
24528 +#include "kern_util.h"
24529 +#include "irq_user.h"
24530 +#include "kern.h"
24531 +#include "os.h"
24532 +
24533 +/* Total count of live CPUs, set by smp_boot_cpus */
24534 +int smp_num_cpus = 1;
24535 +
24536 +/* The 'big kernel lock' */
24537 +spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
24538 +
24539 +/* Per CPU bogomips and other parameters */
24540 +
24541 +/* The only piece used here is the ipi pipe, which is set before SMP is
24542 + * started and never changed.
24543 + */
24544 +struct cpuinfo_um cpu_data[NR_CPUS];
24545 +
24546 +/* CPU online map, set by smp_boot_cpus */
24547 +unsigned long cpu_online_map;
24548 +
24549 +atomic_t global_bh_count;
24550 +
24551 +/* Set when the idlers are all forked */
24552 +int smp_threads_ready = 0;
24553 +
24554 +/* Not used by UML */
24555 +unsigned char global_irq_holder = 0;
24556 +unsigned volatile long global_irq_lock;
24557 +
24558 +/* A statistic, can be a little off */
24559 +static int num_reschedules_sent = 0;
24560 +
24561 +void smp_send_reschedule(int cpu)
24562 +{
24563 +       write(cpu_data[cpu].ipi_pipe[1], "R", 1);
24564 +       num_reschedules_sent++;
24565 +}
24566 +
24567 +static void show(char * str)
24568 +{
24569 +       int cpu = smp_processor_id();
24570 +
24571 +       printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
24572 +}
24573 +       
24574 +#define MAXCOUNT 100000000
24575 +
24576 +static inline void wait_on_bh(void)
24577 +{
24578 +       int count = MAXCOUNT;
24579 +       do {
24580 +               if (!--count) {
24581 +                       show("wait_on_bh");
24582 +                       count = ~0;
24583 +               }
24584 +               /* nothing .. wait for the other bh's to go away */
24585 +       } while (atomic_read(&global_bh_count) != 0);
24586 +}
24587 +
24588 +/*
24589 + * This is called when we want to synchronize with
24590 + * bottom half handlers. We need to wait until
24591 + * no other CPU is executing any bottom half handler.
24592 + *
24593 + * Don't wait if we're already running in an interrupt
24594 + * context or are inside a bh handler. 
24595 + */
24596 +void synchronize_bh(void)
24597 +{
24598 +       if (atomic_read(&global_bh_count) && !in_interrupt())
24599 +               wait_on_bh();
24600 +}
24601 +
24602 +void smp_send_stop(void)
24603 +{
24604 +       int i;
24605
24606 +       printk(KERN_INFO "Stopping all CPUs...");
24607 +       for(i = 0; i < ncpus; i++){
24608 +               if(i == current->processor)
24609 +                       continue;
24610 +               write(cpu_data[i].ipi_pipe[1], "S", 1);
24611 +       }
24612 +       printk("done\n");
24613 +}
24614 +
24615 +
24616 +static atomic_t smp_commenced = ATOMIC_INIT(0);
24617 +static volatile unsigned long smp_callin_map = 0;
24618 +
24619 +void smp_commence(void)
24620 +{
24621 +       printk("All CPUs are go!\n");
24622 +
24623 +       wmb();
24624 +       atomic_set(&smp_commenced, 1);
24625 +}
24626 +
24627 +static int idle_proc(void *unused)
24628 +{
24629 +       int cpu, err;
24630 +
24631 +       set_current(current);
24632 +       del_from_runqueue(current);
24633 +       unhash_process(current);
24634 +
24635 +       cpu = current->processor;
24636 +       err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
24637 +       if(err)
24638 +               panic("CPU#%d failed to create IPI pipe, errno = %d", cpu, 
24639 +                     -err);
24640 +
24641 +       activate_ipi(cpu_data[cpu].ipi_pipe[0], 
24642 +                    current->thread.mode.tt.extern_pid);
24643
24644 +       wmb();
24645 +       if (test_and_set_bit(current->processor, &smp_callin_map)) {
24646 +               printk("huh, CPU#%d already present??\n", current->processor);
24647 +               BUG();
24648 +       }
24649 +
24650 +       while (!atomic_read(&smp_commenced))
24651 +               cpu_relax();
24652 +
24653 +       init_idle();
24654 +       cpu_idle();
24655 +       return(0);
24656 +}
24657 +
24658 +static int idle_thread(int (*fn)(void *), int cpu)
24659 +{
24660 +       struct task_struct *new_task;
24661 +       int pid;
24662 +       unsigned char c;
24663 +
24664 +        current->thread.request.u.thread.proc = fn;
24665 +        current->thread.request.u.thread.arg = NULL;
24666 +       pid = do_fork(CLONE_VM | CLONE_PID, 0, NULL, 0);
24667 +       if(pid < 0) panic("do_fork failed in idle_thread");
24668 +       new_task = get_task(pid, 1);
24669 +
24670 +       cpu_tasks[cpu].pid = new_task->thread.mode.tt.extern_pid;
24671 +       cpu_tasks[cpu].task = new_task;
24672 +       init_tasks[cpu] = new_task;
24673 +       new_task->processor = cpu;
24674 +       new_task->cpus_allowed = 1 << cpu;
24675 +       new_task->cpus_runnable = new_task->cpus_allowed;
24676 +       CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, 
24677 +                         sizeof(c)),
24678 +                   ({ panic("skas mode doesn't support SMP"); }));
24679 +       return(new_task->thread.mode.tt.extern_pid);
24680 +}
24681 +
24682 +void smp_boot_cpus(void)
24683 +{
24684 +       int err;
24685 +
24686 +       set_bit(0, &cpu_online_map);
24687 +       set_bit(0, &smp_callin_map);
24688 +
24689 +       err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
24690 +       if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
24691 +
24692 +       activate_ipi(cpu_data[0].ipi_pipe[0], 
24693 +                    current->thread.mode.tt.extern_pid);
24694 +
24695 +       if(ncpus < 1){
24696 +               printk(KERN_INFO "ncpus set to 1\n");
24697 +               ncpus = 1;
24698 +       }
24699 +       else if(ncpus > NR_CPUS){
24700 +               printk(KERN_INFO 
24701 +                      "ncpus can't be greater than NR_CPUS, set to %d\n",
24702 +                      NR_CPUS);
24703 +               ncpus = NR_CPUS;
24704 +       }
24705 +
24706 +       if(ncpus > 1){
24707 +               int i, pid;
24708 +
24709 +               printk(KERN_INFO "Starting up other processors:\n");
24710 +               for(i=1;i<ncpus;i++){
24711 +                       int waittime;
24712 +
24713 +                       /* Do this early, for hard_smp_processor_id()  */
24714 +                       cpu_tasks[i].pid = -1;
24715 +                       set_bit(i, &cpu_online_map);
24716 +                       smp_num_cpus++;
24717 +
24718 +                       pid = idle_thread(idle_proc, i);
24719 +                       printk(KERN_INFO "\t#%d - idle thread pid = %d.. ",
24720 +                              i, pid);
24721 +
24722 +                       waittime = 200000000;
24723 +                       while (waittime-- && !test_bit(i, &smp_callin_map))
24724 +                               cpu_relax();
24725 +
24726 +                       if (test_bit(i, &smp_callin_map))
24727 +                               printk("online\n");
24728 +                       else {
24729 +                               printk("failed\n");
24730 +                               clear_bit(i, &cpu_online_map);
24731 +                       }
24732 +               }
24733 +       }
24734 +}
24735 +
24736 +int setup_profiling_timer(unsigned int multiplier)
24737 +{
24738 +       printk(KERN_INFO "setup_profiling_timer\n");
24739 +       return(0);
24740 +}
24741 +
24742 +void smp_call_function_slave(int cpu);
24743 +
24744 +void IPI_handler(int cpu)
24745 +{
24746 +       unsigned char c;
24747 +       int fd;
24748 +
24749 +       fd = cpu_data[cpu].ipi_pipe[0];
24750 +       while (read(fd, &c, 1) == 1) {
24751 +               switch (c) {
24752 +               case 'C':
24753 +                       smp_call_function_slave(cpu);
24754 +                       break;
24755 +
24756 +               case 'R':
24757 +                       current->need_resched = 1;
24758 +                       break;
24759 +
24760 +               case 'S':
24761 +                       printk("CPU#%d stopping\n", cpu);
24762 +                       while(1)
24763 +                               pause();
24764 +                       break;
24765 +
24766 +               default:
24767 +                       printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
24768 +                       break;
24769 +               }
24770 +       }
24771 +}
24772 +
24773 +int hard_smp_processor_id(void)
24774 +{
24775 +       return(pid_to_processor_id(os_getpid()));
24776 +}
24777 +
24778 +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
24779 +static atomic_t scf_started;
24780 +static atomic_t scf_finished;
24781 +static void (*func)(void *info);
24782 +static void *info;
24783 +
24784 +void smp_call_function_slave(int cpu)
24785 +{
24786 +       atomic_inc(&scf_started);
24787 +       (*func)(info);
24788 +       atomic_inc(&scf_finished);
24789 +}
24790 +
24791 +int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 
24792 +                     int wait)
24793 +{
24794 +       int cpus = smp_num_cpus - 1;
24795 +       int i;
24796 +
24797 +       if (!cpus)
24798 +               return 0;
24799 +
24800 +       spin_lock_bh(&call_lock);
24801 +       atomic_set(&scf_started, 0);
24802 +       atomic_set(&scf_finished, 0);
24803 +       func = _func;
24804 +       info = _info;
24805 +
24806 +       for (i=0;i<NR_CPUS;i++)
24807 +               if (i != current->processor && test_bit(i, &cpu_online_map))
24808 +                       write(cpu_data[i].ipi_pipe[1], "C", 1);
24809 +
24810 +       while (atomic_read(&scf_started) != cpus)
24811 +               barrier();
24812 +
24813 +       if (wait)
24814 +               while (atomic_read(&scf_finished) != cpus)
24815 +                       barrier();
24816 +
24817 +       spin_unlock_bh(&call_lock);
24818 +       return 0;
24819 +}
24820 +
24821 +#endif
24822 +
24823 +/*
24824 + * Overrides for Emacs so that we follow Linus's tabbing style.
24825 + * Emacs will notice this stuff at the end of the file and automatically
24826 + * adjust the settings for this buffer only.  This must remain at the end
24827 + * of the file.
24828 + * ---------------------------------------------------------------------------
24829 + * Local variables:
24830 + * c-file-style: "linux"
24831 + * End:
24832 + */
24833 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_kern.c um/arch/um/kernel/syscall_kern.c
24834 --- orig/arch/um/kernel/syscall_kern.c  1969-12-31 19:00:00.000000000 -0500
24835 +++ um/arch/um/kernel/syscall_kern.c    2002-11-08 14:04:10.000000000 -0500
24836 @@ -0,0 +1,343 @@
24837 +/* 
24838 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
24839 + * Licensed under the GPL
24840 + */
24841 +
24842 +#include "linux/sched.h"
24843 +#include "linux/file.h"
24844 +#include "linux/smp_lock.h"
24845 +#include "linux/mm.h"
24846 +#include "linux/utsname.h"
24847 +#include "linux/msg.h"
24848 +#include "linux/shm.h"
24849 +#include "linux/sys.h"
24850 +#include "linux/unistd.h"
24851 +#include "linux/slab.h"
24852 +#include "linux/utime.h"
24853 +#include "asm/mman.h"
24854 +#include "asm/uaccess.h"
24855 +#include "asm/ipc.h"
24856 +#include "kern_util.h"
24857 +#include "user_util.h"
24858 +#include "sysdep/syscalls.h"
24859 +#include "mode_kern.h"
24860 +#include "choose-mode.h"
24861 +
24862 +/*  Unlocked, I don't care if this is a bit off */
24863 +int nsyscalls = 0;
24864 +
24865 +long um_mount(char * dev_name, char * dir_name, char * type,
24866 +             unsigned long new_flags, void * data)
24867 +{
24868 +       if(type == NULL) type = "";
24869 +       return(sys_mount(dev_name, dir_name, type, new_flags, data));
24870 +}
24871 +
24872 +long sys_fork(void)
24873 +{
24874 +       long ret;
24875 +
24876 +       current->thread.forking = 1;
24877 +        ret = do_fork(SIGCHLD, 0, NULL, 0);
24878 +       current->thread.forking = 0;
24879 +       return(ret);
24880 +}
24881 +
24882 +long sys_clone(unsigned long clone_flags, unsigned long newsp)
24883 +{
24884 +       long ret;
24885 +
24886 +       current->thread.forking = 1;
24887 +       ret = do_fork(clone_flags, newsp, NULL, 0);
24888 +       current->thread.forking = 0;
24889 +       return(ret);
24890 +}
24891 +
24892 +long sys_vfork(void)
24893 +{
24894 +       long ret;
24895 +
24896 +       current->thread.forking = 1;
24897 +       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0);
24898 +       current->thread.forking = 0;
24899 +       return(ret);
24900 +}
24901 +
24902 +/* common code for old and new mmaps */
24903 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
24904 +             unsigned long prot, unsigned long flags, unsigned long fd,
24905 +             unsigned long pgoff)
24906 +{
24907 +       int error = -EBADF;
24908 +       struct file * file = NULL;
24909 +
24910 +       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
24911 +       if (!(flags & MAP_ANONYMOUS)) {
24912 +               file = fget(fd);
24913 +               if (!file)
24914 +                       goto out;
24915 +       }
24916 +
24917 +       down_write(&mm->mmap_sem);
24918 +       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
24919 +       up_write(&mm->mmap_sem);
24920 +
24921 +       if (file)
24922 +               fput(file);
24923 + out:
24924 +       return error;
24925 +}
24926 +
24927 +long sys_mmap2(unsigned long addr, unsigned long len,
24928 +              unsigned long prot, unsigned long flags,
24929 +              unsigned long fd, unsigned long pgoff)
24930 +{
24931 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
24932 +}
24933 +
24934 +/*
24935 + * Perform the select(nd, in, out, ex, tv) and mmap() system
24936 + * calls. Linux/i386 didn't use to be able to handle more than
24937 + * 4 system call parameters, so these system calls used a memory
24938 + * block for parameter passing..
24939 + */
24940 +
24941 +struct mmap_arg_struct {
24942 +       unsigned long addr;
24943 +       unsigned long len;
24944 +       unsigned long prot;
24945 +       unsigned long flags;
24946 +       unsigned long fd;
24947 +       unsigned long offset;
24948 +};
24949 +
24950 +int old_mmap(unsigned long addr, unsigned long len,
24951 +            unsigned long prot, unsigned long flags,
24952 +            unsigned long fd, unsigned long offset)
24953 +{
24954 +       int err = -EINVAL;
24955 +       if (offset & ~PAGE_MASK)
24956 +               goto out;
24957 +
24958 +       err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
24959 +                      offset >> PAGE_SHIFT);
24960 + out:
24961 +       return err;
24962 +}
24963 +/*
24964 + * sys_pipe() is the normal C calling standard for creating
24965 + * a pipe. It's not the way unix traditionally does this, though.
24966 + */
24967 +int sys_pipe(unsigned long * fildes)
24968 +{
24969 +        int fd[2];
24970 +        int error;
24971 +
24972 +        error = do_pipe(fd);
24973 +        if (!error) {
24974 +                if (copy_to_user(fildes, fd, 2*sizeof(int)))
24975 +                        error = -EFAULT;
24976 +        }
24977 +        return error;
24978 +}
24979 +
24980 +int sys_pause(void)
24981 +{
24982 +       current->state = TASK_INTERRUPTIBLE;
24983 +       schedule();
24984 +       return -ERESTARTNOHAND;
24985 +}
24986 +
24987 +int sys_sigaction(int sig, const struct old_sigaction *act,
24988 +                        struct old_sigaction *oact)
24989 +{
24990 +       struct k_sigaction new_ka, old_ka;
24991 +       int ret;
24992 +
24993 +       if (act) {
24994 +               old_sigset_t mask;
24995 +               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
24996 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
24997 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
24998 +                       return -EFAULT;
24999 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
25000 +               __get_user(mask, &act->sa_mask);
25001 +               siginitset(&new_ka.sa.sa_mask, mask);
25002 +       }
25003 +
25004 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
25005 +
25006 +       if (!ret && oact) {
25007 +               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
25008 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
25009 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
25010 +                       return -EFAULT;
25011 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
25012 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
25013 +       }
25014 +
25015 +       return ret;
25016 +}
25017 +
25018 +/*
25019 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
25020 + *
25021 + * This is really horribly ugly.
25022 + */
25023 +int sys_ipc (uint call, int first, int second,
25024 +            int third, void *ptr, long fifth)
25025 +{
25026 +       int version, ret;
25027 +
25028 +       version = call >> 16; /* hack for backward compatibility */
25029 +       call &= 0xffff;
25030 +
25031 +       switch (call) {
25032 +       case SEMOP:
25033 +               return sys_semop (first, (struct sembuf *)ptr, second);
25034 +       case SEMGET:
25035 +               return sys_semget (first, second, third);
25036 +       case SEMCTL: {
25037 +               union semun fourth;
25038 +               if (!ptr)
25039 +                       return -EINVAL;
25040 +               if (get_user(fourth.__pad, (void **) ptr))
25041 +                       return -EFAULT;
25042 +               return sys_semctl (first, second, third, fourth);
25043 +       }
25044 +
25045 +       case MSGSND:
25046 +               return sys_msgsnd (first, (struct msgbuf *) ptr, 
25047 +                                  second, third);
25048 +       case MSGRCV:
25049 +               switch (version) {
25050 +               case 0: {
25051 +                       struct ipc_kludge tmp;
25052 +                       if (!ptr)
25053 +                               return -EINVAL;
25054 +                       
25055 +                       if (copy_from_user(&tmp,
25056 +                                          (struct ipc_kludge *) ptr, 
25057 +                                          sizeof (tmp)))
25058 +                               return -EFAULT;
25059 +                       return sys_msgrcv (first, tmp.msgp, second,
25060 +                                          tmp.msgtyp, third);
25061 +               }
25062 +               default:
25063 +                       panic("msgrcv with version != 0");
25064 +                       return sys_msgrcv (first,
25065 +                                          (struct msgbuf *) ptr,
25066 +                                          second, fifth, third);
25067 +               }
25068 +       case MSGGET:
25069 +               return sys_msgget ((key_t) first, second);
25070 +       case MSGCTL:
25071 +               return sys_msgctl (first, second, (struct msqid_ds *) ptr);
25072 +
25073 +       case SHMAT:
25074 +               switch (version) {
25075 +               default: {
25076 +                       ulong raddr;
25077 +                       ret = sys_shmat (first, (char *) ptr, second, &raddr);
25078 +                       if (ret)
25079 +                               return ret;
25080 +                       return put_user (raddr, (ulong *) third);
25081 +               }
25082 +               case 1: /* iBCS2 emulator entry point */
25083 +                       if (!segment_eq(get_fs(), get_ds()))
25084 +                               return -EINVAL;
25085 +                       return sys_shmat (first, (char *) ptr, second, (ulong *) third);
25086 +               }
25087 +       case SHMDT: 
25088 +               return sys_shmdt ((char *)ptr);
25089 +       case SHMGET:
25090 +               return sys_shmget (first, second, third);
25091 +       case SHMCTL:
25092 +               return sys_shmctl (first, second,
25093 +                                  (struct shmid_ds *) ptr);
25094 +       default:
25095 +               return -EINVAL;
25096 +       }
25097 +}
25098 +
25099 +int sys_uname(struct old_utsname * name)
25100 +{
25101 +       int err;
25102 +       if (!name)
25103 +               return -EFAULT;
25104 +       down_read(&uts_sem);
25105 +       err=copy_to_user(name, &system_utsname, sizeof (*name));
25106 +       up_read(&uts_sem);
25107 +       return err?-EFAULT:0;
25108 +}
25109 +
25110 +int sys_olduname(struct oldold_utsname * name)
25111 +{
25112 +       int error;
25113 +
25114 +       if (!name)
25115 +               return -EFAULT;
25116 +       if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
25117 +               return -EFAULT;
25118 +  
25119 +       down_read(&uts_sem);
25120 +       
25121 +       error = __copy_to_user(&name->sysname,&system_utsname.sysname,
25122 +                              __OLD_UTS_LEN);
25123 +       error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
25124 +       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
25125 +                               __OLD_UTS_LEN);
25126 +       error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
25127 +       error |= __copy_to_user(&name->release,&system_utsname.release,
25128 +                               __OLD_UTS_LEN);
25129 +       error |= __put_user(0,name->release+__OLD_UTS_LEN);
25130 +       error |= __copy_to_user(&name->version,&system_utsname.version,
25131 +                               __OLD_UTS_LEN);
25132 +       error |= __put_user(0,name->version+__OLD_UTS_LEN);
25133 +       error |= __copy_to_user(&name->machine,&system_utsname.machine,
25134 +                               __OLD_UTS_LEN);
25135 +       error |= __put_user(0,name->machine+__OLD_UTS_LEN);
25136 +       
25137 +       up_read(&uts_sem);
25138 +       
25139 +       error = error ? -EFAULT : 0;
25140 +
25141 +       return error;
25142 +}
25143 +
25144 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
25145 +{
25146 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
25147 +}
25148 +
25149 +long execute_syscall(void *r)
25150 +{
25151 +       return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
25152 +}
25153 +
25154 +spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
25155 +
25156 +static int syscall_index = 0;
25157 +
25158 +int next_syscall_index(int limit)
25159 +{
25160 +       int ret;
25161 +
25162 +       spin_lock(&syscall_lock);
25163 +       ret = syscall_index;
25164 +       if(++syscall_index == limit)
25165 +               syscall_index = 0;
25166 +       spin_unlock(&syscall_lock);
25167 +       return(ret);
25168 +}
25169 +
25170 +/*
25171 + * Overrides for Emacs so that we follow Linus's tabbing style.
25172 + * Emacs will notice this stuff at the end of the file and automatically
25173 + * adjust the settings for this buffer only.  This must remain at the end
25174 + * of the file.
25175 + * ---------------------------------------------------------------------------
25176 + * Local variables:
25177 + * c-file-style: "linux"
25178 + * End:
25179 + */
25180 diff -Naur -X ../exclude-files orig/arch/um/kernel/sys_call_table.c um/arch/um/kernel/sys_call_table.c
25181 --- orig/arch/um/kernel/sys_call_table.c        1969-12-31 19:00:00.000000000 -0500
25182 +++ um/arch/um/kernel/sys_call_table.c  2003-02-27 13:33:23.000000000 -0500
25183 @@ -0,0 +1,485 @@
25184 +/* 
25185 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
25186 + * Licensed under the GPL
25187 + */
25188 +
25189 +#include "linux/unistd.h"
25190 +#include "linux/version.h"
25191 +#include "linux/sys.h"
25192 +#include "asm/signal.h"
25193 +#include "sysdep/syscalls.h"
25194 +#include "kern_util.h"
25195 +
25196 +extern syscall_handler_t sys_ni_syscall;
25197 +extern syscall_handler_t sys_exit;
25198 +extern syscall_handler_t sys_fork;
25199 +extern syscall_handler_t sys_creat;
25200 +extern syscall_handler_t sys_link;
25201 +extern syscall_handler_t sys_unlink;
25202 +extern syscall_handler_t sys_chdir;
25203 +extern syscall_handler_t sys_mknod;
25204 +extern syscall_handler_t sys_chmod;
25205 +extern syscall_handler_t sys_lchown16;
25206 +extern syscall_handler_t sys_ni_syscall;
25207 +extern syscall_handler_t sys_stat;
25208 +extern syscall_handler_t sys_getpid;
25209 +extern syscall_handler_t sys_oldumount;
25210 +extern syscall_handler_t sys_setuid16;
25211 +extern syscall_handler_t sys_getuid16;
25212 +extern syscall_handler_t sys_ptrace;
25213 +extern syscall_handler_t sys_alarm;
25214 +extern syscall_handler_t sys_fstat;
25215 +extern syscall_handler_t sys_pause;
25216 +extern syscall_handler_t sys_utime;
25217 +extern syscall_handler_t sys_ni_syscall;
25218 +extern syscall_handler_t sys_ni_syscall;
25219 +extern syscall_handler_t sys_access;
25220 +extern syscall_handler_t sys_nice;
25221 +extern syscall_handler_t sys_ni_syscall;
25222 +extern syscall_handler_t sys_sync;
25223 +extern syscall_handler_t sys_kill;
25224 +extern syscall_handler_t sys_rename;
25225 +extern syscall_handler_t sys_mkdir;
25226 +extern syscall_handler_t sys_rmdir;
25227 +extern syscall_handler_t sys_pipe;
25228 +extern syscall_handler_t sys_times;
25229 +extern syscall_handler_t sys_ni_syscall;
25230 +extern syscall_handler_t sys_brk;
25231 +extern syscall_handler_t sys_setgid16;
25232 +extern syscall_handler_t sys_getgid16;
25233 +extern syscall_handler_t sys_signal;
25234 +extern syscall_handler_t sys_geteuid16;
25235 +extern syscall_handler_t sys_getegid16;
25236 +extern syscall_handler_t sys_acct;
25237 +extern syscall_handler_t sys_umount;
25238 +extern syscall_handler_t sys_ni_syscall;
25239 +extern syscall_handler_t sys_ioctl;
25240 +extern syscall_handler_t sys_fcntl;
25241 +extern syscall_handler_t sys_ni_syscall;
25242 +extern syscall_handler_t sys_setpgid;
25243 +extern syscall_handler_t sys_ni_syscall;
25244 +extern syscall_handler_t sys_olduname;
25245 +extern syscall_handler_t sys_umask;
25246 +extern syscall_handler_t sys_chroot;
25247 +extern syscall_handler_t sys_ustat;
25248 +extern syscall_handler_t sys_dup2;
25249 +extern syscall_handler_t sys_getppid;
25250 +extern syscall_handler_t sys_getpgrp;
25251 +extern syscall_handler_t sys_sigaction;
25252 +extern syscall_handler_t sys_sgetmask;
25253 +extern syscall_handler_t sys_ssetmask;
25254 +extern syscall_handler_t sys_setreuid16;
25255 +extern syscall_handler_t sys_setregid16;
25256 +extern syscall_handler_t sys_sigsuspend;
25257 +extern syscall_handler_t sys_sigpending;
25258 +extern syscall_handler_t sys_sethostname;
25259 +extern syscall_handler_t sys_setrlimit;
25260 +extern syscall_handler_t sys_old_getrlimit;
25261 +extern syscall_handler_t sys_getrusage;
25262 +extern syscall_handler_t sys_gettimeofday;
25263 +extern syscall_handler_t sys_settimeofday;
25264 +extern syscall_handler_t sys_getgroups16;
25265 +extern syscall_handler_t sys_setgroups16;
25266 +extern syscall_handler_t sys_symlink;
25267 +extern syscall_handler_t sys_lstat;
25268 +extern syscall_handler_t sys_readlink;
25269 +extern syscall_handler_t sys_uselib;
25270 +extern syscall_handler_t sys_swapon;
25271 +extern syscall_handler_t sys_reboot;
25272 +extern syscall_handler_t old_readdir;
25273 +extern syscall_handler_t sys_munmap;
25274 +extern syscall_handler_t sys_truncate;
25275 +extern syscall_handler_t sys_ftruncate;
25276 +extern syscall_handler_t sys_fchmod;
25277 +extern syscall_handler_t sys_fchown16;
25278 +extern syscall_handler_t sys_getpriority;
25279 +extern syscall_handler_t sys_setpriority;
25280 +extern syscall_handler_t sys_ni_syscall;
25281 +extern syscall_handler_t sys_statfs;
25282 +extern syscall_handler_t sys_fstatfs;
25283 +extern syscall_handler_t sys_ni_syscall;
25284 +extern syscall_handler_t sys_socketcall;
25285 +extern syscall_handler_t sys_syslog;
25286 +extern syscall_handler_t sys_setitimer;
25287 +extern syscall_handler_t sys_getitimer;
25288 +extern syscall_handler_t sys_newstat;
25289 +extern syscall_handler_t sys_newlstat;
25290 +extern syscall_handler_t sys_newfstat;
25291 +extern syscall_handler_t sys_uname;
25292 +extern syscall_handler_t sys_ni_syscall;
25293 +extern syscall_handler_t sys_vhangup;
25294 +extern syscall_handler_t sys_ni_syscall;
25295 +extern syscall_handler_t sys_ni_syscall;
25296 +extern syscall_handler_t sys_swapoff;
25297 +extern syscall_handler_t sys_sysinfo;
25298 +extern syscall_handler_t sys_ipc;
25299 +extern syscall_handler_t sys_fsync;
25300 +extern syscall_handler_t sys_sigreturn;
25301 +extern syscall_handler_t sys_rt_sigreturn;
25302 +extern syscall_handler_t sys_clone;
25303 +extern syscall_handler_t sys_setdomainname;
25304 +extern syscall_handler_t sys_newuname;
25305 +extern syscall_handler_t sys_ni_syscall;
25306 +extern syscall_handler_t sys_adjtimex;
25307 +extern syscall_handler_t sys_mprotect;
25308 +extern syscall_handler_t sys_sigprocmask;
25309 +extern syscall_handler_t sys_create_module;
25310 +extern syscall_handler_t sys_init_module;
25311 +extern syscall_handler_t sys_delete_module;
25312 +extern syscall_handler_t sys_get_kernel_syms;
25313 +extern syscall_handler_t sys_quotactl;
25314 +extern syscall_handler_t sys_getpgid;
25315 +extern syscall_handler_t sys_fchdir;
25316 +extern syscall_handler_t sys_bdflush;
25317 +extern syscall_handler_t sys_sysfs;
25318 +extern syscall_handler_t sys_personality;
25319 +extern syscall_handler_t sys_ni_syscall;
25320 +extern syscall_handler_t sys_setfsuid16;
25321 +extern syscall_handler_t sys_setfsgid16;
25322 +extern syscall_handler_t sys_llseek;
25323 +extern syscall_handler_t sys_getdents;
25324 +extern syscall_handler_t sys_flock;
25325 +extern syscall_handler_t sys_msync;
25326 +extern syscall_handler_t sys_readv;
25327 +extern syscall_handler_t sys_writev;
25328 +extern syscall_handler_t sys_getsid;
25329 +extern syscall_handler_t sys_fdatasync;
25330 +extern syscall_handler_t sys_sysctl;
25331 +extern syscall_handler_t sys_mlock;
25332 +extern syscall_handler_t sys_munlock;
25333 +extern syscall_handler_t sys_mlockall;
25334 +extern syscall_handler_t sys_munlockall;
25335 +extern syscall_handler_t sys_sched_setparam;
25336 +extern syscall_handler_t sys_sched_getparam;
25337 +extern syscall_handler_t sys_sched_setscheduler;
25338 +extern syscall_handler_t sys_sched_getscheduler;
25339 +extern syscall_handler_t sys_sched_get_priority_max;
25340 +extern syscall_handler_t sys_sched_get_priority_min;
25341 +extern syscall_handler_t sys_sched_rr_get_interval;
25342 +extern syscall_handler_t sys_nanosleep;
25343 +extern syscall_handler_t sys_mremap;
25344 +extern syscall_handler_t sys_setresuid16;
25345 +extern syscall_handler_t sys_getresuid16;
25346 +extern syscall_handler_t sys_ni_syscall;
25347 +extern syscall_handler_t sys_query_module;
25348 +extern syscall_handler_t sys_poll;
25349 +extern syscall_handler_t sys_nfsservctl;
25350 +extern syscall_handler_t sys_setresgid16;
25351 +extern syscall_handler_t sys_getresgid16;
25352 +extern syscall_handler_t sys_prctl;
25353 +extern syscall_handler_t sys_ni_syscall;
25354 +extern syscall_handler_t sys_rt_sigaction;
25355 +extern syscall_handler_t sys_rt_sigprocmask;
25356 +extern syscall_handler_t sys_rt_sigpending;
25357 +extern syscall_handler_t sys_rt_sigtimedwait;
25358 +extern syscall_handler_t sys_rt_sigqueueinfo;
25359 +extern syscall_handler_t sys_rt_sigsuspend;
25360 +extern syscall_handler_t sys_pread;
25361 +extern syscall_handler_t sys_pwrite;
25362 +extern syscall_handler_t sys_chown16;
25363 +extern syscall_handler_t sys_getcwd;
25364 +extern syscall_handler_t sys_capget;
25365 +extern syscall_handler_t sys_capset;
25366 +extern syscall_handler_t sys_sigaltstack;
25367 +extern syscall_handler_t sys_sendfile;
25368 +extern syscall_handler_t sys_ni_syscall;
25369 +extern syscall_handler_t sys_ni_syscall;
25370 +extern syscall_handler_t sys_vfork;
25371 +extern syscall_handler_t sys_getrlimit;
25372 +extern syscall_handler_t sys_mmap2;
25373 +extern syscall_handler_t sys_truncate64;
25374 +extern syscall_handler_t sys_ftruncate64;
25375 +extern syscall_handler_t sys_stat64;
25376 +extern syscall_handler_t sys_lstat64;
25377 +extern syscall_handler_t sys_fstat64;
25378 +extern syscall_handler_t sys_lchown;
25379 +extern syscall_handler_t sys_getuid;
25380 +extern syscall_handler_t sys_getgid;
25381 +extern syscall_handler_t sys_geteuid;
25382 +extern syscall_handler_t sys_getegid;
25383 +extern syscall_handler_t sys_setreuid;
25384 +extern syscall_handler_t sys_setregid;
25385 +extern syscall_handler_t sys_getgroups;
25386 +extern syscall_handler_t sys_setgroups;
25387 +extern syscall_handler_t sys_fchown;
25388 +extern syscall_handler_t sys_setresuid;
25389 +extern syscall_handler_t sys_getresuid;
25390 +extern syscall_handler_t sys_setresgid;
25391 +extern syscall_handler_t sys_getresgid;
25392 +extern syscall_handler_t sys_chown;
25393 +extern syscall_handler_t sys_setuid;
25394 +extern syscall_handler_t sys_setgid;
25395 +extern syscall_handler_t sys_setfsuid;
25396 +extern syscall_handler_t sys_setfsgid;
25397 +extern syscall_handler_t sys_pivot_root;
25398 +extern syscall_handler_t sys_mincore;
25399 +extern syscall_handler_t sys_madvise;
25400 +extern syscall_handler_t sys_fcntl64;
25401 +extern syscall_handler_t sys_getdents64;
25402 +extern syscall_handler_t sys_gettid;
25403 +extern syscall_handler_t sys_readahead;
25404 +extern syscall_handler_t sys_tkill;
25405 +extern syscall_handler_t sys_setxattr;
25406 +extern syscall_handler_t sys_lsetxattr;
25407 +extern syscall_handler_t sys_fsetxattr;
25408 +extern syscall_handler_t sys_getxattr;
25409 +extern syscall_handler_t sys_lgetxattr;
25410 +extern syscall_handler_t sys_fgetxattr;
25411 +extern syscall_handler_t sys_listxattr;
25412 +extern syscall_handler_t sys_llistxattr;
25413 +extern syscall_handler_t sys_flistxattr;
25414 +extern syscall_handler_t sys_removexattr;
25415 +extern syscall_handler_t sys_lremovexattr;
25416 +extern syscall_handler_t sys_fremovexattr;
25417 +
25418 +extern syscall_handler_t um_mount;
25419 +extern syscall_handler_t um_time;
25420 +extern syscall_handler_t um_stime;
25421 +
25422 +#define LAST_GENERIC_SYSCALL __NR_sched_getaffinity
25423 +
25424 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
25425 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
25426 +#else
25427 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
25428 +#endif
25429 +
25430 +syscall_handler_t *sys_call_table[] = {
25431 +       [ 0 ] = sys_ni_syscall,
25432 +       [ __NR_exit ] = sys_exit,
25433 +       [ __NR_fork ] = sys_fork,
25434 +       [ __NR_read ] = (syscall_handler_t *) sys_read,
25435 +       [ __NR_write ] = (syscall_handler_t *) sys_write,
25436 +
25437 +       /* These three are declared differently in asm/unistd.h */
25438 +       [ __NR_open ] = (syscall_handler_t *) sys_open,
25439 +       [ __NR_close ] = (syscall_handler_t *) sys_close,
25440 +       [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
25441 +       [ __NR_creat ] = sys_creat,
25442 +       [ __NR_link ] = sys_link,
25443 +       [ __NR_unlink ] = sys_unlink,
25444 +
25445 +       /* declared differently in kern_util.h */
25446 +       [ __NR_execve ] = (syscall_handler_t *) sys_execve,
25447 +       [ __NR_chdir ] = sys_chdir,
25448 +       [ __NR_time ] = um_time,
25449 +       [ __NR_mknod ] = sys_mknod,
25450 +       [ __NR_chmod ] = sys_chmod,
25451 +       [ __NR_lchown ] = sys_lchown16,
25452 +       [ __NR_break ] = sys_ni_syscall,
25453 +       [ __NR_oldstat ] = sys_stat,
25454 +       [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
25455 +       [ __NR_getpid ] = sys_getpid,
25456 +       [ __NR_mount ] = um_mount,
25457 +       [ __NR_umount ] = sys_oldumount,
25458 +       [ __NR_setuid ] = sys_setuid16,
25459 +       [ __NR_getuid ] = sys_getuid16,
25460 +       [ __NR_stime ] = um_stime,
25461 +       [ __NR_ptrace ] = sys_ptrace,
25462 +       [ __NR_alarm ] = sys_alarm,
25463 +       [ __NR_oldfstat ] = sys_fstat,
25464 +       [ __NR_pause ] = sys_pause,
25465 +       [ __NR_utime ] = sys_utime,
25466 +       [ __NR_stty ] = sys_ni_syscall,
25467 +       [ __NR_gtty ] = sys_ni_syscall,
25468 +       [ __NR_access ] = sys_access,
25469 +       [ __NR_nice ] = sys_nice,
25470 +       [ __NR_ftime ] = sys_ni_syscall,
25471 +       [ __NR_sync ] = sys_sync,
25472 +       [ __NR_kill ] = sys_kill,
25473 +       [ __NR_rename ] = sys_rename,
25474 +       [ __NR_mkdir ] = sys_mkdir,
25475 +       [ __NR_rmdir ] = sys_rmdir,
25476 +
25477 +       /* Declared differently in asm/unistd.h */
25478 +       [ __NR_dup ] = (syscall_handler_t *) sys_dup,
25479 +       [ __NR_pipe ] = sys_pipe,
25480 +       [ __NR_times ] = sys_times,
25481 +       [ __NR_prof ] = sys_ni_syscall,
25482 +       [ __NR_brk ] = sys_brk,
25483 +       [ __NR_setgid ] = sys_setgid16,
25484 +       [ __NR_getgid ] = sys_getgid16,
25485 +       [ __NR_signal ] = sys_signal,
25486 +       [ __NR_geteuid ] = sys_geteuid16,
25487 +       [ __NR_getegid ] = sys_getegid16,
25488 +       [ __NR_acct ] = sys_acct,
25489 +       [ __NR_umount2 ] = sys_umount,
25490 +       [ __NR_lock ] = sys_ni_syscall,
25491 +       [ __NR_ioctl ] = sys_ioctl,
25492 +       [ __NR_fcntl ] = sys_fcntl,
25493 +       [ __NR_mpx ] = sys_ni_syscall,
25494 +       [ __NR_setpgid ] = sys_setpgid,
25495 +       [ __NR_ulimit ] = sys_ni_syscall,
25496 +       [ __NR_oldolduname ] = sys_olduname,
25497 +       [ __NR_umask ] = sys_umask,
25498 +       [ __NR_chroot ] = sys_chroot,
25499 +       [ __NR_ustat ] = sys_ustat,
25500 +       [ __NR_dup2 ] = sys_dup2,
25501 +       [ __NR_getppid ] = sys_getppid,
25502 +       [ __NR_getpgrp ] = sys_getpgrp,
25503 +       [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
25504 +       [ __NR_sigaction ] = sys_sigaction,
25505 +       [ __NR_sgetmask ] = sys_sgetmask,
25506 +       [ __NR_ssetmask ] = sys_ssetmask,
25507 +       [ __NR_setreuid ] = sys_setreuid16,
25508 +       [ __NR_setregid ] = sys_setregid16,
25509 +       [ __NR_sigsuspend ] = sys_sigsuspend,
25510 +       [ __NR_sigpending ] = sys_sigpending,
25511 +       [ __NR_sethostname ] = sys_sethostname,
25512 +       [ __NR_setrlimit ] = sys_setrlimit,
25513 +       [ __NR_getrlimit ] = sys_old_getrlimit,
25514 +       [ __NR_getrusage ] = sys_getrusage,
25515 +       [ __NR_gettimeofday ] = sys_gettimeofday,
25516 +       [ __NR_settimeofday ] = sys_settimeofday,
25517 +       [ __NR_getgroups ] = sys_getgroups16,
25518 +       [ __NR_setgroups ] = sys_setgroups16,
25519 +       [ __NR_symlink ] = sys_symlink,
25520 +       [ __NR_oldlstat ] = sys_lstat,
25521 +       [ __NR_readlink ] = sys_readlink,
25522 +       [ __NR_uselib ] = sys_uselib,
25523 +       [ __NR_swapon ] = sys_swapon,
25524 +       [ __NR_reboot ] = sys_reboot,
25525 +       [ __NR_readdir ] = old_readdir,
25526 +       [ __NR_munmap ] = sys_munmap,
25527 +       [ __NR_truncate ] = sys_truncate,
25528 +       [ __NR_ftruncate ] = sys_ftruncate,
25529 +       [ __NR_fchmod ] = sys_fchmod,
25530 +       [ __NR_fchown ] = sys_fchown16,
25531 +       [ __NR_getpriority ] = sys_getpriority,
25532 +       [ __NR_setpriority ] = sys_setpriority,
25533 +       [ __NR_profil ] = sys_ni_syscall,
25534 +       [ __NR_statfs ] = sys_statfs,
25535 +       [ __NR_fstatfs ] = sys_fstatfs,
25536 +       [ __NR_ioperm ] = sys_ni_syscall,
25537 +       [ __NR_socketcall ] = sys_socketcall,
25538 +       [ __NR_syslog ] = sys_syslog,
25539 +       [ __NR_setitimer ] = sys_setitimer,
25540 +       [ __NR_getitimer ] = sys_getitimer,
25541 +       [ __NR_stat ] = sys_newstat,
25542 +       [ __NR_lstat ] = sys_newlstat,
25543 +       [ __NR_fstat ] = sys_newfstat,
25544 +       [ __NR_olduname ] = sys_uname,
25545 +       [ __NR_iopl ] = sys_ni_syscall,
25546 +       [ __NR_vhangup ] = sys_vhangup,
25547 +       [ __NR_idle ] = sys_ni_syscall,
25548 +       [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
25549 +       [ __NR_swapoff ] = sys_swapoff,
25550 +       [ __NR_sysinfo ] = sys_sysinfo,
25551 +       [ __NR_ipc ] = sys_ipc,
25552 +       [ __NR_fsync ] = sys_fsync,
25553 +       [ __NR_sigreturn ] = sys_sigreturn,
25554 +       [ __NR_clone ] = sys_clone,
25555 +       [ __NR_setdomainname ] = sys_setdomainname,
25556 +       [ __NR_uname ] = sys_newuname,
25557 +       [ __NR_adjtimex ] = sys_adjtimex,
25558 +       [ __NR_mprotect ] = sys_mprotect,
25559 +       [ __NR_sigprocmask ] = sys_sigprocmask,
25560 +       [ __NR_create_module ] = sys_create_module,
25561 +       [ __NR_init_module ] = sys_init_module,
25562 +       [ __NR_delete_module ] = sys_delete_module,
25563 +       [ __NR_get_kernel_syms ] = sys_get_kernel_syms,
25564 +       [ __NR_quotactl ] = sys_quotactl,
25565 +       [ __NR_getpgid ] = sys_getpgid,
25566 +       [ __NR_fchdir ] = sys_fchdir,
25567 +       [ __NR_bdflush ] = sys_bdflush,
25568 +       [ __NR_sysfs ] = sys_sysfs,
25569 +       [ __NR_personality ] = sys_personality,
25570 +       [ __NR_afs_syscall ] = sys_ni_syscall,
25571 +       [ __NR_setfsuid ] = sys_setfsuid16,
25572 +       [ __NR_setfsgid ] = sys_setfsgid16,
25573 +       [ __NR__llseek ] = sys_llseek,
25574 +       [ __NR_getdents ] = sys_getdents,
25575 +       [ __NR__newselect ] = (syscall_handler_t *) sys_select,
25576 +       [ __NR_flock ] = sys_flock,
25577 +       [ __NR_msync ] = sys_msync,
25578 +       [ __NR_readv ] = sys_readv,
25579 +       [ __NR_writev ] = sys_writev,
25580 +       [ __NR_getsid ] = sys_getsid,
25581 +       [ __NR_fdatasync ] = sys_fdatasync,
25582 +       [ __NR__sysctl ] = sys_sysctl,
25583 +       [ __NR_mlock ] = sys_mlock,
25584 +       [ __NR_munlock ] = sys_munlock,
25585 +       [ __NR_mlockall ] = sys_mlockall,
25586 +       [ __NR_munlockall ] = sys_munlockall,
25587 +       [ __NR_sched_setparam ] = sys_sched_setparam,
25588 +       [ __NR_sched_getparam ] = sys_sched_getparam,
25589 +       [ __NR_sched_setscheduler ] = sys_sched_setscheduler,
25590 +       [ __NR_sched_getscheduler ] = sys_sched_getscheduler,
25591 +       [ __NR_sched_yield ] = (syscall_handler_t *) yield,
25592 +       [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max,
25593 +       [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min,
25594 +       [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval,
25595 +       [ __NR_nanosleep ] = sys_nanosleep,
25596 +       [ __NR_mremap ] = sys_mremap,
25597 +       [ __NR_setresuid ] = sys_setresuid16,
25598 +       [ __NR_getresuid ] = sys_getresuid16,
25599 +       [ __NR_vm86 ] = sys_ni_syscall,
25600 +       [ __NR_query_module ] = sys_query_module,
25601 +       [ __NR_poll ] = sys_poll,
25602 +       [ __NR_nfsservctl ] = sys_nfsservctl,
25603 +       [ __NR_setresgid ] = sys_setresgid16,
25604 +       [ __NR_getresgid ] = sys_getresgid16,
25605 +       [ __NR_prctl ] = sys_prctl,
25606 +       [ __NR_rt_sigreturn ] = sys_rt_sigreturn,
25607 +       [ __NR_rt_sigaction ] = sys_rt_sigaction,
25608 +       [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask,
25609 +       [ __NR_rt_sigpending ] = sys_rt_sigpending,
25610 +       [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait,
25611 +       [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo,
25612 +       [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend,
25613 +       [ __NR_pread ] = sys_pread,
25614 +       [ __NR_pwrite ] = sys_pwrite,
25615 +       [ __NR_chown ] = sys_chown16,
25616 +       [ __NR_getcwd ] = sys_getcwd,
25617 +       [ __NR_capget ] = sys_capget,
25618 +       [ __NR_capset ] = sys_capset,
25619 +       [ __NR_sigaltstack ] = sys_sigaltstack,
25620 +       [ __NR_sendfile ] = sys_sendfile,
25621 +       [ __NR_getpmsg ] = sys_ni_syscall,
25622 +       [ __NR_putpmsg ] = sys_ni_syscall,
25623 +       [ __NR_vfork ] = sys_vfork,
25624 +       [ __NR_ugetrlimit ] = sys_getrlimit,
25625 +       [ __NR_mmap2 ] = sys_mmap2,
25626 +       [ __NR_truncate64 ] = sys_truncate64,
25627 +       [ __NR_ftruncate64 ] = sys_ftruncate64,
25628 +       [ __NR_stat64 ] = sys_stat64,
25629 +       [ __NR_lstat64 ] = sys_lstat64,
25630 +       [ __NR_fstat64 ] = sys_fstat64,
25631 +       [ __NR_fcntl64 ] = sys_fcntl64,
25632 +       [ __NR_getdents64 ] = sys_getdents64,
25633 +        [ __NR_security ] = sys_ni_syscall,
25634 +       [ __NR_gettid ] = sys_gettid,
25635 +       [ __NR_readahead ] = sys_readahead,
25636 +       [ __NR_setxattr ] = sys_setxattr,
25637 +       [ __NR_lsetxattr ] = sys_lsetxattr,
25638 +       [ __NR_fsetxattr ] = sys_fsetxattr,
25639 +       [ __NR_getxattr ] = sys_getxattr,
25640 +       [ __NR_lgetxattr ] = sys_lgetxattr,
25641 +       [ __NR_fgetxattr ] = sys_fgetxattr,
25642 +       [ __NR_listxattr ] = sys_listxattr,
25643 +       [ __NR_llistxattr ] = sys_llistxattr,
25644 +       [ __NR_flistxattr ] = sys_flistxattr,
25645 +       [ __NR_removexattr ] = sys_removexattr,
25646 +       [ __NR_lremovexattr ] = sys_lremovexattr,
25647 +       [ __NR_fremovexattr ] = sys_fremovexattr,
25648 +       [ __NR_tkill ] = sys_tkill,
25649 +       [ __NR_sendfile64 ] = sys_ni_syscall,
25650 +       [ __NR_futex ] = sys_ni_syscall,
25651 +       [ __NR_sched_setaffinity ] = sys_ni_syscall,
25652 +       [ __NR_sched_getaffinity ] = sys_ni_syscall,
25653 +
25654 +       ARCH_SYSCALLS
25655 +       [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
25656 +               (syscall_handler_t *) sys_ni_syscall
25657 +};
25658 +
25659 +/*
25660 + * Overrides for Emacs so that we follow Linus's tabbing style.
25661 + * Emacs will notice this stuff at the end of the file and automatically
25662 + * adjust the settings for this buffer only.  This must remain at the end
25663 + * of the file.
25664 + * ---------------------------------------------------------------------------
25665 + * Local variables:
25666 + * c-file-style: "linux"
25667 + * End:
25668 + */
25669 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_user.c um/arch/um/kernel/syscall_user.c
25670 --- orig/arch/um/kernel/syscall_user.c  1969-12-31 19:00:00.000000000 -0500
25671 +++ um/arch/um/kernel/syscall_user.c    2002-10-23 21:08:04.000000000 -0400
25672 @@ -0,0 +1,48 @@
25673 +/* 
25674 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25675 + * Licensed under the GPL
25676 + */
25677 +
25678 +#include <stdlib.h>
25679 +#include <sys/time.h>
25680 +#include "kern_util.h"
25681 +#include "syscall_user.h"
25682 +
25683 +struct {
25684 +       int syscall;
25685 +       int pid;
25686 +       int result;
25687 +       struct timeval start;
25688 +       struct timeval end;
25689 +} syscall_record[1024];
25690 +
25691 +int record_syscall_start(int syscall)
25692 +{
25693 +       int max, index;
25694 +       
25695 +       max = sizeof(syscall_record)/sizeof(syscall_record[0]);
25696 +       index = next_syscall_index(max);
25697 +
25698 +       syscall_record[index].syscall = syscall;
25699 +       syscall_record[index].pid = current_pid();
25700 +       syscall_record[index].result = 0xdeadbeef;
25701 +       gettimeofday(&syscall_record[index].start, NULL);
25702 +       return(index);
25703 +}
25704 +
25705 +void record_syscall_end(int index, int result)
25706 +{
25707 +       syscall_record[index].result = result;
25708 +       gettimeofday(&syscall_record[index].end, NULL);
25709 +}
25710 +
25711 +/*
25712 + * Overrides for Emacs so that we follow Linus's tabbing style.
25713 + * Emacs will notice this stuff at the end of the file and automatically
25714 + * adjust the settings for this buffer only.  This must remain at the end
25715 + * of the file.
25716 + * ---------------------------------------------------------------------------
25717 + * Local variables:
25718 + * c-file-style: "linux"
25719 + * End:
25720 + */
25721 diff -Naur -X ../exclude-files orig/arch/um/kernel/sysrq.c um/arch/um/kernel/sysrq.c
25722 --- orig/arch/um/kernel/sysrq.c 1969-12-31 19:00:00.000000000 -0500
25723 +++ um/arch/um/kernel/sysrq.c   2002-10-23 21:08:04.000000000 -0400
25724 @@ -0,0 +1,98 @@
25725 +/* 
25726 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
25727 + * Licensed under the GPL
25728 + */
25729 +
25730 +#include "linux/sched.h"
25731 +#include "linux/kernel.h"
25732 +#include "linux/module.h"
25733 +#include "asm/page.h"
25734 +#include "asm/processor.h"
25735 +#include "sysrq.h"
25736 +#include "user_util.h"
25737 +
25738 + /*
25739 +  * If the address is either in the .text section of the
25740 +  * kernel, or in the vmalloc'ed module regions, it *may* 
25741 +  * be the address of a calling routine
25742 +  */
25743
25744 +#ifdef CONFIG_MODULES
25745 +
25746 +extern struct module *module_list;
25747 +extern struct module kernel_module;
25748 +
25749 +static inline int kernel_text_address(unsigned long addr)
25750 +{
25751 +       int retval = 0;
25752 +       struct module *mod;
25753 +
25754 +       if (addr >= (unsigned long) &_stext &&
25755 +           addr <= (unsigned long) &_etext)
25756 +               return 1;
25757 +
25758 +       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
25759 +               /* mod_bound tests for addr being inside the vmalloc'ed
25760 +                * module area. Of course it'd be better to test only
25761 +                * for the .text subset... */
25762 +               if (mod_bound(addr, 0, mod)) {
25763 +                       retval = 1;
25764 +                       break;
25765 +               }
25766 +       }
25767 +
25768 +       return retval;
25769 +}
25770 +
25771 +#else
25772 +
25773 +static inline int kernel_text_address(unsigned long addr)
25774 +{
25775 +       return (addr >= (unsigned long) &_stext &&
25776 +               addr <= (unsigned long) &_etext);
25777 +}
25778 +
25779 +#endif
25780 +
25781 +void show_trace(unsigned long * stack)
25782 +{
25783 +        int i;
25784 +        unsigned long addr;
25785 +
25786 +        if (!stack)
25787 +                stack = (unsigned long*) &stack;
25788 +
25789 +        printk("Call Trace: ");
25790 +        i = 1;
25791 +        while (((long) stack & (THREAD_SIZE-1)) != 0) {
25792 +                addr = *stack++;
25793 +               if (kernel_text_address(addr)) {
25794 +                       if (i && ((i % 6) == 0))
25795 +                               printk("\n   ");
25796 +                       printk("[<%08lx>] ", addr);
25797 +                       i++;
25798 +                }
25799 +        }
25800 +        printk("\n");
25801 +}
25802 +
25803 +void show_trace_task(struct task_struct *tsk)
25804 +{
25805 +       unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
25806 +
25807 +       /* User space on another CPU? */
25808 +       if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
25809 +               return;
25810 +       show_trace((unsigned long *)esp);
25811 +}
25812 +
25813 +/*
25814 + * Overrides for Emacs so that we follow Linus's tabbing style.
25815 + * Emacs will notice this stuff at the end of the file and automatically
25816 + * adjust the settings for this buffer only.  This must remain at the end
25817 + * of the file.
25818 + * ---------------------------------------------------------------------------
25819 + * Local variables:
25820 + * c-file-style: "linux"
25821 + * End:
25822 + */
25823 diff -Naur -X ../exclude-files orig/arch/um/kernel/tempfile.c um/arch/um/kernel/tempfile.c
25824 --- orig/arch/um/kernel/tempfile.c      1969-12-31 19:00:00.000000000 -0500
25825 +++ um/arch/um/kernel/tempfile.c        2003-01-17 23:16:19.000000000 -0500
25826 @@ -0,0 +1,80 @@
25827 +/* 
25828 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25829 + * Licensed under the GPL
25830 + */
25831 +
25832 +#include <stdio.h>
25833 +#include <stdlib.h>
25834 +#include <unistd.h>
25835 +#include <string.h>
25836 +#include <errno.h>
25837 +#include <sys/param.h>
25838 +#include "init.h"
25839 +
25840 +/* Modified from create_mem_file and start_debugger */
25841 +static char *tempdir = NULL;
25842 +
25843 +static void __init find_tempdir(void)
25844 +{
25845 +       char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
25846 +       int i;
25847 +       char *dir = NULL;
25848 +
25849 +       if(tempdir != NULL) return;     /* We've already been called */
25850 +       for(i = 0; dirs[i]; i++){
25851 +               dir = getenv(dirs[i]);
25852 +               if((dir != NULL) && (*dir != '\0'))
25853 +                       break;
25854 +       }
25855 +       if((dir == NULL) || (*dir == '\0')) 
25856 +               dir = "/tmp";
25857 +
25858 +       tempdir = malloc(strlen(dir) + 2);
25859 +       if(tempdir == NULL){
25860 +               fprintf(stderr, "Failed to malloc tempdir, "
25861 +                       "errno = %d\n", errno);
25862 +               return;
25863 +       }
25864 +       strcpy(tempdir, dir);
25865 +       strcat(tempdir, "/");
25866 +}
25867 +
25868 +int make_tempfile(const char *template, char **out_tempname, int do_unlink)
25869 +{
25870 +       char tempname[MAXPATHLEN];
25871 +       int fd;
25872 +
25873 +       find_tempdir();
25874 +       if (*template != '/')
25875 +               strcpy(tempname, tempdir);
25876 +       else
25877 +               *tempname = 0;
25878 +       strcat(tempname, template);
25879 +       if((fd = mkstemp(tempname)) < 0){
25880 +               fprintf(stderr, "open - cannot create %s: %s\n", tempname, 
25881 +                       strerror(errno));
25882 +               return -1;
25883 +       }
25884 +       if(do_unlink && (unlink(tempname) < 0)){
25885 +               perror("unlink");
25886 +               return -1;
25887 +       }
25888 +       if(out_tempname){
25889 +               if((*out_tempname = strdup(tempname)) == NULL){
25890 +                       perror("strdup");
25891 +                       return -1;
25892 +               }
25893 +       }
25894 +       return(fd);
25895 +}
25896 +
25897 +/*
25898 + * Overrides for Emacs so that we follow Linus's tabbing style.
25899 + * Emacs will notice this stuff at the end of the file and automatically
25900 + * adjust the settings for this buffer only.  This must remain at the end
25901 + * of the file.
25902 + * ---------------------------------------------------------------------------
25903 + * Local variables:
25904 + * c-file-style: "linux"
25905 + * End:
25906 + */
25907 diff -Naur -X ../exclude-files orig/arch/um/kernel/time.c um/arch/um/kernel/time.c
25908 --- orig/arch/um/kernel/time.c  1969-12-31 19:00:00.000000000 -0500
25909 +++ um/arch/um/kernel/time.c    2003-04-23 20:45:19.000000000 -0400
25910 @@ -0,0 +1,127 @@
25911 +/* 
25912 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
25913 + * Licensed under the GPL
25914 + */
25915 +
25916 +#include <stdio.h>
25917 +#include <unistd.h>
25918 +#include <time.h>
25919 +#include <sys/time.h>
25920 +#include <signal.h>
25921 +#include <errno.h>
25922 +#include "user_util.h"
25923 +#include "kern_util.h"
25924 +#include "user.h"
25925 +#include "process.h"
25926 +#include "signal_user.h"
25927 +#include "time_user.h"
25928 +
25929 +extern struct timeval xtime;
25930 +
25931 +struct timeval local_offset = { 0, 0 };
25932 +
25933 +void timer(void)
25934 +{
25935 +       gettimeofday(&xtime, NULL);
25936 +       timeradd(&xtime, &local_offset, &xtime);
25937 +}
25938 +
25939 +void set_interval(int timer_type)
25940 +{
25941 +       int usec = 1000000/hz();
25942 +       struct itimerval interval = ((struct itimerval) { { 0, usec },
25943 +                                                         { 0, usec } });
25944 +
25945 +       if(setitimer(timer_type, &interval, NULL) == -1)
25946 +               panic("setitimer failed - errno = %d\n", errno);
25947 +}
25948 +
25949 +void enable_timer(void)
25950 +{
25951 +       int usec = 1000000/hz();
25952 +       struct itimerval enable = ((struct itimerval) { { 0, usec },
25953 +                                                       { 0, usec }});
25954 +       if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
25955 +               printk("enable_timer - setitimer failed, errno = %d\n",
25956 +                      errno);
25957 +}
25958 +
25959 +void switch_timers(int to_real)
25960 +{
25961 +       struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
25962 +       struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
25963 +                                                       { 0, 1000000/hz() }});
25964 +       int old, new;
25965 +
25966 +       if(to_real){
25967 +               old = ITIMER_VIRTUAL;
25968 +               new = ITIMER_REAL;
25969 +       }
25970 +       else {
25971 +               old = ITIMER_REAL;
25972 +               new = ITIMER_VIRTUAL;
25973 +       }
25974 +
25975 +       if((setitimer(old, &disable, NULL) < 0) ||
25976 +          (setitimer(new, &enable, NULL)))
25977 +               printk("switch_timers - setitimer failed, errno = %d\n",
25978 +                      errno);
25979 +}
25980 +
25981 +void idle_timer(void)
25982 +{
25983 +       if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
25984 +               panic("Couldn't unset SIGVTALRM handler");
25985 +       
25986 +       set_handler(SIGALRM, (__sighandler_t) alarm_handler, 
25987 +                   SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
25988 +       set_interval(ITIMER_REAL);
25989 +}
25990 +
25991 +void time_init(void)
25992 +{
25993 +       if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
25994 +               panic("Couldn't set SIGVTALRM handler");
25995 +       set_interval(ITIMER_VIRTUAL);
25996 +}
25997 +
25998 +void do_gettimeofday(struct timeval *tv)
25999 +{
26000 +       unsigned long flags;
26001 +
26002 +       flags = time_lock();
26003 +       gettimeofday(tv, NULL);
26004 +       timeradd(tv, &local_offset, tv);
26005 +       time_unlock(flags);
26006 +}
26007 +
26008 +void do_settimeofday(struct timeval *tv)
26009 +{
26010 +       struct timeval now;
26011 +       unsigned long flags;
26012 +
26013 +       flags = time_lock();
26014 +       gettimeofday(&now, NULL);
26015 +       timersub(tv, &now, &local_offset);
26016 +       time_unlock(flags);
26017 +}
26018 +
26019 +void idle_sleep(int secs)
26020 +{
26021 +       struct timespec ts;
26022 +
26023 +       ts.tv_sec = secs;
26024 +       ts.tv_nsec = 0;
26025 +       nanosleep(&ts, NULL);
26026 +}
26027 +
26028 +/*
26029 + * Overrides for Emacs so that we follow Linus's tabbing style.
26030 + * Emacs will notice this stuff at the end of the file and automatically
26031 + * adjust the settings for this buffer only.  This must remain at the end
26032 + * of the file.
26033 + * ---------------------------------------------------------------------------
26034 + * Local variables:
26035 + * c-file-style: "linux"
26036 + * End:
26037 + */
26038 diff -Naur -X ../exclude-files orig/arch/um/kernel/time_kern.c um/arch/um/kernel/time_kern.c
26039 --- orig/arch/um/kernel/time_kern.c     1969-12-31 19:00:00.000000000 -0500
26040 +++ um/arch/um/kernel/time_kern.c       2003-04-23 22:19:08.000000000 -0400
26041 @@ -0,0 +1,172 @@
26042 +/* 
26043 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26044 + * Licensed under the GPL
26045 + */
26046 +
26047 +#include "linux/kernel.h"
26048 +#include "linux/unistd.h"
26049 +#include "linux/stddef.h"
26050 +#include "linux/spinlock.h"
26051 +#include "linux/sched.h"
26052 +#include "linux/interrupt.h"
26053 +#include "linux/init.h"
26054 +#include "linux/delay.h"
26055 +#include "asm/irq.h"
26056 +#include "asm/param.h"
26057 +#include "asm/current.h"
26058 +#include "kern_util.h"
26059 +#include "user_util.h"
26060 +#include "time_user.h"
26061 +#include "mode.h"
26062 +
26063 +extern rwlock_t xtime_lock;
26064 +
26065 +int hz(void)
26066 +{
26067 +       return(HZ);
26068 +}
26069 +
26070 +/* Changed at early boot */
26071 +int timer_irq_inited = 0;
26072 +
26073 +/* missed_ticks will be modified after kernel memory has been 
26074 + * write-protected, so this puts it in a section which will be left 
26075 + * write-enabled.
26076 + */
26077 +int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
26078 +
26079 +void timer_irq(union uml_pt_regs *regs)
26080 +{
26081 +       int cpu = current->processor, ticks = missed_ticks[cpu];
26082 +
26083 +        if(!timer_irq_inited) return;
26084 +       missed_ticks[cpu] = 0;
26085 +       while(ticks--) do_IRQ(TIMER_IRQ, regs);
26086 +}
26087 +
26088 +void boot_timer_handler(int sig)
26089 +{
26090 +       struct pt_regs regs;
26091 +
26092 +       CHOOSE_MODE((void) 
26093 +                   (UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
26094 +                   (void) (regs.regs.skas.is_user = 0));
26095 +       do_timer(&regs);
26096 +}
26097 +
26098 +void um_timer(int irq, void *dev, struct pt_regs *regs)
26099 +{
26100 +       do_timer(regs);
26101 +       write_lock(&xtime_lock);
26102 +       vxtime_lock();
26103 +       timer();
26104 +       vxtime_unlock();
26105 +       write_unlock(&xtime_lock);
26106 +}
26107 +
26108 +long um_time(int * tloc)
26109 +{
26110 +       struct timeval now;
26111 +
26112 +       do_gettimeofday(&now);
26113 +       if (tloc) {
26114 +               if (put_user(now.tv_sec,tloc))
26115 +                       now.tv_sec = -EFAULT;
26116 +       }
26117 +       return now.tv_sec;
26118 +}
26119 +
26120 +long um_stime(int * tptr)
26121 +{
26122 +       int value;
26123 +       struct timeval new;
26124 +
26125 +       if (get_user(value, tptr))
26126 +                return -EFAULT;
26127 +       new.tv_sec = value;
26128 +       new.tv_usec = 0;
26129 +       do_settimeofday(&new);
26130 +       return 0;
26131 +}
26132 +
26133 +/* XXX Needs to be moved under sys-i386 */
26134 +void __delay(um_udelay_t time)
26135 +{
26136 +       /* Stolen from the i386 __loop_delay */
26137 +       int d0;
26138 +       __asm__ __volatile__(
26139 +               "\tjmp 1f\n"
26140 +               ".align 16\n"
26141 +               "1:\tjmp 2f\n"
26142 +               ".align 16\n"
26143 +               "2:\tdecl %0\n\tjns 2b"
26144 +               :"=&a" (d0)
26145 +               :"0" (time));
26146 +}
26147 +
26148 +void __udelay(um_udelay_t usecs)
26149 +{
26150 +       int i, n;
26151 +
26152 +       n = (loops_per_jiffy * HZ * usecs) / 1000000;
26153 +       for(i=0;i<n;i++) ;
26154 +}
26155 +
26156 +void __const_udelay(um_udelay_t usecs)
26157 +{
26158 +       int i, n;
26159 +
26160 +       n = (loops_per_jiffy * HZ * usecs) / 1000000;
26161 +       for(i=0;i<n;i++) ;
26162 +}
26163 +
26164 +void timer_handler(int sig, union uml_pt_regs *regs)
26165 +{
26166 +#ifdef CONFIG_SMP
26167 +       update_process_times(user_context(UPT_SP(regs)));
26168 +#endif
26169 +       if(current->processor == 0)
26170 +               timer_irq(regs);
26171 +}
26172 +
26173 +static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
26174 +
26175 +unsigned long time_lock(void)
26176 +{
26177 +       unsigned long flags;
26178 +
26179 +       spin_lock_irqsave(&timer_spinlock, flags);
26180 +       return(flags);
26181 +}
26182 +
26183 +void time_unlock(unsigned long flags)
26184 +{
26185 +       spin_unlock_irqrestore(&timer_spinlock, flags);
26186 +}
26187 +
26188 +int __init timer_init(void)
26189 +{
26190 +       int err;
26191 +
26192 +       CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
26193 +       if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", 
26194 +                             NULL)) != 0)
26195 +               printk(KERN_ERR "timer_init : request_irq failed - "
26196 +                      "errno = %d\n", -err);
26197 +       timer_irq_inited = 1;
26198 +       return(0);
26199 +}
26200 +
26201 +__initcall(timer_init);
26202 +
26203 +
26204 +/*
26205 + * Overrides for Emacs so that we follow Linus's tabbing style.
26206 + * Emacs will notice this stuff at the end of the file and automatically
26207 + * adjust the settings for this buffer only.  This must remain at the end
26208 + * of the file.
26209 + * ---------------------------------------------------------------------------
26210 + * Local variables:
26211 + * c-file-style: "linux"
26212 + * End:
26213 + */
26214 diff -Naur -X ../exclude-files orig/arch/um/kernel/tlb.c um/arch/um/kernel/tlb.c
26215 --- orig/arch/um/kernel/tlb.c   1969-12-31 19:00:00.000000000 -0500
26216 +++ um/arch/um/kernel/tlb.c     2002-10-23 22:15:51.000000000 -0400
26217 @@ -0,0 +1,80 @@
26218 +/* 
26219 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26220 + * Licensed under the GPL
26221 + */
26222 +
26223 +#include "linux/mm.h"
26224 +#include "asm/page.h"
26225 +#include "asm/pgalloc.h"
26226 +#include "choose-mode.h"
26227 +#include "mode_kern.h"
26228 +
26229 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
26230 +{
26231 +       address &= PAGE_MASK;
26232 +       flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE);
26233 +}
26234 +
26235 +void flush_tlb_all(void)
26236 +{
26237 +       flush_tlb_mm(current->mm);
26238 +}
26239 +
26240 +void flush_tlb_kernel_vm(void)
26241 +{
26242 +       CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
26243 +}
26244 +
26245 +void __flush_tlb_one(unsigned long addr)
26246 +{
26247 +       CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
26248 +}
26249 +
26250 +void flush_tlb_range(struct mm_struct *mm, unsigned long start, 
26251 +                    unsigned long end)
26252 +{
26253 +       CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start, 
26254 +                        end);
26255 +}
26256 +
26257 +void flush_tlb_mm(struct mm_struct *mm)
26258 +{
26259 +       CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
26260 +}
26261 +
26262 +void force_flush_all(void)
26263 +{
26264 +       CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
26265 +}
26266 +
26267 +
26268 +pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
26269 +{
26270 +       return(pgd_offset(mm, address));
26271 +}
26272 +
26273 +pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
26274 +{
26275 +       return(pmd_offset(pgd, address));
26276 +}
26277 +
26278 +pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
26279 +{
26280 +       return(pte_offset(pmd, address));
26281 +}
26282 +
26283 +pte_t *addr_pte(struct task_struct *task, unsigned long addr)
26284 +{
26285 +       return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr));
26286 +}
26287 +
26288 +/*
26289 + * Overrides for Emacs so that we follow Linus's tabbing style.
26290 + * Emacs will notice this stuff at the end of the file and automatically
26291 + * adjust the settings for this buffer only.  This must remain at the end
26292 + * of the file.
26293 + * ---------------------------------------------------------------------------
26294 + * Local variables:
26295 + * c-file-style: "linux"
26296 + * End:
26297 + */
26298 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_kern.c um/arch/um/kernel/trap_kern.c
26299 --- orig/arch/um/kernel/trap_kern.c     1969-12-31 19:00:00.000000000 -0500
26300 +++ um/arch/um/kernel/trap_kern.c       2003-03-26 13:26:00.000000000 -0500
26301 @@ -0,0 +1,192 @@
26302 +/* 
26303 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
26304 + * Licensed under the GPL
26305 + */
26306 +
26307 +#include "linux/kernel.h"
26308 +#include "linux/sched.h"
26309 +#include "linux/mm.h"
26310 +#include "linux/spinlock.h"
26311 +#include "linux/config.h"
26312 +#include "linux/init.h"
26313 +#include "asm/semaphore.h"
26314 +#include "asm/pgtable.h"
26315 +#include "asm/pgalloc.h"
26316 +#include "asm/a.out.h"
26317 +#include "asm/current.h"
26318 +#include "asm/irq.h"
26319 +#include "user_util.h"
26320 +#include "kern_util.h"
26321 +#include "kern.h"
26322 +#include "chan_kern.h"
26323 +#include "mconsole_kern.h"
26324 +#include "2_5compat.h"
26325 +
26326 +unsigned long handle_page_fault(unsigned long address, unsigned long ip, 
26327 +                               int is_write, int is_user, int *code_out)
26328 +{
26329 +       struct mm_struct *mm = current->mm;
26330 +       struct vm_area_struct *vma;
26331 +       pgd_t *pgd;
26332 +       pmd_t *pmd;
26333 +       pte_t *pte;
26334 +       unsigned long page;
26335 +       int handled = 0;
26336 +
26337 +       *code_out = SEGV_MAPERR;
26338 +       down_read(&mm->mmap_sem);
26339 +       vma = find_vma(mm, address);
26340 +       if(!vma) 
26341 +               goto out;
26342 +       else if(vma->vm_start <= address) 
26343 +               goto good_area;
26344 +       else if(!(vma->vm_flags & VM_GROWSDOWN)) 
26345 +               goto out;
26346 +       else if(expand_stack(vma, address)) 
26347 +               goto out;
26348 +
26349 + good_area:
26350 +       *code_out = SEGV_ACCERR;
26351 +       if(is_write && !(vma->vm_flags & VM_WRITE)) 
26352 +               goto out;
26353 +       page = address & PAGE_MASK;
26354 +       if(page == (unsigned long) current + PAGE_SIZE)
26355 +               panic("Kernel stack overflow");
26356 +       pgd = pgd_offset(mm, page);
26357 +       pmd = pmd_offset(pgd, page);
26358 +       do {
26359 +       survive:
26360 +               switch (handle_mm_fault(mm, vma, address, is_write)) {
26361 +               case 1:
26362 +                       current->min_flt++;
26363 +                       break;
26364 +               case 2:
26365 +                       current->maj_flt++;
26366 +                       break;
26367 +               default:
26368 +                       if (current->pid == 1) {
26369 +                               up_read(&mm->mmap_sem);
26370 +                               yield();
26371 +                               down_read(&mm->mmap_sem);
26372 +                               goto survive;
26373 +                       }
26374 +                       /* Fall through to bad area case */
26375 +               case 0:
26376 +                       goto out;
26377 +               }
26378 +               pte = pte_offset(pmd, page);
26379 +       } while(!pte_present(*pte));
26380 +       handled = 1;
26381 +       *pte = pte_mkyoung(*pte);
26382 +       if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
26383 +       flush_tlb_page(vma, page);
26384 + out:
26385 +       up_read(&mm->mmap_sem);
26386 +       return(handled);
26387 +}
26388 +
26389 +unsigned long segv(unsigned long address, unsigned long ip, int is_write, 
26390 +                  int is_user, void *sc)
26391 +{
26392 +       struct siginfo si;
26393 +       void *catcher;
26394 +       int handled;
26395 +
26396 +        if(!is_user && (address >= start_vm) && (address < end_vm)){
26397 +                flush_tlb_kernel_vm();
26398 +                return(0);
26399 +        }
26400 +        if(current->mm == NULL)
26401 +               panic("Segfault with no mm");
26402 +
26403 +       handled = handle_page_fault(address, ip, is_write, is_user, 
26404 +                                   &si.si_code);
26405 +
26406 +       catcher = current->thread.fault_catcher;
26407 +       if(handled)
26408 +               return(0);
26409 +       else if(catcher != NULL){
26410 +               current->thread.fault_addr = (void *) address;
26411 +               do_longjmp(catcher, 1);
26412 +       } 
26413 +       else if(current->thread.fault_addr != NULL){
26414 +               panic("fault_addr set but no fault catcher");
26415 +       }
26416 +       else if(arch_fixup(ip, sc))
26417 +               return(0);
26418 +
26419 +       if(!is_user) 
26420 +               panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", 
26421 +                     address, ip);
26422 +       si.si_signo = SIGSEGV;
26423 +       si.si_addr = (void *) address;
26424 +       current->thread.cr2 = address;
26425 +       current->thread.err = is_write;
26426 +       force_sig_info(SIGSEGV, &si, current);
26427 +       return(0);
26428 +}
26429 +
26430 +void bad_segv(unsigned long address, unsigned long ip, int is_write)
26431 +{
26432 +       struct siginfo si;
26433 +
26434 +       printk(KERN_ERR "Unfixable SEGV in '%s' (pid %d) at 0x%lx "
26435 +              "(ip 0x%lx)\n", current->comm, current->pid, address, ip);
26436 +       si.si_signo = SIGSEGV;
26437 +       si.si_code = SEGV_ACCERR;
26438 +       si.si_addr = (void *) address;
26439 +       current->thread.cr2 = address;
26440 +       current->thread.err = is_write;
26441 +       force_sig_info(SIGSEGV, &si, current);
26442 +}
26443 +
26444 +void relay_signal(int sig, union uml_pt_regs *regs)
26445 +{
26446 +       if(arch_handle_signal(sig, regs)) return;
26447 +       if(!UPT_IS_USER(regs))
26448 +               panic("Kernel mode signal %d", sig);
26449 +       force_sig(sig, current);
26450 +}
26451 +
26452 +void bus_handler(int sig, union uml_pt_regs *regs)
26453 +{
26454 +       if(current->thread.fault_catcher != NULL)
26455 +               do_longjmp(current->thread.fault_catcher, 1);
26456 +       else relay_signal(sig, regs);
26457 +}
26458 +
26459 +void winch(int sig, union uml_pt_regs *regs)
26460 +{
26461 +       do_IRQ(WINCH_IRQ, regs);
26462 +}
26463 +
26464 +void trap_init(void)
26465 +{
26466 +}
26467 +
26468 +spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
26469 +
26470 +static int trap_index = 0;
26471 +
26472 +int next_trap_index(int limit)
26473 +{
26474 +       int ret;
26475 +
26476 +       spin_lock(&trap_lock);
26477 +       ret = trap_index;
26478 +       if(++trap_index == limit)
26479 +               trap_index = 0;
26480 +       spin_unlock(&trap_lock);
26481 +       return(ret);
26482 +}
26483 +
26484 +/*
26485 + * Overrides for Emacs so that we follow Linus's tabbing style.
26486 + * Emacs will notice this stuff at the end of the file and automatically
26487 + * adjust the settings for this buffer only.  This must remain at the end
26488 + * of the file.
26489 + * ---------------------------------------------------------------------------
26490 + * Local variables:
26491 + * c-file-style: "linux"
26492 + * End:
26493 + */
26494 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_user.c um/arch/um/kernel/trap_user.c
26495 --- orig/arch/um/kernel/trap_user.c     1969-12-31 19:00:00.000000000 -0500
26496 +++ um/arch/um/kernel/trap_user.c       2003-03-26 13:25:50.000000000 -0500
26497 @@ -0,0 +1,140 @@
26498 +/* 
26499 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26500 + * Licensed under the GPL
26501 + */
26502 +
26503 +#include <stdlib.h>
26504 +#include <errno.h>
26505 +#include <fcntl.h>
26506 +#include <setjmp.h>
26507 +#include <signal.h>
26508 +#include <sys/time.h>
26509 +#include <sys/ioctl.h>
26510 +#include <sys/ptrace.h>
26511 +#include <sys/wait.h>
26512 +#include <asm/page.h>
26513 +#include <asm/unistd.h>
26514 +#include <asm/ptrace.h>
26515 +#include "init.h"
26516 +#include "sysdep/ptrace.h"
26517 +#include "sigcontext.h"
26518 +#include "sysdep/sigcontext.h"
26519 +#include "irq_user.h"
26520 +#include "frame_user.h"
26521 +#include "signal_user.h"
26522 +#include "time_user.h"
26523 +#include "task.h"
26524 +#include "mode.h"
26525 +#include "choose-mode.h"
26526 +#include "kern_util.h"
26527 +#include "user_util.h"
26528 +#include "os.h"
26529 +
26530 +void kill_child_dead(int pid)
26531 +{
26532 +       kill(pid, SIGKILL);
26533 +       kill(pid, SIGCONT);
26534 +       while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
26535 +}
26536 +
26537 +/* Unlocked - don't care if this is a bit off */
26538 +int nsegfaults = 0;
26539 +
26540 +struct {
26541 +       unsigned long address;
26542 +       int is_write;
26543 +       int pid;
26544 +       unsigned long sp;
26545 +       int is_user;
26546 +} segfault_record[1024];
26547 +
26548 +void segv_handler(int sig, union uml_pt_regs *regs)
26549 +{
26550 +       int index, max;
26551 +
26552 +       if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
26553 +               bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), 
26554 +                        UPT_FAULT_WRITE(regs));
26555 +               return;
26556 +       }
26557 +       max = sizeof(segfault_record)/sizeof(segfault_record[0]);
26558 +       index = next_trap_index(max);
26559 +
26560 +       nsegfaults++;
26561 +       segfault_record[index].address = UPT_FAULT_ADDR(regs);
26562 +       segfault_record[index].pid = os_getpid();
26563 +       segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
26564 +       segfault_record[index].sp = UPT_SP(regs);
26565 +       segfault_record[index].is_user = UPT_IS_USER(regs);
26566 +       segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
26567 +            UPT_IS_USER(regs), regs);
26568 +}
26569 +
26570 +void usr2_handler(int sig, union uml_pt_regs *regs)
26571 +{
26572 +       CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
26573 +}
26574 +
26575 +struct signal_info sig_info[] = {
26576 +       [ SIGTRAP ] { .handler          = relay_signal,
26577 +                     .is_irq           = 0 },
26578 +       [ SIGFPE ] { .handler           = relay_signal,
26579 +                    .is_irq            = 0 },
26580 +       [ SIGILL ] { .handler           = relay_signal,
26581 +                    .is_irq            = 0 },
26582 +       [ SIGWINCH ] { .handler         = winch,
26583 +                      .is_irq          = 1 },
26584 +       [ SIGBUS ] { .handler           = bus_handler,
26585 +                    .is_irq            = 0 },
26586 +       [ SIGSEGV] { .handler           = segv_handler,
26587 +                    .is_irq            = 0 },
26588 +       [ SIGIO ] { .handler            = sigio_handler,
26589 +                   .is_irq             = 1 },
26590 +       [ SIGVTALRM ] { .handler        = timer_handler,
26591 +                       .is_irq         = 1 },
26592 +        [ SIGALRM ] { .handler          = timer_handler,
26593 +                      .is_irq           = 1 },
26594 +       [ SIGUSR2 ] { .handler          = usr2_handler,
26595 +                     .is_irq           = 0 },
26596 +};
26597 +
26598 +void sig_handler(int sig, struct sigcontext sc)
26599 +{
26600 +       CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
26601 +                        sig, &sc);
26602 +}
26603 +
26604 +extern int timer_irq_inited, missed_ticks[];
26605 +
26606 +void alarm_handler(int sig, struct sigcontext sc)
26607 +{
26608 +       if(!timer_irq_inited) return;
26609 +       missed_ticks[cpu()]++;
26610 +
26611 +       if(sig == SIGALRM)
26612 +               switch_timers(0);
26613 +
26614 +       CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
26615 +                        sig, &sc);
26616 +
26617 +       if(sig == SIGALRM)
26618 +               switch_timers(1);
26619 +}
26620 +
26621 +void do_longjmp(void *b, int val)
26622 +{
26623 +       jmp_buf *buf = b;
26624 +
26625 +       longjmp(*buf, val);
26626 +}
26627 +
26628 +/*
26629 + * Overrides for Emacs so that we follow Linus's tabbing style.
26630 + * Emacs will notice this stuff at the end of the file and automatically
26631 + * adjust the settings for this buffer only.  This must remain at the end
26632 + * of the file.
26633 + * ---------------------------------------------------------------------------
26634 + * Local variables:
26635 + * c-file-style: "linux"
26636 + * End:
26637 + */
26638 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_kern.c um/arch/um/kernel/tt/exec_kern.c
26639 --- orig/arch/um/kernel/tt/exec_kern.c  1969-12-31 19:00:00.000000000 -0500
26640 +++ um/arch/um/kernel/tt/exec_kern.c    2002-10-24 19:22:17.000000000 -0400
26641 @@ -0,0 +1,83 @@
26642 +/* 
26643 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26644 + * Licensed under the GPL
26645 + */
26646 +
26647 +#include "linux/kernel.h"
26648 +#include "linux/mm.h"
26649 +#include "asm/signal.h"
26650 +#include "asm/ptrace.h"
26651 +#include "asm/uaccess.h"
26652 +#include "asm/pgalloc.h"
26653 +#include "user_util.h"
26654 +#include "kern_util.h"
26655 +#include "irq_user.h"
26656 +#include "time_user.h"
26657 +#include "mem_user.h"
26658 +#include "os.h"
26659 +#include "tlb.h"
26660 +
26661 +static int exec_tramp(void *sig_stack)
26662 +{
26663 +       init_new_thread_stack(sig_stack, NULL);
26664 +       init_new_thread_signals(1);
26665 +       os_stop_process(os_getpid());
26666 +       return(0);
26667 +}
26668 +
26669 +void flush_thread_tt(void)
26670 +{
26671 +       unsigned long stack;
26672 +       int new_pid;
26673 +
26674 +       stack = alloc_stack(0, 0);
26675 +       if(stack == 0){
26676 +               printk(KERN_ERR 
26677 +                      "flush_thread : failed to allocate temporary stack\n");
26678 +               do_exit(SIGKILL);
26679 +       }
26680 +               
26681 +       new_pid = start_fork_tramp((void *) current->thread.kernel_stack,
26682 +                                  stack, 0, exec_tramp);
26683 +       if(new_pid < 0){
26684 +               printk(KERN_ERR 
26685 +                      "flush_thread : new thread failed, errno = %d\n",
26686 +                      -new_pid);
26687 +               do_exit(SIGKILL);
26688 +       }
26689 +
26690 +       if(current->processor == 0)
26691 +               forward_interrupts(new_pid);
26692 +       current->thread.request.op = OP_EXEC;
26693 +       current->thread.request.u.exec.pid = new_pid;
26694 +       unprotect_stack((unsigned long) current);
26695 +       os_usr1_process(os_getpid());
26696 +
26697 +       enable_timer();
26698 +       free_page(stack);
26699 +       protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
26700 +       task_protections((unsigned long) current);
26701 +       force_flush_all();
26702 +       unblock_signals();
26703 +}
26704 +
26705 +void start_thread_tt(struct pt_regs *regs, unsigned long eip, 
26706 +                    unsigned long esp)
26707 +{
26708 +       set_fs(USER_DS);
26709 +       flush_tlb_mm(current->mm);
26710 +       PT_REGS_IP(regs) = eip;
26711 +       PT_REGS_SP(regs) = esp;
26712 +       PT_FIX_EXEC_STACK(esp);
26713 +}
26714 +
26715 +/*
26716 + * Overrides for Emacs so that we follow Linus's tabbing style.
26717 + * Emacs will notice this stuff at the end of the file and automatically
26718 + * adjust the settings for this buffer only.  This must remain at the end
26719 + * of the file.
26720 + * ---------------------------------------------------------------------------
26721 + * Local variables:
26722 + * c-file-style: "linux"
26723 + * End:
26724 + */
26725 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_user.c um/arch/um/kernel/tt/exec_user.c
26726 --- orig/arch/um/kernel/tt/exec_user.c  1969-12-31 19:00:00.000000000 -0500
26727 +++ um/arch/um/kernel/tt/exec_user.c    2002-12-05 19:36:57.000000000 -0500
26728 @@ -0,0 +1,49 @@
26729 +/* 
26730 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
26731 + * Licensed under the GPL
26732 + */
26733 +
26734 +#include <stdio.h>
26735 +#include <unistd.h>
26736 +#include <stdlib.h>
26737 +#include <sched.h>
26738 +#include <errno.h>
26739 +#include <sys/wait.h>
26740 +#include <sys/ptrace.h>
26741 +#include <signal.h>
26742 +#include "user_util.h"
26743 +#include "kern_util.h"
26744 +#include "user.h"
26745 +#include "ptrace_user.h"
26746 +
26747 +void do_exec(int old_pid, int new_pid)
26748 +{
26749 +       unsigned long regs[FRAME_SIZE];
26750 +
26751 +       if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
26752 +          (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) ||
26753 +          (waitpid(new_pid, 0, WUNTRACED) < 0))
26754 +               tracer_panic("do_exec failed to attach proc - errno = %d",
26755 +                            errno);
26756 +
26757 +       if(ptrace_getregs(old_pid, regs) < 0)
26758 +               tracer_panic("do_exec failed to get registers - errno = %d",
26759 +                            errno);
26760 +
26761 +       kill(old_pid, SIGKILL);
26762 +
26763 +       if(ptrace_setregs(new_pid, regs) < 0)
26764 +               tracer_panic("do_exec failed to start new proc - errno = %d",
26765 +                            errno);
26766 +}
26767 +
26768 +/*
26769 + * Overrides for Emacs so that we follow Linus's tabbing style.
26770 + * Emacs will notice this stuff at the end of the file and automatically
26771 + * adjust the settings for this buffer only.  This must remain at the end
26772 + * of the file.
26773 + * ---------------------------------------------------------------------------
26774 + * Local variables:
26775 + * c-file-style: "linux"
26776 + * End:
26777 + */
26778 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb.c um/arch/um/kernel/tt/gdb.c
26779 --- orig/arch/um/kernel/tt/gdb.c        1969-12-31 19:00:00.000000000 -0500
26780 +++ um/arch/um/kernel/tt/gdb.c  2003-01-17 13:23:31.000000000 -0500
26781 @@ -0,0 +1,278 @@
26782 +/* 
26783 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
26784 + * Licensed under the GPL
26785 + */
26786 +
26787 +#include <stdio.h>
26788 +#include <stdlib.h>
26789 +#include <errno.h>
26790 +#include <string.h>
26791 +#include <signal.h>
26792 +#include <sys/ptrace.h>
26793 +#include <sys/types.h>
26794 +#include "uml-config.h"
26795 +#include "kern_constants.h"
26796 +#include "chan_user.h"
26797 +#include "init.h"
26798 +#include "user.h"
26799 +#include "debug.h"
26800 +#include "kern_util.h"
26801 +#include "user_util.h"
26802 +#include "tt.h"
26803 +#include "sysdep/thread.h"
26804 +
26805 +extern int debugger_pid;
26806 +extern int debugger_fd;
26807 +extern int debugger_parent;
26808 +
26809 +int detach(int pid, int sig)
26810 +{
26811 +       return(ptrace(PTRACE_DETACH, pid, 0, sig));
26812 +}
26813 +
26814 +int attach(int pid)
26815 +{
26816 +       int err;
26817 +
26818 +       err = ptrace(PTRACE_ATTACH, pid, 0, 0);
26819 +       if(err < 0) return(-errno);
26820 +       else return(err);
26821 +}
26822 +
26823 +int cont(int pid)
26824 +{
26825 +       return(ptrace(PTRACE_CONT, pid, 0, 0));
26826 +}
26827 +
26828 +#ifdef UML_CONFIG_PT_PROXY
26829 +
26830 +int debugger_signal(int status, pid_t pid)
26831 +{
26832 +       return(debugger_proxy(status, pid));
26833 +}
26834 +
26835 +void child_signal(pid_t pid, int status)
26836 +{
26837 +       child_proxy(pid, status);
26838 +}
26839 +
26840 +static void gdb_announce(char *dev_name, int dev)
26841 +{
26842 +       printf("gdb assigned device '%s'\n", dev_name);
26843 +}
26844 +
26845 +static struct chan_opts opts = {
26846 +       .announce       = gdb_announce,
26847 +       .xterm_title    = "UML kernel debugger",
26848 +       .raw            = 0,
26849 +       .tramp_stack    = 0,
26850 +       .in_kernel      = 0,
26851 +};
26852 +
26853 +/* Accessed by the tracing thread, which automatically serializes access */
26854 +static void *xterm_data;
26855 +static int xterm_fd;
26856 +
26857 +extern void *xterm_init(char *, int, struct chan_opts *);
26858 +extern int xterm_open(int, int, int, void *, char **);
26859 +extern void xterm_close(int, void *);
26860 +
26861 +int open_gdb_chan(void)
26862 +{
26863 +       char stack[UM_KERN_PAGE_SIZE], *dummy;
26864 +
26865 +       opts.tramp_stack = (unsigned long) stack;
26866 +       xterm_data = xterm_init("", 0, &opts);
26867 +       xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
26868 +       return(xterm_fd);
26869 +}
26870 +
26871 +static void exit_debugger_cb(void *unused)
26872 +{
26873 +       if(debugger_pid != -1){
26874 +               if(gdb_pid != -1){
26875 +                       fake_child_exit();
26876 +                       gdb_pid = -1;
26877 +               }
26878 +               else kill_child_dead(debugger_pid);
26879 +               debugger_pid = -1;
26880 +               if(debugger_parent != -1)
26881 +                       detach(debugger_parent, SIGINT);
26882 +       }
26883 +       if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
26884 +}
26885 +
26886 +static void exit_debugger(void)
26887 +{
26888 +       initial_thread_cb(exit_debugger_cb, NULL);
26889 +}
26890 +
26891 +__uml_exitcall(exit_debugger);
26892 +
26893 +struct gdb_data {
26894 +       char *str;
26895 +       int err;
26896 +};
26897 +
26898 +static void config_gdb_cb(void *arg)
26899 +{
26900 +       struct gdb_data *data = arg;
26901 +       void *task;
26902 +       int pid;
26903 +
26904 +       data->err = -1;
26905 +       if(debugger_pid != -1) exit_debugger_cb(NULL);
26906 +       if(!strncmp(data->str, "pid,", strlen("pid,"))){
26907 +               data->str += strlen("pid,");
26908 +               pid = strtoul(data->str, NULL, 0);
26909 +               task = cpu_tasks[0].task;
26910 +               debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
26911 +               if(debugger_pid != -1){
26912 +                       data->err = 0;
26913 +                       gdb_pid = pid;
26914 +               }
26915 +               return;
26916 +       }
26917 +       data->err = 0;
26918 +       debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
26919 +       init_proxy(debugger_pid, 0, 0);
26920 +}
26921 +
26922 +int gdb_config(char *str)
26923 +{
26924 +       struct gdb_data data;
26925 +
26926 +       if(*str++ != '=') return(-1);
26927 +       data.str = str;
26928 +       initial_thread_cb(config_gdb_cb, &data);
26929 +       return(data.err);
26930 +}
26931 +
26932 +void remove_gdb_cb(void *unused)
26933 +{
26934 +       exit_debugger_cb(NULL);
26935 +}
26936 +
26937 +int gdb_remove(char *unused)
26938 +{
26939 +       initial_thread_cb(remove_gdb_cb, NULL);
26940 +       return(0);
26941 +}
26942 +
26943 +void signal_usr1(int sig)
26944 +{
26945 +       if(debugger_pid != -1){
26946 +               printk(UM_KERN_ERR "The debugger is already running\n");
26947 +               return;
26948 +       }
26949 +       debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
26950 +       init_proxy(debugger_pid, 0, 0);
26951 +}
26952 +
26953 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
26954 +{
26955 +       int pid, status;
26956 +
26957 +       pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
26958 +       status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
26959 +       if(pid < 0){
26960 +               cont(idle_pid);
26961 +               return(-1);
26962 +       }
26963 +       init_proxy(pid, 1, status);
26964 +       return(pid);
26965 +}
26966 +
26967 +int attach_debugger(int idle_pid, int pid, int stop)
26968 +{
26969 +       int status = 0, err;
26970 +
26971 +       err = attach(pid);
26972 +       if(err < 0){
26973 +               printf("Failed to attach pid %d, errno = %d\n", pid, -err);
26974 +               return(-1);
26975 +       }
26976 +       if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
26977 +       init_proxy(pid, 1, status);
26978 +       return(pid);
26979 +}
26980 +
26981 +#ifdef notdef /* Put this back in when it does something useful */
26982 +static int __init uml_gdb_init_setup(char *line, int *add)
26983 +{
26984 +       gdb_init = uml_strdup(line);
26985 +       return 0;
26986 +}
26987 +
26988 +__uml_setup("gdb=", uml_gdb_init_setup, 
26989 +"gdb=<channel description>\n\n"
26990 +);
26991 +#endif
26992 +
26993 +static int __init uml_gdb_pid_setup(char *line, int *add)
26994 +{
26995 +       gdb_pid = strtoul(line, NULL, 0);
26996 +       *add = 0;
26997 +       return 0;
26998 +}
26999 +
27000 +__uml_setup("gdb-pid=", uml_gdb_pid_setup, 
27001 +"gdb-pid=<pid>\n"
27002 +"    gdb-pid is used to attach an external debugger to UML.  This may be\n"
27003 +"    an already-running gdb or a debugger-like process like strace.\n\n"
27004 +);
27005 +
27006 +#else
27007 +
27008 +int debugger_signal(int status, pid_t pid){ return(0); }
27009 +void child_signal(pid_t pid, int status){ }
27010 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
27011 +{
27012 +       printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
27013 +       kill_child_dead(idle_pid);
27014 +       exit(1);
27015 +}
27016 +
27017 +void signal_usr1(int sig)
27018 +{
27019 +       printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
27020 +}
27021 +
27022 +int attach_debugger(int idle_pid, int pid, int stop)
27023 +{
27024 +       printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
27025 +              "is off\n");
27026 +       return(-1);
27027 +}
27028 +
27029 +int config_gdb(char *str)
27030 +{
27031 +       return(-1);
27032 +}
27033 +
27034 +int remove_gdb(void)
27035 +{
27036 +       return(-1);
27037 +}
27038 +
27039 +int init_parent_proxy(int pid)
27040 +{
27041 +       return(-1);
27042 +}
27043 +
27044 +void debugger_parent_signal(int status, int pid)
27045 +{
27046 +}
27047 +
27048 +#endif
27049 +
27050 +/*
27051 + * Overrides for Emacs so that we follow Linus's tabbing style.
27052 + * Emacs will notice this stuff at the end of the file and automatically
27053 + * adjust the settings for this buffer only.  This must remain at the end
27054 + * of the file.
27055 + * ---------------------------------------------------------------------------
27056 + * Local variables:
27057 + * c-file-style: "linux"
27058 + * End:
27059 + */
27060 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb_kern.c um/arch/um/kernel/tt/gdb_kern.c
27061 --- orig/arch/um/kernel/tt/gdb_kern.c   1969-12-31 19:00:00.000000000 -0500
27062 +++ um/arch/um/kernel/tt/gdb_kern.c     2002-12-15 21:16:17.000000000 -0500
27063 @@ -0,0 +1,40 @@
27064 +/* 
27065 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27066 + * Licensed under the GPL
27067 + */
27068 +
27069 +#include "linux/init.h"
27070 +#include "linux/config.h"
27071 +#include "mconsole_kern.h"
27072 +
27073 +#ifdef CONFIG_MCONSOLE
27074 +
27075 +extern int gdb_config(char *str);
27076 +extern int gdb_remove(char *unused);
27077 +
27078 +static struct mc_device gdb_mc = {
27079 +       .name           = "gdb",
27080 +       .config         = gdb_config,
27081 +       .remove         = gdb_remove,
27082 +};
27083 +
27084 +int gdb_mc_init(void)
27085 +{
27086 +       mconsole_register_dev(&gdb_mc);
27087 +       return(0);
27088 +}
27089 +
27090 +__initcall(gdb_mc_init);
27091 +
27092 +#endif
27093 +
27094 +/*
27095 + * Overrides for Emacs so that we follow Linus's tabbing style.
27096 + * Emacs will notice this stuff at the end of the file and automatically
27097 + * adjust the settings for this buffer only.  This must remain at the end
27098 + * of the file.
27099 + * ---------------------------------------------------------------------------
27100 + * Local variables:
27101 + * c-file-style: "linux"
27102 + * End:
27103 + */
27104 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/debug.h um/arch/um/kernel/tt/include/debug.h
27105 --- orig/arch/um/kernel/tt/include/debug.h      1969-12-31 19:00:00.000000000 -0500
27106 +++ um/arch/um/kernel/tt/include/debug.h        2002-10-23 21:08:04.000000000 -0400
27107 @@ -0,0 +1,29 @@
27108 +/* 
27109 + * Copyright (C) 2000, 2001, 2002  Jeff Dike (jdike@karaya.com) and
27110 + * Lars Brinkhoff.
27111 + * Licensed under the GPL
27112 + */
27113 +
27114 +#ifndef __DEBUG_H
27115 +#define __DEBUG_H
27116 +
27117 +extern int debugger_proxy(int status, pid_t pid);
27118 +extern void child_proxy(pid_t pid, int status);
27119 +extern void init_proxy (pid_t pid, int waiting, int status);
27120 +extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
27121 +extern void fake_child_exit(void);
27122 +extern int gdb_config(char *str);
27123 +extern int gdb_remove(char *unused);
27124 +
27125 +#endif
27126 +
27127 +/*
27128 + * Overrides for Emacs so that we follow Linus's tabbing style.
27129 + * Emacs will notice this stuff at the end of the file and automatically
27130 + * adjust the settings for this buffer only.  This must remain at the end
27131 + * of the file.
27132 + * ---------------------------------------------------------------------------
27133 + * Local variables:
27134 + * c-file-style: "linux"
27135 + * End:
27136 + */
27137 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mmu.h um/arch/um/kernel/tt/include/mmu.h
27138 --- orig/arch/um/kernel/tt/include/mmu.h        1969-12-31 19:00:00.000000000 -0500
27139 +++ um/arch/um/kernel/tt/include/mmu.h  2002-11-09 12:51:32.000000000 -0500
27140 @@ -0,0 +1,23 @@
27141 +/* 
27142 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27143 + * Licensed under the GPL
27144 + */
27145 +
27146 +#ifndef __TT_MMU_H
27147 +#define __TT_MMU_H
27148 +
27149 +struct mmu_context_tt {
27150 +};
27151 +
27152 +#endif
27153 +
27154 +/*
27155 + * Overrides for Emacs so that we follow Linus's tabbing style.
27156 + * Emacs will notice this stuff at the end of the file and automatically
27157 + * adjust the settings for this buffer only.  This must remain at the end
27158 + * of the file.
27159 + * ---------------------------------------------------------------------------
27160 + * Local variables:
27161 + * c-file-style: "linux"
27162 + * End:
27163 + */
27164 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode.h um/arch/um/kernel/tt/include/mode.h
27165 --- orig/arch/um/kernel/tt/include/mode.h       1969-12-31 19:00:00.000000000 -0500
27166 +++ um/arch/um/kernel/tt/include/mode.h 2002-12-09 00:34:40.000000000 -0500
27167 @@ -0,0 +1,36 @@
27168 +/* 
27169 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27170 + * Licensed under the GPL
27171 + */
27172 +
27173 +#ifndef __MODE_TT_H__
27174 +#define __MODE_TT_H__
27175 +
27176 +#include "sysdep/ptrace.h"
27177 +
27178 +extern int tracing_pid;
27179 +
27180 +extern int tracer(int (*init_proc)(void *), void *sp);
27181 +extern void user_time_init_tt(void);
27182 +extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
27183 +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, 
27184 +                             void *data);
27185 +extern void sig_handler_common_tt(int sig, void *sc);
27186 +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
27187 +extern void reboot_tt(void);
27188 +extern void halt_tt(void);
27189 +extern int is_tracer_winch(int pid, int fd, void *data);
27190 +extern void kill_off_processes_tt(void);
27191 +
27192 +#endif
27193 +
27194 +/*
27195 + * Overrides for Emacs so that we follow Linus's tabbing style.
27196 + * Emacs will notice this stuff at the end of the file and automatically
27197 + * adjust the settings for this buffer only.  This must remain at the end
27198 + * of the file.
27199 + * ---------------------------------------------------------------------------
27200 + * Local variables:
27201 + * c-file-style: "linux"
27202 + * End:
27203 + */
27204 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode_kern.h um/arch/um/kernel/tt/include/mode_kern.h
27205 --- orig/arch/um/kernel/tt/include/mode_kern.h  1969-12-31 19:00:00.000000000 -0500
27206 +++ um/arch/um/kernel/tt/include/mode_kern.h    2002-12-16 21:49:18.000000000 -0500
27207 @@ -0,0 +1,52 @@
27208 +/* 
27209 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27210 + * Licensed under the GPL
27211 + */
27212 +
27213 +#ifndef __TT_MODE_KERN_H__
27214 +#define __TT_MODE_KERN_H__
27215 +
27216 +#include "linux/sched.h"
27217 +#include "asm/page.h"
27218 +#include "asm/ptrace.h"
27219 +#include "asm/uaccess.h"
27220 +
27221 +extern void *_switch_to_tt(void *prev, void *next);
27222 +extern void flush_thread_tt(void);
27223 +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, 
27224 +                          unsigned long esp);
27225 +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
27226 +                         unsigned long stack_top, struct task_struct *p, 
27227 +                         struct pt_regs *regs);
27228 +extern void release_thread_tt(struct task_struct *task);
27229 +extern void exit_thread_tt(void);
27230 +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
27231 +extern void init_idle_tt(void);
27232 +extern void flush_tlb_kernel_vm_tt(void);
27233 +extern void __flush_tlb_one_tt(unsigned long addr);
27234 +extern void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, 
27235 +                              unsigned long end);
27236 +extern void flush_tlb_mm_tt(struct mm_struct *mm);
27237 +extern void force_flush_all_tt(void);
27238 +extern long execute_syscall_tt(void *r);
27239 +extern void before_mem_tt(unsigned long brk_start);
27240 +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
27241 +                                      unsigned long *task_size_out);
27242 +extern int start_uml_tt(void);
27243 +extern int external_pid_tt(struct task_struct *task);
27244 +extern int thread_pid_tt(struct thread_struct *thread);
27245 +
27246 +#define kmem_end_tt (host_task_size - ABOVE_KMEM)
27247 +
27248 +#endif
27249 +
27250 +/*
27251 + * Overrides for Emacs so that we follow Linus's tabbing style.
27252 + * Emacs will notice this stuff at the end of the file and automatically
27253 + * adjust the settings for this buffer only.  This must remain at the end
27254 + * of the file.
27255 + * ---------------------------------------------------------------------------
27256 + * Local variables:
27257 + * c-file-style: "linux"
27258 + * End:
27259 + */
27260 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/ptrace-tt.h um/arch/um/kernel/tt/include/ptrace-tt.h
27261 --- orig/arch/um/kernel/tt/include/ptrace-tt.h  1969-12-31 19:00:00.000000000 -0500
27262 +++ um/arch/um/kernel/tt/include/ptrace-tt.h    2003-01-17 13:23:30.000000000 -0500
27263 @@ -0,0 +1,26 @@
27264 +/* 
27265 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27266 + * Licensed under the GPL
27267 + */
27268 +
27269 +#ifndef __PTRACE_TT_H
27270 +#define __PTRACE_TT_H
27271 +
27272 +#include "uml-config.h"
27273 +
27274 +#ifdef UML_CONFIG_MODE_TT
27275 +#include "sysdep/sc.h"
27276 +#endif
27277 +
27278 +#endif
27279 +
27280 +/*
27281 + * Overrides for Emacs so that we follow Linus's tabbing style.
27282 + * Emacs will notice this stuff at the end of the file and automatically
27283 + * adjust the settings for this buffer only.  This must remain at the end
27284 + * of the file.
27285 + * ---------------------------------------------------------------------------
27286 + * Local variables:
27287 + * c-file-style: "linux"
27288 + * End:
27289 + */
27290 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/tt.h um/arch/um/kernel/tt/include/tt.h
27291 --- orig/arch/um/kernel/tt/include/tt.h 1969-12-31 19:00:00.000000000 -0500
27292 +++ um/arch/um/kernel/tt/include/tt.h   2002-12-20 23:29:11.000000000 -0500
27293 @@ -0,0 +1,46 @@
27294 +/* 
27295 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27296 + * Licensed under the GPL
27297 + */
27298 +
27299 +#ifndef __TT_H__
27300 +#define __TT_H__
27301 +
27302 +#include "sysdep/ptrace.h"
27303 +
27304 +extern int gdb_pid;
27305 +extern int debug;
27306 +extern int debug_stop;
27307 +extern int debug_trace;
27308 +
27309 +extern int honeypot;
27310 +
27311 +extern int fork_tramp(void *sig_stack);
27312 +extern int do_proc_op(void *t, int proc_id);
27313 +extern int tracer(int (*init_proc)(void *), void *sp);
27314 +extern void attach_process(int pid);
27315 +extern void tracer_panic(char *format, ...);
27316 +extern void set_init_pid(int pid);
27317 +extern int set_user_mode(void *task);
27318 +extern void set_tracing(void *t, int tracing);
27319 +extern int is_tracing(void *task);
27320 +extern int singlestepping_tt(void *t);
27321 +extern void clear_singlestep(void *t);
27322 +extern void syscall_handler(int sig, union uml_pt_regs *regs);
27323 +extern void exit_kernel(int pid, void *task);
27324 +extern int do_syscall(void *task, int pid);
27325 +extern int is_valid_pid(int pid);
27326 +extern void remap_data(void *segment_start, void *segment_end, int w);
27327 +
27328 +#endif
27329 +
27330 +/*
27331 + * Overrides for Emacs so that we follow Linus's tabbing style.
27332 + * Emacs will notice this stuff at the end of the file and automatically
27333 + * adjust the settings for this buffer only.  This must remain at the end
27334 + * of the file.
27335 + * ---------------------------------------------------------------------------
27336 + * Local variables:
27337 + * c-file-style: "linux"
27338 + * End:
27339 + */
27340 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/uaccess.h um/arch/um/kernel/tt/include/uaccess.h
27341 --- orig/arch/um/kernel/tt/include/uaccess.h    1969-12-31 19:00:00.000000000 -0500
27342 +++ um/arch/um/kernel/tt/include/uaccess.h      2003-03-25 16:58:42.000000000 -0500
27343 @@ -0,0 +1,122 @@
27344 +/* 
27345 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
27346 + * Licensed under the GPL
27347 + */
27348 +
27349 +#ifndef __TT_UACCESS_H
27350 +#define __TT_UACCESS_H
27351 +
27352 +#include "linux/string.h"
27353 +#include "linux/sched.h"
27354 +#include "asm/processor.h"
27355 +#include "asm/errno.h"
27356 +#include "asm/current.h"
27357 +#include "asm/a.out.h"
27358 +#include "uml_uaccess.h"
27359 +
27360 +#define ABOVE_KMEM (16 * 1024 * 1024)
27361 +
27362 +extern unsigned long end_vm;
27363 +extern unsigned long uml_physmem;
27364 +
27365 +#define under_task_size(addr, size) \
27366 +       (((unsigned long) (addr) < TASK_SIZE) && \
27367 +         (((unsigned long) (addr) + (size)) < TASK_SIZE))
27368 +
27369 +#define is_stack(addr, size) \
27370 +       (((unsigned long) (addr) < STACK_TOP) && \
27371 +        ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
27372 +        (((unsigned long) (addr) + (size)) <= STACK_TOP))
27373 +
27374 +#define access_ok_tt(type, addr, size) \
27375 +       ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
27376 +         (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
27377 +          (under_task_size(addr, size) || is_stack(addr, size))))
27378 +
27379 +static inline int verify_area_tt(int type, const void * addr, 
27380 +                                unsigned long size)
27381 +{
27382 +       return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
27383 +}
27384 +
27385 +extern unsigned long get_fault_addr(void);
27386 +
27387 +extern int __do_copy_from_user(void *to, const void *from, int n,
27388 +                              void **fault_addr, void **fault_catcher);
27389 +
27390 +static inline int copy_from_user_tt(void *to, const void *from, int n)
27391 +{
27392 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
27393 +               return(n);
27394 +
27395 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
27396 +                                  &current->thread.fault_catcher));
27397 +}
27398 +
27399 +static inline int copy_to_user_tt(void *to, const void *from, int n)
27400 +{
27401 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
27402 +               return(n);
27403 +               
27404 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
27405 +                                &current->thread.fault_catcher));
27406 +}
27407 +
27408 +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
27409 +                                 void **fault_addr, void **fault_catcher);
27410 +
27411 +static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
27412 +{
27413 +       int n;
27414 +
27415 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
27416 +               return(-EFAULT);
27417 +
27418 +       n = __do_strncpy_from_user(dst, src, count, 
27419 +                                  &current->thread.fault_addr,
27420 +                                  &current->thread.fault_catcher);
27421 +       if(n < 0) return(-EFAULT);
27422 +       return(n);
27423 +}
27424 +
27425 +extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
27426 +                          void **fault_catcher);
27427 +
27428 +static inline int __clear_user_tt(void *mem, int len)
27429 +{
27430 +       return(__do_clear_user(mem, len,
27431 +                              &current->thread.fault_addr,
27432 +                              &current->thread.fault_catcher));
27433 +}
27434 +
27435 +static inline int clear_user_tt(void *mem, int len)
27436 +{
27437 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
27438 +               return(len);
27439 +
27440 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
27441 +                              &current->thread.fault_catcher));
27442 +}
27443 +
27444 +extern int __do_strnlen_user(const char *str, unsigned long n,
27445 +                            void **fault_addr, void **fault_catcher);
27446 +
27447 +static inline int strnlen_user_tt(const void *str, int len)
27448 +{
27449 +       return(__do_strnlen_user(str, len,
27450 +                                &current->thread.fault_addr,
27451 +                                &current->thread.fault_catcher));
27452 +}
27453 +
27454 +#endif
27455 +
27456 +/*
27457 + * Overrides for Emacs so that we follow Linus's tabbing style.
27458 + * Emacs will notice this stuff at the end of the file and automatically
27459 + * adjust the settings for this buffer only.  This must remain at the end
27460 + * of the file.
27461 + * ---------------------------------------------------------------------------
27462 + * Local variables:
27463 + * c-file-style: "linux"
27464 + * End:
27465 + */
27466 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ksyms.c um/arch/um/kernel/tt/ksyms.c
27467 --- orig/arch/um/kernel/tt/ksyms.c      1969-12-31 19:00:00.000000000 -0500
27468 +++ um/arch/um/kernel/tt/ksyms.c        2002-10-27 17:01:56.000000000 -0500
27469 @@ -0,0 +1,28 @@
27470 +/* 
27471 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
27472 + * Licensed under the GPL
27473 + */
27474 +
27475 +#include "linux/module.h"
27476 +#include "asm/uaccess.h"
27477 +#include "mode.h"
27478 +
27479 +EXPORT_SYMBOL(__do_copy_from_user);
27480 +EXPORT_SYMBOL(__do_copy_to_user);
27481 +EXPORT_SYMBOL(__do_strncpy_from_user);
27482 +EXPORT_SYMBOL(__do_strnlen_user); 
27483 +EXPORT_SYMBOL(__do_clear_user);
27484 +
27485 +EXPORT_SYMBOL(tracing_pid);
27486 +EXPORT_SYMBOL(honeypot);
27487 +
27488 +/*
27489 + * Overrides for Emacs so that we follow Linus's tabbing style.
27490 + * Emacs will notice this stuff at the end of the file and automatically
27491 + * adjust the settings for this buffer only.  This must remain at the end
27492 + * of the file.
27493 + * ---------------------------------------------------------------------------
27494 + * Local variables:
27495 + * c-file-style: "linux"
27496 + * End:
27497 + */
27498 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/Makefile um/arch/um/kernel/tt/Makefile
27499 --- orig/arch/um/kernel/tt/Makefile     1969-12-31 19:00:00.000000000 -0500
27500 +++ um/arch/um/kernel/tt/Makefile       2002-12-20 23:29:42.000000000 -0500
27501 @@ -0,0 +1,39 @@
27502 +# 
27503 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27504 +# Licensed under the GPL
27505 +#
27506 +
27507 +O_TARGET = tt.o
27508 +
27509 +obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
27510 +       syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
27511 +       uaccess_user.o
27512 +
27513 +obj-$(CONFIG_PT_PROXY) += gdb_kern.o 
27514 +
27515 +subdir-y = sys-$(SUBARCH)
27516 +subdir-$(CONFIG_PT_PROXY) += ptproxy
27517 +
27518 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
27519 +
27520 +export-objs = ksyms.o
27521 +
27522 +USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
27523 +
27524 +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
27525 +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
27526 +
27527 +include $(TOPDIR)/Rules.make
27528 +
27529 +$(USER_OBJS) : %.o: %.c
27530 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
27531 +
27532 +$(O_TARGET) : unmap_fin.o
27533 +
27534 +unmap.o: unmap.c
27535 +       $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
27536 +
27537 +unmap_fin.o : unmap.o
27538 +       ld -r -o $@ $< -lc -L/usr/lib
27539 +
27540 +clean :
27541 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem.c um/arch/um/kernel/tt/mem.c
27542 --- orig/arch/um/kernel/tt/mem.c        1969-12-31 19:00:00.000000000 -0500
27543 +++ um/arch/um/kernel/tt/mem.c  2002-12-16 21:49:51.000000000 -0500
27544 @@ -0,0 +1,51 @@
27545 +/* 
27546 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27547 + * Licensed under the GPL
27548 + */
27549 +
27550 +#include "linux/stddef.h"
27551 +#include "linux/config.h"
27552 +#include "linux/mm.h"
27553 +#include "asm/uaccess.h"
27554 +#include "mem_user.h"
27555 +#include "kern_util.h"
27556 +#include "user_util.h"
27557 +#include "kern.h"
27558 +#include "tt.h"
27559 +
27560 +void before_mem_tt(unsigned long brk_start)
27561 +{
27562 +       if(!jail || debug)
27563 +               remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
27564 +       remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
27565 +       remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(brk_start), 1);
27566 +}
27567 +
27568 +#ifdef CONFIG_HOST_2G_2G
27569 +#define TOP 0x80000000
27570 +#else
27571 +#define TOP 0xc0000000
27572 +#endif
27573 +
27574 +#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
27575 +#define START (TOP - SIZE)
27576 +
27577 +unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
27578 +                               unsigned long *task_size_out)
27579 +{
27580 +       /* Round up to the nearest 4M */
27581 +       *host_size_out = ROUND_4M((unsigned long) &arg);
27582 +       *task_size_out = START;
27583 +       return(START);
27584 +}
27585 +
27586 +/*
27587 + * Overrides for Emacs so that we follow Linus's tabbing style.
27588 + * Emacs will notice this stuff at the end of the file and automatically
27589 + * adjust the settings for this buffer only.  This must remain at the end
27590 + * of the file.
27591 + * ---------------------------------------------------------------------------
27592 + * Local variables:
27593 + * c-file-style: "linux"
27594 + * End:
27595 + */
27596 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem_user.c um/arch/um/kernel/tt/mem_user.c
27597 --- orig/arch/um/kernel/tt/mem_user.c   1969-12-31 19:00:00.000000000 -0500
27598 +++ um/arch/um/kernel/tt/mem_user.c     2003-01-17 22:07:31.000000000 -0500
27599 @@ -0,0 +1,50 @@
27600 +/* 
27601 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27602 + * Licensed under the GPL
27603 + */
27604 +
27605 +#include <stdlib.h>
27606 +#include <stdio.h>
27607 +#include <unistd.h>
27608 +#include <string.h>
27609 +#include <errno.h>
27610 +#include <sys/mman.h>
27611 +#include "tt.h"
27612 +#include "mem_user.h"
27613 +#include "user_util.h"
27614 +
27615 +void remap_data(void *segment_start, void *segment_end, int w)
27616 +{
27617 +       void *addr;
27618 +       unsigned long size;
27619 +       int data, prot;
27620 +
27621 +       if(w) prot = PROT_WRITE;
27622 +       else prot = 0;
27623 +       prot |= PROT_READ | PROT_EXEC;
27624 +       size = (unsigned long) segment_end - 
27625 +               (unsigned long) segment_start;
27626 +       data = create_mem_file(size);
27627 +       if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ, 
27628 +                       MAP_SHARED, data, 0)) == MAP_FAILED){
27629 +               perror("mapping new data segment");
27630 +               exit(1);
27631 +       }
27632 +       memcpy(addr, segment_start, size);
27633 +       if(switcheroo(data, prot, addr, segment_start, 
27634 +                     size) < 0){
27635 +               printf("switcheroo failed\n");
27636 +               exit(1);
27637 +       }
27638 +}
27639 +
27640 +/*
27641 + * Overrides for Emacs so that we follow Linus's tabbing style.
27642 + * Emacs will notice this stuff at the end of the file and automatically
27643 + * adjust the settings for this buffer only.  This must remain at the end
27644 + * of the file.
27645 + * ---------------------------------------------------------------------------
27646 + * Local variables:
27647 + * c-file-style: "linux"
27648 + * End:
27649 + */
27650 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/process_kern.c um/arch/um/kernel/tt/process_kern.c
27651 --- orig/arch/um/kernel/tt/process_kern.c       1969-12-31 19:00:00.000000000 -0500
27652 +++ um/arch/um/kernel/tt/process_kern.c 2003-05-29 13:46:00.000000000 -0400
27653 @@ -0,0 +1,517 @@
27654 +/* 
27655 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27656 + * Licensed under the GPL
27657 + */
27658 +
27659 +#include "linux/sched.h"
27660 +#include "linux/signal.h"
27661 +#include "linux/kernel.h"
27662 +#include "asm/system.h"
27663 +#include "asm/pgalloc.h"
27664 +#include "asm/ptrace.h"
27665 +#include "irq_user.h"
27666 +#include "signal_user.h"
27667 +#include "kern_util.h"
27668 +#include "user_util.h"
27669 +#include "os.h"
27670 +#include "kern.h"
27671 +#include "sigcontext.h"
27672 +#include "time_user.h"
27673 +#include "mem_user.h"
27674 +#include "tlb.h"
27675 +#include "mode.h"
27676 +#include "init.h"
27677 +#include "tt.h"
27678 +
27679 +void *_switch_to_tt(void *prev, void *next)
27680 +{
27681 +       struct task_struct *from, *to;
27682 +       unsigned long flags;
27683 +       int err, vtalrm, alrm, prof, cpu;
27684 +       char c;
27685 +       /* jailing and SMP are incompatible, so this doesn't need to be 
27686 +        * made per-cpu 
27687 +        */
27688 +       static int reading;
27689 +
27690 +       from = prev;
27691 +       to = next;
27692 +
27693 +       to->thread.prev_sched = from;
27694 +
27695 +       cpu = from->processor;
27696 +       if(cpu == 0)
27697 +               forward_interrupts(to->thread.mode.tt.extern_pid);
27698 +#ifdef CONFIG_SMP
27699 +       forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
27700 +#endif
27701 +       local_irq_save(flags);
27702 +
27703 +       vtalrm = change_sig(SIGVTALRM, 0);
27704 +       alrm = change_sig(SIGALRM, 0);
27705 +       prof = change_sig(SIGPROF, 0);
27706 +
27707 +       c = 0;
27708 +       set_current(to);
27709 +
27710 +       reading = 0;
27711 +       err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
27712 +       if(err != sizeof(c))
27713 +               panic("write of switch_pipe failed, errno = %d", -err);
27714 +
27715 +       reading = 1;
27716 +       if(from->state == TASK_ZOMBIE)
27717 +               os_kill_process(os_getpid(), 0);
27718 +
27719 +       err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
27720 +       if(err != sizeof(c))
27721 +               panic("read of switch_pipe failed, errno = %d", -err);
27722 +
27723 +       /* This works around a nasty race with 'jail'.  If we are switching
27724 +        * between two threads of a threaded app and the incoming process 
27725 +        * runs before the outgoing process reaches the read, and it makes
27726 +        * it all the way out to userspace, then it will have write-protected 
27727 +        * the outgoing process stack.  Then, when the outgoing process 
27728 +        * returns from the write, it will segfault because it can no longer
27729 +        * write its own stack.  So, in order to avoid that, the incoming 
27730 +        * thread sits in a loop yielding until 'reading' is set.  This 
27731 +        * isn't entirely safe, since there may be a reschedule from a timer
27732 +        * happening between setting 'reading' and sleeping in read.  But,
27733 +        * it should get a whole quantum in which to reach the read and sleep,
27734 +        * which should be enough.
27735 +        */
27736 +
27737 +       if(jail){
27738 +               while(!reading) sched_yield();
27739 +       }
27740 +
27741 +       change_sig(SIGVTALRM, vtalrm);
27742 +       change_sig(SIGALRM, alrm);
27743 +       change_sig(SIGPROF, prof);
27744 +
27745 +       arch_switch();
27746 +
27747 +       flush_tlb_all();
27748 +       local_irq_restore(flags);
27749 +
27750 +       return(current->thread.prev_sched);
27751 +}
27752 +
27753 +void release_thread_tt(struct task_struct *task)
27754 +{
27755 +       os_kill_process(task->thread.mode.tt.extern_pid, 0);
27756 +}
27757 +
27758 +void exit_thread_tt(void)
27759 +{
27760 +       close(current->thread.mode.tt.switch_pipe[0]);
27761 +       close(current->thread.mode.tt.switch_pipe[1]);
27762 +}
27763 +
27764 +extern void schedule_tail(struct task_struct *prev);
27765 +
27766 +static void new_thread_handler(int sig)
27767 +{
27768 +       int (*fn)(void *);
27769 +       void *arg;
27770 +
27771 +       fn = current->thread.request.u.thread.proc;
27772 +       arg = current->thread.request.u.thread.arg;
27773 +       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
27774 +       suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
27775 +
27776 +       init_new_thread_signals(1);
27777 +       enable_timer();
27778 +       free_page(current->thread.temp_stack);
27779 +       set_cmdline("(kernel thread)");
27780 +       force_flush_all();
27781 +
27782 +       if(current->thread.prev_sched != NULL)
27783 +               schedule_tail(current->thread.prev_sched);
27784 +       current->thread.prev_sched = NULL;
27785 +
27786 +       change_sig(SIGUSR1, 1);
27787 +       change_sig(SIGVTALRM, 1);
27788 +       change_sig(SIGPROF, 1);
27789 +       sti();
27790 +       if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
27791 +               do_exit(0);
27792 +}
27793 +
27794 +static int new_thread_proc(void *stack)
27795 +{
27796 +       cli();
27797 +       init_new_thread_stack(stack, new_thread_handler);
27798 +       os_usr1_process(os_getpid());
27799 +       return(0);
27800 +}
27801 +
27802 +/* Signal masking - signals are blocked at the start of fork_tramp.  They
27803 + * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
27804 + * itself with a SIGUSR1.  set_user_mode has to be run with SIGUSR1 off,
27805 + * so it is blocked before it's called.  They are re-enabled on sigreturn
27806 + * despite the fact that they were blocked when the SIGUSR1 was issued because
27807 + * copy_thread copies the parent's signcontext, including the signal mask
27808 + * onto the signal frame.
27809 + */
27810 +
27811 +static void finish_fork_handler(int sig)
27812 +{
27813 +       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
27814 +       suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
27815 +       
27816 +       init_new_thread_signals(1);
27817 +       enable_timer();
27818 +       sti();
27819 +       force_flush_all();
27820 +       if(current->mm != current->p_pptr->mm)
27821 +               protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
27822 +                              1, 0, 1);
27823 +       task_protections((unsigned long) current);
27824 +
27825 +       if(current->thread.prev_sched != NULL)
27826 +               schedule_tail(current->thread.prev_sched);
27827 +       current->thread.prev_sched = NULL;
27828 +
27829 +       free_page(current->thread.temp_stack);
27830 +       cli();
27831 +       change_sig(SIGUSR1, 0);
27832 +       set_user_mode(current);
27833 +}
27834 +
27835 +int fork_tramp(void *stack)
27836 +{
27837 +       cli();
27838 +       arch_init_thread();
27839 +       init_new_thread_stack(stack, finish_fork_handler);
27840 +       os_usr1_process(os_getpid());
27841 +       return(0);
27842 +}
27843 +
27844 +int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
27845 +                  unsigned long stack_top, struct task_struct * p, 
27846 +                  struct pt_regs *regs)
27847 +{
27848 +       int (*tramp)(void *);
27849 +       int new_pid, err;
27850 +       unsigned long stack;
27851 +       
27852 +       if(current->thread.forking)
27853 +               tramp = fork_tramp;
27854 +       else {
27855 +               tramp = new_thread_proc;
27856 +               p->thread.request.u.thread = current->thread.request.u.thread;
27857 +       }
27858 +
27859 +       err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
27860 +       if(err){
27861 +               printk("copy_thread : pipe failed, errno = %d\n", -err);
27862 +               return(err);
27863 +       }
27864 +
27865 +       stack = alloc_stack(0, 0);
27866 +       if(stack == 0){
27867 +               printk(KERN_ERR "copy_thread : failed to allocate "
27868 +                      "temporary stack\n");
27869 +               return(-ENOMEM);
27870 +       }
27871 +
27872 +       clone_flags &= CLONE_VM;
27873 +       p->thread.temp_stack = stack;
27874 +       new_pid = start_fork_tramp((void *) p->thread.kernel_stack, stack,
27875 +                                  clone_flags, tramp);
27876 +       if(new_pid < 0){
27877 +               printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", 
27878 +                      -new_pid);
27879 +               return(new_pid);
27880 +       }
27881 +
27882 +       if(current->thread.forking){
27883 +               sc_to_sc(UPT_SC(&p->thread.regs.regs), 
27884 +                        UPT_SC(&current->thread.regs.regs));
27885 +               SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
27886 +               if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
27887 +       }
27888 +       p->thread.mode.tt.extern_pid = new_pid;
27889 +
27890 +       current->thread.request.op = OP_FORK;
27891 +       current->thread.request.u.fork.pid = new_pid;
27892 +       os_usr1_process(os_getpid());
27893 +       return(0);
27894 +}
27895 +
27896 +void reboot_tt(void)
27897 +{
27898 +       current->thread.request.op = OP_REBOOT;
27899 +       os_usr1_process(os_getpid());
27900 +       os_kill_process(os_getpid(), 0);
27901 +}
27902 +
27903 +void halt_tt(void)
27904 +{
27905 +       current->thread.request.op = OP_HALT;
27906 +       os_usr1_process(os_getpid());
27907 +       os_kill_process(os_getpid(), 0);
27908 +}
27909 +
27910 +void kill_off_processes_tt(void)
27911 +{
27912 +       struct task_struct *p;
27913 +       int me;
27914 +
27915 +       me = os_getpid();
27916 +       for_each_task(p){
27917 +               int pid = p->thread.mode.tt.extern_pid;
27918 +               if((pid != me) && (pid != -1))
27919 +                       os_kill_process(p->thread.mode.tt.extern_pid, 0);
27920 +       }
27921 +       if((init_task.thread.mode.tt.extern_pid != me) &&
27922 +          (init_task.thread.mode.tt.extern_pid != -1))
27923 +               os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
27924 +}
27925 +
27926 +void initial_thread_cb_tt(void (*proc)(void *), void *arg)
27927 +{
27928 +       if(os_getpid() == tracing_pid){
27929 +               (*proc)(arg);
27930 +       }
27931 +       else {
27932 +               current->thread.request.op = OP_CB;
27933 +               current->thread.request.u.cb.proc = proc;
27934 +               current->thread.request.u.cb.arg = arg;
27935 +               os_usr1_process(os_getpid());
27936 +       }
27937 +}
27938 +
27939 +int do_proc_op(void *t, int proc_id)
27940 +{
27941 +       struct task_struct *task;
27942 +       struct thread_struct *thread;
27943 +       int op, pid;
27944 +
27945 +       task = t;
27946 +       thread = &task->thread;
27947 +       op = thread->request.op;
27948 +       switch(op){
27949 +       case OP_NONE:
27950 +       case OP_TRACE_ON:
27951 +               break;
27952 +       case OP_EXEC:
27953 +               pid = thread->request.u.exec.pid;
27954 +               do_exec(thread->mode.tt.extern_pid, pid);
27955 +               thread->mode.tt.extern_pid = pid;
27956 +               cpu_tasks[task->processor].pid = pid;
27957 +               break;
27958 +       case OP_FORK:
27959 +               attach_process(thread->request.u.fork.pid);
27960 +               break;
27961 +       case OP_CB:
27962 +               (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
27963 +               break;
27964 +       case OP_REBOOT:
27965 +       case OP_HALT:
27966 +               break;
27967 +       default:
27968 +               tracer_panic("Bad op in do_proc_op");
27969 +               break;
27970 +       }
27971 +       thread->request.op = OP_NONE;
27972 +       return(op);
27973 +}
27974 +
27975 +void init_idle_tt(void)
27976 +{
27977 +       idle_timer();
27978 +}
27979 +
27980 +/* Changed by jail_setup, which is a setup */
27981 +int jail = 0;
27982 +
27983 +int __init jail_setup(char *line, int *add)
27984 +{
27985 +       int ok = 1;
27986 +
27987 +       if(jail) return(0);
27988 +#ifdef CONFIG_SMP
27989 +       printf("'jail' may not used used in a kernel with CONFIG_SMP "
27990 +              "enabled\n");
27991 +       ok = 0;
27992 +#endif
27993 +#ifdef CONFIG_HOSTFS
27994 +       printf("'jail' may not used used in a kernel with CONFIG_HOSTFS "
27995 +              "enabled\n");
27996 +       ok = 0;
27997 +#endif
27998 +#ifdef CONFIG_MODULES
27999 +       printf("'jail' may not used used in a kernel with CONFIG_MODULES "
28000 +              "enabled\n");
28001 +       ok = 0;
28002 +#endif 
28003 +       if(!ok) exit(1);
28004 +
28005 +       /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem.
28006 +        * Removing it from the bounding set eliminates the ability of anything
28007 +        * to acquire it, and thus read or write kernel memory.
28008 +        */
28009 +       cap_lower(cap_bset, CAP_SYS_RAWIO);
28010 +       jail = 1;
28011 +       return(0);
28012 +}
28013 +
28014 +__uml_setup("jail", jail_setup,
28015 +"jail\n"
28016 +"    Enables the protection of kernel memory from processes.\n\n"
28017 +);
28018 +
28019 +static void mprotect_kernel_mem(int w)
28020 +{
28021 +       unsigned long start, end;
28022 +       int pages;
28023 +
28024 +       if(!jail || (current == &init_task)) return;
28025 +
28026 +       pages = (1 << CONFIG_KERNEL_STACK_ORDER);
28027 +
28028 +       start = (unsigned long) current + PAGE_SIZE;
28029 +       end = (unsigned long) current + PAGE_SIZE * pages;
28030 +       protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
28031 +       protect_memory(end, high_physmem - end, 1, w, 1, 1);
28032 +
28033 +       start = (unsigned long) UML_ROUND_DOWN(&_stext);
28034 +       end = (unsigned long) UML_ROUND_UP(&_etext);
28035 +       protect_memory(start, end - start, 1, w, 1, 1);
28036 +
28037 +       start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end);
28038 +       end = (unsigned long) UML_ROUND_UP(&_edata);
28039 +       protect_memory(start, end - start, 1, w, 1, 1);
28040 +
28041 +       start = (unsigned long) UML_ROUND_DOWN(&__bss_start);
28042 +       end = (unsigned long) UML_ROUND_UP(brk_start);
28043 +       protect_memory(start, end - start, 1, w, 1, 1);
28044 +
28045 +       mprotect_kernel_vm(w);
28046 +}
28047 +
28048 +void unprotect_kernel_mem(void)
28049 +{
28050 +       mprotect_kernel_mem(1);
28051 +}
28052 +
28053 +void protect_kernel_mem(void)
28054 +{
28055 +       mprotect_kernel_mem(0);
28056 +}
28057 +
28058 +extern void start_kernel(void);
28059 +
28060 +static int start_kernel_proc(void *unused)
28061 +{
28062 +       int pid;
28063 +
28064 +       block_signals();
28065 +       pid = os_getpid();
28066 +
28067 +       cpu_tasks[0].pid = pid;
28068 +       cpu_tasks[0].task = current;
28069 +#ifdef CONFIG_SMP
28070 +       cpu_online_map = 1;
28071 +#endif
28072 +       if(debug) os_stop_process(pid);
28073 +       start_kernel();
28074 +       return(0);
28075 +}
28076 +
28077 +void set_tracing(void *task, int tracing)
28078 +{
28079 +       ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
28080 +}
28081 +
28082 +int is_tracing(void *t)
28083 +{
28084 +       return (((struct task_struct *) t)->thread.mode.tt.tracing);
28085 +}
28086 +
28087 +int set_user_mode(void *t)
28088 +{
28089 +       struct task_struct *task;
28090 +
28091 +       task = t ? t : current;
28092 +       if(task->thread.mode.tt.tracing) 
28093 +               return(1);
28094 +       task->thread.request.op = OP_TRACE_ON;
28095 +       os_usr1_process(os_getpid());
28096 +       return(0);
28097 +}
28098 +
28099 +void set_init_pid(int pid)
28100 +{
28101 +       int err;
28102 +
28103 +       init_task.thread.mode.tt.extern_pid = pid;
28104 +       err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
28105 +       if(err) panic("Can't create switch pipe for init_task, errno = %d", 
28106 +                     err);
28107 +}
28108 +
28109 +int singlestepping_tt(void *t)
28110 +{
28111 +       struct task_struct *task = t;
28112 +
28113 +       if(task->thread.mode.tt.singlestep_syscall)
28114 +               return(0);
28115 +       return(task->ptrace & PT_DTRACE);
28116 +}
28117 +
28118 +void clear_singlestep(void *t)
28119 +{
28120 +       struct task_struct *task = t;
28121 +
28122 +       task->ptrace &= ~PT_DTRACE;
28123 +}
28124 +
28125 +int start_uml_tt(void)
28126 +{
28127 +       void *sp;
28128 +       int pages;
28129 +
28130 +       pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
28131 +       sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE - 
28132 +               sizeof(unsigned long);
28133 +       return(tracer(start_kernel_proc, sp));
28134 +}
28135 +
28136 +int external_pid_tt(struct task_struct *task)
28137 +{
28138 +       return(task->thread.mode.tt.extern_pid);
28139 +}
28140 +
28141 +int thread_pid_tt(struct thread_struct *thread)
28142 +{
28143 +       return(thread->mode.tt.extern_pid);
28144 +}
28145 +
28146 +int is_valid_pid(int pid)
28147 +{
28148 +       struct task_struct *task;
28149 +
28150 +        read_lock(&tasklist_lock);
28151 +        for_each_task(task){
28152 +                if(task->thread.mode.tt.extern_pid == pid){
28153 +                       read_unlock(&tasklist_lock);
28154 +                       return(1);
28155 +                }
28156 +        }
28157 +       read_unlock(&tasklist_lock);
28158 +       return(0);
28159 +}
28160 +
28161 +/*
28162 + * Overrides for Emacs so that we follow Linus's tabbing style.
28163 + * Emacs will notice this stuff at the end of the file and automatically
28164 + * adjust the settings for this buffer only.  This must remain at the end
28165 + * of the file.
28166 + * ---------------------------------------------------------------------------
28167 + * Local variables:
28168 + * c-file-style: "linux"
28169 + * End:
28170 + */
28171 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/Makefile um/arch/um/kernel/tt/ptproxy/Makefile
28172 --- orig/arch/um/kernel/tt/ptproxy/Makefile     1969-12-31 19:00:00.000000000 -0500
28173 +++ um/arch/um/kernel/tt/ptproxy/Makefile       2002-10-23 21:08:04.000000000 -0400
28174 @@ -0,0 +1,12 @@
28175 +O_TARGET = ptproxy.o
28176 +
28177 +obj-y = proxy.o ptrace.o sysdep.o wait.o
28178 +
28179 +USER_OBJS = $(obj-y)
28180 +
28181 +include $(TOPDIR)/Rules.make
28182 +
28183 +$(USER_OBJS) : %.o: %.c
28184 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
28185 +
28186 +clean:
28187 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/proxy.c um/arch/um/kernel/tt/ptproxy/proxy.c
28188 --- orig/arch/um/kernel/tt/ptproxy/proxy.c      1969-12-31 19:00:00.000000000 -0500
28189 +++ um/arch/um/kernel/tt/ptproxy/proxy.c        2003-04-16 14:01:03.000000000 -0400
28190 @@ -0,0 +1,370 @@
28191 +/**********************************************************************
28192 +proxy.c
28193 +
28194 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
28195 +terms and conditions.
28196 +
28197 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
28198 +**********************************************************************/
28199 +
28200 +/* XXX This file shouldn't refer to CONFIG_* */
28201 +
28202 +#include <errno.h>
28203 +#include <stdio.h>
28204 +#include <stdlib.h>
28205 +#include <unistd.h>
28206 +#include <signal.h>
28207 +#include <string.h>
28208 +#include <fcntl.h>
28209 +#include <termios.h>
28210 +#include <sys/wait.h>
28211 +#include <sys/types.h>
28212 +#include <sys/ptrace.h>
28213 +#include <sys/ioctl.h>
28214 +#include <asm/unistd.h>
28215 +
28216 +#include "ptproxy.h"
28217 +#include "sysdep.h"
28218 +#include "wait.h"
28219 +
28220 +#include "user_util.h"
28221 +#include "user.h"
28222 +#include "os.h"
28223 +#include "tempfile.h"
28224 +
28225 +static int debugger_wait(debugger_state *debugger, int *status, int options,
28226 +                        int (*syscall)(debugger_state *debugger, pid_t child),
28227 +                        int (*normal_return)(debugger_state *debugger, 
28228 +                                             pid_t unused),
28229 +                        int (*wait_return)(debugger_state *debugger, 
28230 +                                           pid_t unused))
28231 +{
28232 +       if(debugger->real_wait){
28233 +               debugger->handle_trace = normal_return;
28234 +               syscall_continue(debugger->pid);
28235 +               debugger->real_wait = 0;
28236 +               return(1);
28237 +       }
28238 +       debugger->wait_status_ptr = status;
28239 +       debugger->wait_options = options;
28240 +       if((debugger->debugee != NULL) && debugger->debugee->event){
28241 +               syscall_continue(debugger->pid);
28242 +               wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
28243 +                             NULL);
28244 +               (*wait_return)(debugger, -1);
28245 +               return(0);
28246 +       }
28247 +       else if(debugger->wait_options & WNOHANG){
28248 +               syscall_cancel(debugger->pid, 0);
28249 +               debugger->handle_trace = syscall;
28250 +               return(0);
28251 +       }
28252 +       else {
28253 +               syscall_pause(debugger->pid);
28254 +               debugger->handle_trace = wait_return;
28255 +               debugger->waiting = 1;
28256 +       }
28257 +       return(1);
28258 +}
28259 +
28260 +/*
28261 + * Handle debugger trap, i.e. syscall.
28262 + */
28263 +
28264 +int debugger_syscall(debugger_state *debugger, pid_t child)
28265 +{
28266 +       long arg1, arg2, arg3, arg4, arg5, result;
28267 +       int syscall, ret = 0;
28268 +
28269 +       syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4, 
28270 +                             &arg5);
28271 +
28272 +       switch(syscall){
28273 +       case __NR_execve:
28274 +               /* execve never returns */
28275 +               debugger->handle_trace = debugger_syscall; 
28276 +               break;
28277 +
28278 +       case __NR_ptrace:
28279 +               if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
28280 +               if(!debugger->debugee->in_context) 
28281 +                       child = debugger->debugee->pid;
28282 +               result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
28283 +                                     &ret);
28284 +               syscall_cancel(debugger->pid, result);
28285 +               debugger->handle_trace = debugger_syscall;
28286 +               return(ret);
28287 +
28288 +       case __NR_waitpid:
28289 +       case __NR_wait4:
28290 +               if(!debugger_wait(debugger, (int *) arg2, arg3, 
28291 +                                 debugger_syscall, debugger_normal_return, 
28292 +                                 proxy_wait_return))
28293 +                       return(0);
28294 +               break;
28295 +
28296 +       case __NR_kill:
28297 +               if(!debugger->debugee->in_context) 
28298 +                       child = debugger->debugee->pid;
28299 +               if(arg1 == debugger->debugee->pid){
28300 +                       result = kill(child, arg2);
28301 +                       syscall_cancel(debugger->pid, result);
28302 +                       debugger->handle_trace = debugger_syscall;
28303 +                       return(0);
28304 +               }
28305 +               else debugger->handle_trace = debugger_normal_return;
28306 +               break;
28307 +
28308 +       default:
28309 +               debugger->handle_trace = debugger_normal_return;
28310 +       }
28311 +
28312 +       syscall_continue(debugger->pid);
28313 +       return(0);
28314 +}
28315 +
28316 +/* Used by the tracing thread */
28317 +static debugger_state parent;
28318 +static int parent_syscall(debugger_state *debugger, int pid);
28319 +
28320 +int init_parent_proxy(int pid)
28321 +{
28322 +       parent = ((debugger_state) { .pid               = pid,
28323 +                                    .wait_options      = 0,
28324 +                                    .wait_status_ptr   = NULL,
28325 +                                    .waiting           = 0,
28326 +                                    .real_wait         = 0,
28327 +                                    .expecting_child   = 0,
28328 +                                    .handle_trace      = parent_syscall,
28329 +                                    .debugee           = NULL } );
28330 +       return(0);
28331 +}
28332 +
28333 +int parent_normal_return(debugger_state *debugger, pid_t unused)
28334 +{
28335 +       debugger->handle_trace = parent_syscall;
28336 +       syscall_continue(debugger->pid);
28337 +       return(0);
28338 +}
28339 +
28340 +static int parent_syscall(debugger_state *debugger, int pid)
28341 +{
28342 +       long arg1, arg2, arg3, arg4, arg5;
28343 +       int syscall;
28344 +
28345 +       syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
28346 +               
28347 +       if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
28348 +               debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
28349 +                             parent_normal_return, parent_wait_return);
28350 +       }
28351 +       else ptrace(PTRACE_SYSCALL, pid, 0, 0);
28352 +       return(0);
28353 +}
28354 +
28355 +int debugger_normal_return(debugger_state *debugger, pid_t unused)
28356 +{
28357 +       debugger->handle_trace = debugger_syscall;
28358 +       syscall_continue(debugger->pid);
28359 +       return(0);
28360 +}
28361 +
28362 +void debugger_cancelled_return(debugger_state *debugger, int result)
28363 +{
28364 +       debugger->handle_trace = debugger_syscall;
28365 +       syscall_set_result(debugger->pid, result);
28366 +       syscall_continue(debugger->pid);
28367 +}
28368 +
28369 +/* Used by the tracing thread */
28370 +static debugger_state debugger;
28371 +static debugee_state debugee;
28372 +
28373 +void init_proxy (pid_t debugger_pid, int stopped, int status)
28374 +{
28375 +       debugger.pid = debugger_pid;
28376 +       debugger.handle_trace = debugger_syscall;
28377 +       debugger.debugee = &debugee;
28378 +       debugger.waiting = 0;
28379 +       debugger.real_wait = 0;
28380 +       debugger.expecting_child = 0;
28381 +
28382 +       debugee.pid = 0;
28383 +       debugee.traced = 0;
28384 +       debugee.stopped = stopped;
28385 +       debugee.event = 0;
28386 +       debugee.zombie = 0;
28387 +       debugee.died = 0;
28388 +       debugee.wait_status = status;
28389 +       debugee.in_context = 1;
28390 +}
28391 +
28392 +int debugger_proxy(int status, int pid)
28393 +{
28394 +       int ret = 0, sig;
28395 +
28396 +       if(WIFSTOPPED(status)){
28397 +               sig = WSTOPSIG(status);
28398 +               if (sig == SIGTRAP)
28399 +                       ret = (*debugger.handle_trace)(&debugger, pid);
28400 +                                                      
28401 +               else if(sig == SIGCHLD){
28402 +                       if(debugger.expecting_child){
28403 +                               ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28404 +                               debugger.expecting_child = 0;
28405 +                       }
28406 +                       else if(debugger.waiting)
28407 +                               real_wait_return(&debugger);
28408 +                       else {
28409 +                               ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28410 +                               debugger.real_wait = 1;
28411 +                       }
28412 +               }
28413 +               else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
28414 +       }
28415 +       else if(WIFEXITED(status)){
28416 +               tracer_panic("debugger (pid %d) exited with status %d", 
28417 +                            debugger.pid, WEXITSTATUS(status));
28418 +       }
28419 +       else if(WIFSIGNALED(status)){
28420 +               tracer_panic("debugger (pid %d) exited with signal %d", 
28421 +                            debugger.pid, WTERMSIG(status));
28422 +       }
28423 +       else {
28424 +               tracer_panic("proxy got unknown status (0x%x) on debugger "
28425 +                            "(pid %d)", status, debugger.pid);
28426 +       }
28427 +       return(ret);
28428 +}
28429 +
28430 +void child_proxy(pid_t pid, int status)
28431 +{
28432 +       debugee.event = 1;
28433 +       debugee.wait_status = status;
28434 +
28435 +       if(WIFSTOPPED(status)){
28436 +               debugee.stopped = 1;
28437 +               debugger.expecting_child = 1;
28438 +               kill(debugger.pid, SIGCHLD);
28439 +       }
28440 +       else if(WIFEXITED(status) || WIFSIGNALED(status)){
28441 +               debugee.zombie = 1;
28442 +               debugger.expecting_child = 1;
28443 +               kill(debugger.pid, SIGCHLD);
28444 +       }
28445 +       else panic("proxy got unknown status (0x%x) on child (pid %d)", 
28446 +                  status, pid);
28447 +}
28448 +
28449 +void debugger_parent_signal(int status, int pid)
28450 +{
28451 +       int sig;
28452 +
28453 +       if(WIFSTOPPED(status)){
28454 +               sig = WSTOPSIG(status);
28455 +               if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
28456 +               else ptrace(PTRACE_SYSCALL, pid, 0, sig);
28457 +       }
28458 +}
28459 +
28460 +void fake_child_exit(void)
28461 +{
28462 +       int status, pid;
28463 +
28464 +       child_proxy(1, W_EXITCODE(0, 0));
28465 +       while(debugger.waiting == 1){
28466 +               pid = waitpid(debugger.pid, &status, WUNTRACED);
28467 +               if(pid != debugger.pid){
28468 +                       printk("fake_child_exit - waitpid failed, "
28469 +                              "errno = %d\n", errno);
28470 +                       return;
28471 +               }
28472 +               debugger_proxy(status, debugger.pid);
28473 +       }
28474 +       pid = waitpid(debugger.pid, &status, WUNTRACED);
28475 +       if(pid != debugger.pid){
28476 +               printk("fake_child_exit - waitpid failed, "
28477 +                      "errno = %d\n", errno);
28478 +               return;
28479 +       }
28480 +       if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
28481 +               printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
28482 +                      errno);
28483 +}
28484 +
28485 +char gdb_init_string[] = 
28486 +"att 1 \n\
28487 +b panic \n\
28488 +b stop \n\
28489 +handle SIGWINCH nostop noprint pass \n\
28490 +";
28491 +
28492 +int start_debugger(char *prog, int startup, int stop, int *fd_out)
28493 +{
28494 +       int slave, child;
28495 +
28496 +       slave = open_gdb_chan();
28497 +       if((child = fork()) == 0){
28498 +               char *tempname = NULL;
28499 +               int fd;
28500 +
28501 +               if(setsid() < 0) perror("setsid");
28502 +               if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) || 
28503 +                  (dup2(slave, 2) < 0)){
28504 +                       printk("start_debugger : dup2 failed, errno = %d\n",
28505 +                              errno);
28506 +                       exit(1);
28507 +               }
28508 +               if(ioctl(0, TIOCSCTTY, 0) < 0){
28509 +                       printk("start_debugger : TIOCSCTTY failed, "
28510 +                              "errno = %d\n", errno);
28511 +                       exit(1);
28512 +               }
28513 +               if(tcsetpgrp (1, os_getpid()) < 0){
28514 +                       printk("start_debugger : tcsetpgrp failed, "
28515 +                              "errno = %d\n", errno);
28516 +#ifdef notdef
28517 +                       exit(1);
28518 +#endif
28519 +               }
28520 +               if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
28521 +                       printk("start_debugger : make_tempfile failed, errno = %d\n",
28522 +                              errno);
28523 +                       exit(1);
28524 +               }
28525 +               write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
28526 +               if(startup){
28527 +                       if(stop){
28528 +                               write(fd, "b start_kernel\n",
28529 +                                     strlen("b start_kernel\n"));
28530 +                       }
28531 +                       write(fd, "c\n", strlen("c\n"));
28532 +               }
28533 +               if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
28534 +                       printk("start_debugger :  PTRACE_TRACEME failed, "
28535 +                              "errno = %d\n", errno);
28536 +                       exit(1);
28537 +               }
28538 +               execlp("gdb", "gdb", "--command", tempname, prog, NULL);
28539 +               printk("start_debugger : exec of gdb failed, errno = %d\n",
28540 +                      errno);
28541 +       }
28542 +       if(child < 0){
28543 +               printk("start_debugger : fork for gdb failed, errno = %d\n",
28544 +                      errno);
28545 +               return(-1);
28546 +       }
28547 +       *fd_out = slave;
28548 +       return(child);
28549 +}
28550 +
28551 +/*
28552 + * Overrides for Emacs so that we follow Linus's tabbing style.
28553 + * Emacs will notice this stuff at the end of the file and automatically
28554 + * adjust the settings for this buffer only.  This must remain at the end
28555 + * of the file.
28556 + * ---------------------------------------------------------------------------
28557 + * Local variables:
28558 + * c-file-style: "linux"
28559 + * End:
28560 + */
28561 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptproxy.h um/arch/um/kernel/tt/ptproxy/ptproxy.h
28562 --- orig/arch/um/kernel/tt/ptproxy/ptproxy.h    1969-12-31 19:00:00.000000000 -0500
28563 +++ um/arch/um/kernel/tt/ptproxy/ptproxy.h      2002-10-23 21:08:04.000000000 -0400
28564 @@ -0,0 +1,61 @@
28565 +/**********************************************************************
28566 +ptproxy.h
28567 +
28568 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
28569 +terms and conditions.
28570 +**********************************************************************/
28571 +
28572 +#ifndef __PTPROXY_H
28573 +#define __PTPROXY_H
28574 +
28575 +#include <sys/types.h>
28576 +
28577 +typedef struct debugger debugger_state;
28578 +typedef struct debugee debugee_state;
28579 +
28580 +struct debugger
28581 +{
28582 +       pid_t pid;
28583 +       int wait_options;
28584 +       int *wait_status_ptr;
28585 +       unsigned int waiting : 1;
28586 +       unsigned int real_wait : 1;
28587 +       unsigned int expecting_child : 1;
28588 +       int (*handle_trace) (debugger_state *, pid_t);
28589 +
28590 +       debugee_state *debugee;
28591 +};
28592 +
28593 +struct debugee
28594 +{
28595 +       pid_t pid;
28596 +       int wait_status;
28597 +       unsigned int died : 1;
28598 +       unsigned int event : 1;
28599 +       unsigned int stopped : 1;
28600 +       unsigned int trace_singlestep : 1;
28601 +       unsigned int trace_syscall : 1;
28602 +       unsigned int traced : 1;
28603 +       unsigned int zombie : 1;
28604 +       unsigned int in_context : 1;
28605 +};
28606 +
28607 +extern int debugger_syscall(debugger_state *debugger, pid_t pid);
28608 +extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
28609 +
28610 +extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
28611 +                         int *strace_out);
28612 +extern void debugger_cancelled_return(debugger_state *debugger, int result);
28613 +
28614 +#endif
28615 +
28616 +/*
28617 + * Overrides for Emacs so that we follow Linus's tabbing style.
28618 + * Emacs will notice this stuff at the end of the file and automatically
28619 + * adjust the settings for this buffer only.  This must remain at the end
28620 + * of the file.
28621 + * ---------------------------------------------------------------------------
28622 + * Local variables:
28623 + * c-file-style: "linux"
28624 + * End:
28625 + */
28626 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptrace.c um/arch/um/kernel/tt/ptproxy/ptrace.c
28627 --- orig/arch/um/kernel/tt/ptproxy/ptrace.c     1969-12-31 19:00:00.000000000 -0500
28628 +++ um/arch/um/kernel/tt/ptproxy/ptrace.c       2002-11-11 13:06:03.000000000 -0500
28629 @@ -0,0 +1,239 @@
28630 +/**********************************************************************
28631 +ptrace.c
28632 +
28633 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
28634 +terms and conditions.
28635 +
28636 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
28637 +**********************************************************************/
28638 +
28639 +#include <errno.h>
28640 +#include <unistd.h>
28641 +#include <signal.h>
28642 +#include <sys/types.h>
28643 +#include <sys/time.h>
28644 +#include <sys/ptrace.h>
28645 +#include <sys/wait.h>
28646 +#include <asm/ptrace.h>
28647 +
28648 +#include "ptproxy.h"
28649 +#include "debug.h"
28650 +#include "user_util.h"
28651 +#include "kern_util.h"
28652 +#include "ptrace_user.h"
28653 +#include "tt.h"
28654 +
28655 +long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
28656 +                 long arg3, long arg4, pid_t child, int *ret)
28657 +{
28658 +       sigset_t relay;
28659 +       long result;
28660 +       int status;
28661 +
28662 +       *ret = 0;
28663 +       if(debugger->debugee->died) return(-ESRCH);
28664 +
28665 +       switch(arg1){
28666 +       case PTRACE_ATTACH:
28667 +               if(debugger->debugee->traced) return(-EPERM);
28668 +
28669 +               debugger->debugee->pid = arg2;
28670 +               debugger->debugee->traced = 1;
28671 +
28672 +               if(is_valid_pid(arg2) && (arg2 != child)){
28673 +                       debugger->debugee->in_context = 0;
28674 +                       kill(arg2, SIGSTOP);
28675 +                       debugger->debugee->event = 1;
28676 +                       debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
28677 +               }
28678 +               else {
28679 +                       debugger->debugee->in_context = 1;
28680 +                       if(debugger->debugee->stopped) 
28681 +                               child_proxy(child, W_STOPCODE(SIGSTOP));
28682 +                       else kill(child, SIGSTOP);
28683 +               }
28684 +
28685 +               return(0);
28686 +
28687 +       case PTRACE_DETACH:
28688 +               if(!debugger->debugee->traced) return(-EPERM);
28689 +               
28690 +               debugger->debugee->traced = 0;
28691 +               debugger->debugee->pid = 0;
28692 +               if(!debugger->debugee->in_context)
28693 +                       kill(child, SIGCONT);
28694 +
28695 +               return(0);
28696 +
28697 +       case PTRACE_CONT:
28698 +               if(!debugger->debugee->in_context) return(-EPERM);
28699 +               *ret = PTRACE_CONT;
28700 +               return(ptrace(PTRACE_CONT, child, arg3, arg4));
28701 +
28702 +#ifdef UM_HAVE_GETFPREGS
28703 +       case PTRACE_GETFPREGS:
28704 +       {
28705 +               long regs[FP_FRAME_SIZE];
28706 +               int i, result;
28707 +
28708 +               result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
28709 +               if(result == -1) return(-errno);
28710 +               
28711 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28712 +                       ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
28713 +                              regs[i]);
28714 +               return(result);
28715 +       }
28716 +#endif
28717 +
28718 +#ifdef UM_HAVE_GETFPXREGS
28719 +       case PTRACE_GETFPXREGS:
28720 +       {
28721 +               long regs[FPX_FRAME_SIZE];
28722 +               int i, result;
28723 +
28724 +               result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
28725 +               if(result == -1) return(-errno);
28726 +               
28727 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28728 +                       ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
28729 +                              regs[i]);
28730 +               return(result);
28731 +       }
28732 +#endif
28733 +
28734 +#ifdef UM_HAVE_GETREGS
28735 +       case PTRACE_GETREGS:
28736 +       {
28737 +               long regs[FRAME_SIZE];
28738 +               int i, result;
28739 +
28740 +               result = ptrace(PTRACE_GETREGS, child, 0, regs);
28741 +               if(result == -1) return(-errno);
28742 +
28743 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28744 +                       ptrace (PTRACE_POKEDATA, debugger->pid,
28745 +                               arg4 + 4 * i, regs[i]);
28746 +               return(result);
28747 +       }
28748 +       break;
28749 +#endif
28750 +
28751 +       case PTRACE_KILL:
28752 +               result = ptrace(PTRACE_KILL, child, arg3, arg4);
28753 +               if(result == -1) return(-errno);
28754 +
28755 +               return(result);
28756 +
28757 +       case PTRACE_PEEKDATA:
28758 +       case PTRACE_PEEKTEXT:
28759 +       case PTRACE_PEEKUSER:
28760 +               /* The value being read out could be -1, so we have to 
28761 +                * check errno to see if there's an error, and zero it
28762 +                * beforehand so we're not faked out by an old error
28763 +                */
28764 +
28765 +               errno = 0;
28766 +               result = ptrace(arg1, child, arg3, 0);
28767 +               if((result == -1) && (errno != 0)) return(-errno);
28768 +
28769 +               result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
28770 +               if(result == -1) return(-errno);
28771 +                       
28772 +               return(result);
28773 +
28774 +       case PTRACE_POKEDATA:
28775 +       case PTRACE_POKETEXT:
28776 +       case PTRACE_POKEUSER:
28777 +               result = ptrace(arg1, child, arg3, arg4);
28778 +               if(result == -1) return(-errno);
28779 +
28780 +               if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
28781 +               return(result);
28782 +
28783 +#ifdef UM_HAVE_SETFPREGS
28784 +       case PTRACE_SETFPREGS:
28785 +       {
28786 +               long regs[FP_FRAME_SIZE];
28787 +               int i;
28788 +
28789 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28790 +                       regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
28791 +                                         arg4 + 4 * i, 0);
28792 +               result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
28793 +               if(result == -1) return(-errno);
28794 +
28795 +               return(result);
28796 +       }
28797 +#endif
28798 +
28799 +#ifdef UM_HAVE_SETFPXREGS
28800 +       case PTRACE_SETFPXREGS:
28801 +       {
28802 +               long regs[FPX_FRAME_SIZE];
28803 +               int i;
28804 +
28805 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28806 +                       regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
28807 +                                         arg4 + 4 * i, 0);
28808 +               result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
28809 +               if(result == -1) return(-errno);
28810 +
28811 +               return(result);
28812 +       }
28813 +#endif
28814 +
28815 +#ifdef UM_HAVE_SETREGS
28816 +       case PTRACE_SETREGS:
28817 +       {
28818 +               long regs[FRAME_SIZE];
28819 +               int i;
28820 +
28821 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
28822 +                       regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
28823 +                                        arg4 + 4 * i, 0);
28824 +               result = ptrace(PTRACE_SETREGS, child, 0, regs);
28825 +               if(result == -1) return(-errno);
28826 +
28827 +               return(result);
28828 +       }
28829 +#endif
28830 +
28831 +       case PTRACE_SINGLESTEP:
28832 +               if(!debugger->debugee->in_context) return(-EPERM);
28833 +               sigemptyset(&relay);
28834 +               sigaddset(&relay, SIGSEGV);
28835 +               sigaddset(&relay, SIGILL);
28836 +               sigaddset(&relay, SIGBUS);
28837 +               result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
28838 +               if(result == -1) return(-errno);
28839 +               
28840 +               status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
28841 +                                      &relay);
28842 +               child_proxy(child, status);
28843 +               return(result);
28844 +
28845 +       case PTRACE_SYSCALL:
28846 +               if(!debugger->debugee->in_context) return(-EPERM);
28847 +               result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
28848 +               if(result == -1) return(-errno);
28849 +
28850 +               *ret = PTRACE_SYSCALL;
28851 +               return(result);
28852 +
28853 +       case PTRACE_TRACEME:
28854 +       default:
28855 +               return(-EINVAL);
28856 +       }
28857 +}
28858 +
28859 +/*
28860 + * Overrides for Emacs so that we follow Linus's tabbing style.
28861 + * Emacs will notice this stuff at the end of the file and automatically
28862 + * adjust the settings for this buffer only.  This must remain at the end
28863 + * of the file.
28864 + * ---------------------------------------------------------------------------
28865 + * Local variables:
28866 + * c-file-style: "linux"
28867 + * End:
28868 + */
28869 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.c um/arch/um/kernel/tt/ptproxy/sysdep.c
28870 --- orig/arch/um/kernel/tt/ptproxy/sysdep.c     1969-12-31 19:00:00.000000000 -0500
28871 +++ um/arch/um/kernel/tt/ptproxy/sysdep.c       2002-10-23 21:08:04.000000000 -0400
28872 @@ -0,0 +1,71 @@
28873 +/**********************************************************************
28874 +sysdep.c
28875 +
28876 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
28877 +terms and conditions.
28878 +**********************************************************************/
28879 +
28880 +#include <stdio.h>
28881 +#include <string.h>
28882 +#include <stdlib.h>
28883 +#include <signal.h>
28884 +#include <sys/types.h>
28885 +#include <sys/ptrace.h>
28886 +#include <asm/ptrace.h>
28887 +#include <linux/unistd.h>
28888 +#include "ptrace_user.h"
28889 +#include "user_util.h"
28890 +#include "user.h"
28891 +
28892 +int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, 
28893 +               long *arg5)
28894 +{
28895 +       *arg1 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG1_OFFSET, 0);
28896 +       *arg2 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG2_OFFSET, 0);
28897 +       *arg3 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG3_OFFSET, 0);
28898 +       *arg4 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG4_OFFSET, 0);
28899 +       *arg5 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG5_OFFSET, 0);
28900 +       return(ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0));
28901 +}
28902 +
28903 +void syscall_cancel(pid_t pid, int result)
28904 +{
28905 +       if((ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
28906 +                  __NR_getpid) < 0) ||
28907 +          (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
28908 +          (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
28909 +          (ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
28910 +          (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
28911 +               printk("ptproxy: couldn't cancel syscall: errno = %d\n", 
28912 +                      errno);
28913 +}
28914 +
28915 +void syscall_set_result(pid_t pid, long result)
28916 +{
28917 +       ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result);
28918 +}
28919 +
28920 +void syscall_continue(pid_t pid)
28921 +{
28922 +       ptrace(PTRACE_SYSCALL, pid, 0, 0);
28923 +}
28924 +
28925 +int syscall_pause(pid_t pid) 
28926 +{
28927 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
28928 +               printk("syscall_change - ptrace failed, errno = %d\n", errno);
28929 +               return(-1);
28930 +       }
28931 +       return(0);
28932 +}
28933 +
28934 +/*
28935 + * Overrides for Emacs so that we follow Linus's tabbing style.
28936 + * Emacs will notice this stuff at the end of the file and automatically
28937 + * adjust the settings for this buffer only.  This must remain at the end
28938 + * of the file.
28939 + * ---------------------------------------------------------------------------
28940 + * Local variables:
28941 + * c-file-style: "linux"
28942 + * End:
28943 + */
28944 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.h um/arch/um/kernel/tt/ptproxy/sysdep.h
28945 --- orig/arch/um/kernel/tt/ptproxy/sysdep.h     1969-12-31 19:00:00.000000000 -0500
28946 +++ um/arch/um/kernel/tt/ptproxy/sysdep.h       2002-10-23 21:08:04.000000000 -0400
28947 @@ -0,0 +1,25 @@
28948 +/**********************************************************************
28949 +sysdep.h
28950 +
28951 +Copyright (C) 1999 Lars Brinkhoff.
28952 +Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
28953 +See the file COPYING for licensing terms and conditions.
28954 +**********************************************************************/
28955 +
28956 +extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, 
28957 +                      long *arg4, long *arg5);
28958 +extern void syscall_cancel (pid_t pid, long result);
28959 +extern void syscall_set_result (pid_t pid, long result);
28960 +extern void syscall_continue (pid_t pid);
28961 +extern int syscall_pause(pid_t pid);
28962 +
28963 +/*
28964 + * Overrides for Emacs so that we follow Linus's tabbing style.
28965 + * Emacs will notice this stuff at the end of the file and automatically
28966 + * adjust the settings for this buffer only.  This must remain at the end
28967 + * of the file.
28968 + * ---------------------------------------------------------------------------
28969 + * Local variables:
28970 + * c-file-style: "linux"
28971 + * End:
28972 + */
28973 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.c um/arch/um/kernel/tt/ptproxy/wait.c
28974 --- orig/arch/um/kernel/tt/ptproxy/wait.c       1969-12-31 19:00:00.000000000 -0500
28975 +++ um/arch/um/kernel/tt/ptproxy/wait.c 2002-10-23 21:08:04.000000000 -0400
28976 @@ -0,0 +1,86 @@
28977 +/**********************************************************************
28978 +wait.c
28979 +
28980 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
28981 +terms and conditions.
28982 +
28983 +**********************************************************************/
28984 +
28985 +#include <errno.h>
28986 +#include <signal.h>
28987 +#include <sys/wait.h>
28988 +#include <sys/ptrace.h>
28989 +#include <asm/ptrace.h>
28990 +
28991 +#include "ptproxy.h"
28992 +#include "sysdep.h"
28993 +#include "wait.h"
28994 +#include "user_util.h"
28995 +#include "sysdep/ptrace.h"
28996 +#include "sysdep/ptrace_user.h"
28997 +#include "sysdep/sigcontext.h"
28998 +
28999 +int proxy_wait_return(struct debugger *debugger, pid_t unused)
29000 +{
29001 +       debugger->waiting = 0;
29002 +
29003 +       if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
29004 +               debugger_cancelled_return(debugger, -ECHILD);
29005 +               return(0);
29006 +       }
29007 +
29008 +       if(debugger->debugee->zombie && debugger->debugee->event)
29009 +               debugger->debugee->died = 1;
29010 +
29011 +       if(debugger->debugee->event){
29012 +               debugger->debugee->event = 0;
29013 +               ptrace(PTRACE_POKEDATA, debugger->pid,
29014 +                      debugger->wait_status_ptr, 
29015 +                      debugger->debugee->wait_status);
29016 +               /* if (wait4)
29017 +                  ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
29018 +               debugger_cancelled_return(debugger, debugger->debugee->pid);
29019 +               return(0);
29020 +       }
29021 +
29022 +       /* pause will return -EINTR, which happens to be right for wait */
29023 +       debugger_normal_return(debugger, -1);
29024 +       return(0);
29025 +}
29026 +
29027 +int parent_wait_return(struct debugger *debugger, pid_t unused)
29028 +{
29029 +       return(debugger_normal_return(debugger, -1));
29030 +}
29031 +
29032 +int real_wait_return(struct debugger *debugger)
29033 +{
29034 +       unsigned long ip;
29035 +       int err, pid;
29036 +
29037 +       pid = debugger->pid;
29038 +       ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
29039 +       ip = IP_RESTART_SYSCALL(ip);
29040 +       err = ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip);
29041 +       if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
29042 +               tracer_panic("real_wait_return : Failed to restart system "
29043 +                            "call, errno = %d\n");
29044 +       if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
29045 +          (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
29046 +          (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
29047 +          debugger_normal_return(debugger, -1))
29048 +               tracer_panic("real_wait_return : gdb failed to wait, "
29049 +                            "errno = %d\n");
29050 +       return(0);
29051 +}
29052 +
29053 +/*
29054 + * Overrides for Emacs so that we follow Linus's tabbing style.
29055 + * Emacs will notice this stuff at the end of the file and automatically
29056 + * adjust the settings for this buffer only.  This must remain at the end
29057 + * of the file.
29058 + * ---------------------------------------------------------------------------
29059 + * Local variables:
29060 + * c-file-style: "linux"
29061 + * End:
29062 + */
29063 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.h um/arch/um/kernel/tt/ptproxy/wait.h
29064 --- orig/arch/um/kernel/tt/ptproxy/wait.h       1969-12-31 19:00:00.000000000 -0500
29065 +++ um/arch/um/kernel/tt/ptproxy/wait.h 2002-10-23 21:08:04.000000000 -0400
29066 @@ -0,0 +1,15 @@
29067 +/**********************************************************************
29068 +wait.h
29069 +
29070 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
29071 +terms and conditions.
29072 +**********************************************************************/
29073 +
29074 +#ifndef __PTPROXY_WAIT_H
29075 +#define __PTPROXY_WAIT_H
29076 +
29077 +extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
29078 +extern int real_wait_return(struct debugger *debugger);
29079 +extern int parent_wait_return(struct debugger *debugger, pid_t unused);
29080 +
29081 +#endif
29082 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_kern.c um/arch/um/kernel/tt/syscall_kern.c
29083 --- orig/arch/um/kernel/tt/syscall_kern.c       1969-12-31 19:00:00.000000000 -0500
29084 +++ um/arch/um/kernel/tt/syscall_kern.c 2002-12-08 19:32:53.000000000 -0500
29085 @@ -0,0 +1,142 @@
29086 +/* 
29087 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
29088 + * Licensed under the GPL
29089 + */
29090 +
29091 +#include "linux/types.h"
29092 +#include "linux/utime.h"
29093 +#include "linux/sys.h"
29094 +#include "asm/unistd.h"
29095 +#include "asm/ptrace.h"
29096 +#include "asm/uaccess.h"
29097 +#include "sysdep/syscalls.h"
29098 +#include "kern_util.h"
29099 +
29100 +static inline int check_area(void *ptr, int size)
29101 +{
29102 +       return(verify_area(VERIFY_WRITE, ptr, size));
29103 +}
29104 +
29105 +static int check_readlink(struct pt_regs *regs)
29106 +{
29107 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
29108 +                         UPT_SYSCALL_ARG2(&regs->regs)));
29109 +}
29110 +
29111 +static int check_utime(struct pt_regs *regs)
29112 +{
29113 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
29114 +                         sizeof(struct utimbuf)));
29115 +}
29116 +
29117 +static int check_oldstat(struct pt_regs *regs)
29118 +{
29119 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
29120 +                         sizeof(struct __old_kernel_stat)));
29121 +}
29122 +
29123 +static int check_stat(struct pt_regs *regs)
29124 +{
29125 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
29126 +                         sizeof(struct stat)));
29127 +}
29128 +
29129 +static int check_stat64(struct pt_regs *regs)
29130 +{
29131 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
29132 +                         sizeof(struct stat64)));
29133 +}
29134 +
29135 +struct bogus {
29136 +       int kernel_ds;
29137 +       int (*check_params)(struct pt_regs *);
29138 +};
29139 +
29140 +struct bogus this_is_bogus[256] = {
29141 +       [ __NR_mknod ] = { 1, NULL },
29142 +       [ __NR_mkdir ] = { 1, NULL },
29143 +       [ __NR_rmdir ] = { 1, NULL },
29144 +       [ __NR_unlink ] = { 1, NULL },
29145 +       [ __NR_symlink ] = { 1, NULL },
29146 +       [ __NR_link ] = { 1, NULL },
29147 +       [ __NR_rename ] = { 1, NULL },
29148 +       [ __NR_umount ] = { 1, NULL },
29149 +       [ __NR_mount ] = { 1, NULL },
29150 +       [ __NR_pivot_root ] = { 1, NULL },
29151 +       [ __NR_chdir ] = { 1, NULL },
29152 +       [ __NR_chroot ] = { 1, NULL },
29153 +       [ __NR_open ] = { 1, NULL },
29154 +       [ __NR_quotactl ] = { 1, NULL },
29155 +       [ __NR_sysfs ] = { 1, NULL },
29156 +       [ __NR_readlink ] = { 1, check_readlink },
29157 +       [ __NR_acct ] = { 1, NULL },
29158 +       [ __NR_execve ] = { 1, NULL },
29159 +       [ __NR_uselib ] = { 1, NULL },
29160 +       [ __NR_statfs ] = { 1, NULL },
29161 +       [ __NR_truncate ] = { 1, NULL },
29162 +       [ __NR_access ] = { 1, NULL },
29163 +       [ __NR_chmod ] = { 1, NULL },
29164 +       [ __NR_chown ] = { 1, NULL },
29165 +       [ __NR_lchown ] = { 1, NULL },
29166 +       [ __NR_utime ] = { 1, check_utime },
29167 +       [ __NR_oldlstat ] = { 1, check_oldstat },
29168 +       [ __NR_oldstat ] = { 1, check_oldstat },
29169 +       [ __NR_stat ] = { 1, check_stat },
29170 +       [ __NR_lstat ] = { 1, check_stat },
29171 +       [ __NR_stat64 ] = { 1, check_stat64 },
29172 +       [ __NR_lstat64 ] = { 1, check_stat64 },
29173 +       [ __NR_chown32 ] = { 1, NULL },
29174 +};
29175 +
29176 +/* sys_utimes */
29177 +
29178 +static int check_bogosity(struct pt_regs *regs)
29179 +{
29180 +       struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
29181 +
29182 +       if(!bogon->kernel_ds) return(0);
29183 +       if(bogon->check_params && (*bogon->check_params)(regs))
29184 +               return(-EFAULT);
29185 +       set_fs(KERNEL_DS);
29186 +       return(0);
29187 +}
29188 +
29189 +extern syscall_handler_t *sys_call_table[];
29190 +
29191 +long execute_syscall_tt(void *r)
29192 +{
29193 +       struct pt_regs *regs = r;
29194 +       long res;
29195 +       int syscall;
29196 +
29197 +       current->thread.nsyscalls++;
29198 +       nsyscalls++;
29199 +       syscall = UPT_SYSCALL_NR(&regs->regs);
29200 +
29201 +       if((syscall >= NR_syscalls) || (syscall < 0))
29202 +               res = -ENOSYS;
29203 +       else if(honeypot && check_bogosity(regs))
29204 +               res = -EFAULT;
29205 +       else res = EXECUTE_SYSCALL(syscall, regs);
29206 +
29207 +       set_fs(USER_DS);
29208 +
29209 +       if(current->thread.mode.tt.singlestep_syscall){
29210 +               current->thread.mode.tt.singlestep_syscall = 0;
29211 +               current->ptrace &= ~PT_DTRACE;
29212 +               force_sig(SIGTRAP, current);
29213 +       }
29214 +
29215 +       return(res);
29216 +}
29217 +
29218 +/*
29219 + * Overrides for Emacs so that we follow Linus's tabbing style.
29220 + * Emacs will notice this stuff at the end of the file and automatically
29221 + * adjust the settings for this buffer only.  This must remain at the end
29222 + * of the file.
29223 + * ---------------------------------------------------------------------------
29224 + * Local variables:
29225 + * c-file-style: "linux"
29226 + * End:
29227 + */
29228 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_user.c um/arch/um/kernel/tt/syscall_user.c
29229 --- orig/arch/um/kernel/tt/syscall_user.c       1969-12-31 19:00:00.000000000 -0500
29230 +++ um/arch/um/kernel/tt/syscall_user.c 2002-12-08 21:00:11.000000000 -0500
29231 @@ -0,0 +1,89 @@
29232 +/* 
29233 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
29234 + * Licensed under the GPL
29235 + */
29236 +
29237 +#include <unistd.h>
29238 +#include <signal.h>
29239 +#include <errno.h>
29240 +#include <sys/ptrace.h>
29241 +#include <asm/unistd.h>
29242 +#include "sysdep/ptrace.h"
29243 +#include "sigcontext.h"
29244 +#include "ptrace_user.h"
29245 +#include "task.h"
29246 +#include "user_util.h"
29247 +#include "kern_util.h"
29248 +#include "syscall_user.h"
29249 +#include "tt.h"
29250 +
29251 +/* XXX Bogus */
29252 +#define ERESTARTSYS    512
29253 +#define ERESTARTNOINTR 513
29254 +#define ERESTARTNOHAND 514
29255 +
29256 +void syscall_handler_tt(int sig, union uml_pt_regs *regs)
29257 +{
29258 +       void *sc;
29259 +       long result;
29260 +       int index, syscall;
29261 +
29262 +       syscall = UPT_SYSCALL_NR(regs);
29263 +       sc = UPT_SC(regs);
29264 +       SC_START_SYSCALL(sc);
29265 +
29266 +       index = record_syscall_start(syscall);
29267 +       syscall_trace();
29268 +       result = execute_syscall(regs);
29269 +
29270 +       /* regs->sc may have changed while the system call ran (there may
29271 +        * have been an interrupt or segfault), so it needs to be refreshed.
29272 +        */
29273 +       UPT_SC(regs) = sc;
29274 +
29275 +       SC_SET_SYSCALL_RETURN(sc, result);
29276 +       if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
29277 +          (result == -ERESTARTNOINTR))
29278 +               do_signal(result);
29279 +
29280 +       syscall_trace();
29281 +       record_syscall_end(index, result);
29282 +}
29283 +
29284 +int do_syscall(void *task, int pid)
29285 +{
29286 +       unsigned long proc_regs[FRAME_SIZE];
29287 +       union uml_pt_regs *regs;
29288 +       int syscall;
29289 +
29290 +       if(ptrace_getregs(pid, proc_regs) < 0)
29291 +               tracer_panic("Couldn't read registers");
29292 +       syscall = PT_SYSCALL_NR(proc_regs);
29293 +
29294 +       regs = TASK_REGS(task);
29295 +       UPT_SYSCALL_NR(regs) = syscall;
29296 +
29297 +       if(syscall < 1) return(0);
29298 +
29299 +       if((syscall != __NR_sigreturn) &&
29300 +          ((unsigned long *) PT_IP(proc_regs) >= &_stext) && 
29301 +          ((unsigned long *) PT_IP(proc_regs) <= &_etext))
29302 +               tracer_panic("I'm tracing myself and I can't get out");
29303 +
29304 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
29305 +                 __NR_getpid) < 0)
29306 +               tracer_panic("do_syscall : Nullifying syscall failed, "
29307 +                            "errno = %d", errno);
29308 +       return(1);
29309 +}
29310 +
29311 +/*
29312 + * Overrides for Emacs so that we follow Linus's tabbing style.
29313 + * Emacs will notice this stuff at the end of the file and automatically
29314 + * adjust the settings for this buffer only.  This must remain at the end
29315 + * of the file.
29316 + * ---------------------------------------------------------------------------
29317 + * Local variables:
29318 + * c-file-style: "linux"
29319 + * End:
29320 + */
29321 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/Makefile um/arch/um/kernel/tt/sys-i386/Makefile
29322 --- orig/arch/um/kernel/tt/sys-i386/Makefile    1969-12-31 19:00:00.000000000 -0500
29323 +++ um/arch/um/kernel/tt/sys-i386/Makefile      2002-10-23 21:08:04.000000000 -0400
29324 @@ -0,0 +1,17 @@
29325 +# 
29326 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29327 +# Licensed under the GPL
29328 +#
29329 +
29330 +O_TARGET = sys-i386.o
29331 +
29332 +obj-y = sigcontext.o
29333 +
29334 +USER_OBJS = sigcontext.o
29335 +
29336 +include $(TOPDIR)/Rules.make
29337 +
29338 +$(USER_OBJS) : %.o: %.c
29339 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
29340 +
29341 +clean :
29342 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/sigcontext.c um/arch/um/kernel/tt/sys-i386/sigcontext.c
29343 --- orig/arch/um/kernel/tt/sys-i386/sigcontext.c        1969-12-31 19:00:00.000000000 -0500
29344 +++ um/arch/um/kernel/tt/sys-i386/sigcontext.c  2002-12-01 23:33:52.000000000 -0500
29345 @@ -0,0 +1,60 @@
29346 +/* 
29347 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29348 + * Licensed under the GPL
29349 + */
29350 +
29351 +#include <stdlib.h>
29352 +#include <asm/sigcontext.h>
29353 +#include "kern_util.h"
29354 +#include "sysdep/frame.h"
29355 +
29356 +int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
29357 +{
29358 +       struct arch_frame_data *arch = data;
29359 +       struct sigcontext *to = to_ptr, *from = from_ptr;
29360 +       struct _fpstate *to_fp, *from_fp;
29361 +       unsigned long sigs;
29362 +       int err;
29363 +
29364 +       to_fp = to->fpstate;
29365 +       from_fp = from->fpstate;
29366 +       sigs = to->oldmask;
29367 +       err = copy_from_user_proc(to, from, sizeof(*to));
29368 +       to->oldmask = sigs;
29369 +       if(to_fp != NULL){
29370 +               err |= copy_from_user_proc(&to->fpstate, &to_fp,
29371 +                                          sizeof(to->fpstate));
29372 +               err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
29373 +       }
29374 +       return(err);
29375 +}
29376 +
29377 +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
29378 +{
29379 +       struct arch_frame_data *arch = data;
29380 +       struct sigcontext *to = to_ptr, *from = from_ptr;
29381 +       struct _fpstate *to_fp, *from_fp;
29382 +       int err;
29383 +
29384 +       to_fp = (struct _fpstate *) 
29385 +               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
29386 +       from_fp = from->fpstate;
29387 +       err = copy_to_user_proc(to, from, sizeof(*to));
29388 +       if(from_fp != NULL){
29389 +               err |= copy_to_user_proc(&to->fpstate, &to_fp,
29390 +                                        sizeof(to->fpstate));
29391 +               err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
29392 +       }
29393 +       return(err);
29394 +}
29395 +
29396 +/*
29397 + * Overrides for Emacs so that we follow Linus's tabbing style.
29398 + * Emacs will notice this stuff at the end of the file and automatically
29399 + * adjust the settings for this buffer only.  This must remain at the end
29400 + * of the file.
29401 + * ---------------------------------------------------------------------------
29402 + * Local variables:
29403 + * c-file-style: "linux"
29404 + * End:
29405 + */
29406 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/time.c um/arch/um/kernel/tt/time.c
29407 --- orig/arch/um/kernel/tt/time.c       1969-12-31 19:00:00.000000000 -0500
29408 +++ um/arch/um/kernel/tt/time.c 2002-10-23 21:08:04.000000000 -0400
29409 @@ -0,0 +1,28 @@
29410 +/* 
29411 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
29412 + * Licensed under the GPL
29413 + */
29414 +
29415 +#include <signal.h>
29416 +#include <sys/time.h>
29417 +#include <time_user.h>
29418 +#include "process.h"
29419 +#include "user.h"
29420 +
29421 +void user_time_init_tt(void)
29422 +{
29423 +       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
29424 +               panic("Couldn't set SIGVTALRM handler");
29425 +       set_interval(ITIMER_VIRTUAL);
29426 +}
29427 +
29428 +/*
29429 + * Overrides for Emacs so that we follow Linus's tabbing style.
29430 + * Emacs will notice this stuff at the end of the file and automatically
29431 + * adjust the settings for this buffer only.  This must remain at the end
29432 + * of the file.
29433 + * ---------------------------------------------------------------------------
29434 + * Local variables:
29435 + * c-file-style: "linux"
29436 + * End:
29437 + */
29438 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tlb.c um/arch/um/kernel/tt/tlb.c
29439 --- orig/arch/um/kernel/tt/tlb.c        1969-12-31 19:00:00.000000000 -0500
29440 +++ um/arch/um/kernel/tt/tlb.c  2002-12-19 13:03:11.000000000 -0500
29441 @@ -0,0 +1,220 @@
29442 +/* 
29443 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29444 + * Licensed under the GPL
29445 + */
29446 +
29447 +#include "linux/stddef.h"
29448 +#include "linux/kernel.h"
29449 +#include "linux/sched.h"
29450 +#include "asm/page.h"
29451 +#include "asm/pgtable.h"
29452 +#include "asm/uaccess.h"
29453 +#include "user_util.h"
29454 +#include "mem_user.h"
29455 +#include "os.h"
29456 +
29457 +static void fix_range(struct mm_struct *mm, unsigned long start_addr, 
29458 +                     unsigned long end_addr, int force)
29459 +{
29460 +       pgd_t *npgd;
29461 +       pmd_t *npmd;
29462 +       pte_t *npte;
29463 +       unsigned long addr;
29464 +       int r, w, x, err;
29465 +
29466 +       if((current->thread.mode.tt.extern_pid != -1) && 
29467 +          (current->thread.mode.tt.extern_pid != os_getpid()))
29468 +               panic("fix_range fixing wrong address space, current = 0x%p",
29469 +                     current);
29470 +       if(mm == NULL) return;
29471 +       for(addr=start_addr;addr<end_addr;){
29472 +               if(addr == TASK_SIZE){
29473 +                       /* Skip over kernel text, kernel data, and physical
29474 +                        * memory, which don't have ptes, plus kernel virtual
29475 +                        * memory, which is flushed separately, and remap
29476 +                        * the process stack.  The only way to get here is
29477 +                        * if (end_addr == STACK_TOP) > TASK_SIZE, which is
29478 +                        * only true in the honeypot case.
29479 +                        */
29480 +                       addr = STACK_TOP - ABOVE_KMEM;
29481 +                       continue;
29482 +               }
29483 +               npgd = pgd_offset(mm, addr);
29484 +               npmd = pmd_offset(npgd, addr);
29485 +               if(pmd_present(*npmd)){
29486 +                       npte = pte_offset(npmd, addr);
29487 +                       r = pte_read(*npte);
29488 +                       w = pte_write(*npte);
29489 +                       x = pte_exec(*npte);
29490 +                       if(!pte_dirty(*npte)) w = 0;
29491 +                       if(!pte_young(*npte)){
29492 +                               r = 0;
29493 +                               w = 0;
29494 +                       }
29495 +                       if(force || pte_newpage(*npte)){
29496 +                               err = os_unmap_memory((void *) addr, 
29497 +                                                     PAGE_SIZE);
29498 +                               if(err < 0)
29499 +                                       panic("munmap failed, errno = %d\n",
29500 +                                             -err);
29501 +                               if(pte_present(*npte))
29502 +                                       map_memory(addr, 
29503 +                                                  pte_val(*npte) & PAGE_MASK,
29504 +                                                  PAGE_SIZE, r, w, x);
29505 +                       }
29506 +                       else if(pte_newprot(*npte)){
29507 +                               protect_memory(addr, PAGE_SIZE, r, w, x, 1);
29508 +                       }
29509 +                       *npte = pte_mkuptodate(*npte);
29510 +                       addr += PAGE_SIZE;
29511 +               }
29512 +               else {
29513 +                       if(force || pmd_newpage(*npmd)){
29514 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
29515 +                               if(err < 0)
29516 +                                       panic("munmap failed, errno = %d\n",
29517 +                                             -err);
29518 +                               pmd_mkuptodate(*npmd);
29519 +                       }
29520 +                       addr += PMD_SIZE;
29521 +               }
29522 +       }
29523 +}
29524 +
29525 +atomic_t vmchange_seq = ATOMIC_INIT(1);
29526 +
29527 +static void flush_kernel_vm_range(unsigned long start, unsigned long end,
29528 +                                 int update_seq)
29529 +{
29530 +       struct mm_struct *mm;
29531 +       pgd_t *pgd;
29532 +       pmd_t *pmd;
29533 +       pte_t *pte;
29534 +       unsigned long addr;
29535 +       int updated = 0, err;
29536 +
29537 +       mm = &init_mm;
29538 +       for(addr = start; addr < end;){
29539 +               pgd = pgd_offset(mm, addr);
29540 +               pmd = pmd_offset(pgd, addr);
29541 +               if(pmd_present(*pmd)){
29542 +                       pte = pte_offset(pmd, addr);
29543 +                       if(!pte_present(*pte) || pte_newpage(*pte)){
29544 +                               updated = 1;
29545 +                               err = os_unmap_memory((void *) addr, 
29546 +                                                     PAGE_SIZE);
29547 +                               if(err < 0)
29548 +                                       panic("munmap failed, errno = %d\n",
29549 +                                             -err);
29550 +                               if(pte_present(*pte))
29551 +                                       map_memory(addr, 
29552 +                                                  pte_val(*pte) & PAGE_MASK,
29553 +                                                  PAGE_SIZE, 1, 1, 1);
29554 +                       }
29555 +                       else if(pte_newprot(*pte)){
29556 +                               updated = 1;
29557 +                               protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
29558 +                       }
29559 +                       addr += PAGE_SIZE;
29560 +               }
29561 +               else {
29562 +                       if(pmd_newpage(*pmd)){
29563 +                               updated = 1;
29564 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
29565 +                               if(err < 0)
29566 +                                       panic("munmap failed, errno = %d\n",
29567 +                                             -err);
29568 +                       }
29569 +                       addr += PMD_SIZE;
29570 +               }
29571 +       }
29572 +       if(updated && update_seq) atomic_inc(&vmchange_seq);
29573 +}
29574 +
29575 +static void protect_vm_page(unsigned long addr, int w, int must_succeed)
29576 +{
29577 +       int err;
29578 +
29579 +       err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
29580 +       if(err == 0) return;
29581 +       else if((err == -EFAULT) || (err == -ENOMEM)){
29582 +               flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
29583 +               protect_vm_page(addr, w, 1);
29584 +       }
29585 +       else panic("protect_vm_page : protect failed, errno = %d\n", err);
29586 +}
29587 +
29588 +void mprotect_kernel_vm(int w)
29589 +{
29590 +       struct mm_struct *mm;
29591 +       pgd_t *pgd;
29592 +       pmd_t *pmd;
29593 +       pte_t *pte;
29594 +       unsigned long addr;
29595 +       
29596 +       mm = &init_mm;
29597 +       for(addr = start_vm; addr < end_vm;){
29598 +               pgd = pgd_offset(mm, addr);
29599 +               pmd = pmd_offset(pgd, addr);
29600 +               if(pmd_present(*pmd)){
29601 +                       pte = pte_offset(pmd, addr);
29602 +                       if(pte_present(*pte)) protect_vm_page(addr, w, 0);
29603 +                       addr += PAGE_SIZE;
29604 +               }
29605 +               else addr += PMD_SIZE;
29606 +       }
29607 +}
29608 +
29609 +void flush_tlb_kernel_vm_tt(void)
29610 +{
29611 +       flush_kernel_vm_range(start_vm, end_vm, 1);
29612 +}
29613 +
29614 +void __flush_tlb_one_tt(unsigned long addr)
29615 +{
29616 +       flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
29617 +}
29618 +
29619 +void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, 
29620 +                    unsigned long end)
29621 +{
29622 +       if(mm != current->mm) return;
29623 +
29624 +       /* Assumes that the range start ... end is entirely within
29625 +        * either process memory or kernel vm
29626 +        */
29627 +       if((start >= start_vm) && (start < end_vm)) 
29628 +               flush_kernel_vm_range(start, end, 1);
29629 +       else fix_range(mm, start, end, 0);
29630 +}
29631 +
29632 +void flush_tlb_mm_tt(struct mm_struct *mm)
29633 +{
29634 +       unsigned long seq;
29635 +
29636 +       if(mm != current->mm) return;
29637 +
29638 +       fix_range(mm, 0, STACK_TOP, 0);
29639 +
29640 +       seq = atomic_read(&vmchange_seq);
29641 +       if(current->thread.mode.tt.vm_seq == seq) return;
29642 +       current->thread.mode.tt.vm_seq = seq;
29643 +       flush_kernel_vm_range(start_vm, end_vm, 0);
29644 +}
29645 +
29646 +void force_flush_all_tt(void)
29647 +{
29648 +       fix_range(current->mm, 0, STACK_TOP, 1);
29649 +       flush_kernel_vm_range(start_vm, end_vm, 0);
29650 +}
29651 +
29652 +/*
29653 + * Overrides for Emacs so that we follow Linus's tabbing style.
29654 + * Emacs will notice this stuff at the end of the file and automatically
29655 + * adjust the settings for this buffer only.  This must remain at the end
29656 + * of the file.
29657 + * ---------------------------------------------------------------------------
29658 + * Local variables:
29659 + * c-file-style: "linux"
29660 + * End:
29661 + */
29662 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tracer.c um/arch/um/kernel/tt/tracer.c
29663 --- orig/arch/um/kernel/tt/tracer.c     1969-12-31 19:00:00.000000000 -0500
29664 +++ um/arch/um/kernel/tt/tracer.c       2003-03-26 10:01:33.000000000 -0500
29665 @@ -0,0 +1,453 @@
29666 +/* 
29667 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29668 + * Licensed under the GPL
29669 + */
29670 +
29671 +#include <stdio.h>
29672 +#include <stdlib.h>
29673 +#include <stdarg.h>
29674 +#include <unistd.h>
29675 +#include <signal.h>
29676 +#include <errno.h>
29677 +#include <sched.h>
29678 +#include <string.h>
29679 +#include <sys/mman.h>
29680 +#include <sys/ptrace.h>
29681 +#include <sys/time.h>
29682 +#include <sys/wait.h>
29683 +#include "user.h"
29684 +#include "sysdep/ptrace.h"
29685 +#include "sigcontext.h"
29686 +#include "sysdep/sigcontext.h"
29687 +#include "os.h"
29688 +#include "signal_user.h"
29689 +#include "user_util.h"
29690 +#include "mem_user.h"
29691 +#include "process.h"
29692 +#include "kern_util.h"
29693 +#include "frame.h"
29694 +#include "chan_user.h"
29695 +#include "ptrace_user.h"
29696 +#include "mode.h"
29697 +#include "tt.h"
29698 +
29699 +static int tracer_winch[2];
29700 +
29701 +int is_tracer_winch(int pid, int fd, void *data)
29702 +{
29703 +       if(pid != tracing_pid)
29704 +               return(0);
29705 +
29706 +       register_winch_irq(tracer_winch[0], fd, -1, data);
29707 +       return(1);
29708 +}
29709 +
29710 +static void tracer_winch_handler(int sig)
29711 +{
29712 +       char c = 1;
29713 +
29714 +       if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
29715 +               printk("tracer_winch_handler - write failed, errno = %d\n",
29716 +                      errno);
29717 +}
29718 +
29719 +/* Called only by the tracing thread during initialization */
29720 +
29721 +static void setup_tracer_winch(void)
29722 +{
29723 +       int err;
29724 +
29725 +       err = os_pipe(tracer_winch, 1, 1);
29726 +       if(err){
29727 +               printk("setup_tracer_winch : os_pipe failed, errno = %d\n", 
29728 +                      -err);
29729 +               return;
29730 +       }
29731 +       signal(SIGWINCH, tracer_winch_handler);
29732 +}
29733 +
29734 +void attach_process(int pid)
29735 +{
29736 +       if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
29737 +          (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
29738 +               tracer_panic("OP_FORK failed to attach pid");
29739 +       wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
29740 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
29741 +               tracer_panic("OP_FORK failed to continue process");
29742 +}
29743 +
29744 +void tracer_panic(char *format, ...)
29745 +{
29746 +       va_list ap;
29747 +
29748 +       va_start(ap, format);
29749 +       vprintf(format, ap);
29750 +       printf("\n");
29751 +       while(1) pause();
29752 +}
29753 +
29754 +static void tracer_segv(int sig, struct sigcontext sc)
29755 +{
29756 +       printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
29757 +              SC_FAULT_ADDR(&sc), SC_IP(&sc));
29758 +       while(1)
29759 +               pause();
29760 +}
29761 +
29762 +/* Changed early in boot, and then only read */
29763 +int debug = 0;
29764 +int debug_stop = 1;
29765 +int debug_parent = 0;
29766 +int honeypot = 0;
29767 +
29768 +static int signal_tramp(void *arg)
29769 +{
29770 +       int (*proc)(void *);
29771 +
29772 +       if(honeypot && munmap((void *) (host_task_size - 0x10000000),
29773 +                             0x10000000)) 
29774 +               panic("Unmapping stack failed");
29775 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
29776 +               panic("ptrace PTRACE_TRACEME failed");
29777 +       os_stop_process(os_getpid());
29778 +       change_sig(SIGWINCH, 0);
29779 +       signal(SIGUSR1, SIG_IGN);
29780 +       change_sig(SIGCHLD, 0);
29781 +       signal(SIGSEGV, (__sighandler_t) sig_handler);
29782 +       set_cmdline("(idle thread)");
29783 +       set_init_pid(os_getpid());
29784 +       proc = arg;
29785 +       return((*proc)(NULL));
29786 +}
29787 +
29788 +static void sleeping_process_signal(int pid, int sig)
29789 +{
29790 +       switch(sig){
29791 +       /* These two result from UML being ^Z-ed and bg-ed.  PTRACE_CONT is
29792 +        * right because the process must be in the kernel already.
29793 +        */
29794 +       case SIGCONT:
29795 +       case SIGTSTP:
29796 +               if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
29797 +                       tracer_panic("sleeping_process_signal : Failed to "
29798 +                                    "continue pid %d, errno = %d\n", pid,
29799 +                                    sig);
29800 +               break;
29801 +
29802 +       /* This happens when the debugger (e.g. strace) is doing system call 
29803 +        * tracing on the kernel.  During a context switch, the current task
29804 +        * will be set to the incoming process and the outgoing process will
29805 +        * hop into write and then read.  Since it's not the current process
29806 +        * any more, the trace of those will land here.  So, we need to just 
29807 +        * PTRACE_SYSCALL it.
29808 +        */
29809 +       case SIGTRAP:
29810 +               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
29811 +                       tracer_panic("sleeping_process_signal : Failed to "
29812 +                                    "PTRACE_SYSCALL pid %d, errno = %d\n",
29813 +                                    pid, sig);
29814 +               break;
29815 +       case SIGSTOP:
29816 +               break;
29817 +       default:
29818 +               tracer_panic("sleeping process %d got unexpected "
29819 +                            "signal : %d\n", pid, sig);
29820 +               break;
29821 +       }
29822 +}
29823 +
29824 +/* Accessed only by the tracing thread */
29825 +int debugger_pid = -1;
29826 +int debugger_parent = -1;
29827 +int debugger_fd = -1;
29828 +int gdb_pid = -1;
29829 +
29830 +struct {
29831 +       int pid;
29832 +       int signal;
29833 +       unsigned long addr;
29834 +       struct timeval time;
29835 +} signal_record[1024][32];
29836 +
29837 +int signal_index[32];
29838 +int nsignals = 0;
29839 +int debug_trace = 0;
29840 +extern int io_nsignals, io_count, intr_count;
29841 +
29842 +extern void signal_usr1(int sig);
29843 +
29844 +int tracing_pid = -1;
29845 +
29846 +int tracer(int (*init_proc)(void *), void *sp)
29847 +{
29848 +       void *task = NULL;
29849 +       unsigned long eip = 0;
29850 +       int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
29851 +       int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
29852 +
29853 +       capture_signal_stack();
29854 +       signal(SIGPIPE, SIG_IGN);
29855 +       setup_tracer_winch();
29856 +       tracing_pid = os_getpid();
29857 +       printf("tracing thread pid = %d\n", tracing_pid);
29858 +
29859 +       pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
29860 +       n = waitpid(pid, &status, WUNTRACED);
29861 +       if(n < 0){
29862 +               printf("waitpid on idle thread failed, errno = %d\n", errno);
29863 +               exit(1);
29864 +       }
29865 +       if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
29866 +               printf("Failed to continue idle thread, errno = %d\n", errno);
29867 +               exit(1);
29868 +       }
29869 +
29870 +       signal(SIGSEGV, (sighandler_t) tracer_segv);
29871 +       signal(SIGUSR1, signal_usr1);
29872 +       if(debug_trace){
29873 +               printf("Tracing thread pausing to be attached\n");
29874 +               stop();
29875 +       }
29876 +       if(debug){
29877 +               if(gdb_pid != -1) 
29878 +                       debugger_pid = attach_debugger(pid, gdb_pid, 1);
29879 +               else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
29880 +               if(debug_parent){
29881 +                       debugger_parent = os_process_parent(debugger_pid);
29882 +                       init_parent_proxy(debugger_parent);
29883 +                       err = attach(debugger_parent);
29884 +                       if(err){
29885 +                               printf("Failed to attach debugger parent %d, "
29886 +                                      "errno = %d\n", debugger_parent, err);
29887 +                               debugger_parent = -1;
29888 +                       }
29889 +                       else {
29890 +                               if(ptrace(PTRACE_SYSCALL, debugger_parent, 
29891 +                                         0, 0) < 0){
29892 +                                       printf("Failed to continue debugger "
29893 +                                              "parent, errno = %d\n", errno);
29894 +                                       debugger_parent = -1;
29895 +                               }
29896 +                       }
29897 +               }
29898 +       }
29899 +       set_cmdline("(tracing thread)");
29900 +       while(1){
29901 +               if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
29902 +                       if(errno != ECHILD){
29903 +                               printf("wait failed - errno = %d\n", errno);
29904 +                       }
29905 +                       continue;
29906 +               }
29907 +               if(pid == debugger_pid){
29908 +                       int cont = 0;
29909 +
29910 +                       if(WIFEXITED(status) || WIFSIGNALED(status))
29911 +                               debugger_pid = -1;
29912 +                       /* XXX Figure out how to deal with gdb and SMP */
29913 +                       else cont = debugger_signal(status, cpu_tasks[0].pid);
29914 +                       if(cont == PTRACE_SYSCALL) strace = 1;
29915 +                       continue;
29916 +               }
29917 +               else if(pid == debugger_parent){
29918 +                       debugger_parent_signal(status, pid);
29919 +                       continue;
29920 +               }
29921 +               nsignals++;
29922 +               if(WIFEXITED(status)) ;
29923 +#ifdef notdef
29924 +               {
29925 +                       printf("Child %d exited with status %d\n", pid, 
29926 +                              WEXITSTATUS(status));
29927 +               }
29928 +#endif
29929 +               else if(WIFSIGNALED(status)){
29930 +                       sig = WTERMSIG(status);
29931 +                       if(sig != 9){
29932 +                               printf("Child %d exited with signal %d\n", pid,
29933 +                                      sig);
29934 +                       }
29935 +               }
29936 +               else if(WIFSTOPPED(status)){
29937 +                       proc_id = pid_to_processor_id(pid);
29938 +                       sig = WSTOPSIG(status);
29939 +                       if(signal_index[proc_id] == 1024){
29940 +                               signal_index[proc_id] = 0;
29941 +                               last_index = 1023;
29942 +                       }
29943 +                       else last_index = signal_index[proc_id] - 1;
29944 +                       if(((sig == SIGPROF) || (sig == SIGVTALRM) || 
29945 +                           (sig == SIGALRM)) &&
29946 +                          (signal_record[proc_id][last_index].signal == sig)&&
29947 +                          (signal_record[proc_id][last_index].pid == pid))
29948 +                               signal_index[proc_id] = last_index;
29949 +                       signal_record[proc_id][signal_index[proc_id]].pid = pid;
29950 +                       gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
29951 +                       eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
29952 +                       signal_record[proc_id][signal_index[proc_id]].addr = eip;
29953 +                       signal_record[proc_id][signal_index[proc_id]++].signal = sig;
29954 +                       
29955 +                       if(proc_id == -1){
29956 +                               sleeping_process_signal(pid, sig);
29957 +                               continue;
29958 +                       }
29959 +
29960 +                       task = cpu_tasks[proc_id].task;
29961 +                       tracing = is_tracing(task);
29962 +                       old_tracing = tracing;
29963 +
29964 +                       switch(sig){
29965 +                       case SIGUSR1:
29966 +                               sig = 0;
29967 +                               op = do_proc_op(task, proc_id);
29968 +                               switch(op){
29969 +                               case OP_TRACE_ON:
29970 +                                       arch_leave_kernel(task, pid);
29971 +                                       tracing = 1;
29972 +                                       break;
29973 +                               case OP_REBOOT:
29974 +                               case OP_HALT:
29975 +                                       unmap_physmem();
29976 +                                       kmalloc_ok = 0;
29977 +                                       ptrace(PTRACE_KILL, pid, 0, 0);
29978 +                                       return(op == OP_REBOOT);
29979 +                               case OP_NONE:
29980 +                                       printf("Detaching pid %d\n", pid);
29981 +                                       detach(pid, SIGSTOP);
29982 +                                       continue;
29983 +                               default:
29984 +                                       break;
29985 +                               }
29986 +                               /* OP_EXEC switches host processes on us,
29987 +                                * we want to continue the new one.
29988 +                                */
29989 +                               pid = cpu_tasks[proc_id].pid;
29990 +                               break;
29991 +                       case SIGTRAP:
29992 +                               if(!tracing && (debugger_pid != -1)){
29993 +                                       child_signal(pid, status);
29994 +                                       continue;
29995 +                               }
29996 +                               tracing = 0;
29997 +                               if(do_syscall(task, pid)) sig = SIGUSR2;
29998 +                               else clear_singlestep(task);
29999 +                               break;
30000 +                       case SIGPROF:
30001 +                               if(tracing) sig = 0;
30002 +                               break;
30003 +                       case SIGCHLD:
30004 +                       case SIGHUP:
30005 +                               sig = 0;
30006 +                               break;
30007 +                       case SIGSEGV:
30008 +                       case SIGIO:
30009 +                       case SIGALRM:
30010 +                       case SIGVTALRM:
30011 +                       case SIGFPE:
30012 +                       case SIGBUS:
30013 +                       case SIGILL:
30014 +                       case SIGWINCH:
30015 +                       default:
30016 +                               tracing = 0;
30017 +                               break;
30018 +                       }
30019 +                       set_tracing(task, tracing);
30020 +
30021 +                       if(!tracing && old_tracing)
30022 +                               arch_enter_kernel(task, pid);
30023 +
30024 +                       if(!tracing && (debugger_pid != -1) && (sig != 0) &&
30025 +                               (sig != SIGALRM) && (sig != SIGVTALRM) &&
30026 +                               (sig != SIGSEGV) && (sig != SIGTRAP) &&
30027 +                               (sig != SIGUSR2) && (sig != SIGIO) &&
30028 +                               (sig != SIGFPE)){
30029 +                               child_signal(pid, status);
30030 +                               continue;
30031 +                       }
30032 +
30033 +                       if(tracing){
30034 +                               if(singlestepping_tt(task))
30035 +                                       cont_type = PTRACE_SINGLESTEP;
30036 +                               else cont_type = PTRACE_SYSCALL;
30037 +                       }
30038 +                       else cont_type = PTRACE_CONT;
30039 +
30040 +                       if((cont_type == PTRACE_CONT) && 
30041 +                          (debugger_pid != -1) && strace)
30042 +                               cont_type = PTRACE_SYSCALL;
30043 +
30044 +                       if(ptrace(cont_type, pid, 0, sig) != 0){
30045 +                               tracer_panic("ptrace failed to continue "
30046 +                                            "process - errno = %d\n", 
30047 +                                            errno);
30048 +                       }
30049 +               }
30050 +       }
30051 +       return(0);
30052 +}
30053 +
30054 +static int __init uml_debug_setup(char *line, int *add)
30055 +{
30056 +       char *next;
30057 +
30058 +       debug = 1;
30059 +       *add = 0;
30060 +       if(*line != '=') return(0);
30061 +       line++;
30062 +
30063 +       while(line != NULL){
30064 +               next = strchr(line, ',');
30065 +               if(next) *next++ = '\0';
30066 +               
30067 +               if(!strcmp(line, "go")) debug_stop = 0;
30068 +               else if(!strcmp(line, "parent")) debug_parent = 1;
30069 +               else printf("Unknown debug option : '%s'\n", line);
30070 +
30071 +               line = next;
30072 +       }
30073 +       return(0);
30074 +}
30075 +
30076 +__uml_setup("debug", uml_debug_setup,
30077 +"debug\n"
30078 +"    Starts up the kernel under the control of gdb. See the \n"
30079 +"    kernel debugging tutorial and the debugging session pages\n"
30080 +"    at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
30081 +);
30082 +
30083 +static int __init uml_debugtrace_setup(char *line, int *add)
30084 +{
30085 +       debug_trace = 1;
30086 +       return 0;
30087 +}
30088 +__uml_setup("debugtrace", uml_debugtrace_setup,
30089 +"debugtrace\n"
30090 +"    Causes the tracing thread to pause until it is attached by a\n"
30091 +"    debugger and continued.  This is mostly for debugging crashes\n"
30092 +"    early during boot, and should be pretty much obsoleted by\n"
30093 +"    the debug switch.\n\n"
30094 +);
30095 +
30096 +static int __init uml_honeypot_setup(char *line, int *add)
30097 +{
30098 +       jail_setup("", add);
30099 +       honeypot = 1;
30100 +       return 0;
30101 +}
30102 +__uml_setup("honeypot", uml_honeypot_setup, 
30103 +"honeypot\n"
30104 +"    This makes UML put process stacks in the same location as they are\n"
30105 +"    on the host, allowing expoits such as stack smashes to work against\n"
30106 +"    UML.  This implies 'jail'.\n\n"
30107 +);
30108 +
30109 +/*
30110 + * Overrides for Emacs so that we follow Linus's tabbing style.
30111 + * Emacs will notice this stuff at the end of the file and automatically
30112 + * adjust the settings for this buffer only.  This must remain at the end
30113 + * of the file.
30114 + * ---------------------------------------------------------------------------
30115 + * Local variables:
30116 + * c-file-style: "linux"
30117 + * End:
30118 + */
30119 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/trap_user.c um/arch/um/kernel/tt/trap_user.c
30120 --- orig/arch/um/kernel/tt/trap_user.c  1969-12-31 19:00:00.000000000 -0500
30121 +++ um/arch/um/kernel/tt/trap_user.c    2002-12-09 13:14:42.000000000 -0500
30122 @@ -0,0 +1,59 @@
30123 +/* 
30124 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30125 + * Licensed under the GPL
30126 + */
30127 +
30128 +#include <stdlib.h>
30129 +#include <errno.h>
30130 +#include <signal.h>
30131 +#include <asm/sigcontext.h>
30132 +#include "sysdep/ptrace.h"
30133 +#include "signal_user.h"
30134 +#include "user_util.h"
30135 +#include "kern_util.h"
30136 +#include "task.h"
30137 +#include "tt.h"
30138 +
30139 +void sig_handler_common_tt(int sig, void *sc_ptr)
30140 +{
30141 +       struct sigcontext *sc = sc_ptr;
30142 +       struct tt_regs save_regs, *r;
30143 +       struct signal_info *info;
30144 +       int save_errno = errno, is_user;
30145 +
30146 +       unprotect_kernel_mem();
30147 +
30148 +       r = &TASK_REGS(get_current())->tt;
30149 +       save_regs = *r;
30150 +       is_user = user_context(SC_SP(sc));
30151 +       r->sc = sc;
30152 +       if(sig != SIGUSR2) 
30153 +               r->syscall = -1;
30154 +
30155 +       change_sig(SIGUSR1, 1);
30156 +       info = &sig_info[sig];
30157 +       if(!info->is_irq) unblock_signals();
30158 +
30159 +       (*info->handler)(sig, (union uml_pt_regs *) r);
30160 +
30161 +       if(is_user){
30162 +               interrupt_end();
30163 +               block_signals();
30164 +               change_sig(SIGUSR1, 0);
30165 +               set_user_mode(NULL);
30166 +       }
30167 +       *r = save_regs;
30168 +       errno = save_errno;
30169 +       if(is_user) protect_kernel_mem();
30170 +}
30171 +
30172 +/*
30173 + * Overrides for Emacs so that we follow Linus's tabbing style.
30174 + * Emacs will notice this stuff at the end of the file and automatically
30175 + * adjust the settings for this buffer only.  This must remain at the end
30176 + * of the file.
30177 + * ---------------------------------------------------------------------------
30178 + * Local variables:
30179 + * c-file-style: "linux"
30180 + * End:
30181 + */
30182 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess_user.c um/arch/um/kernel/tt/uaccess_user.c
30183 --- orig/arch/um/kernel/tt/uaccess_user.c       1969-12-31 19:00:00.000000000 -0500
30184 +++ um/arch/um/kernel/tt/uaccess_user.c 2003-03-25 17:10:54.000000000 -0500
30185 @@ -0,0 +1,100 @@
30186 +/* 
30187 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
30188 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
30189 + * Licensed under the GPL
30190 + */
30191 +
30192 +#include <setjmp.h>
30193 +#include <string.h>
30194 +#include "user_util.h"
30195 +#include "uml_uaccess.h"
30196 +#include "task.h"
30197 +#include "kern_util.h"
30198 +
30199 +int __do_copy_from_user(void *to, const void *from, int n,
30200 +                       void **fault_addr, void **fault_catcher)
30201 +{
30202 +       struct tt_regs save = TASK_REGS(get_current())->tt;
30203 +       unsigned long fault;
30204 +       int faulted;
30205 +
30206 +       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
30207 +                              __do_copy, &faulted);
30208 +       TASK_REGS(get_current())->tt = save;
30209 +
30210 +       if(!faulted) return(0);
30211 +       else return(n - (fault - (unsigned long) from));
30212 +}
30213 +
30214 +static void __do_strncpy(void *dst, const void *src, int count)
30215 +{
30216 +       strncpy(dst, src, count);
30217 +}      
30218 +
30219 +int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
30220 +                          void **fault_addr, void **fault_catcher)
30221 +{
30222 +       struct tt_regs save = TASK_REGS(get_current())->tt;
30223 +       unsigned long fault;
30224 +       int faulted;
30225 +
30226 +       fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
30227 +                              __do_strncpy, &faulted);
30228 +       TASK_REGS(get_current())->tt = save;
30229 +
30230 +       if(!faulted) return(strlen(dst));
30231 +       else return(-1);
30232 +}
30233 +
30234 +static void __do_clear(void *to, const void *from, int n)
30235 +{
30236 +       memset(to, 0, n);
30237 +}      
30238 +
30239 +int __do_clear_user(void *mem, unsigned long len,
30240 +                   void **fault_addr, void **fault_catcher)
30241 +{
30242 +       struct tt_regs save = TASK_REGS(get_current())->tt;
30243 +       unsigned long fault;
30244 +       int faulted;
30245 +
30246 +       fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
30247 +                              __do_clear, &faulted);
30248 +       TASK_REGS(get_current())->tt = save;
30249 +
30250 +       if(!faulted) return(0);
30251 +       else return(len - (fault - (unsigned long) mem));
30252 +}
30253 +
30254 +int __do_strnlen_user(const char *str, unsigned long n,
30255 +                     void **fault_addr, void **fault_catcher)
30256 +{
30257 +       struct tt_regs save = TASK_REGS(get_current())->tt;
30258 +       int ret;
30259 +       unsigned long *faddrp = (unsigned long *)fault_addr;
30260 +       jmp_buf jbuf;
30261 +
30262 +       *fault_catcher = &jbuf;
30263 +       if(setjmp(jbuf) == 0){
30264 +               ret = strlen(str) + 1;
30265 +       } 
30266 +       else {
30267 +               ret = *faddrp - (unsigned long) str;
30268 +       }
30269 +       *fault_addr = NULL;
30270 +       *fault_catcher = NULL;
30271 +
30272 +       TASK_REGS(get_current())->tt = save;
30273 +       return ret;
30274 +}
30275 +
30276 +/*
30277 + * Overrides for Emacs so that we follow Linus's tabbing style.
30278 + * Emacs will notice this stuff at the end of the file and automatically
30279 + * adjust the settings for this buffer only.  This must remain at the end
30280 + * of the file.
30281 + * ---------------------------------------------------------------------------
30282 + * Local variables:
30283 + * c-file-style: "linux"
30284 + * End:
30285 + */
30286 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/unmap.c um/arch/um/kernel/tt/unmap.c
30287 --- orig/arch/um/kernel/tt/unmap.c      1969-12-31 19:00:00.000000000 -0500
30288 +++ um/arch/um/kernel/tt/unmap.c        2002-12-11 10:42:21.000000000 -0500
30289 @@ -0,0 +1,31 @@
30290 +/* 
30291 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
30292 + * Licensed under the GPL
30293 + */
30294 +
30295 +#include <sys/mman.h>
30296 +
30297 +int switcheroo(int fd, int prot, void *from, void *to, int size)
30298 +{
30299 +       if(munmap(to, size) < 0){
30300 +               return(-1);
30301 +       }
30302 +       if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
30303 +               return(-1);
30304 +       }
30305 +       if(munmap(from, size) < 0){
30306 +               return(-1);
30307 +       }
30308 +       return(0);
30309 +}
30310 +
30311 +/*
30312 + * Overrides for Emacs so that we follow Linus's tabbing style.
30313 + * Emacs will notice this stuff at the end of the file and automatically
30314 + * adjust the settings for this buffer only.  This must remain at the end
30315 + * of the file.
30316 + * ---------------------------------------------------------------------------
30317 + * Local variables:
30318 + * c-file-style: "linux"
30319 + * End:
30320 + */
30321 diff -Naur -X ../exclude-files orig/arch/um/kernel/tty_log.c um/arch/um/kernel/tty_log.c
30322 --- orig/arch/um/kernel/tty_log.c       1969-12-31 19:00:00.000000000 -0500
30323 +++ um/arch/um/kernel/tty_log.c 2003-04-16 16:35:20.000000000 -0400
30324 @@ -0,0 +1,213 @@
30325 +/* 
30326 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and 
30327 + * geoffrey hing <ghing@net.ohio-state.edu>
30328 + * Licensed under the GPL
30329 + */
30330 +
30331 +#include <errno.h>
30332 +#include <string.h>
30333 +#include <stdio.h>
30334 +#include <stdlib.h>
30335 +#include <unistd.h>
30336 +#include <fcntl.h>
30337 +#include <sys/time.h>
30338 +#include "init.h"
30339 +#include "user.h"
30340 +#include "kern_util.h"
30341 +#include "os.h"
30342 +
30343 +#define TTY_LOG_DIR "./"
30344 +
30345 +/* Set early in boot and then unchanged */
30346 +static char *tty_log_dir = TTY_LOG_DIR;
30347 +static int tty_log_fd = -1;
30348 +
30349 +#define TTY_LOG_OPEN 1
30350 +#define TTY_LOG_CLOSE 2
30351 +#define TTY_LOG_WRITE 3
30352 +#define TTY_LOG_EXEC 4
30353 +
30354 +#define TTY_READ 1
30355 +#define TTY_WRITE 2
30356 +
30357 +struct tty_log_buf {
30358 +       int what;
30359 +       unsigned long tty;
30360 +       int len;
30361 +       int direction;
30362 +       unsigned long sec;
30363 +       unsigned long usec;
30364 +};
30365 +
30366 +int open_tty_log(void *tty, void *current_tty)
30367 +{
30368 +       struct timeval tv;
30369 +       struct tty_log_buf data;
30370 +       char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
30371 +       int fd;
30372 +
30373 +       gettimeofday(&tv, NULL);
30374 +       if(tty_log_fd != -1){
30375 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
30376 +                                              .tty  = (unsigned long) tty,
30377 +                                              .len  = sizeof(current_tty),
30378 +                                              .direction = 0,
30379 +                                              .sec = tv.tv_sec,
30380 +                                              .usec = tv.tv_usec } );
30381 +               write(tty_log_fd, &data, sizeof(data));
30382 +               write(tty_log_fd, &current_tty, data.len);
30383 +               return(tty_log_fd);
30384 +       }
30385 +
30386 +       sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
30387 +               (unsigned int) tv.tv_usec);
30388 +
30389 +       fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
30390 +                         0644);
30391 +       if(fd < 0){
30392 +               printk("open_tty_log : couldn't open '%s', errno = %d\n",
30393 +                      buf, -fd);
30394 +       }
30395 +       return(fd);
30396 +}
30397 +
30398 +void close_tty_log(int fd, void *tty)
30399 +{
30400 +       struct tty_log_buf data;
30401 +       struct timeval tv;
30402 +
30403 +       if(tty_log_fd != -1){
30404 +               gettimeofday(&tv, NULL);
30405 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
30406 +                                              .tty  = (unsigned long) tty,
30407 +                                              .len  = 0,
30408 +                                              .direction = 0,
30409 +                                              .sec = tv.tv_sec,
30410 +                                              .usec = tv.tv_usec } );
30411 +               write(tty_log_fd, &data, sizeof(data));
30412 +               return;
30413 +       }
30414 +       close(fd);
30415 +}
30416 +
30417 +static int log_chunk(int fd, char *buf, int len)
30418 +{
30419 +       int total = 0, try, missed, n;
30420 +       char chunk[64];
30421 +
30422 +       while(len > 0){
30423 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
30424 +               missed = copy_from_user_proc(chunk, buf, try);
30425 +               try -= missed;
30426 +               n = write(fd, chunk, try);
30427 +               if(n != try)
30428 +                       return(-errno);
30429 +               if(missed != 0)
30430 +                       return(-EFAULT);
30431 +
30432 +               len -= try;
30433 +               total += try;
30434 +               buf += try;
30435 +       }
30436 +
30437 +       return(total);
30438 +}
30439 +
30440 +int write_tty_log(int fd, char *buf, int len, void *tty, int is_read)
30441 +{
30442 +       struct timeval tv;
30443 +       struct tty_log_buf data;
30444 +       int direction;
30445 +
30446 +       if(fd == tty_log_fd){
30447 +               gettimeofday(&tv, NULL);
30448 +               direction = is_read ? TTY_READ : TTY_WRITE;
30449 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
30450 +                                              .tty  = (unsigned long) tty,
30451 +                                              .len  = len,
30452 +                                              .direction = direction,
30453 +                                              .sec = tv.tv_sec,
30454 +                                              .usec = tv.tv_usec } );
30455 +               write(tty_log_fd, &data, sizeof(data));
30456 +       }
30457 +
30458 +       return(log_chunk(fd, buf, len));
30459 +}
30460 +
30461 +void log_exec(char **argv, void *tty)
30462 +{
30463 +       struct timeval tv;
30464 +       struct tty_log_buf data;
30465 +       char **ptr,*arg;
30466 +       int len;
30467 +       
30468 +       if(tty_log_fd == -1) return;
30469 +
30470 +       gettimeofday(&tv, NULL);
30471 +
30472 +       len = 0;
30473 +       for(ptr = argv; ; ptr++){
30474 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
30475 +                       return;
30476 +               if(arg == NULL) break;
30477 +               len += strlen_user_proc(arg);
30478 +       }
30479 +
30480 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
30481 +                                      .tty  = (unsigned long) tty,
30482 +                                      .len  = len,
30483 +                                      .direction = 0,
30484 +                                      .sec = tv.tv_sec,
30485 +                                      .usec = tv.tv_usec } );
30486 +       write(tty_log_fd, &data, sizeof(data));
30487 +
30488 +       for(ptr = argv; ; ptr++){
30489 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
30490 +                       return;
30491 +               if(arg == NULL) break;
30492 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
30493 +       }
30494 +}
30495 +
30496 +static int __init set_tty_log_dir(char *name, int *add)
30497 +{
30498 +       tty_log_dir = name;
30499 +       return 0;
30500 +}
30501 +
30502 +__uml_setup("tty_log_dir=", set_tty_log_dir,
30503 +"tty_log_dir=<directory>\n"
30504 +"    This is used to specify the directory where the logs of all pty\n"
30505 +"    data from this UML machine will be written.\n\n"
30506 +);
30507 +
30508 +static int __init set_tty_log_fd(char *name, int *add)
30509 +{
30510 +       char *end;
30511 +
30512 +       tty_log_fd = strtoul(name, &end, 0);
30513 +       if((*end != '\0') || (end == name)){
30514 +               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
30515 +               tty_log_fd = -1;
30516 +       }
30517 +       return 0;
30518 +}
30519 +
30520 +__uml_setup("tty_log_fd=", set_tty_log_fd,
30521 +"tty_log_fd=<fd>\n"
30522 +"    This is used to specify a preconfigured file descriptor to which all\n"
30523 +"    tty data will be written.  Preconfigure the descriptor with something\n"
30524 +"    like '10>tty_log tty_log_fd=10'.\n\n"
30525 +);
30526 +
30527 +
30528 +/*
30529 + * Overrides for Emacs so that we follow Linus's tabbing style.
30530 + * Emacs will notice this stuff at the end of the file and automatically
30531 + * adjust the settings for this buffer only.  This must remain at the end
30532 + * of the file.
30533 + * ---------------------------------------------------------------------------
30534 + * Local variables:
30535 + * c-file-style: "linux"
30536 + * End:
30537 + */
30538 diff -Naur -X ../exclude-files orig/arch/um/kernel/uaccess_user.c um/arch/um/kernel/uaccess_user.c
30539 --- orig/arch/um/kernel/uaccess_user.c  1969-12-31 19:00:00.000000000 -0500
30540 +++ um/arch/um/kernel/uaccess_user.c    2003-03-25 17:06:05.000000000 -0500
30541 @@ -0,0 +1,64 @@
30542 +/* 
30543 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
30544 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
30545 + * Licensed under the GPL
30546 + */
30547 +
30548 +#include <setjmp.h>
30549 +#include <string.h>
30550 +
30551 +/* These are here rather than tt/uaccess.c because skas mode needs them in
30552 + * order to do SIGBUS recovery when a tmpfs mount runs out of room.
30553 + */
30554 +
30555 +unsigned long __do_user_copy(void *to, const void *from, int n,
30556 +                            void **fault_addr, void **fault_catcher,
30557 +                            void (*op)(void *to, const void *from,
30558 +                                       int n), int *faulted_out)
30559 +{
30560 +       unsigned long *faddrp = (unsigned long *) fault_addr, ret;
30561 +
30562 +       jmp_buf jbuf;
30563 +       *fault_catcher = &jbuf;
30564 +       if(setjmp(jbuf) == 0){
30565 +               (*op)(to, from, n);
30566 +               ret = 0;
30567 +               *faulted_out = 0;
30568 +       } 
30569 +       else {
30570 +               ret = *faddrp;
30571 +               *faulted_out = 1;
30572 +       }
30573 +       *fault_addr = NULL;
30574 +       *fault_catcher = NULL;
30575 +       return ret;
30576 +}
30577 +
30578 +void __do_copy(void *to, const void *from, int n)
30579 +{
30580 +       memcpy(to, from, n);
30581 +}      
30582 +
30583 +
30584 +int __do_copy_to_user(void *to, const void *from, int n,
30585 +                     void **fault_addr, void **fault_catcher)
30586 +{
30587 +       unsigned long fault;
30588 +       int faulted;
30589 +
30590 +       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
30591 +                              __do_copy, &faulted);
30592 +       if(!faulted) return(0);
30593 +       else return(n - (fault - (unsigned long) to));
30594 +}
30595 +
30596 +/*
30597 + * Overrides for Emacs so that we follow Linus's tabbing style.
30598 + * Emacs will notice this stuff at the end of the file and automatically
30599 + * adjust the settings for this buffer only.  This must remain at the end
30600 + * of the file.
30601 + * ---------------------------------------------------------------------------
30602 + * Local variables:
30603 + * c-file-style: "linux"
30604 + * End:
30605 + */
30606 diff -Naur -X ../exclude-files orig/arch/um/kernel/um_arch.c um/arch/um/kernel/um_arch.c
30607 --- orig/arch/um/kernel/um_arch.c       1969-12-31 19:00:00.000000000 -0500
30608 +++ um/arch/um/kernel/um_arch.c 2003-03-06 19:06:09.000000000 -0500
30609 @@ -0,0 +1,425 @@
30610 +/* 
30611 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
30612 + * Licensed under the GPL
30613 + */
30614 +
30615 +#include "linux/config.h"
30616 +#include "linux/kernel.h"
30617 +#include "linux/sched.h"
30618 +#include "linux/notifier.h"
30619 +#include "linux/mm.h"
30620 +#include "linux/types.h"
30621 +#include "linux/tty.h"
30622 +#include "linux/init.h"
30623 +#include "linux/bootmem.h"
30624 +#include "linux/spinlock.h"
30625 +#include "linux/utsname.h"
30626 +#include "linux/sysrq.h"
30627 +#include "linux/seq_file.h"
30628 +#include "linux/delay.h"
30629 +#include "asm/page.h"
30630 +#include "asm/pgtable.h"
30631 +#include "asm/ptrace.h"
30632 +#include "asm/elf.h"
30633 +#include "asm/user.h"
30634 +#include "ubd_user.h"
30635 +#include "asm/current.h"
30636 +#include "user_util.h"
30637 +#include "kern_util.h"
30638 +#include "kern.h"
30639 +#include "mprot.h"
30640 +#include "mem_user.h"
30641 +#include "mem.h"
30642 +#include "umid.h"
30643 +#include "initrd.h"
30644 +#include "init.h"
30645 +#include "os.h"
30646 +#include "choose-mode.h"
30647 +#include "mode_kern.h"
30648 +#include "mode.h"
30649 +
30650 +#define DEFAULT_COMMAND_LINE "root=/dev/ubd0"
30651 +
30652 +struct cpuinfo_um boot_cpu_data = { 
30653 +       .loops_per_jiffy        = 0,
30654 +       .pgd_quick              = NULL,
30655 +       .pmd_quick              = NULL,
30656 +       .pte_quick              = NULL,
30657 +       .pgtable_cache_sz       = 0,
30658 +       .ipi_pipe               = { -1, -1 }
30659 +};
30660 +
30661 +unsigned long thread_saved_pc(struct thread_struct *thread)
30662 +{
30663 +       return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
30664 +                                             thread)));
30665 +}
30666 +
30667 +static int show_cpuinfo(struct seq_file *m, void *v)
30668 +{
30669 +       int index;
30670 +
30671 +       index = (struct cpuinfo_um *)v - cpu_data;
30672 +#ifdef CONFIG_SMP
30673 +       if (!(cpu_online_map & (1 << index)))
30674 +               return 0;
30675 +#endif
30676 +
30677 +       seq_printf(m, "processor\t: %d\n", index);
30678 +       seq_printf(m, "vendor_id\t: User Mode Linux\n");
30679 +       seq_printf(m, "model name\t: UML\n");
30680 +       seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
30681 +       seq_printf(m, "host\t\t: %s\n", host_info);
30682 +       seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
30683 +                  loops_per_jiffy/(500000/HZ),
30684 +                  (loops_per_jiffy/(5000/HZ)) % 100);
30685 +
30686 +       return(0);
30687 +}
30688 +
30689 +static void *c_start(struct seq_file *m, loff_t *pos)
30690 +{
30691 +       return *pos < NR_CPUS ? cpu_data + *pos : NULL;
30692 +}
30693 +
30694 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
30695 +{
30696 +       ++*pos;
30697 +       return c_start(m, pos);
30698 +}
30699 +
30700 +static void c_stop(struct seq_file *m, void *v)
30701 +{
30702 +}
30703 +
30704 +struct seq_operations cpuinfo_op = {
30705 +       .start  = c_start,
30706 +       .next   = c_next,
30707 +       .stop   = c_stop,
30708 +       .show   = show_cpuinfo,
30709 +};
30710 +
30711 +pte_t * __bad_pagetable(void)
30712 +{
30713 +       panic("Someone should implement __bad_pagetable");
30714 +       return(NULL);
30715 +}
30716 +
30717 +/* Set in linux_main */
30718 +unsigned long host_task_size;
30719 +unsigned long task_size;
30720 +unsigned long uml_start;
30721 +
30722 +/* Set in early boot */
30723 +unsigned long uml_physmem;
30724 +unsigned long uml_reserved;
30725 +unsigned long start_vm;
30726 +unsigned long end_vm;
30727 +int ncpus = 1;
30728 +
30729 +#ifdef CONFIG_MODE_TT
30730 +/* Pointer set in linux_main, the array itself is private to each thread,
30731 + * and changed at address space creation time so this poses no concurrency
30732 + * problems.
30733 + */
30734 +static char *argv1_begin = NULL;
30735 +static char *argv1_end = NULL;
30736 +#endif
30737 +
30738 +/* Set in early boot */
30739 +static int have_root __initdata = 0;
30740 +long physmem_size = 32 * 1024 * 1024;
30741 +
30742 +void set_cmdline(char *cmd)
30743 +{
30744 +#ifdef CONFIG_MODE_TT
30745 +       char *umid, *ptr;
30746 +
30747 +       if(CHOOSE_MODE(honeypot, 0)) return;
30748 +
30749 +       umid = get_umid(1);
30750 +       if(umid != NULL){
30751 +               snprintf(argv1_begin, 
30752 +                        (argv1_end - argv1_begin) * sizeof(*ptr), 
30753 +                        "(%s) ", umid);
30754 +               ptr = &argv1_begin[strlen(argv1_begin)];
30755 +       }
30756 +       else ptr = argv1_begin;
30757 +
30758 +       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
30759 +       memset(argv1_begin + strlen(argv1_begin), '\0', 
30760 +              argv1_end - argv1_begin - strlen(argv1_begin));
30761 +#endif
30762 +}
30763 +
30764 +static char *usage_string = 
30765 +"User Mode Linux v%s\n"
30766 +"      available at http://user-mode-linux.sourceforge.net/\n\n";
30767 +
30768 +static int __init uml_version_setup(char *line, int *add)
30769 +{
30770 +       printf("%s\n", system_utsname.release);
30771 +       exit(0);
30772 +}
30773 +
30774 +__uml_setup("--version", uml_version_setup,
30775 +"--version\n"
30776 +"    Prints the version number of the kernel.\n\n"
30777 +);
30778 +
30779 +static int __init uml_root_setup(char *line, int *add)
30780 +{
30781 +       have_root = 1;
30782 +       return 0;
30783 +}
30784 +
30785 +__uml_setup("root=", uml_root_setup,
30786 +"root=<file containing the root fs>\n"
30787 +"    This is actually used by the generic kernel in exactly the same\n"
30788 +"    way as in any other kernel. If you configure a number of block\n"
30789 +"    devices and want to boot off something other than ubd0, you \n"
30790 +"    would use something like:\n"
30791 +"        root=/dev/ubd5\n\n"
30792 +);
30793 +
30794 +#ifdef CONFIG_SMP
30795 +static int __init uml_ncpus_setup(char *line, int *add)
30796 +{
30797 +       if (!sscanf(line, "%d", &ncpus)) {
30798 +               printf("Couldn't parse [%s]\n", line);
30799 +               return -1;
30800 +       }
30801 +
30802 +       return 0;
30803 +}
30804 +
30805 +__uml_setup("ncpus=", uml_ncpus_setup,
30806 +"ncpus=<# of desired CPUs>\n"
30807 +"    This tells an SMP kernel how many virtual processors to start.\n\n" 
30808 +);
30809 +#endif
30810 +
30811 +int force_tt = 0;
30812 +
30813 +#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
30814 +#define DEFAULT_TT 0
30815 +
30816 +static int __init mode_tt_setup(char *line, int *add)
30817 +{
30818 +       force_tt = 1;
30819 +       return(0);
30820 +}
30821 +
30822 +#else
30823 +#ifdef CONFIG_MODE_SKAS
30824 +
30825 +#define DEFAULT_TT 0
30826 +
30827 +static int __init mode_tt_setup(char *line, int *add)
30828 +{
30829 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
30830 +       return(0);
30831 +}
30832 +
30833 +#else
30834 +#ifdef CONFIG_MODE_TT
30835 +
30836 +#define DEFAULT_TT 1
30837 +
30838 +static int __init mode_tt_setup(char *line, int *add)
30839 +{
30840 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
30841 +       return(0);
30842 +}
30843 +
30844 +#else
30845 +
30846 +#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
30847 +
30848 +#endif
30849 +#endif
30850 +#endif
30851 +
30852 +__uml_setup("mode=tt", mode_tt_setup,
30853 +"mode=tt\n"
30854 +"    When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
30855 +"    forces UML to run in tt (tracing thread) mode.  It is not the default\n"
30856 +"    because it's slower and less secure than skas mode.\n\n"
30857 +);
30858 +
30859 +int mode_tt = DEFAULT_TT;
30860 +
30861 +static int __init Usage(char *line, int *add)
30862 +{
30863 +       const char **p;
30864 +
30865 +       printf(usage_string, system_utsname.release);
30866 +       p = &__uml_help_start;
30867 +       while (p < &__uml_help_end) {
30868 +               printf("%s", *p);
30869 +               p++;
30870 +       }
30871 +       exit(0);
30872 +}
30873 +
30874 +__uml_setup("--help", Usage,
30875 +"--help\n"
30876 +"    Prints this message.\n\n"
30877 +);
30878 +
30879 +static int __init uml_checksetup(char *line, int *add)
30880 +{
30881 +       struct uml_param *p;
30882 +
30883 +       p = &__uml_setup_start;
30884 +       while(p < &__uml_setup_end) {
30885 +               int n;
30886 +
30887 +               n = strlen(p->str);
30888 +               if(!strncmp(line, p->str, n)){
30889 +                       if (p->setup_func(line + n, add)) return 1;
30890 +               }
30891 +               p++;
30892 +       }
30893 +       return 0;
30894 +}
30895 +
30896 +static void __init uml_postsetup(void)
30897 +{
30898 +       initcall_t *p;
30899 +
30900 +       p = &__uml_postsetup_start;
30901 +       while(p < &__uml_postsetup_end){
30902 +               (*p)();
30903 +               p++;
30904 +       }
30905 +       return;
30906 +}
30907 +
30908 +/* Set during early boot */
30909 +unsigned long brk_start;
30910 +static struct vm_reserved kernel_vm_reserved;
30911 +
30912 +#define MIN_VMALLOC (32 * 1024 * 1024)
30913 +
30914 +int linux_main(int argc, char **argv)
30915 +{
30916 +       unsigned long avail;
30917 +       unsigned long virtmem_size, max_physmem;
30918 +       unsigned int i, add, err;
30919 +
30920 +       for (i = 1; i < argc; i++){
30921 +               if((i == 1) && (argv[i][0] == ' ')) continue;
30922 +               add = 1;
30923 +               uml_checksetup(argv[i], &add);
30924 +               if(add) add_arg(saved_command_line, argv[i]);
30925 +       }
30926 +       if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
30927 +
30928 +       mode_tt = force_tt ? 1 : !can_do_skas();
30929 +       uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
30930 +                                    &host_task_size, &task_size);
30931 +
30932 +       brk_start = (unsigned long) sbrk(0);
30933 +       CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
30934 +
30935 +       uml_physmem = uml_start;
30936 +
30937 +       /* Reserve up to 4M after the current brk */
30938 +       uml_reserved = ROUND_4M(brk_start) + (1 << 22);
30939 +
30940 +       setup_machinename(system_utsname.machine);
30941 +
30942 +#ifdef CONFIG_MODE_TT
30943 +       argv1_begin = argv[1];
30944 +       argv1_end = &argv[1][strlen(argv[1])];
30945 +#endif
30946 +  
30947 +       set_usable_vm(uml_physmem, get_kmem_end());
30948 +
30949 +       highmem = 0;
30950 +       max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC;
30951 +       if(physmem_size > max_physmem){
30952 +               highmem = physmem_size - max_physmem;
30953 +               physmem_size -= highmem;
30954 +#ifndef CONFIG_HIGHMEM
30955 +               highmem = 0;
30956 +               printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
30957 +                      "to %ld bytes\n", physmem_size);
30958 +#endif
30959 +       }
30960 +
30961 +       high_physmem = uml_physmem + physmem_size;
30962 +       high_memory = (void *) high_physmem;
30963 +
30964 +       start_vm = VMALLOC_START;
30965 +
30966 +       setup_physmem(uml_physmem, uml_reserved, physmem_size);
30967 +       virtmem_size = physmem_size;
30968 +       avail = get_kmem_end() - start_vm;
30969 +       if(physmem_size > avail) virtmem_size = avail;
30970 +       end_vm = start_vm + virtmem_size;
30971 +
30972 +       if(virtmem_size < physmem_size)
30973 +               printf("Kernel virtual memory size shrunk to %ld bytes\n",
30974 +                      virtmem_size);
30975 +
30976 +       err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
30977 +       if(err){
30978 +               printf("Failed to reserve VM area for kernel VM\n");
30979 +               exit(1);
30980 +       }
30981 +
30982 +       uml_postsetup();
30983 +
30984 +       init_task.thread.kernel_stack = (unsigned long) &init_task + 
30985 +               2 * PAGE_SIZE;
30986 +
30987 +       task_protections((unsigned long) &init_task);
30988 +       os_flush_stdout();
30989 +
30990 +       return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
30991 +}
30992 +
30993 +static int panic_exit(struct notifier_block *self, unsigned long unused1,
30994 +                     void *unused2)
30995 +{
30996 +#ifdef CONFIG_SYSRQ
30997 +       handle_sysrq('p', &current->thread.regs, NULL, NULL);
30998 +#endif
30999 +       machine_halt();
31000 +       return(0);
31001 +}
31002 +
31003 +static struct notifier_block panic_exit_notifier = {
31004 +       .notifier_call          = panic_exit,
31005 +       .next                   = NULL,
31006 +       .priority               = 0
31007 +};
31008 +
31009 +void __init setup_arch(char **cmdline_p)
31010 +{
31011 +       notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
31012 +       paging_init();
31013 +       strcpy(command_line, saved_command_line);
31014 +       *cmdline_p = command_line;
31015 +       setup_hostinfo();
31016 +}
31017 +
31018 +void __init check_bugs(void)
31019 +{
31020 +       arch_check_bugs();
31021 +       check_ptrace();
31022 +       check_sigio();
31023 +}
31024 +
31025 +/*
31026 + * Overrides for Emacs so that we follow Linus's tabbing style.
31027 + * Emacs will notice this stuff at the end of the file and automatically
31028 + * adjust the settings for this buffer only.  This must remain at the end
31029 + * of the file.
31030 + * ---------------------------------------------------------------------------
31031 + * Local variables:
31032 + * c-file-style: "linux"
31033 + * End:
31034 + */
31035 diff -Naur -X ../exclude-files orig/arch/um/kernel/umid.c um/arch/um/kernel/umid.c
31036 --- orig/arch/um/kernel/umid.c  1969-12-31 19:00:00.000000000 -0500
31037 +++ um/arch/um/kernel/umid.c    2003-02-24 23:11:23.000000000 -0500
31038 @@ -0,0 +1,319 @@
31039 +/* 
31040 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
31041 + * Licensed under the GPL
31042 + */
31043 +
31044 +#include <stdio.h>
31045 +#include <unistd.h>
31046 +#include <fcntl.h>
31047 +#include <errno.h>
31048 +#include <string.h>
31049 +#include <stdlib.h>
31050 +#include <dirent.h>
31051 +#include <signal.h>
31052 +#include <sys/stat.h>
31053 +#include <sys/param.h>
31054 +#include "user.h"
31055 +#include "umid.h"
31056 +#include "init.h"
31057 +#include "os.h"
31058 +#include "user_util.h"
31059 +#include "choose-mode.h"
31060 +
31061 +#define UMID_LEN 64
31062 +#define UML_DIR "~/.uml/"
31063 +
31064 +/* Changed by set_umid and make_umid, which are run early in boot */
31065 +static char umid[UMID_LEN] = { 0 };
31066 +
31067 +/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
31068 +static char *uml_dir = UML_DIR;
31069 +
31070 +/* Changed by set_umid */
31071 +static int umid_is_random = 1;
31072 +static int umid_inited = 0;
31073 +
31074 +static int make_umid(int (*printer)(const char *fmt, ...));
31075 +
31076 +static int __init set_umid(char *name, int is_random, 
31077 +                          int (*printer)(const char *fmt, ...))
31078 +{
31079 +       if(umid_inited){
31080 +               (*printer)("Unique machine name can't be set twice\n");
31081 +               return(-1);
31082 +       }
31083 +
31084 +       if(strlen(name) > UMID_LEN - 1)
31085 +               (*printer)("Unique machine name is being truncated to %s "
31086 +                          "characters\n", UMID_LEN);
31087 +       strncpy(umid, name, UMID_LEN - 1);
31088 +       umid[UMID_LEN - 1] = '\0';
31089 +
31090 +       umid_is_random = is_random;
31091 +       umid_inited = 1;
31092 +       return 0;
31093 +}
31094 +
31095 +static int __init set_umid_arg(char *name, int *add)
31096 +{
31097 +       return(set_umid(name, 0, printf));
31098 +}
31099 +
31100 +__uml_setup("umid=", set_umid_arg,
31101 +"umid=<name>\n"
31102 +"    This is used to assign a unique identity to this UML machine and\n"
31103 +"    is used for naming the pid file and management console socket.\n\n"
31104 +);
31105 +
31106 +int __init umid_file_name(char *name, char *buf, int len)
31107 +{
31108 +       int n;
31109 +
31110 +       if(!umid_inited && make_umid(printk)) return(-1);
31111 +
31112 +       n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
31113 +       if(n > len){
31114 +               printk("umid_file_name : buffer too short\n");
31115 +               return(-1);
31116 +       }
31117 +
31118 +       sprintf(buf, "%s%s/%s", uml_dir, umid, name);
31119 +       return(0);
31120 +}
31121 +
31122 +extern int tracing_pid;
31123 +
31124 +static int __init create_pid_file(void)
31125 +{
31126 +       char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
31127 +       char pid[sizeof("nnnnn\0")];
31128 +       int fd;
31129 +
31130 +       if(umid_file_name("pid", file, sizeof(file))) return 0;
31131 +
31132 +       fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
31133 +                         0644);
31134 +       if(fd < 0){
31135 +               printf("Open of machine pid file \"%s\" failed - "
31136 +                      "errno = %d\n", file, -fd);
31137 +               return 0;
31138 +       }
31139 +
31140 +       sprintf(pid, "%d\n", os_getpid());
31141 +       if(write(fd, pid, strlen(pid)) != strlen(pid))
31142 +               printf("Write of pid file failed - errno = %d\n", errno);
31143 +       close(fd);
31144 +       return 0;
31145 +}
31146 +
31147 +static int actually_do_remove(char *dir)
31148 +{
31149 +       DIR *directory;
31150 +       struct dirent *ent;
31151 +       int len;
31152 +       char file[256];
31153 +
31154 +       if((directory = opendir(dir)) == NULL){
31155 +               printk("actually_do_remove : couldn't open directory '%s', "
31156 +                      "errno = %d\n", dir, errno);
31157 +               return(1);
31158 +       }
31159 +       while((ent = readdir(directory)) != NULL){
31160 +               if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
31161 +                       continue;
31162 +               len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
31163 +               if(len > sizeof(file)){
31164 +                       printk("Not deleting '%s' from '%s' - name too long\n",
31165 +                              ent->d_name, dir);
31166 +                       continue;
31167 +               }
31168 +               sprintf(file, "%s/%s", dir, ent->d_name);
31169 +               if(unlink(file) < 0){
31170 +                       printk("actually_do_remove : couldn't remove '%s' "
31171 +                              "from '%s', errno = %d\n", ent->d_name, dir, 
31172 +                              errno);
31173 +                       return(1);
31174 +               }
31175 +       }
31176 +       if(rmdir(dir) < 0){
31177 +               printk("actually_do_remove : couldn't rmdir '%s', "
31178 +                      "errno = %d\n", dir, errno);
31179 +               return(1);
31180 +       }
31181 +       return(0);
31182 +}
31183 +
31184 +void remove_umid_dir(void)
31185 +{
31186 +       char dir[strlen(uml_dir) + UMID_LEN + 1];
31187 +       if(!umid_inited) return;
31188 +
31189 +       sprintf(dir, "%s%s", uml_dir, umid);
31190 +       actually_do_remove(dir);
31191 +}
31192 +
31193 +char *get_umid(int only_if_set)
31194 +{
31195 +       if(only_if_set && umid_is_random) return(NULL);
31196 +       return(umid);
31197 +}
31198 +
31199 +int not_dead_yet(char *dir)
31200 +{
31201 +       char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
31202 +       char pid[sizeof("nnnnn\0")], *end;
31203 +       int dead, fd, p;
31204 +
31205 +       sprintf(file, "%s/pid", dir);
31206 +       dead = 0;
31207 +       if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
31208 +               if(fd != -ENOENT){
31209 +                       printk("not_dead_yet : couldn't open pid file '%s', "
31210 +                              "errno = %d\n", file, -fd);
31211 +                       return(1);
31212 +               }
31213 +               dead = 1;
31214 +       }
31215 +       if(fd > 0){
31216 +               if(read(fd, pid, sizeof(pid)) < 0){
31217 +                       printk("not_dead_yet : couldn't read pid file '%s', "
31218 +                              "errno = %d\n", file, errno);
31219 +                       return(1);
31220 +               }
31221 +               p = strtoul(pid, &end, 0);
31222 +               if(end == pid){
31223 +                       printk("not_dead_yet : couldn't parse pid file '%s', "
31224 +                              "errno = %d\n", file, errno);
31225 +                       dead = 1;
31226 +               }
31227 +               if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
31228 +                  (p == CHOOSE_MODE(tracing_pid, os_getpid())))
31229 +                       dead = 1;
31230 +       }
31231 +       if(!dead) return(1);
31232 +       return(actually_do_remove(dir));
31233 +}
31234 +
31235 +static int __init set_uml_dir(char *name, int *add)
31236 +{
31237 +       if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
31238 +               uml_dir = malloc(strlen(name) + 1);
31239 +               if(uml_dir == NULL){
31240 +                       printf("Failed to malloc uml_dir - error = %d\n",
31241 +                              errno);
31242 +                       uml_dir = name;
31243 +                       return(0);
31244 +               }
31245 +               sprintf(uml_dir, "%s/", name);
31246 +       }
31247 +       else uml_dir = name;
31248 +       return 0;
31249 +}
31250 +
31251 +static int __init make_uml_dir(void)
31252 +{
31253 +       char dir[MAXPATHLEN + 1] = { '\0' };
31254 +       int len;
31255 +
31256 +       if(*uml_dir == '~'){
31257 +               char *home = getenv("HOME");
31258 +
31259 +               if(home == NULL){
31260 +                       printf("make_uml_dir : no value in environment for "
31261 +                              "$HOME\n");
31262 +                       exit(1);
31263 +               }
31264 +               strncpy(dir, home, sizeof(dir));
31265 +               uml_dir++;
31266 +       }
31267 +       len = strlen(dir);
31268 +       strncat(dir, uml_dir, sizeof(dir) - len);
31269 +       len = strlen(dir);
31270 +       if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
31271 +               dir[len] = '/';
31272 +               dir[len + 1] = '\0';
31273 +       }
31274 +
31275 +       if((uml_dir = malloc(strlen(dir) + 1)) == NULL){
31276 +               printf("make_uml_dir : malloc failed, errno = %d\n", errno);
31277 +               exit(1);
31278 +       }
31279 +       strcpy(uml_dir, dir);
31280 +       
31281 +       if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
31282 +               printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
31283 +               return(-1);
31284 +       }
31285 +       return 0;
31286 +}
31287 +
31288 +static int __init make_umid(int (*printer)(const char *fmt, ...))
31289 +{
31290 +       int fd, err;
31291 +       char tmp[strlen(uml_dir) + UMID_LEN + 1];
31292 +
31293 +       strncpy(tmp, uml_dir, sizeof(tmp) - 1);
31294 +       tmp[sizeof(tmp) - 1] = '\0';
31295 +
31296 +       if(!umid_inited){
31297 +               strcat(tmp, "XXXXXX");
31298 +               fd = mkstemp(tmp);
31299 +               if(fd < 0){
31300 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
31301 +                                  errno);
31302 +                       return(1);
31303 +               }
31304 +
31305 +               close(fd);
31306 +               /* There's a nice tiny little race between this unlink and
31307 +                * the mkdir below.  It'd be nice if there were a mkstemp
31308 +                * for directories.
31309 +                */
31310 +               unlink(tmp);
31311 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
31312 +       }
31313 +       
31314 +       sprintf(tmp, "%s%s", uml_dir, umid);
31315 +
31316 +       if((err = mkdir(tmp, 0777)) < 0){
31317 +               if(errno == EEXIST){
31318 +                       if(not_dead_yet(tmp)){
31319 +                               (*printer)("umid '%s' is in use\n", umid);
31320 +                               return(-1);
31321 +                       }
31322 +                       err = mkdir(tmp, 0777);
31323 +               }
31324 +       }
31325 +       if(err < 0){
31326 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
31327 +               return(-1);
31328 +       }
31329 +
31330 +       return(0);
31331 +}
31332 +
31333 +__uml_setup("uml_dir=", set_uml_dir,
31334 +"uml_dir=<directory>\n"
31335 +"    The location to place the pid and umid files.\n\n"
31336 +);
31337 +
31338 +__uml_postsetup(make_uml_dir);
31339 +
31340 +static int __init make_umid_setup(void)
31341 +{
31342 +       return(make_umid(printf));
31343 +}
31344 +
31345 +__uml_postsetup(make_umid_setup);
31346 +__uml_postsetup(create_pid_file);
31347 +
31348 +/*
31349 + * Overrides for Emacs so that we follow Linus's tabbing style.
31350 + * Emacs will notice this stuff at the end of the file and automatically
31351 + * adjust the settings for this buffer only.  This must remain at the end
31352 + * of the file.
31353 + * ---------------------------------------------------------------------------
31354 + * Local variables:
31355 + * c-file-style: "linux"
31356 + * End:
31357 + */
31358 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_syms.c um/arch/um/kernel/user_syms.c
31359 --- orig/arch/um/kernel/user_syms.c     1969-12-31 19:00:00.000000000 -0500
31360 +++ um/arch/um/kernel/user_syms.c       2002-10-23 21:08:04.000000000 -0400
31361 @@ -0,0 +1,116 @@
31362 +#include <stdio.h>
31363 +#include <unistd.h>
31364 +#include <fcntl.h>
31365 +#include <dirent.h>
31366 +#include <errno.h>
31367 +#include <utime.h>
31368 +#include <string.h>
31369 +#include <sys/stat.h>
31370 +#include <sys/vfs.h>
31371 +#include <sys/ioctl.h>
31372 +#include "user_util.h"
31373 +#include "mem_user.h"
31374 +
31375 +/* XXX All the __CONFIG_* stuff is broken because this file can't include
31376 + * config.h
31377 + */
31378 +
31379 +/* Had to steal this from linux/module.h because that file can't be included
31380 + * since this includes various user-level headers.
31381 + */
31382 +
31383 +struct module_symbol
31384 +{
31385 +       unsigned long value;
31386 +       const char *name;
31387 +};
31388 +
31389 +/* Indirect stringification.  */
31390 +
31391 +#define __MODULE_STRING_1(x)   #x
31392 +#define __MODULE_STRING(x)     __MODULE_STRING_1(x)
31393 +
31394 +#if !defined(__AUTOCONF_INCLUDED__)
31395 +
31396 +#define __EXPORT_SYMBOL(sym,str)   error config_must_be_included_before_module
31397 +#define EXPORT_SYMBOL(var)        error config_must_be_included_before_module
31398 +#define EXPORT_SYMBOL_NOVERS(var)  error config_must_be_included_before_module
31399 +
31400 +#elif !defined(__CONFIG_MODULES__)
31401 +
31402 +#define __EXPORT_SYMBOL(sym,str)
31403 +#define EXPORT_SYMBOL(var)
31404 +#define EXPORT_SYMBOL_NOVERS(var)
31405 +
31406 +#else
31407 +
31408 +#define __EXPORT_SYMBOL(sym, str)                      \
31409 +const char __kstrtab_##sym[]                           \
31410 +__attribute__((section(".kstrtab"))) = str;            \
31411 +const struct module_symbol __ksymtab_##sym             \
31412 +__attribute__((section("__ksymtab"))) =                        \
31413 +{ (unsigned long)&sym, __kstrtab_##sym }
31414 +
31415 +#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__)
31416 +#define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
31417 +#else
31418 +#define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
31419 +#endif
31420 +
31421 +#define EXPORT_SYMBOL_NOVERS(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
31422 +
31423 +#endif
31424 +
31425 +EXPORT_SYMBOL(__errno_location);
31426 +
31427 +EXPORT_SYMBOL(access);
31428 +EXPORT_SYMBOL(open);
31429 +EXPORT_SYMBOL(open64);
31430 +EXPORT_SYMBOL(close);
31431 +EXPORT_SYMBOL(read);
31432 +EXPORT_SYMBOL(write);
31433 +EXPORT_SYMBOL(dup2);
31434 +EXPORT_SYMBOL(__xstat);
31435 +EXPORT_SYMBOL(__lxstat);
31436 +EXPORT_SYMBOL(__lxstat64);
31437 +EXPORT_SYMBOL(lseek);
31438 +EXPORT_SYMBOL(lseek64);
31439 +EXPORT_SYMBOL(chown);
31440 +EXPORT_SYMBOL(truncate);
31441 +EXPORT_SYMBOL(utime);
31442 +EXPORT_SYMBOL(chmod);
31443 +EXPORT_SYMBOL(rename);
31444 +EXPORT_SYMBOL(__xmknod);
31445 +
31446 +EXPORT_SYMBOL(symlink);
31447 +EXPORT_SYMBOL(link);
31448 +EXPORT_SYMBOL(unlink);
31449 +EXPORT_SYMBOL(readlink);
31450 +
31451 +EXPORT_SYMBOL(mkdir);
31452 +EXPORT_SYMBOL(rmdir);
31453 +EXPORT_SYMBOL(opendir);
31454 +EXPORT_SYMBOL(readdir);
31455 +EXPORT_SYMBOL(closedir);
31456 +EXPORT_SYMBOL(seekdir);
31457 +EXPORT_SYMBOL(telldir);
31458 +
31459 +EXPORT_SYMBOL(ioctl);
31460 +
31461 +extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
31462 +                       __off64_t __offset);
31463 +extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n,
31464 +                        __off64_t __offset);
31465 +EXPORT_SYMBOL(pread64);
31466 +EXPORT_SYMBOL(pwrite64);
31467 +
31468 +EXPORT_SYMBOL(statfs);
31469 +EXPORT_SYMBOL(statfs64);
31470 +
31471 +EXPORT_SYMBOL(memcpy);
31472 +EXPORT_SYMBOL(getuid);
31473 +
31474 +EXPORT_SYMBOL(memset);
31475 +EXPORT_SYMBOL(strstr);
31476 +
31477 +EXPORT_SYMBOL(find_iomem);
31478 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_util.c um/arch/um/kernel/user_util.c
31479 --- orig/arch/um/kernel/user_util.c     1969-12-31 19:00:00.000000000 -0500
31480 +++ um/arch/um/kernel/user_util.c       2003-04-23 20:41:54.000000000 -0400
31481 @@ -0,0 +1,164 @@
31482 +/* 
31483 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
31484 + * Licensed under the GPL
31485 + */
31486 +
31487 +#include <stdio.h>
31488 +#include <stdlib.h>
31489 +#include <fcntl.h>
31490 +#include <unistd.h>
31491 +#include <limits.h>
31492 +#include <sys/mman.h> 
31493 +#include <sys/stat.h>
31494 +#include <sys/ptrace.h>
31495 +#include <sys/utsname.h>
31496 +#include <sys/param.h>
31497 +#include <sys/time.h>
31498 +#include "asm/types.h"
31499 +#include <ctype.h>
31500 +#include <signal.h>
31501 +#include <wait.h>
31502 +#include <errno.h>
31503 +#include <stdarg.h>
31504 +#include <sched.h>
31505 +#include <termios.h>
31506 +#include <string.h>
31507 +#include "user_util.h"
31508 +#include "kern_util.h"
31509 +#include "user.h"
31510 +#include "mem_user.h"
31511 +#include "init.h"
31512 +#include "helper.h"
31513 +#include "uml-config.h"
31514 +
31515 +#define COMMAND_LINE_SIZE _POSIX_ARG_MAX
31516 +
31517 +/* Changed in linux_main and setup_arch, which run before SMP is started */
31518 +char saved_command_line[COMMAND_LINE_SIZE] = { 0 };
31519 +char command_line[COMMAND_LINE_SIZE] = { 0 };
31520 +
31521 +void add_arg(char *cmd_line, char *arg)
31522 +{
31523 +       if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
31524 +               printf("add_arg: Too much command line!\n");
31525 +               exit(1);
31526 +       }
31527 +       if(strlen(cmd_line) > 0) strcat(cmd_line, " ");
31528 +       strcat(cmd_line, arg);
31529 +}
31530 +
31531 +void stop(void)
31532 +{
31533 +       while(1) sleep(1000000);
31534 +}
31535 +
31536 +void stack_protections(unsigned long address)
31537 +{
31538 +       int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
31539 +
31540 +        if(mprotect((void *) address, page_size(), prot) < 0)
31541 +               panic("protecting stack failed, errno = %d", errno);
31542 +}
31543 +
31544 +void task_protections(unsigned long address)
31545 +{
31546 +       unsigned long guard = address + page_size();
31547 +       unsigned long stack = guard + page_size();
31548 +       int prot = 0, pages;
31549 +#ifdef notdef
31550 +       if(mprotect((void *) guard, page_size(), prot) < 0)
31551 +               panic("protecting guard page failed, errno = %d", errno);
31552 +#endif
31553 +       pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
31554 +       prot = PROT_READ | PROT_WRITE | PROT_EXEC;
31555 +       if(mprotect((void *) stack, pages * page_size(), prot) < 0)
31556 +               panic("protecting stack failed, errno = %d", errno);
31557 +}
31558 +
31559 +int wait_for_stop(int pid, int sig, int cont_type, void *relay)
31560 +{
31561 +       sigset_t *relay_signals = relay;
31562 +       int status, ret;
31563 +
31564 +       while(1){
31565 +               if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
31566 +                  !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
31567 +                       if(ret < 0){
31568 +                               if(errno == EINTR) continue;
31569 +                               printk("wait failed, errno = %d\n",
31570 +                                      errno);
31571 +                       }
31572 +                       else if(WIFEXITED(status)) 
31573 +                               printk("process exited with status %d\n", 
31574 +                                      WEXITSTATUS(status));
31575 +                       else if(WIFSIGNALED(status))
31576 +                               printk("process exited with signal %d\n", 
31577 +                                      WTERMSIG(status));
31578 +                       else if((WSTOPSIG(status) == SIGVTALRM) ||
31579 +                               (WSTOPSIG(status) == SIGALRM) ||
31580 +                               (WSTOPSIG(status) == SIGIO) ||
31581 +                               (WSTOPSIG(status) == SIGPROF) ||
31582 +                               (WSTOPSIG(status) == SIGCHLD) ||
31583 +                               (WSTOPSIG(status) == SIGWINCH) ||
31584 +                               (WSTOPSIG(status) == SIGINT)){
31585 +                               ptrace(cont_type, pid, 0, WSTOPSIG(status));
31586 +                               continue;
31587 +                       }
31588 +                       else if((relay_signals != NULL) &&
31589 +                               sigismember(relay_signals, WSTOPSIG(status))){
31590 +                               ptrace(cont_type, pid, 0, WSTOPSIG(status));
31591 +                               continue;
31592 +                       }
31593 +                       else printk("process stopped with signal %d\n", 
31594 +                                   WSTOPSIG(status));
31595 +                       panic("wait_for_stop failed to wait for %d to stop "
31596 +                             "with %d\n", pid, sig);
31597 +               }
31598 +               return(status);
31599 +       }
31600 +}
31601 +
31602 +int raw(int fd, int complain)
31603 +{
31604 +       struct termios tt;
31605 +       int err;
31606 +
31607 +       tcgetattr(fd, &tt);
31608 +       cfmakeraw(&tt);
31609 +       err = tcsetattr(fd, TCSANOW, &tt);
31610 +       if((err < 0) && complain){
31611 +               printk("tcsetattr failed, errno = %d\n", errno);
31612 +               return(-errno);
31613 +       }
31614 +       return(0);
31615 +}
31616 +
31617 +void setup_machinename(char *machine_out)
31618 +{
31619 +       struct utsname host;
31620 +
31621 +       uname(&host);
31622 +       strcpy(machine_out, host.machine);
31623 +}
31624 +
31625 +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
31626 +
31627 +void setup_hostinfo(void)
31628 +{
31629 +       struct utsname host;
31630 +
31631 +       uname(&host);
31632 +       sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
31633 +               host.release, host.version, host.machine);
31634 +}
31635 +
31636 +/*
31637 + * Overrides for Emacs so that we follow Linus's tabbing style.
31638 + * Emacs will notice this stuff at the end of the file and automatically
31639 + * adjust the settings for this buffer only.  This must remain at the end
31640 + * of the file.
31641 + * ---------------------------------------------------------------------------
31642 + * Local variables:
31643 + * c-file-style: "linux"
31644 + * End:
31645 + */
31646 diff -Naur -X ../exclude-files orig/arch/um/link.ld.in um/arch/um/link.ld.in
31647 --- orig/arch/um/link.ld.in     1969-12-31 19:00:00.000000000 -0500
31648 +++ um/arch/um/link.ld.in       2003-01-17 23:11:30.000000000 -0500
31649 @@ -0,0 +1,95 @@
31650 +OUTPUT_FORMAT("ELF_FORMAT")
31651 +OUTPUT_ARCH(ELF_ARCH)
31652 +ENTRY(_start)
31653 +
31654 +SECTIONS
31655 +{
31656 +  . = START() + SIZEOF_HEADERS;
31657 +
31658 +  . = ALIGN(4096);
31659 +  __binary_start = .;
31660 +ifdef(`MODE_TT', `
31661 +  .thread_private : {
31662 +    __start_thread_private = .;
31663 +    errno = .;
31664 +    . += 4;
31665 +    arch/um/kernel/tt/unmap_fin.o (.data)
31666 +    __end_thread_private = .;
31667 +  }
31668 +  . = ALIGN(4096);
31669 +  .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
31670 +')
31671 +  . = ALIGN(4096);             /* Init code and data */
31672 +  _stext = .;
31673 +  __init_begin = .;
31674 +  .text.init : { *(.text.init) }
31675 +  . = ALIGN(4096);
31676 +  .text      :
31677 +  {
31678 +    *(.text)
31679 +    /* .gnu.warning sections are handled specially by elf32.em.  */
31680 +    *(.gnu.warning)
31681 +    *(.gnu.linkonce.t*)
31682 +  }
31683 +  .fini      : { *(.fini)    } =0x9090
31684 +  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
31685 +  .rodata1   : { *(.rodata1) }
31686 +  _etext = .;
31687 +  PROVIDE (etext = .);
31688 +
31689 +  . = ALIGN(4096);
31690 +  PROVIDE (_sdata = .);
31691 +
31692 +include(`arch/um/common.ld.in')
31693 +
31694 +  .data    :
31695 +  {
31696 +    . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
31697 +    *(.data.init_task)
31698 +    *(.data)
31699 +    *(.gnu.linkonce.d*)
31700 +    CONSTRUCTORS
31701 +  }
31702 +  .data1   : { *(.data1) }
31703 +  .ctors         :
31704 +  {
31705 +    *(.ctors)
31706 +  }
31707 +  .dtors         :
31708 +  {
31709 +    *(.dtors)
31710 +  }
31711 +
31712 +  .got           : { *(.got.plt) *(.got) }
31713 +  .dynamic       : { *(.dynamic) }
31714 +  /* We want the small data sections together, so single-instruction offsets
31715 +     can access them all, and initialized data all before uninitialized, so
31716 +     we can shorten the on-disk segment size.  */
31717 +  .sdata     : { *(.sdata) }
31718 +  _edata  =  .;
31719 +  PROVIDE (edata = .);
31720 +  . = ALIGN(0x1000);
31721 +  .sbss      : 
31722 +  {
31723 +   __bss_start = .;
31724 +   PROVIDE(_bss_start = .);
31725 +   *(.sbss) 
31726 +   *(.scommon) 
31727 +  }
31728 +  .bss       :
31729 +  {
31730 +   *(.dynbss)
31731 +   *(.bss)
31732 +   *(COMMON)
31733 +  }
31734 +  _end = . ;
31735 +  PROVIDE (end = .);
31736 +  /* Stabs debugging sections.  */
31737 +  .stab 0 : { *(.stab) }
31738 +  .stabstr 0 : { *(.stabstr) }
31739 +  .stab.excl 0 : { *(.stab.excl) }
31740 +  .stab.exclstr 0 : { *(.stab.exclstr) }
31741 +  .stab.index 0 : { *(.stab.index) }
31742 +  .stab.indexstr 0 : { *(.stab.indexstr) }
31743 +  .comment 0 : { *(.comment) }
31744 +}
31745 diff -Naur -X ../exclude-files orig/arch/um/main.c um/arch/um/main.c
31746 --- orig/arch/um/main.c 1969-12-31 19:00:00.000000000 -0500
31747 +++ um/arch/um/main.c   2003-01-17 13:22:40.000000000 -0500
31748 @@ -0,0 +1,195 @@
31749 +/* 
31750 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
31751 + * Licensed under the GPL
31752 + */
31753 +
31754 +#include <unistd.h>
31755 +#include <stdio.h> 
31756 +#include <stdlib.h>
31757 +#include <string.h>
31758 +#include <signal.h>
31759 +#include <sys/resource.h>
31760 +#include <sys/mman.h>
31761 +#include <sys/user.h>
31762 +#include <asm/page.h>
31763 +#include "user_util.h"
31764 +#include "kern_util.h"
31765 +#include "mem_user.h"
31766 +#include "signal_user.h"
31767 +#include "user.h"
31768 +#include "init.h"
31769 +#include "mode.h"
31770 +#include "choose-mode.h"
31771 +#include "uml-config.h"
31772 +
31773 +/* Set in set_stklim, which is called from main and __wrap_malloc.  
31774 + * __wrap_malloc only calls it if main hasn't started.
31775 + */
31776 +unsigned long stacksizelim;
31777 +
31778 +/* Set in main */
31779 +char *linux_prog;
31780 +
31781 +#define PGD_BOUND (4 * 1024 * 1024)
31782 +#define STACKSIZE (8 * 1024 * 1024)
31783 +#define THREAD_NAME_LEN (256)
31784 +
31785 +static void set_stklim(void)
31786 +{
31787 +       struct rlimit lim;
31788 +
31789 +       if(getrlimit(RLIMIT_STACK, &lim) < 0){
31790 +               perror("getrlimit");
31791 +               exit(1);
31792 +       }
31793 +       if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
31794 +               lim.rlim_cur = STACKSIZE;
31795 +               if(setrlimit(RLIMIT_STACK, &lim) < 0){
31796 +                       perror("setrlimit");
31797 +                       exit(1);
31798 +               }
31799 +       }
31800 +       stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
31801 +}
31802 +
31803 +static __init void do_uml_initcalls(void)
31804 +{
31805 +       initcall_t *call;
31806 +
31807 +       call = &__uml_initcall_start;
31808 +       while (call < &__uml_initcall_end){;
31809 +               (*call)();
31810 +               call++;
31811 +       }
31812 +}
31813 +
31814 +static void last_ditch_exit(int sig)
31815 +{
31816 +       CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
31817 +       signal(SIGINT, SIG_DFL);
31818 +       signal(SIGTERM, SIG_DFL);
31819 +       signal(SIGHUP, SIG_DFL);
31820 +       uml_cleanup();
31821 +       exit(1);
31822 +}
31823 +
31824 +extern int uml_exitcode;
31825 +
31826 +int main(int argc, char **argv, char **envp)
31827 +{
31828 +       char **new_argv;
31829 +       sigset_t mask;
31830 +       int ret, i;
31831 +
31832 +       /* Enable all signals except SIGIO - in some environments, we can 
31833 +        * enter with some signals blocked
31834 +        */
31835 +
31836 +       sigemptyset(&mask);
31837 +       sigaddset(&mask, SIGIO);
31838 +       if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
31839 +               perror("sigprocmask");
31840 +               exit(1);
31841 +       }
31842 +
31843 +#ifdef UML_CONFIG_MODE_TT
31844 +       /* Allocate memory for thread command lines */
31845 +       if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
31846 +
31847 +               char padding[THREAD_NAME_LEN] = { 
31848 +                       [ 0 ...  THREAD_NAME_LEN - 2] = ' ', '\0' 
31849 +               };
31850 +
31851 +               new_argv = malloc((argc + 2) * sizeof(char*));
31852 +               if(!new_argv) {
31853 +                       perror("Allocating extended argv");
31854 +                       exit(1);
31855 +               }       
31856 +               
31857 +               new_argv[0] = argv[0];
31858 +               new_argv[1] = padding;
31859 +               
31860 +               for(i = 2; i <= argc; i++)
31861 +                       new_argv[i] = argv[i - 1];
31862 +               new_argv[argc + 1] = NULL;
31863 +               
31864 +               execvp(new_argv[0], new_argv);
31865 +               perror("execing with extended args");
31866 +               exit(1);
31867 +       }       
31868 +#endif
31869 +
31870 +       linux_prog = argv[0];
31871 +
31872 +       set_stklim();
31873 +
31874 +       if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){
31875 +               perror("Mallocing argv");
31876 +               exit(1);
31877 +       }
31878 +       for(i=0;i<argc;i++){
31879 +               if((new_argv[i] = strdup(argv[i])) == NULL){
31880 +                       perror("Mallocing an arg");
31881 +                       exit(1);
31882 +               }
31883 +       }
31884 +       new_argv[argc] = NULL;
31885 +
31886 +       set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
31887 +       set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
31888 +       set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
31889 +
31890 +       do_uml_initcalls();
31891 +       ret = linux_main(argc, argv);
31892 +       
31893 +       /* Reboot */
31894 +       if(ret){
31895 +               printf("\n");
31896 +               execvp(new_argv[0], new_argv);
31897 +               perror("Failed to exec kernel");
31898 +               ret = 1;
31899 +       }
31900 +       printf("\n");
31901 +       return(uml_exitcode);
31902 +}
31903 +
31904 +#define CAN_KMALLOC() \
31905 +       (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
31906 +
31907 +extern void *__real_malloc(int);
31908 +
31909 +void *__wrap_malloc(int size)
31910 +{
31911 +       if(CAN_KMALLOC())
31912 +               return(um_kmalloc(size));
31913 +       else
31914 +               return(__real_malloc(size));
31915 +}
31916 +
31917 +void *__wrap_calloc(int n, int size)
31918 +{
31919 +       void *ptr = __wrap_malloc(n * size);
31920 +
31921 +       if(ptr == NULL) return(NULL);
31922 +       memset(ptr, 0, n * size);
31923 +       return(ptr);
31924 +}
31925 +
31926 +extern void __real_free(void *);
31927 +
31928 +void __wrap_free(void *ptr)
31929 +{
31930 +       if(CAN_KMALLOC()) kfree(ptr);
31931 +       else __real_free(ptr);
31932 +}
31933 +
31934 +/*
31935 + * Overrides for Emacs so that we follow Linus's tabbing style.
31936 + * Emacs will notice this stuff at the end of the file and automatically
31937 + * adjust the settings for this buffer only.  This must remain at the end
31938 + * of the file.
31939 + * ---------------------------------------------------------------------------
31940 + * Local variables:
31941 + * c-file-style: "linux"
31942 + * End:
31943 + */
31944 diff -Naur -X ../exclude-files orig/arch/um/Makefile um/arch/um/Makefile
31945 --- orig/arch/um/Makefile       1969-12-31 19:00:00.000000000 -0500
31946 +++ um/arch/um/Makefile 2003-06-05 15:42:11.000000000 -0400
31947 @@ -0,0 +1,168 @@
31948 +# 
31949 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31950 +# Licensed under the GPL
31951 +#
31952 +
31953 +OS := $(shell uname -s)
31954 +
31955 +ARCH_DIR = arch/um
31956 +
31957 +core-y := kernel sys-$(SUBARCH) os-$(OS)
31958 +drivers-y := fs drivers
31959 +subdir-y := $(core-y) $(drivers-y)
31960 +SUBDIRS += $(foreach dir,$(subdir-y),$(ARCH_DIR)/$(dir))
31961 +
31962 +CORE_FILES += $(foreach dir,$(core-y),$(ARCH_DIR)/$(dir)/built-in.o)
31963 +DRIVERS += $(foreach dir,$(drivers-y),$(ARCH_DIR)/$(dir)/built-in.o)
31964 +
31965 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
31966 +include $(ARCH_DIR)/Makefile-os-$(OS)
31967 +
31968 +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
31969 +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
31970 +
31971 +ifneq ($(MAKEFILE-y),)
31972 +  include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
31973 +endif
31974 +
31975 +EXTRAVERSION := $(EXTRAVERSION)-6um
31976 +
31977 +include/linux/version.h: arch/$(ARCH)/Makefile
31978 +
31979 +# Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE)
31980 +# The way the toplevel Makefile is written EXTRAVERSION is not supposed
31981 +# to be changed outside the toplevel Makefile, but recalculating MODLIB is
31982 +# a sufficient workaround until we no longer need architecture dependent
31983 +# EXTRAVERSION...
31984 +MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
31985 +
31986 +ifeq ($(CONFIG_DEBUGSYM),y)
31987 +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
31988 +endif
31989 +
31990 +CFLAGS-$(CONFIG_DEBUGSYM) += -g
31991 +
31992 +ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include
31993 +
31994 +# -Derrno=kernel_errno - This turns all kernel references to errno into
31995 +# kernel_errno to separate them from the libc errno.  This allows -fno-common
31996 +# in CFLAGS.  Otherwise, it would cause ld to complain about the two different
31997 +# errnos.
31998 +
31999 +CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
32000 +       -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
32001 +       $(MODE_INCLUDE)
32002 +
32003 +LINKFLAGS += -r
32004 +
32005 +LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
32006 +
32007 +SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
32008 +
32009 +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
32010 +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
32011 +
32012 +LINK_TT = -static
32013 +LD_SCRIPT_TT := link.ld
32014 +
32015 +ifeq ($(CONFIG_STATIC_LINK),y)
32016 +  LINK-y += $(LINK_TT)
32017 +  LD_SCRIPT-y := $(LD_SCRIPT_TT)
32018 +else
32019 +ifeq ($(CONFIG_MODE_TT),y)
32020 +  LINK-y += $(LINK_TT)
32021 +  LD_SCRIPT-y := $(LD_SCRIPT_TT)
32022 +else
32023 +ifeq ($(CONFIG_MODE_SKAS),y)
32024 +  LINK-y += $(LINK_SKAS)
32025 +  LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
32026 +endif
32027 +endif
32028 +endif
32029 +
32030 +LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
32031 +M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
32032 +
32033 +$(LD_SCRIPT-y): $(LD_SCRIPT-y).in
32034 +       pages=$$(( 1 << $(CONFIG_KERNEL_STACK_ORDER) )) ; \
32035 +       m4 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
32036 +               -DELF_FORMAT=$(ELF_FORMAT) $(M4_MODE_TT) \
32037 +               -DKERNEL_STACK_SIZE=$$(( 4096 * $$pages )) $< > $@
32038 +
32039 +SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
32040 +       include/asm-um/sigcontext.h include/asm-um/processor.h \
32041 +       include/asm-um/ptrace.h include/asm-um/arch-signal.h
32042 +
32043 +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
32044 +       $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
32045 +
32046 +ifeq ($(CONFIG_MODE_SKAS), y)
32047 +$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
32048 +endif
32049 +
32050 +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h 
32051 +
32052 +setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) 
32053 +
32054 +linux: setup $(ARCH_DIR)/main.o vmlinux $(LD_SCRIPT-y)
32055 +       mv vmlinux vmlinux.o
32056 +       $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
32057 +               -o linux $(ARCH_DIR)/main.o vmlinux.o -L/usr/lib -lutil
32058 +
32059 +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
32060 +USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
32061 +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
32062 +       $(MODE_INCLUDE)
32063 +
32064 +# To get a definition of F_SETSIG
32065 +USER_CFLAGS += -D_GNU_SOURCE
32066 +
32067 +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \
32068 +       $(GEN_HEADERS) $(ARCH_DIR)/include/uml-config.h
32069 +
32070 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
32071 +       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
32072 +
32073 +archmrproper:
32074 +       rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
32075 +               $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
32076 +
32077 +archclean: sysclean
32078 +       find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
32079 +               -o -name '*.gcov' \) -type f -print | xargs rm -f
32080 +       cd $(ARCH_DIR) ; \
32081 +       for dir in $(subdir-y) util ; do $(MAKE) -C $$dir clean; done
32082 +
32083 +archdep: 
32084 +
32085 +$(SYMLINK_HEADERS):
32086 +       cd $(TOPDIR)/$(dir $@) ; \
32087 +       ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
32088 +
32089 +include/asm-um/arch:
32090 +       cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
32091 +
32092 +arch/um/include/sysdep:
32093 +       cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep
32094 +
32095 +arch/um/os:
32096 +       cd $(ARCH_DIR) && ln -sf os-$(OS) os
32097 +
32098 +$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
32099 +       $< > $@
32100 +
32101 +$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
32102 +       $< > $@
32103 +
32104 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
32105 +       sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
32106 +
32107 +$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/util/mk_task_user.c \
32108 +       $(ARCH_DIR)/util/mk_task_kern.c $(SYS_HEADERS)
32109 +       $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_task
32110 +
32111 +$(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util/mk_constants_user.c \
32112 +       $(ARCH_DIR)/util/mk_constants_kern.c 
32113 +       $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_constants
32114 +
32115 +export SUBARCH USER_CFLAGS OS
32116 diff -Naur -X ../exclude-files orig/arch/um/Makefile-i386 um/arch/um/Makefile-i386
32117 --- orig/arch/um/Makefile-i386  1969-12-31 19:00:00.000000000 -0500
32118 +++ um/arch/um/Makefile-i386    2002-10-23 21:08:04.000000000 -0400
32119 @@ -0,0 +1,35 @@
32120 +ifeq ($(CONFIG_HOST_2G_2G), y)
32121 +TOP_ADDR = 0x80000000
32122 +else
32123 +TOP_ADDR = 0xc0000000
32124 +endif
32125 +
32126 +ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH) -DUM_FASTCALL
32127 +ELF_ARCH = $(SUBARCH)
32128 +ELF_FORMAT = elf32-$(SUBARCH)
32129 +
32130 +I386_H = $(ARCH_DIR)/include/sysdep-i386
32131 +SYS = $(ARCH_DIR)/sys-i386
32132 +UTIL = $(SYS)/util
32133 +SUBDIRS += $(UTIL)
32134 +
32135 +SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h
32136 +
32137 +$(I386_H)/sc.h : $(UTIL)/mk_sc
32138 +       $(UTIL)/mk_sc > $@
32139 +
32140 +$(I386_H)/thread.h : $(UTIL)/mk_thread
32141 +       $(UTIL)/mk_thread > $@
32142 +
32143 +$(UTIL)/mk_sc : $(UTIL)/mk_sc.c
32144 +       $(MAKE) -C $(UTIL) mk_sc
32145 +
32146 +$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \
32147 +       $(I386_H)/sc.h
32148 +       $(MAKE) -C $(UTIL) mk_thread
32149 +
32150 +sysclean :
32151 +       rm -f $(SYS_HEADERS)
32152 +       $(MAKE) -C $(UTIL) clean
32153 +       $(MAKE) -C $(SYS) clean
32154 +
32155 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ia64 um/arch/um/Makefile-ia64
32156 --- orig/arch/um/Makefile-ia64  1969-12-31 19:00:00.000000000 -0500
32157 +++ um/arch/um/Makefile-ia64    2002-10-23 21:08:04.000000000 -0400
32158 @@ -0,0 +1 @@
32159 +START_ADDR = 0x1000000000000000
32160 diff -Naur -X ../exclude-files orig/arch/um/Makefile-os-Linux um/arch/um/Makefile-os-Linux
32161 --- orig/arch/um/Makefile-os-Linux      1969-12-31 19:00:00.000000000 -0500
32162 +++ um/arch/um/Makefile-os-Linux        2002-12-09 14:21:51.000000000 -0500
32163 @@ -0,0 +1,7 @@
32164 +# 
32165 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
32166 +# Licensed under the GPL
32167 +#
32168 +
32169 +SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers
32170 +DRIVERS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o
32171 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ppc um/arch/um/Makefile-ppc
32172 --- orig/arch/um/Makefile-ppc   1969-12-31 19:00:00.000000000 -0500
32173 +++ um/arch/um/Makefile-ppc     2002-10-23 21:08:04.000000000 -0400
32174 @@ -0,0 +1,9 @@
32175 +ifeq ($(CONFIG_HOST_2G_2G), y)
32176 +START_ADDR = 0x80000000
32177 +else
32178 +START_ADDR = 0xc0000000
32179 +endif
32180 +ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
32181 +
32182 +# The arch is ppc, but the elf32 name is powerpc
32183 +ELF_SUBARCH = powerpc
32184 diff -Naur -X ../exclude-files orig/arch/um/Makefile-skas um/arch/um/Makefile-skas
32185 --- orig/arch/um/Makefile-skas  1969-12-31 19:00:00.000000000 -0500
32186 +++ um/arch/um/Makefile-skas    2002-12-15 22:02:57.000000000 -0500
32187 @@ -0,0 +1,20 @@
32188 +# 
32189 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32190 +# Licensed under the GPL
32191 +#
32192 +
32193 +PROFILE += -pg
32194 +
32195 +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
32196 +CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
32197 +LINK-$(CONFIG_GPROF) += $(PROFILE)
32198 +
32199 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
32200 +
32201 +LINK_SKAS = -Wl,-rpath,/lib 
32202 +LD_SCRIPT_SKAS = dyn_link.ld
32203 +
32204 +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
32205 +
32206 +$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
32207 +       $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
32208 diff -Naur -X ../exclude-files orig/arch/um/Makefile-tt um/arch/um/Makefile-tt
32209 --- orig/arch/um/Makefile-tt    1969-12-31 19:00:00.000000000 -0500
32210 +++ um/arch/um/Makefile-tt      2002-12-16 20:22:23.000000000 -0500
32211 @@ -0,0 +1,7 @@
32212 +# 
32213 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
32214 +# Licensed under the GPL
32215 +#
32216 +
32217 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
32218 +
32219 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/etap.h um/arch/um/os-Linux/drivers/etap.h
32220 --- orig/arch/um/os-Linux/drivers/etap.h        1969-12-31 19:00:00.000000000 -0500
32221 +++ um/arch/um/os-Linux/drivers/etap.h  2002-10-23 21:08:04.000000000 -0400
32222 @@ -0,0 +1,27 @@
32223 +/* 
32224 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
32225 + * Licensed under the GPL
32226 + */
32227 +
32228 +#include "net_user.h"
32229 +
32230 +struct ethertap_data {
32231 +       char *dev_name;
32232 +       char *gate_addr;
32233 +       int data_fd;
32234 +       int control_fd;
32235 +       void *dev;
32236 +};
32237 +
32238 +extern struct net_user_info ethertap_user_info;
32239 +
32240 +/*
32241 + * Overrides for Emacs so that we follow Linus's tabbing style.
32242 + * Emacs will notice this stuff at the end of the file and automatically
32243 + * adjust the settings for this buffer only.  This must remain at the end
32244 + * of the file.
32245 + * ---------------------------------------------------------------------------
32246 + * Local variables:
32247 + * c-file-style: "linux"
32248 + * End:
32249 + */
32250 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_kern.c um/arch/um/os-Linux/drivers/ethertap_kern.c
32251 --- orig/arch/um/os-Linux/drivers/ethertap_kern.c       1969-12-31 19:00:00.000000000 -0500
32252 +++ um/arch/um/os-Linux/drivers/ethertap_kern.c 2002-12-15 21:17:37.000000000 -0500
32253 @@ -0,0 +1,122 @@
32254 +/*
32255 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
32256 + * James Leu (jleu@mindspring.net).
32257 + * Copyright (C) 2001 by various other people who didn't put their name here.
32258 + * Licensed under the GPL.
32259 + */
32260 +
32261 +#include "linux/init.h"
32262 +#include "linux/netdevice.h"
32263 +#include "linux/etherdevice.h"
32264 +#include "linux/init.h"
32265 +#include "net_kern.h"
32266 +#include "net_user.h"
32267 +#include "etap.h"
32268 +
32269 +struct ethertap_init {
32270 +       char *dev_name;
32271 +       char *gate_addr;
32272 +};
32273 +
32274 +static void etap_init(struct net_device *dev, void *data)
32275 +{
32276 +       struct uml_net_private *pri;
32277 +       struct ethertap_data *epri;
32278 +       struct ethertap_init *init = data;
32279 +
32280 +       init_etherdev(dev, 0);
32281 +       pri = dev->priv;
32282 +       epri = (struct ethertap_data *) pri->user;
32283 +       *epri = ((struct ethertap_data)
32284 +               { .dev_name             = init->dev_name,
32285 +                 .gate_addr            = init->gate_addr,
32286 +                 .data_fd              = -1,
32287 +                 .control_fd           = -1,
32288 +                 .dev                  = dev });
32289 +
32290 +       printk("ethertap backend - %s", epri->dev_name);
32291 +       if(epri->gate_addr != NULL) 
32292 +               printk(", IP = %s", epri->gate_addr);
32293 +       printk("\n");
32294 +}
32295 +
32296 +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
32297 +{
32298 +       int len;
32299 +
32300 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
32301 +       if(*skb == NULL) return(-ENOMEM);
32302 +       len = net_recvfrom(fd, (*skb)->mac.raw, 
32303 +                          (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
32304 +       if(len <= 0) return(len);
32305 +       skb_pull(*skb, 2);
32306 +       len -= 2;
32307 +       return(len);
32308 +}
32309 +
32310 +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
32311 +{
32312 +       if(skb_headroom(*skb) < 2){
32313 +               struct sk_buff *skb2;
32314 +
32315 +               skb2 = skb_realloc_headroom(*skb, 2);
32316 +               dev_kfree_skb(*skb);
32317 +               if (skb2 == NULL) return(-ENOMEM);
32318 +               *skb = skb2;
32319 +       }
32320 +       skb_push(*skb, 2);
32321 +       return(net_send(fd, (*skb)->data, (*skb)->len));
32322 +}
32323 +
32324 +struct net_kern_info ethertap_kern_info = {
32325 +       .init                   = etap_init,
32326 +       .protocol               = eth_protocol,
32327 +       .read                   = etap_read,
32328 +       .write                  = etap_write,
32329 +};
32330 +
32331 +int ethertap_setup(char *str, char **mac_out, void *data)
32332 +{
32333 +       struct ethertap_init *init = data;
32334 +
32335 +       *init = ((struct ethertap_init)
32336 +               { .dev_name     = NULL,
32337 +                 .gate_addr    = NULL });
32338 +       if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
32339 +                           &init->gate_addr))
32340 +               return(0);
32341 +       if(init->dev_name == NULL){
32342 +               printk("ethertap_setup : Missing tap device name\n");
32343 +               return(0);
32344 +       }
32345 +
32346 +       return(1);
32347 +}
32348 +
32349 +static struct transport ethertap_transport = {
32350 +       .list           = LIST_HEAD_INIT(ethertap_transport.list),
32351 +       .name           = "ethertap",
32352 +       .setup          = ethertap_setup,
32353 +       .user           = &ethertap_user_info,
32354 +       .kern           = &ethertap_kern_info,
32355 +       .private_size   = sizeof(struct ethertap_data),
32356 +};
32357 +
32358 +static int register_ethertap(void)
32359 +{
32360 +       register_transport(&ethertap_transport);
32361 +       return(1);
32362 +}
32363 +
32364 +__initcall(register_ethertap);
32365 +
32366 +/*
32367 + * Overrides for Emacs so that we follow Linus's tabbing style.
32368 + * Emacs will notice this stuff at the end of the file and automatically
32369 + * adjust the settings for this buffer only.  This must remain at the end
32370 + * of the file.
32371 + * ---------------------------------------------------------------------------
32372 + * Local variables:
32373 + * c-file-style: "linux"
32374 + * End:
32375 + */
32376 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_user.c um/arch/um/os-Linux/drivers/ethertap_user.c
32377 --- orig/arch/um/os-Linux/drivers/ethertap_user.c       1969-12-31 19:00:00.000000000 -0500
32378 +++ um/arch/um/os-Linux/drivers/ethertap_user.c 2002-12-15 21:17:52.000000000 -0500
32379 @@ -0,0 +1,238 @@
32380 +/*
32381 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
32382 + * James Leu (jleu@mindspring.net).
32383 + * Copyright (C) 2001 by various other people who didn't put their name here.
32384 + * Licensed under the GPL.
32385 + */
32386 +
32387 +#include <stdio.h>
32388 +#include <unistd.h>
32389 +#include <stddef.h>
32390 +#include <fcntl.h>
32391 +#include <stdlib.h>
32392 +#include <sys/errno.h>
32393 +#include <sys/socket.h>
32394 +#include <sys/wait.h>
32395 +#include <sys/un.h>
32396 +#include <net/if.h>
32397 +#include "user.h"
32398 +#include "kern_util.h"
32399 +#include "net_user.h"
32400 +#include "etap.h"
32401 +#include "helper.h"
32402 +#include "os.h"
32403 +
32404 +#define MAX_PACKET ETH_MAX_PACKET
32405 +
32406 +void etap_user_init(void *data, void *dev)
32407 +{
32408 +       struct ethertap_data *pri = data;
32409 +
32410 +       pri->dev = dev;
32411 +}
32412 +
32413 +struct addr_change {
32414 +       enum { ADD_ADDR, DEL_ADDR } what;
32415 +       unsigned char addr[4];
32416 +       unsigned char netmask[4];
32417 +};
32418 +
32419 +static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
32420 +                       int fd)
32421 +{
32422 +       struct addr_change change;
32423 +       void *output;
32424 +
32425 +       change.what = op;
32426 +       memcpy(change.addr, addr, sizeof(change.addr));
32427 +       memcpy(change.netmask, netmask, sizeof(change.netmask));
32428 +       if(write(fd, &change, sizeof(change)) != sizeof(change))
32429 +               printk("etap_change - request failed, errno = %d\n",
32430 +                      errno);
32431 +       output = um_kmalloc(page_size());
32432 +       if(output == NULL)
32433 +               printk("etap_change : Failed to allocate output buffer\n");
32434 +       read_output(fd, output, page_size());
32435 +       if(output != NULL){
32436 +               printk("%s", output);
32437 +               kfree(output);
32438 +       }
32439 +}
32440 +
32441 +static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
32442 +                          void *arg)
32443 +{
32444 +       etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
32445 +}
32446 +
32447 +static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
32448 +                           void *arg)
32449 +{
32450 +       etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
32451 +}
32452 +
32453 +struct etap_pre_exec_data {
32454 +       int control_remote;
32455 +       int control_me;
32456 +       int data_me;
32457 +};
32458 +
32459 +static void etap_pre_exec(void *arg)
32460 +{
32461 +       struct etap_pre_exec_data *data = arg;
32462 +
32463 +       dup2(data->control_remote, 1);
32464 +       close(data->data_me);
32465 +       close(data->control_me);
32466 +}
32467 +
32468 +static int etap_tramp(char *dev, char *gate, int control_me, 
32469 +                     int control_remote, int data_me, int data_remote)
32470 +{
32471 +       struct etap_pre_exec_data pe_data;
32472 +       int pid, status, err;
32473 +       char version_buf[sizeof("nnnnn\0")];
32474 +       char data_fd_buf[sizeof("nnnnnn\0")];
32475 +       char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
32476 +       char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
32477 +                              data_fd_buf, gate_buf, NULL };
32478 +       char *nosetup_args[] = { "uml_net", version_buf, "ethertap", 
32479 +                                dev, data_fd_buf, NULL };
32480 +       char **args, c;
32481 +
32482 +       sprintf(data_fd_buf, "%d", data_remote);
32483 +       sprintf(version_buf, "%d", UML_NET_VERSION);
32484 +       if(gate != NULL){
32485 +               strcpy(gate_buf, gate);
32486 +               args = setup_args;
32487 +       }
32488 +       else args = nosetup_args;
32489 +
32490 +       err = 0;
32491 +       pe_data.control_remote = control_remote;
32492 +       pe_data.control_me = control_me;
32493 +       pe_data.data_me = data_me;
32494 +       pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
32495 +
32496 +       if(pid < 0) err = errno;
32497 +       close(data_remote);
32498 +       close(control_remote);
32499 +       if(read(control_me, &c, sizeof(c)) != sizeof(c)){
32500 +               printk("etap_tramp : read of status failed, errno = %d\n",
32501 +                      errno);
32502 +               return(EINVAL);
32503 +       }
32504 +       if(c != 1){
32505 +               printk("etap_tramp : uml_net failed\n");
32506 +               err = EINVAL;
32507 +               if(waitpid(pid, &status, 0) < 0) err = errno;
32508 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
32509 +                       printk("uml_net didn't exit with status 1\n");
32510 +               }
32511 +       }
32512 +       return(err);
32513 +}
32514 +
32515 +static int etap_open(void *data)
32516 +{
32517 +       struct ethertap_data *pri = data;
32518 +       char *output;
32519 +       int data_fds[2], control_fds[2], err, output_len;
32520 +
32521 +       err = tap_open_common(pri->dev, pri->gate_addr);
32522 +       if(err) return(err);
32523 +
32524 +       err = os_pipe(data_fds, 0, 0);
32525 +       if(err){
32526 +               printk("data os_pipe failed - errno = %d\n", -err);
32527 +               return(err);
32528 +       }
32529 +
32530 +       err = os_pipe(control_fds, 1, 0);
32531 +       if(err){
32532 +               printk("control os_pipe failed - errno = %d\n", -err);
32533 +               return(err);
32534 +       }
32535 +       
32536 +       err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], 
32537 +                        control_fds[1], data_fds[0], data_fds[1]);
32538 +       output_len = page_size();
32539 +       output = um_kmalloc(output_len);
32540 +       read_output(control_fds[0], output, output_len);
32541 +
32542 +       if(output == NULL)
32543 +               printk("etap_open : failed to allocate output buffer\n");
32544 +       else {
32545 +               printk("%s", output);
32546 +               kfree(output);
32547 +       }
32548 +
32549 +       if(err != 0){
32550 +               printk("etap_tramp failed - errno = %d\n", err);
32551 +               return(-err);
32552 +       }
32553 +
32554 +       pri->data_fd = data_fds[0];
32555 +       pri->control_fd = control_fds[0];
32556 +       iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
32557 +       return(data_fds[0]);
32558 +}
32559 +
32560 +static void etap_close(int fd, void *data)
32561 +{
32562 +       struct ethertap_data *pri = data;
32563 +
32564 +       iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
32565 +       close(fd);
32566 +       os_shutdown_socket(pri->data_fd, 1, 1);
32567 +       close(pri->data_fd);
32568 +       pri->data_fd = -1;
32569 +       close(pri->control_fd);
32570 +       pri->control_fd = -1;
32571 +}
32572 +
32573 +static int etap_set_mtu(int mtu, void *data)
32574 +{
32575 +       return(mtu);
32576 +}
32577 +
32578 +static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
32579 +                         void *data)
32580 +{
32581 +       struct ethertap_data *pri = data;
32582 +
32583 +       tap_check_ips(pri->gate_addr, addr);
32584 +       if(pri->control_fd == -1) return;
32585 +       etap_open_addr(addr, netmask, &pri->control_fd);
32586 +}
32587 +
32588 +static void etap_del_addr(unsigned char *addr, unsigned char *netmask, 
32589 +                         void *data)
32590 +{
32591 +       struct ethertap_data *pri = data;
32592 +
32593 +       if(pri->control_fd == -1) return;
32594 +       etap_close_addr(addr, netmask, &pri->control_fd);
32595 +}
32596 +
32597 +struct net_user_info ethertap_user_info = {
32598 +       .init           = etap_user_init,
32599 +       .open           = etap_open,
32600 +       .close          = etap_close,
32601 +       .remove         = NULL,
32602 +       .set_mtu        = etap_set_mtu,
32603 +       .add_address    = etap_add_addr,
32604 +       .delete_address = etap_del_addr,
32605 +       .max_packet     = MAX_PACKET - ETH_HEADER_ETHERTAP
32606 +};
32607 +
32608 +/*
32609 + * Overrides for Emacs so that we follow Linus's tabbing style.
32610 + * Emacs will notice this stuff at the end of the file and automatically
32611 + * adjust the settings for this buffer only.  This must remain at the end
32612 + * of the file.
32613 + * ---------------------------------------------------------------------------
32614 + * Local variables:
32615 + * c-file-style: "linux"
32616 + * End:
32617 + */
32618 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/Makefile um/arch/um/os-Linux/drivers/Makefile
32619 --- orig/arch/um/os-Linux/drivers/Makefile      1969-12-31 19:00:00.000000000 -0500
32620 +++ um/arch/um/os-Linux/drivers/Makefile        2002-10-23 21:08:04.000000000 -0400
32621 @@ -0,0 +1,31 @@
32622 +# 
32623 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
32624 +# Licensed under the GPL
32625 +#
32626 +
32627 +O_TARGET := drivers.o
32628 +
32629 +list-multi := tuntap.o ethertap.o
32630 +
32631 +ethertap-objs := ethertap_kern.o ethertap_user.o
32632 +tuntap-objs := tuntap_kern.o tuntap_user.o
32633 +
32634 +obj-y = 
32635 +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
32636 +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
32637 +
32638 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
32639 +
32640 +USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
32641 +
32642 +include $(TOPDIR)/Rules.make
32643 +
32644 +$(USER_OBJS) : %.o: %.c
32645 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
32646 +
32647 +ethertap.o : $(ethertap-objs)
32648 +
32649 +tuntap.o : $(tuntap-objs)
32650 +
32651 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
32652 +       $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
32653 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap.h um/arch/um/os-Linux/drivers/tuntap.h
32654 --- orig/arch/um/os-Linux/drivers/tuntap.h      1969-12-31 19:00:00.000000000 -0500
32655 +++ um/arch/um/os-Linux/drivers/tuntap.h        2002-10-23 21:08:04.000000000 -0400
32656 @@ -0,0 +1,32 @@
32657 +/* 
32658 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32659 + * Licensed under the GPL
32660 + */
32661 +
32662 +#ifndef __UM_TUNTAP_H
32663 +#define __UM_TUNTAP_H
32664 +
32665 +#include "net_user.h"
32666 +
32667 +struct tuntap_data {
32668 +       char *dev_name;
32669 +       int fixed_config;
32670 +       char *gate_addr;
32671 +       int fd;
32672 +       void *dev;
32673 +};
32674 +
32675 +extern struct net_user_info tuntap_user_info;
32676 +
32677 +#endif
32678 +
32679 +/*
32680 + * Overrides for Emacs so that we follow Linus's tabbing style.
32681 + * Emacs will notice this stuff at the end of the file and automatically
32682 + * adjust the settings for this buffer only.  This must remain at the end
32683 + * of the file.
32684 + * ---------------------------------------------------------------------------
32685 + * Local variables:
32686 + * c-file-style: "linux"
32687 + * End:
32688 + */
32689 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_kern.c um/arch/um/os-Linux/drivers/tuntap_kern.c
32690 --- orig/arch/um/os-Linux/drivers/tuntap_kern.c 1969-12-31 19:00:00.000000000 -0500
32691 +++ um/arch/um/os-Linux/drivers/tuntap_kern.c   2002-12-15 21:18:16.000000000 -0500
32692 @@ -0,0 +1,105 @@
32693 +/* 
32694 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
32695 + * Licensed under the GPL
32696 + */
32697 +
32698 +#include "linux/stddef.h"
32699 +#include "linux/netdevice.h"
32700 +#include "linux/etherdevice.h"
32701 +#include "linux/skbuff.h"
32702 +#include "linux/init.h"
32703 +#include "asm/errno.h"
32704 +#include "net_kern.h"
32705 +#include "net_user.h"
32706 +#include "tuntap.h"
32707 +
32708 +struct tuntap_init {
32709 +       char *dev_name;
32710 +       char *gate_addr;
32711 +};
32712 +
32713 +static void tuntap_init(struct net_device *dev, void *data)
32714 +{
32715 +       struct uml_net_private *pri;
32716 +       struct tuntap_data *tpri;
32717 +       struct tuntap_init *init = data;
32718 +
32719 +       init_etherdev(dev, 0);
32720 +       pri = dev->priv;
32721 +       tpri = (struct tuntap_data *) pri->user;
32722 +       *tpri = ((struct tuntap_data)
32723 +               { .dev_name             = init->dev_name,
32724 +                 .fixed_config         = (init->dev_name != NULL),
32725 +                 .gate_addr            = init->gate_addr,
32726 +                 .fd                   = -1,
32727 +                 .dev                  = dev });
32728 +       printk("TUN/TAP backend - ");
32729 +       if(tpri->gate_addr != NULL) 
32730 +               printk("IP = %s", tpri->gate_addr);
32731 +       printk("\n");
32732 +}
32733 +
32734 +static int tuntap_read(int fd, struct sk_buff **skb, 
32735 +                      struct uml_net_private *lp)
32736 +{
32737 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
32738 +       if(*skb == NULL) return(-ENOMEM);
32739 +       return(net_read(fd, (*skb)->mac.raw, 
32740 +                       (*skb)->dev->mtu + ETH_HEADER_OTHER));
32741 +}
32742 +
32743 +static int tuntap_write(int fd, struct sk_buff **skb, 
32744 +                       struct uml_net_private *lp)
32745 +{
32746 +       return(net_write(fd, (*skb)->data, (*skb)->len));
32747 +}
32748 +
32749 +struct net_kern_info tuntap_kern_info = {
32750 +       .init                   = tuntap_init,
32751 +       .protocol               = eth_protocol,
32752 +       .read                   = tuntap_read,
32753 +       .write                  = tuntap_write,
32754 +};
32755 +
32756 +int tuntap_setup(char *str, char **mac_out, void *data)
32757 +{
32758 +       struct tuntap_init *init = data;
32759 +
32760 +       *init = ((struct tuntap_init)
32761 +               { .dev_name     = NULL,
32762 +                 .gate_addr    = NULL });
32763 +       if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
32764 +                           &init->gate_addr))
32765 +               return(0);
32766 +
32767 +       return(1);
32768 +}
32769 +
32770 +static struct transport tuntap_transport = {
32771 +       .list           = LIST_HEAD_INIT(tuntap_transport.list),
32772 +       .name           = "tuntap",
32773 +       .setup          = tuntap_setup,
32774 +       .user           = &tuntap_user_info,
32775 +       .kern           = &tuntap_kern_info,
32776 +       .private_size   = sizeof(struct tuntap_data),
32777 +       .setup_size     = sizeof(struct tuntap_init),
32778 +};
32779 +
32780 +static int register_tuntap(void)
32781 +{
32782 +       register_transport(&tuntap_transport);
32783 +       return(1);
32784 +}
32785 +
32786 +__initcall(register_tuntap);
32787 +
32788 +/*
32789 + * Overrides for Emacs so that we follow Linus's tabbing style.
32790 + * Emacs will notice this stuff at the end of the file and automatically
32791 + * adjust the settings for this buffer only.  This must remain at the end
32792 + * of the file.
32793 + * ---------------------------------------------------------------------------
32794 + * Local variables:
32795 + * c-file-style: "linux"
32796 + * End:
32797 + */
32798 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_user.c um/arch/um/os-Linux/drivers/tuntap_user.c
32799 --- orig/arch/um/os-Linux/drivers/tuntap_user.c 1969-12-31 19:00:00.000000000 -0500
32800 +++ um/arch/um/os-Linux/drivers/tuntap_user.c   2002-12-15 21:18:25.000000000 -0500
32801 @@ -0,0 +1,223 @@
32802 +/* 
32803 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32804 + * Licensed under the GPL
32805 + */
32806 +
32807 +#include <stdio.h>
32808 +#include <stddef.h>
32809 +#include <stdlib.h>
32810 +#include <unistd.h>
32811 +#include <errno.h>
32812 +#include <fcntl.h>
32813 +#include <sys/wait.h>
32814 +#include <sys/socket.h>
32815 +#include <sys/un.h>
32816 +#include <sys/uio.h>
32817 +#include <sys/ioctl.h>
32818 +#include <net/if.h>
32819 +#include <linux/if_tun.h>
32820 +#include "net_user.h"
32821 +#include "tuntap.h"
32822 +#include "kern_util.h"
32823 +#include "user.h"
32824 +#include "helper.h"
32825 +#include "os.h"
32826 +
32827 +#define MAX_PACKET ETH_MAX_PACKET
32828 +
32829 +void tuntap_user_init(void *data, void *dev)
32830 +{
32831 +       struct tuntap_data *pri = data;
32832 +
32833 +       pri->dev = dev;
32834 +}
32835 +
32836 +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
32837 +                           void *data)
32838 +{
32839 +       struct tuntap_data *pri = data;
32840 +
32841 +       tap_check_ips(pri->gate_addr, addr);
32842 +       if((pri->fd == -1) || pri->fixed_config) return;
32843 +       open_addr(addr, netmask, pri->dev_name);
32844 +}
32845 +
32846 +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
32847 +                           void *data)
32848 +{
32849 +       struct tuntap_data *pri = data;
32850 +
32851 +       if((pri->fd == -1) || pri->fixed_config) return;
32852 +       close_addr(addr, netmask, pri->dev_name);
32853 +}
32854 +
32855 +struct tuntap_pre_exec_data {
32856 +       int stdout;
32857 +       int close_me;
32858 +};
32859 +
32860 +static void tuntap_pre_exec(void *arg)
32861 +{
32862 +       struct tuntap_pre_exec_data *data = arg;
32863 +       
32864 +       dup2(data->stdout, 1);
32865 +       close(data->close_me);
32866 +}
32867 +
32868 +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
32869 +                            char *buffer, int buffer_len, int *used_out)
32870 +{
32871 +       struct tuntap_pre_exec_data data;
32872 +       char version_buf[sizeof("nnnnn\0")];
32873 +       char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
32874 +                        NULL };
32875 +       char buf[CMSG_SPACE(sizeof(*fd_out))];
32876 +       struct msghdr msg;
32877 +       struct cmsghdr *cmsg;
32878 +       struct iovec iov;
32879 +       int pid, n;
32880 +
32881 +       sprintf(version_buf, "%d", UML_NET_VERSION);
32882 +
32883 +       data.stdout = remote;
32884 +       data.close_me = me;
32885 +
32886 +       pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
32887 +
32888 +       if(pid < 0) return(-pid);
32889 +
32890 +       close(remote);
32891 +
32892 +       msg.msg_name = NULL;
32893 +       msg.msg_namelen = 0;
32894 +       if(buffer != NULL){
32895 +               iov = ((struct iovec) { buffer, buffer_len });
32896 +               msg.msg_iov = &iov;
32897 +               msg.msg_iovlen = 1;
32898 +       }
32899 +       else {
32900 +               msg.msg_iov = NULL;
32901 +               msg.msg_iovlen = 0;
32902 +       }
32903 +       msg.msg_control = buf;
32904 +       msg.msg_controllen = sizeof(buf);
32905 +       msg.msg_flags = 0;
32906 +       n = recvmsg(me, &msg, 0);
32907 +       *used_out = n;
32908 +       if(n < 0){
32909 +               printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", 
32910 +                      errno);
32911 +               return(errno);
32912 +       }
32913 +       waitpid(pid, NULL, 0);
32914 +
32915 +       cmsg = CMSG_FIRSTHDR(&msg);
32916 +       if(cmsg == NULL){
32917 +               printk("tuntap_open_tramp : didn't receive a message\n");
32918 +               return(EINVAL);
32919 +       }
32920 +       if((cmsg->cmsg_level != SOL_SOCKET) || 
32921 +          (cmsg->cmsg_type != SCM_RIGHTS)){
32922 +               printk("tuntap_open_tramp : didn't receive a descriptor\n");
32923 +               return(EINVAL);
32924 +       }
32925 +       *fd_out = ((int *) CMSG_DATA(cmsg))[0];
32926 +       return(0);
32927 +}
32928 +
32929 +static int tuntap_open(void *data)
32930 +{
32931 +       struct ifreq ifr;
32932 +       struct tuntap_data *pri = data;
32933 +       char *output, *buffer;
32934 +       int err, fds[2], len, used;
32935 +
32936 +       err = tap_open_common(pri->dev, pri->gate_addr);
32937 +       if(err) return(err);
32938 +
32939 +       if(pri->fixed_config){
32940 +               if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){
32941 +                       printk("Failed to open /dev/net/tun, errno = %d\n",
32942 +                              errno);
32943 +                       return(-errno);
32944 +               }
32945 +               memset(&ifr, 0, sizeof(ifr));
32946 +               ifr.ifr_flags = IFF_TAP;
32947 +               strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1);
32948 +               if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
32949 +                       printk("TUNSETIFF failed, errno = %d", errno);
32950 +                       close(pri->fd);
32951 +                       return(-errno);
32952 +               }
32953 +       }
32954 +       else {
32955 +               err = os_pipe(fds, 0, 0);
32956 +               if(err){
32957 +                       printk("tuntap_open : os_pipe failed - errno = %d\n",
32958 +                              -err);
32959 +                       return(err);
32960 +               }
32961 +
32962 +               buffer = get_output_buffer(&len);
32963 +               if(buffer != NULL) len--;
32964 +               used = 0;
32965 +
32966 +               err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
32967 +                                       fds[1], buffer, len, &used);
32968 +
32969 +               output = buffer;
32970 +               if(err == 0){
32971 +                       pri->dev_name = uml_strdup(buffer);
32972 +                       output += IFNAMSIZ;
32973 +                       printk(output);
32974 +                       free_output_buffer(buffer);
32975 +               }
32976 +               else {
32977 +                       printk(output);
32978 +                       free_output_buffer(buffer);
32979 +                       printk("tuntap_open_tramp failed - errno = %d\n", err);
32980 +                       return(-err);
32981 +               }
32982 +               close(fds[0]);
32983 +               iter_addresses(pri->dev, open_addr, pri->dev_name);
32984 +       }
32985 +
32986 +       return(pri->fd);
32987 +}
32988 +
32989 +static void tuntap_close(int fd, void *data)
32990 +{
32991 +       struct tuntap_data *pri = data;
32992 +
32993 +       if(!pri->fixed_config) 
32994 +               iter_addresses(pri->dev, close_addr, pri->dev_name);
32995 +       close(fd);
32996 +       pri->fd = -1;
32997 +}
32998 +
32999 +static int tuntap_set_mtu(int mtu, void *data)
33000 +{
33001 +       return(mtu);
33002 +}
33003 +
33004 +struct net_user_info tuntap_user_info = {
33005 +       .init           = tuntap_user_init,
33006 +       .open           = tuntap_open,
33007 +       .close          = tuntap_close,
33008 +       .remove         = NULL,
33009 +       .set_mtu        = tuntap_set_mtu,
33010 +       .add_address    = tuntap_add_addr,
33011 +       .delete_address = tuntap_del_addr,
33012 +       .max_packet     = MAX_PACKET
33013 +};
33014 +
33015 +/*
33016 + * Overrides for Emacs so that we follow Linus's tabbing style.
33017 + * Emacs will notice this stuff at the end of the file and automatically
33018 + * adjust the settings for this buffer only.  This must remain at the end
33019 + * of the file.
33020 + * ---------------------------------------------------------------------------
33021 + * Local variables:
33022 + * c-file-style: "linux"
33023 + * End:
33024 + */
33025 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/file.c um/arch/um/os-Linux/file.c
33026 --- orig/arch/um/os-Linux/file.c        1969-12-31 19:00:00.000000000 -0500
33027 +++ um/arch/um/os-Linux/file.c  2003-02-04 19:32:10.000000000 -0500
33028 @@ -0,0 +1,384 @@
33029 +/* 
33030 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33031 + * Licensed under the GPL
33032 + */
33033 +
33034 +#include <stdio.h>
33035 +#include <unistd.h>
33036 +#include <errno.h>
33037 +#include <fcntl.h>
33038 +#include <signal.h>
33039 +#include <sys/socket.h>
33040 +#include <sys/un.h>
33041 +#include <sys/ioctl.h>
33042 +#include <sys/mount.h>
33043 +#include <sys/uio.h>
33044 +#include "os.h"
33045 +#include "user.h"
33046 +#include "kern_util.h"
33047 +
33048 +int os_file_type(char *file)
33049 +{
33050 +       struct stat64 buf;
33051 +
33052 +       if(stat64(file, &buf) == -1)
33053 +               return(-errno);
33054 +
33055 +       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
33056 +       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
33057 +       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
33058 +       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
33059 +       else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO);
33060 +       else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK);
33061 +       else return(OS_TYPE_FILE);
33062 +}
33063 +
33064 +int os_file_mode(char *file, struct openflags *mode_out)
33065 +{
33066 +       *mode_out = OPENFLAGS();
33067 +
33068 +       if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
33069 +       else if(errno != EACCES) 
33070 +               return(-errno);
33071 +
33072 +       if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
33073 +       else if(errno != EACCES) 
33074 +               return(-errno);
33075 +
33076 +       return(0);
33077 +}
33078 +
33079 +int os_open_file(char *file, struct openflags flags, int mode)
33080 +{
33081 +       int fd, f = 0;
33082 +
33083 +       if(flags.r && flags.w) f = O_RDWR;
33084 +       else if(flags.r) f = O_RDONLY;
33085 +       else if(flags.w) f = O_WRONLY;
33086 +       else f = 0;
33087 +
33088 +       if(flags.s) f |= O_SYNC;
33089 +       if(flags.c) f |= O_CREAT;
33090 +       if(flags.t) f |= O_TRUNC;
33091 +       if(flags.e) f |= O_EXCL;
33092 +
33093 +       fd = open64(file, f, mode);
33094 +       if(fd < 0) return(-errno);
33095 +
33096 +       if(flags.cl){
33097 +               if(fcntl(fd, F_SETFD, 1)){
33098 +                       close(fd);
33099 +                       return(-errno);
33100 +               }
33101 +       }
33102 +
33103 +       return(fd);
33104 +}
33105 +
33106 +int os_connect_socket(char *name)
33107 +{
33108 +       struct sockaddr_un sock;
33109 +       int fd, err;
33110 +
33111 +       sock.sun_family = AF_UNIX;
33112 +       snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
33113 +
33114 +       fd = socket(AF_UNIX, SOCK_STREAM, 0);
33115 +       if(fd < 0)
33116 +               return(fd);
33117 +
33118 +       err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
33119 +       if(err)
33120 +               return(err);
33121 +
33122 +       return(fd);
33123 +}
33124 +
33125 +void os_close_file(int fd)
33126 +{
33127 +       close(fd);
33128 +}
33129 +
33130 +int os_seek_file(int fd, __u64 offset)
33131 +{
33132 +       __u64 actual;
33133 +
33134 +       actual = lseek64(fd, offset, SEEK_SET);
33135 +       if(actual != offset) return(-errno);
33136 +       return(0);
33137 +}
33138 +
33139 +int os_read_file(int fd, void *buf, int len)
33140 +{
33141 +       int n;
33142 +
33143 +       /* Force buf into memory if it's not already. */
33144 +
33145 +       /* XXX This fails if buf is kernel memory */
33146 +#ifdef notdef
33147 +       if(copy_to_user_proc(buf, &c, sizeof(c)))
33148 +               return(-EFAULT);
33149 +#endif
33150 +
33151 +       n = read(fd, buf, len);
33152 +       if(n < 0)
33153 +               return(-errno);
33154 +       return(n);
33155 +}
33156 +
33157 +int os_write_file(int fd, void *buf, int count)
33158 +{
33159 +       int n;
33160 +
33161 +       /* Force buf into memory if it's not already. */
33162 +       
33163 +       /* XXX This fails if buf is kernel memory */
33164 +#ifdef notdef
33165 +       if(copy_to_user_proc(buf, buf, buf[0]))
33166 +               return(-EFAULT);
33167 +#endif
33168 +
33169 +       n = write(fd, buf, count);
33170 +       if(n < 0)
33171 +               return(-errno);
33172 +       return(n);
33173 +}
33174 +
33175 +int os_file_size(char *file, long long *size_out)
33176 +{
33177 +       struct stat64 buf;
33178 +
33179 +       if(stat64(file, &buf) == -1){
33180 +               printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
33181 +               return(-errno);
33182 +       }
33183 +       if(S_ISBLK(buf.st_mode)){
33184 +               int fd, blocks;
33185 +
33186 +               if((fd = open64(file, O_RDONLY)) < 0){
33187 +                       printk("Couldn't open \"%s\", errno = %d\n", file,
33188 +                              errno);
33189 +                       return(-errno);
33190 +               }
33191 +               if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
33192 +                       printk("Couldn't get the block size of \"%s\", "
33193 +                              "errno = %d\n", file, errno);
33194 +                       close(fd);
33195 +                       return(-errno);
33196 +               }
33197 +               *size_out = ((long long) blocks) * 512;
33198 +               close(fd);
33199 +               return(0);
33200 +       }
33201 +       *size_out = buf.st_size;
33202 +       return(0);
33203 +}
33204 +
33205 +int os_pipe(int *fds, int stream, int close_on_exec)
33206 +{
33207 +       int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
33208 +
33209 +       err = socketpair(AF_UNIX, type, 0, fds);
33210 +       if(err) 
33211 +               return(-errno);
33212 +
33213 +       if(!close_on_exec)
33214 +               return(0);
33215 +
33216 +       if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0))
33217 +               printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d", 
33218 +                      errno);
33219 +
33220 +       return(0);
33221 +}
33222 +
33223 +int os_set_fd_async(int fd, int owner)
33224 +{
33225 +       /* XXX This should do F_GETFL first */
33226 +       if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){
33227 +               printk("os_set_fd_async : failed to set O_ASYNC and "
33228 +                      "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
33229 +               return(-errno);
33230 +       }
33231 +#ifdef notdef
33232 +       if(fcntl(fd, F_SETFD, 1) < 0){
33233 +               printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
33234 +                      "errno = %d\n", errno);
33235 +       }
33236 +#endif
33237 +
33238 +       if((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
33239 +          (fcntl(fd, F_SETOWN, owner) < 0)){
33240 +               printk("os_set_fd_async : Failed to fcntl F_SETOWN "
33241 +                      "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, 
33242 +                      owner, errno);
33243 +               return(-errno);
33244 +       }
33245 +
33246 +       return(0);
33247 +}
33248 +
33249 +int os_set_fd_block(int fd, int blocking)
33250 +{
33251 +       int flags;
33252 +
33253 +       flags = fcntl(fd, F_GETFL);
33254 +
33255 +       if(blocking) flags &= ~O_NONBLOCK;
33256 +       else flags |= O_NONBLOCK;
33257 +
33258 +       if(fcntl(fd, F_SETFL, flags) < 0){
33259 +               printk("Failed to change blocking on fd # %d, errno = %d\n",
33260 +                      fd, errno);
33261 +               return(-errno);
33262 +       }
33263 +       return(0);
33264 +}
33265 +
33266 +int os_accept_connection(int fd)
33267 +{
33268 +       int new;
33269 +
33270 +       new = accept(fd, NULL, 0);
33271 +       if(new < 0) 
33272 +               return(-errno);
33273 +       return(new);
33274 +}
33275 +
33276 +#ifndef SHUT_RD
33277 +#define SHUT_RD 0
33278 +#endif
33279 +
33280 +#ifndef SHUT_WR
33281 +#define SHUT_WR 1
33282 +#endif
33283 +
33284 +#ifndef SHUT_RDWR
33285 +#define SHUT_RDWR 2
33286 +#endif
33287 +
33288 +int os_shutdown_socket(int fd, int r, int w)
33289 +{
33290 +       int what, err;
33291 +
33292 +       if(r && w) what = SHUT_RDWR;
33293 +       else if(r) what = SHUT_RD;
33294 +       else if(w) what = SHUT_WR;
33295 +       else {
33296 +               printk("os_shutdown_socket : neither r or w was set\n");
33297 +               return(-EINVAL);
33298 +       }
33299 +       err = shutdown(fd, what);
33300 +       if(err)
33301 +               return(-errno);
33302 +       return(0);
33303 +}
33304 +
33305 +int os_rcv_fd(int fd, int *helper_pid_out)
33306 +{
33307 +       int new, n;
33308 +       char buf[CMSG_SPACE(sizeof(new))];
33309 +       struct msghdr msg;
33310 +       struct cmsghdr *cmsg;
33311 +       struct iovec iov;
33312 +
33313 +       msg.msg_name = NULL;
33314 +       msg.msg_namelen = 0;
33315 +       iov = ((struct iovec) { .iov_base  = helper_pid_out,
33316 +                               .iov_len   = sizeof(*helper_pid_out) });
33317 +       msg.msg_iov = &iov;
33318 +       msg.msg_iovlen = 1;
33319 +       msg.msg_control = buf;
33320 +       msg.msg_controllen = sizeof(buf);
33321 +       msg.msg_flags = 0;
33322 +
33323 +       n = recvmsg(fd, &msg, 0);
33324 +       if(n < 0)
33325 +               return(-errno);
33326 +
33327 +       else if(n != sizeof(iov.iov_len))
33328 +               *helper_pid_out = -1;
33329 +
33330 +       cmsg = CMSG_FIRSTHDR(&msg);
33331 +       if(cmsg == NULL){
33332 +               printk("rcv_fd didn't receive anything, error = %d\n", errno);
33333 +               return(-1);
33334 +       }
33335 +       if((cmsg->cmsg_level != SOL_SOCKET) || 
33336 +          (cmsg->cmsg_type != SCM_RIGHTS)){
33337 +               printk("rcv_fd didn't receive a descriptor\n");
33338 +               return(-1);
33339 +       }
33340 +
33341 +       new = ((int *) CMSG_DATA(cmsg))[0];
33342 +       return(new);
33343 +}
33344 +
33345 +int create_unix_socket(char *file, int len)
33346 +{
33347 +       struct sockaddr_un addr;
33348 +       int sock, err;
33349 +
33350 +       sock = socket(PF_UNIX, SOCK_DGRAM, 0);
33351 +       if (sock < 0){
33352 +               printk("create_unix_socket - socket failed, errno = %d\n",
33353 +                      errno);
33354 +               return(-errno);
33355 +       }
33356 +
33357 +       addr.sun_family = AF_UNIX;
33358 +
33359 +       /* XXX Be more careful about overflow */
33360 +       snprintf(addr.sun_path, len, "%s", file);
33361 +
33362 +       err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
33363 +       if (err < 0){
33364 +               printk("create_listening_socket - bind failed, errno = %d\n",
33365 +                      errno);
33366 +               return(-errno);
33367 +       }
33368 +
33369 +       return(sock);
33370 +}
33371 +
33372 +void os_flush_stdout(void)
33373 +{
33374 +       fflush(stdout);
33375 +}
33376 +
33377 +int os_lock_file(int fd, int excl)
33378 +{
33379 +       int type = excl ? F_WRLCK : F_RDLCK;
33380 +       struct flock lock = ((struct flock) { .l_type   = type,
33381 +                                             .l_whence = SEEK_SET,
33382 +                                             .l_start  = 0,
33383 +                                             .l_len    = 0 } );
33384 +       int err, save;
33385 +
33386 +       err = fcntl(fd, F_SETLK, &lock);
33387 +       if(!err)
33388 +               goto out;
33389 +
33390 +       save = -errno;
33391 +       err = fcntl(fd, F_GETLK, &lock);
33392 +       if(err){
33393 +               err = -errno;
33394 +               goto out;
33395 +       }
33396 +               
33397 +       printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
33398 +       err = save;
33399 + out:
33400 +       return(err);
33401 +}
33402 +
33403 +/*
33404 + * Overrides for Emacs so that we follow Linus's tabbing style.
33405 + * Emacs will notice this stuff at the end of the file and automatically
33406 + * adjust the settings for this buffer only.  This must remain at the end
33407 + * of the file.
33408 + * ---------------------------------------------------------------------------
33409 + * Local variables:
33410 + * c-file-style: "linux"
33411 + * End:
33412 + */
33413 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/include/file.h um/arch/um/os-Linux/include/file.h
33414 --- orig/arch/um/os-Linux/include/file.h        1969-12-31 19:00:00.000000000 -0500
33415 +++ um/arch/um/os-Linux/include/file.h  2002-10-23 21:08:04.000000000 -0400
33416 @@ -0,0 +1,22 @@
33417 +/* 
33418 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33419 + * Licensed under the GPL
33420 + */
33421 +
33422 +#ifndef __OS_FILE_H__
33423 +#define __OS_FILE_H__
33424 +
33425 +#define DEV_NULL "/dev/null"
33426 +
33427 +#endif
33428 +
33429 +/*
33430 + * Overrides for Emacs so that we follow Linus's tabbing style.
33431 + * Emacs will notice this stuff at the end of the file and automatically
33432 + * adjust the settings for this buffer only.  This must remain at the end
33433 + * of the file.
33434 + * ---------------------------------------------------------------------------
33435 + * Local variables:
33436 + * c-file-style: "linux"
33437 + * End:
33438 + */
33439 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/Makefile um/arch/um/os-Linux/Makefile
33440 --- orig/arch/um/os-Linux/Makefile      1969-12-31 19:00:00.000000000 -0500
33441 +++ um/arch/um/os-Linux/Makefile        2002-10-23 21:08:04.000000000 -0400
33442 @@ -0,0 +1,17 @@
33443 +# 
33444 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
33445 +# Licensed under the GPL
33446 +#
33447 +
33448 +O_TARGET = built-in.o
33449 +
33450 +obj-y = file.o process.o tty.o
33451 +
33452 +include $(TOPDIR)/Rules.make
33453 +
33454 +$(obj-y) : %.o: %.c
33455 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
33456 +
33457 +clean :
33458 +
33459 +archmrproper:
33460 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/process.c um/arch/um/os-Linux/process.c
33461 --- orig/arch/um/os-Linux/process.c     1969-12-31 19:00:00.000000000 -0500
33462 +++ um/arch/um/os-Linux/process.c       2003-01-08 14:19:00.000000000 -0500
33463 @@ -0,0 +1,142 @@
33464 +/* 
33465 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33466 + * Licensed under the GPL
33467 + */
33468 +
33469 +#include <unistd.h>
33470 +#include <stdio.h>
33471 +#include <errno.h>
33472 +#include <signal.h>
33473 +#include <sys/mman.h>
33474 +#include <sys/wait.h>
33475 +#include "os.h"
33476 +#include "user.h"
33477 +
33478 +unsigned long os_process_pc(int pid)
33479 +{
33480 +       char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
33481 +       unsigned long pc;
33482 +       int fd;
33483 +
33484 +       sprintf(proc_stat, "/proc/%d/stat", pid);
33485 +       fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
33486 +       if(fd < 0){
33487 +               printk("os_process_pc - couldn't open '%s', errno = %d\n", 
33488 +                      proc_stat, errno);
33489 +               return(-1);
33490 +       }
33491 +       if(read(fd, buf, sizeof(buf)) < 0){
33492 +               printk("os_process_pc - couldn't read '%s', errno = %d\n", 
33493 +                      proc_stat, errno);
33494 +               close(fd);
33495 +               return(-1);
33496 +       }
33497 +       close(fd);
33498 +       pc = -1;
33499 +       if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
33500 +                 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
33501 +                 "%*d %*d %*d %*d %ld", &pc) != 1){
33502 +               printk("os_process_pc - couldn't find pc in '%s'\n", buf);
33503 +       }
33504 +       return(pc);
33505 +}
33506 +
33507 +int os_process_parent(int pid)
33508 +{
33509 +       char stat[sizeof("/proc/nnnnn/stat\0")];
33510 +       char data[256];
33511 +       int parent, n, fd;
33512 +
33513 +       if(pid == -1) return(-1);
33514 +
33515 +       snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
33516 +       fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
33517 +       if(fd < 0){
33518 +               printk("Couldn't open '%s', errno = %d\n", stat, -fd);
33519 +               return(-1);
33520 +       }
33521 +
33522 +       n = read(fd, data, sizeof(data));
33523 +       close(fd);
33524 +
33525 +       if(n < 0){
33526 +               printk("Couldn't read '%s', errno = %d\n", stat);
33527 +               return(-1);
33528 +       }
33529 +
33530 +       parent = -1;
33531 +       /* XXX This will break if there is a space in the command */
33532 +       n = sscanf(data, "%*d %*s %*c %d", &parent);
33533 +       if(n != 1) printk("Failed to scan '%s'\n", data);
33534 +
33535 +       return(parent);
33536 +}
33537 +
33538 +void os_stop_process(int pid)
33539 +{
33540 +       kill(pid, SIGSTOP);
33541 +}
33542 +
33543 +void os_kill_process(int pid, int reap_child)
33544 +{
33545 +       kill(pid, SIGKILL);
33546 +       if(reap_child)
33547 +               waitpid(pid, NULL, 0);
33548 +               
33549 +}
33550 +
33551 +void os_usr1_process(int pid)
33552 +{
33553 +       kill(pid, SIGUSR1);
33554 +}
33555 +
33556 +int os_getpid(void)
33557 +{
33558 +       return(getpid());
33559 +}
33560 +
33561 +int os_map_memory(void *virt, int fd, unsigned long off, unsigned long len, 
33562 +                 int r, int w, int x)
33563 +{
33564 +       void *loc;
33565 +       int prot;
33566 +
33567 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
33568 +               (x ? PROT_EXEC : 0);
33569 +
33570 +       loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
33571 +                  fd, off);
33572 +       if(loc == MAP_FAILED)
33573 +               return(-errno);
33574 +       return(0);
33575 +}
33576 +
33577 +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
33578 +{
33579 +        int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
33580 +                   (x ? PROT_EXEC : 0));
33581 +
33582 +        if(mprotect(addr, len, prot) < 0)
33583 +               return(-errno);
33584 +        return(0);
33585 +}
33586 +
33587 +int os_unmap_memory(void *addr, int len)
33588 +{
33589 +        int err;
33590 +
33591 +        err = munmap(addr, len);
33592 +        if(err < 0) return(-errno);
33593 +        return(0);
33594 +}
33595 +
33596 +/*
33597 + * Overrides for Emacs so that we follow Linus's tabbing style.
33598 + * Emacs will notice this stuff at the end of the file and automatically
33599 + * adjust the settings for this buffer only.  This must remain at the end
33600 + * of the file.
33601 + * ---------------------------------------------------------------------------
33602 + * Local variables:
33603 + * c-file-style: "linux"
33604 + * End:
33605 + */
33606 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/tty.c um/arch/um/os-Linux/tty.c
33607 --- orig/arch/um/os-Linux/tty.c 1969-12-31 19:00:00.000000000 -0500
33608 +++ um/arch/um/os-Linux/tty.c   2002-10-23 21:08:04.000000000 -0400
33609 @@ -0,0 +1,61 @@
33610 +/* 
33611 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33612 + * Licensed under the GPL
33613 + */
33614 +
33615 +#include <stdlib.h>
33616 +#include <errno.h>
33617 +#include "os.h"
33618 +#include "user.h"
33619 +#include "kern_util.h"
33620 +
33621 +struct grantpt_info {
33622 +       int fd;
33623 +       int res;
33624 +       int err;
33625 +};
33626 +
33627 +static void grantpt_cb(void *arg)
33628 +{
33629 +       struct grantpt_info *info = arg;
33630 +
33631 +       info->res = grantpt(info->fd);
33632 +       info->err = errno;
33633 +}
33634 +
33635 +int get_pty(void)
33636 +{
33637 +       struct grantpt_info info;
33638 +       int fd;
33639 +
33640 +       if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){
33641 +               printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n",
33642 +                      errno);
33643 +               return(-1);
33644 +       }
33645 +
33646 +       info.fd = fd;
33647 +       initial_thread_cb(grantpt_cb, &info);
33648 +
33649 +       if(info.res < 0){
33650 +               printk("get_pty : Couldn't grant pty - errno = %d\n", 
33651 +                      info.err);
33652 +               return(-1);
33653 +       }
33654 +       if(unlockpt(fd) < 0){
33655 +               printk("get_pty : Couldn't unlock pty - errno = %d\n", errno);
33656 +               return(-1);
33657 +       }
33658 +       return(fd);
33659 +}
33660 +
33661 +/*
33662 + * Overrides for Emacs so that we follow Linus's tabbing style.
33663 + * Emacs will notice this stuff at the end of the file and automatically
33664 + * adjust the settings for this buffer only.  This must remain at the end
33665 + * of the file.
33666 + * ---------------------------------------------------------------------------
33667 + * Local variables:
33668 + * c-file-style: "linux"
33669 + * End:
33670 + */
33671 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/bugs.c um/arch/um/sys-i386/bugs.c
33672 --- orig/arch/um/sys-i386/bugs.c        1969-12-31 19:00:00.000000000 -0500
33673 +++ um/arch/um/sys-i386/bugs.c  2003-05-29 13:46:50.000000000 -0400
33674 @@ -0,0 +1,177 @@
33675 +/* 
33676 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33677 + * Licensed under the GPL
33678 + */
33679 +
33680 +#include <unistd.h>
33681 +#include <fcntl.h>
33682 +#include <errno.h>
33683 +#include <string.h>
33684 +#include <sys/signal.h>
33685 +#include <asm/ldt.h>
33686 +#include "kern_util.h"
33687 +#include "user.h"
33688 +#include "sysdep/ptrace.h"
33689 +#include "task.h"
33690 +
33691 +#define MAXTOKEN 64
33692 +
33693 +/* Set during early boot */
33694 +int cpu_has_cmov = 1;
33695 +int cpu_has_xmm = 0;
33696 +
33697 +static char token(int fd, char *buf, int len, char stop)
33698 +{
33699 +       int n;
33700 +       char *ptr, *end, c;
33701 +
33702 +       ptr = buf;
33703 +       end = &buf[len];
33704 +       do {
33705 +               n = read(fd, ptr, sizeof(*ptr));
33706 +               c = *ptr++;
33707 +               if(n == 0) return(0);
33708 +               else if(n != sizeof(*ptr)){
33709 +                       printk("Reading /proc/cpuinfo failed, "
33710 +                              "errno = %d\n", errno);
33711 +                       return(-errno);
33712 +               }
33713 +       } while((c != '\n') && (c != stop) && (ptr < end));
33714 +
33715 +       if(ptr == end){
33716 +               printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
33717 +               return(-1);
33718 +       }
33719 +       *(ptr - 1) = '\0';
33720 +       return(c);
33721 +}
33722 +
33723 +static int check_cpu_feature(char *feature, int *have_it)
33724 +{
33725 +       char buf[MAXTOKEN], c;
33726 +       int fd, len = sizeof(buf)/sizeof(buf[0]), n;
33727 +
33728 +       printk("Checking for host processor %s support...", feature);
33729 +       fd = open("/proc/cpuinfo", O_RDONLY);
33730 +       if(fd < 0){
33731 +               printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
33732 +               return(0);
33733 +       }
33734 +
33735 +       *have_it = 0;
33736 +       buf[len - 1] = '\0';
33737 +       while(1){
33738 +               c = token(fd, buf, len - 1, ':');
33739 +               if(c <= 0) goto out;
33740 +               else if(c != ':'){
33741 +                       printk("Failed to find ':' in /proc/cpuinfo\n");
33742 +                       goto out;
33743 +               }
33744 +
33745 +               if(!strncmp(buf, "flags", strlen("flags"))) break;
33746 +
33747 +               do {
33748 +                       n = read(fd, &c, sizeof(c));
33749 +                       if(n != sizeof(c)){
33750 +                               printk("Failed to find newline in "
33751 +                                      "/proc/cpuinfo, n = %d, errno = %d\n",
33752 +                                      n, errno);
33753 +                               goto out;
33754 +                       }
33755 +               } while(c != '\n');
33756 +       }
33757 +
33758 +       c = token(fd, buf, len - 1, ' ');
33759 +       if(c < 0) goto out;
33760 +       else if(c != ' '){
33761 +               printk("Failed to find ':' in /proc/cpuinfo\n");
33762 +               goto out;
33763 +       }
33764 +
33765 +       while(1){
33766 +               c = token(fd, buf, len - 1, ' ');
33767 +               if(c < 0) goto out;
33768 +               else if(c == '\n') break;
33769 +
33770 +               if(!strcmp(buf, feature)){
33771 +                       *have_it = 1;
33772 +                       goto out;
33773 +               }
33774 +       }
33775 + out:
33776 +       if(*have_it == 0) printk("No\n");
33777 +       else if(*have_it == 1) printk("Yes\n");
33778 +       close(fd);
33779 +       return(1);
33780 +}
33781 +
33782 +static void disable_lcall(void)
33783 +{
33784 +       struct modify_ldt_ldt_s ldt;
33785 +       int err;
33786 +
33787 +       bzero(&ldt, sizeof(ldt));
33788 +       ldt.entry_number = 7;
33789 +       ldt.base_addr = 0;
33790 +       ldt.limit = 0;
33791 +       err = modify_ldt(1, &ldt, sizeof(ldt));
33792 +       if(err)
33793 +               printk("Failed to disable lcall7 - errno = %d\n", errno);
33794 +}
33795 +
33796 +void arch_init_thread(void)
33797 +{
33798 +       disable_lcall();
33799 +}
33800 +
33801 +void arch_check_bugs(void)
33802 +{
33803 +       int have_it;
33804 +
33805 +       if(access("/proc/cpuinfo", R_OK)){
33806 +               printk("/proc/cpuinfo not available - skipping CPU capability "
33807 +                      "checks\n");
33808 +               return;
33809 +       }
33810 +       if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
33811 +       if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
33812 +}
33813 +
33814 +int arch_handle_signal(int sig, union uml_pt_regs *regs)
33815 +{
33816 +       unsigned long ip;
33817 +
33818 +       /* This is testing for a cmov (0x0f 0x4x) instruction causing a
33819 +        * SIGILL in init.
33820 +        */
33821 +       if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
33822 +
33823 +       ip = UPT_IP(regs);
33824 +       if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
33825 +               return(0);
33826 +
33827 +       if(cpu_has_cmov == 0)
33828 +               panic("SIGILL caused by cmov, which this processor doesn't "
33829 +                     "implement, boot a filesystem compiled for older "
33830 +                     "processors");
33831 +       else if(cpu_has_cmov == 1)
33832 +               panic("SIGILL caused by cmov, which this processor claims to "
33833 +                     "implement");
33834 +       else if(cpu_has_cmov == -1)
33835 +               panic("SIGILL caused by cmov, couldn't tell if this processor "
33836 +                     "implements it, boot a filesystem compiled for older "
33837 +                     "processors");
33838 +       else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
33839 +       return(0);
33840 +}
33841 +
33842 +/*
33843 + * Overrides for Emacs so that we follow Linus's tabbing style.
33844 + * Emacs will notice this stuff at the end of the file and automatically
33845 + * adjust the settings for this buffer only.  This must remain at the end
33846 + * of the file.
33847 + * ---------------------------------------------------------------------------
33848 + * Local variables:
33849 + * c-file-style: "linux"
33850 + * End:
33851 + */
33852 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/checksum.S um/arch/um/sys-i386/checksum.S
33853 --- orig/arch/um/sys-i386/checksum.S    1969-12-31 19:00:00.000000000 -0500
33854 +++ um/arch/um/sys-i386/checksum.S      2002-10-31 20:17:50.000000000 -0500
33855 @@ -0,0 +1,460 @@
33856 +/*
33857 + * INET                An implementation of the TCP/IP protocol suite for the LINUX
33858 + *             operating system.  INET is implemented using the  BSD Socket
33859 + *             interface as the means of communication with the user level.
33860 + *
33861 + *             IP/TCP/UDP checksumming routines
33862 + *
33863 + * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
33864 + *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
33865 + *             Tom May, <ftom@netcom.com>
33866 + *              Pentium Pro/II routines:
33867 + *              Alexander Kjeldaas <astor@guardian.no>
33868 + *              Finn Arne Gangstad <finnag@guardian.no>
33869 + *             Lots of code moved from tcp.c and ip.c; see those files
33870 + *             for more names.
33871 + *
33872 + * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception
33873 + *                          handling.
33874 + *             Andi Kleen,  add zeroing on error
33875 + *                   converted to pure assembler
33876 + *
33877 + *             This program is free software; you can redistribute it and/or
33878 + *             modify it under the terms of the GNU General Public License
33879 + *             as published by the Free Software Foundation; either version
33880 + *             2 of the License, or (at your option) any later version.
33881 + */
33882 +
33883 +#include <linux/config.h>
33884 +#include <asm/errno.h>
33885 +                               
33886 +/*
33887 + * computes a partial checksum, e.g. for TCP/UDP fragments
33888 + */
33889 +
33890 +/*     
33891 +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
33892 + */
33893 +               
33894 +.text
33895 +.align 4
33896 +.globl arch_csum_partial                                                               
33897 +               
33898 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
33899 +
33900 +         /*            
33901 +          * Experiments with Ethernet and SLIP connections show that buff
33902 +          * is aligned on either a 2-byte or 4-byte boundary.  We get at
33903 +          * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
33904 +          * Fortunately, it is easy to convert 2-byte alignment to 4-byte
33905 +          * alignment for the unrolled loop.
33906 +          */           
33907 +arch_csum_partial:     
33908 +       pushl %esi
33909 +       pushl %ebx
33910 +       movl 20(%esp),%eax      # Function arg: unsigned int sum
33911 +       movl 16(%esp),%ecx      # Function arg: int len
33912 +       movl 12(%esp),%esi      # Function arg: unsigned char *buff
33913 +       testl $2, %esi          # Check alignment.
33914 +       jz 2f                   # Jump if alignment is ok.
33915 +       subl $2, %ecx           # Alignment uses up two bytes.
33916 +       jae 1f                  # Jump if we had at least two bytes.
33917 +       addl $2, %ecx           # ecx was < 2.  Deal with it.
33918 +       jmp 4f
33919 +1:     movw (%esi), %bx
33920 +       addl $2, %esi
33921 +       addw %bx, %ax
33922 +       adcl $0, %eax
33923 +2:
33924 +       movl %ecx, %edx
33925 +       shrl $5, %ecx
33926 +       jz 2f
33927 +       testl %esi, %esi
33928 +1:     movl (%esi), %ebx
33929 +       adcl %ebx, %eax
33930 +       movl 4(%esi), %ebx
33931 +       adcl %ebx, %eax
33932 +       movl 8(%esi), %ebx
33933 +       adcl %ebx, %eax
33934 +       movl 12(%esi), %ebx
33935 +       adcl %ebx, %eax
33936 +       movl 16(%esi), %ebx
33937 +       adcl %ebx, %eax
33938 +       movl 20(%esi), %ebx
33939 +       adcl %ebx, %eax
33940 +       movl 24(%esi), %ebx
33941 +       adcl %ebx, %eax
33942 +       movl 28(%esi), %ebx
33943 +       adcl %ebx, %eax
33944 +       lea 32(%esi), %esi
33945 +       dec %ecx
33946 +       jne 1b
33947 +       adcl $0, %eax
33948 +2:     movl %edx, %ecx
33949 +       andl $0x1c, %edx
33950 +       je 4f
33951 +       shrl $2, %edx           # This clears CF
33952 +3:     adcl (%esi), %eax
33953 +       lea 4(%esi), %esi
33954 +       dec %edx
33955 +       jne 3b
33956 +       adcl $0, %eax
33957 +4:     andl $3, %ecx
33958 +       jz 7f
33959 +       cmpl $2, %ecx
33960 +       jb 5f
33961 +       movw (%esi),%cx
33962 +       leal 2(%esi),%esi
33963 +       je 6f
33964 +       shll $16,%ecx
33965 +5:     movb (%esi),%cl
33966 +6:     addl %ecx,%eax
33967 +       adcl $0, %eax 
33968 +7:     
33969 +       popl %ebx
33970 +       popl %esi
33971 +       ret
33972 +
33973 +#else
33974 +
33975 +/* Version for PentiumII/PPro */
33976 +
33977 +arch_csum_partial:
33978 +       pushl %esi
33979 +       pushl %ebx
33980 +       movl 20(%esp),%eax      # Function arg: unsigned int sum
33981 +       movl 16(%esp),%ecx      # Function arg: int len
33982 +       movl 12(%esp),%esi      # Function arg: const unsigned char *buf
33983 +
33984 +       testl $2, %esi         
33985 +       jnz 30f                 
33986 +10:
33987 +       movl %ecx, %edx
33988 +       movl %ecx, %ebx
33989 +       andl $0x7c, %ebx
33990 +       shrl $7, %ecx
33991 +       addl %ebx,%esi
33992 +       shrl $2, %ebx  
33993 +       negl %ebx
33994 +       lea 45f(%ebx,%ebx,2), %ebx
33995 +       testl %esi, %esi
33996 +       jmp *%ebx
33997 +
33998 +       # Handle 2-byte-aligned regions
33999 +20:    addw (%esi), %ax
34000 +       lea 2(%esi), %esi
34001 +       adcl $0, %eax
34002 +       jmp 10b
34003 +
34004 +30:    subl $2, %ecx          
34005 +       ja 20b                 
34006 +       je 32f
34007 +       movzbl (%esi),%ebx      # csumming 1 byte, 2-aligned
34008 +       addl %ebx, %eax
34009 +       adcl $0, %eax
34010 +       jmp 80f
34011 +32:
34012 +       addw (%esi), %ax        # csumming 2 bytes, 2-aligned
34013 +       adcl $0, %eax
34014 +       jmp 80f
34015 +
34016 +40: 
34017 +       addl -128(%esi), %eax
34018 +       adcl -124(%esi), %eax
34019 +       adcl -120(%esi), %eax
34020 +       adcl -116(%esi), %eax   
34021 +       adcl -112(%esi), %eax   
34022 +       adcl -108(%esi), %eax
34023 +       adcl -104(%esi), %eax
34024 +       adcl -100(%esi), %eax
34025 +       adcl -96(%esi), %eax
34026 +       adcl -92(%esi), %eax
34027 +       adcl -88(%esi), %eax
34028 +       adcl -84(%esi), %eax
34029 +       adcl -80(%esi), %eax
34030 +       adcl -76(%esi), %eax
34031 +       adcl -72(%esi), %eax
34032 +       adcl -68(%esi), %eax
34033 +       adcl -64(%esi), %eax     
34034 +       adcl -60(%esi), %eax     
34035 +       adcl -56(%esi), %eax     
34036 +       adcl -52(%esi), %eax   
34037 +       adcl -48(%esi), %eax   
34038 +       adcl -44(%esi), %eax
34039 +       adcl -40(%esi), %eax
34040 +       adcl -36(%esi), %eax
34041 +       adcl -32(%esi), %eax
34042 +       adcl -28(%esi), %eax
34043 +       adcl -24(%esi), %eax
34044 +       adcl -20(%esi), %eax
34045 +       adcl -16(%esi), %eax
34046 +       adcl -12(%esi), %eax
34047 +       adcl -8(%esi), %eax
34048 +       adcl -4(%esi), %eax
34049 +45:
34050 +       lea 128(%esi), %esi
34051 +       adcl $0, %eax
34052 +       dec %ecx
34053 +       jge 40b
34054 +       movl %edx, %ecx
34055 +50:    andl $3, %ecx
34056 +       jz 80f
34057 +
34058 +       # Handle the last 1-3 bytes without jumping
34059 +       notl %ecx               # 1->2, 2->1, 3->0, higher bits are masked
34060 +       movl $0xffffff,%ebx     # by the shll and shrl instructions
34061 +       shll $3,%ecx
34062 +       shrl %cl,%ebx
34063 +       andl -128(%esi),%ebx    # esi is 4-aligned so should be ok
34064 +       addl %ebx,%eax
34065 +       adcl $0,%eax
34066 +80: 
34067 +       popl %ebx
34068 +       popl %esi
34069 +       ret
34070 +                               
34071 +#endif
34072 +
34073 +/*
34074 +unsigned int csum_partial_copy_generic (const char *src, char *dst,
34075 +                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr)
34076 + */ 
34077 +
34078 +/*
34079 + * Copy from ds while checksumming, otherwise like csum_partial
34080 + *
34081 + * The macros SRC and DST specify the type of access for the instruction.
34082 + * thus we can call a custom exception handler for all access types.
34083 + *
34084 + * FIXME: could someone double-check whether I haven't mixed up some SRC and
34085 + *       DST definitions? It's damn hard to trigger all cases.  I hope I got
34086 + *       them all but there's no guarantee.
34087 + */
34088 +
34089 +#define SRC(y...)                      \
34090 +       9999: y;                        \
34091 +       .section __ex_table, "a";       \
34092 +       .long 9999b, 6001f      ;       \
34093 +       .previous
34094 +
34095 +#define DST(y...)                      \
34096 +       9999: y;                        \
34097 +       .section __ex_table, "a";       \
34098 +       .long 9999b, 6002f      ;       \
34099 +       .previous
34100 +
34101 +.align 4
34102 +.globl csum_partial_copy_generic_i386
34103 +                               
34104 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
34105 +
34106 +#define ARGBASE 16             
34107 +#define FP             12
34108 +               
34109 +csum_partial_copy_generic_i386:
34110 +       subl  $4,%esp   
34111 +       pushl %edi
34112 +       pushl %esi
34113 +       pushl %ebx
34114 +       movl ARGBASE+16(%esp),%eax      # sum
34115 +       movl ARGBASE+12(%esp),%ecx      # len
34116 +       movl ARGBASE+4(%esp),%esi       # src
34117 +       movl ARGBASE+8(%esp),%edi       # dst
34118 +
34119 +       testl $2, %edi                  # Check alignment. 
34120 +       jz 2f                           # Jump if alignment is ok.
34121 +       subl $2, %ecx                   # Alignment uses up two bytes.
34122 +       jae 1f                          # Jump if we had at least two bytes.
34123 +       addl $2, %ecx                   # ecx was < 2.  Deal with it.
34124 +       jmp 4f
34125 +SRC(1: movw (%esi), %bx        )
34126 +       addl $2, %esi
34127 +DST(   movw %bx, (%edi)        )
34128 +       addl $2, %edi
34129 +       addw %bx, %ax   
34130 +       adcl $0, %eax
34131 +2:
34132 +       movl %ecx, FP(%esp)
34133 +       shrl $5, %ecx
34134 +       jz 2f
34135 +       testl %esi, %esi
34136 +SRC(1: movl (%esi), %ebx       )
34137 +SRC(   movl 4(%esi), %edx      )
34138 +       adcl %ebx, %eax
34139 +DST(   movl %ebx, (%edi)       )
34140 +       adcl %edx, %eax
34141 +DST(   movl %edx, 4(%edi)      )
34142 +
34143 +SRC(   movl 8(%esi), %ebx      )
34144 +SRC(   movl 12(%esi), %edx     )
34145 +       adcl %ebx, %eax
34146 +DST(   movl %ebx, 8(%edi)      )
34147 +       adcl %edx, %eax
34148 +DST(   movl %edx, 12(%edi)     )
34149 +
34150 +SRC(   movl 16(%esi), %ebx     )
34151 +SRC(   movl 20(%esi), %edx     )
34152 +       adcl %ebx, %eax
34153 +DST(   movl %ebx, 16(%edi)     )
34154 +       adcl %edx, %eax
34155 +DST(   movl %edx, 20(%edi)     )
34156 +
34157 +SRC(   movl 24(%esi), %ebx     )
34158 +SRC(   movl 28(%esi), %edx     )
34159 +       adcl %ebx, %eax
34160 +DST(   movl %ebx, 24(%edi)     )
34161 +       adcl %edx, %eax
34162 +DST(   movl %edx, 28(%edi)     )
34163 +
34164 +       lea 32(%esi), %esi
34165 +       lea 32(%edi), %edi
34166 +       dec %ecx
34167 +       jne 1b
34168 +       adcl $0, %eax
34169 +2:     movl FP(%esp), %edx
34170 +       movl %edx, %ecx
34171 +       andl $0x1c, %edx
34172 +       je 4f
34173 +       shrl $2, %edx                   # This clears CF
34174 +SRC(3: movl (%esi), %ebx       )
34175 +       adcl %ebx, %eax
34176 +DST(   movl %ebx, (%edi)       )
34177 +       lea 4(%esi), %esi
34178 +       lea 4(%edi), %edi
34179 +       dec %edx
34180 +       jne 3b
34181 +       adcl $0, %eax
34182 +4:     andl $3, %ecx
34183 +       jz 7f
34184 +       cmpl $2, %ecx
34185 +       jb 5f
34186 +SRC(   movw (%esi), %cx        )
34187 +       leal 2(%esi), %esi
34188 +DST(   movw %cx, (%edi)        )
34189 +       leal 2(%edi), %edi
34190 +       je 6f
34191 +       shll $16,%ecx
34192 +SRC(5: movb (%esi), %cl        )
34193 +DST(   movb %cl, (%edi)        )
34194 +6:     addl %ecx, %eax
34195 +       adcl $0, %eax
34196 +7:
34197 +5000:
34198 +
34199 +# Exception handler:
34200 +.section .fixup, "ax"                                                  
34201 +
34202 +6001:
34203 +       movl ARGBASE+20(%esp), %ebx     # src_err_ptr
34204 +       movl $-EFAULT, (%ebx)
34205 +
34206 +       # zero the complete destination - computing the rest
34207 +       # is too much work 
34208 +       movl ARGBASE+8(%esp), %edi      # dst
34209 +       movl ARGBASE+12(%esp), %ecx     # len
34210 +       xorl %eax,%eax
34211 +       rep ; stosb
34212 +
34213 +       jmp 5000b
34214 +
34215 +6002:
34216 +       movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
34217 +       movl $-EFAULT,(%ebx)
34218 +       jmp 5000b
34219 +
34220 +.previous
34221 +
34222 +       popl %ebx
34223 +       popl %esi
34224 +       popl %edi
34225 +       popl %ecx                       # equivalent to addl $4,%esp
34226 +       ret     
34227 +
34228 +#else
34229 +
34230 +/* Version for PentiumII/PPro */
34231 +
34232 +#define ROUND1(x) \
34233 +       SRC(movl x(%esi), %ebx  )       ;       \
34234 +       addl %ebx, %eax                 ;       \
34235 +       DST(movl %ebx, x(%edi)  )       ; 
34236 +
34237 +#define ROUND(x) \
34238 +       SRC(movl x(%esi), %ebx  )       ;       \
34239 +       adcl %ebx, %eax                 ;       \
34240 +       DST(movl %ebx, x(%edi)  )       ;
34241 +
34242 +#define ARGBASE 12
34243 +               
34244 +csum_partial_copy_generic_i386:
34245 +       pushl %ebx
34246 +       pushl %edi
34247 +       pushl %esi
34248 +       movl ARGBASE+4(%esp),%esi       #src
34249 +       movl ARGBASE+8(%esp),%edi       #dst    
34250 +       movl ARGBASE+12(%esp),%ecx      #len
34251 +       movl ARGBASE+16(%esp),%eax      #sum
34252 +#      movl %ecx, %edx  
34253 +       movl %ecx, %ebx  
34254 +       movl %esi, %edx
34255 +       shrl $6, %ecx     
34256 +       andl $0x3c, %ebx  
34257 +       negl %ebx
34258 +       subl %ebx, %esi  
34259 +       subl %ebx, %edi  
34260 +       lea  -1(%esi),%edx
34261 +       andl $-32,%edx
34262 +       lea 3f(%ebx,%ebx), %ebx
34263 +       testl %esi, %esi 
34264 +       jmp *%ebx
34265 +1:     addl $64,%esi
34266 +       addl $64,%edi 
34267 +       SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
34268 +       ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)    
34269 +       ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)    
34270 +       ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)    
34271 +       ROUND (-16) ROUND(-12) ROUND(-8)  ROUND(-4)     
34272 +3:     adcl $0,%eax
34273 +       addl $64, %edx
34274 +       dec %ecx
34275 +       jge 1b
34276 +4:     movl ARGBASE+12(%esp),%edx      #len
34277 +       andl $3, %edx
34278 +       jz 7f
34279 +       cmpl $2, %edx
34280 +       jb 5f
34281 +SRC(   movw (%esi), %dx         )
34282 +       leal 2(%esi), %esi
34283 +DST(   movw %dx, (%edi)         )
34284 +       leal 2(%edi), %edi
34285 +       je 6f
34286 +       shll $16,%edx
34287 +5:
34288 +SRC(   movb (%esi), %dl         )
34289 +DST(   movb %dl, (%edi)         )
34290 +6:     addl %edx, %eax
34291 +       adcl $0, %eax
34292 +7:
34293 +.section .fixup, "ax"
34294 +6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
34295 +       movl $-EFAULT, (%ebx)
34296 +       # zero the complete destination (computing the rest is too much work)
34297 +       movl ARGBASE+8(%esp),%edi       # dst
34298 +       movl ARGBASE+12(%esp),%ecx      # len
34299 +       xorl %eax,%eax
34300 +       rep; stosb
34301 +       jmp 7b
34302 +6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
34303 +       movl $-EFAULT, (%ebx)
34304 +       jmp  7b                 
34305 +.previous                              
34306 +
34307 +       popl %esi
34308 +       popl %edi
34309 +       popl %ebx
34310 +       ret
34311 +                               
34312 +#undef ROUND
34313 +#undef ROUND1          
34314 +               
34315 +#endif
34316 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/fault.c um/arch/um/sys-i386/fault.c
34317 --- orig/arch/um/sys-i386/fault.c       1969-12-31 19:00:00.000000000 -0500
34318 +++ um/arch/um/sys-i386/fault.c 2002-10-27 16:49:35.000000000 -0500
34319 @@ -0,0 +1,34 @@
34320 +/* 
34321 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34322 + * Licensed under the GPL
34323 + */
34324 +
34325 +#include <signal.h>
34326 +#include "sysdep/ptrace.h"
34327 +#include "sysdep/sigcontext.h"
34328 +
34329 +extern unsigned long search_exception_table(unsigned long addr);
34330 +
34331 +int arch_fixup(unsigned long address, void *sc_ptr)
34332 +{
34333 +       struct sigcontext *sc = sc_ptr;
34334 +       unsigned long fixup;
34335 +
34336 +       fixup = search_exception_table(address);
34337 +       if(fixup != 0){
34338 +               sc->eip = fixup;
34339 +               return(1);
34340 +       }
34341 +       return(0);
34342 +}
34343 +
34344 +/*
34345 + * Overrides for Emacs so that we follow Linus's tabbing style.
34346 + * Emacs will notice this stuff at the end of the file and automatically
34347 + * adjust the settings for this buffer only.  This must remain at the end
34348 + * of the file.
34349 + * ---------------------------------------------------------------------------
34350 + * Local variables:
34351 + * c-file-style: "linux"
34352 + * End:
34353 + */
34354 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ksyms.c um/arch/um/sys-i386/ksyms.c
34355 --- orig/arch/um/sys-i386/ksyms.c       1969-12-31 19:00:00.000000000 -0500
34356 +++ um/arch/um/sys-i386/ksyms.c 2002-10-29 21:01:45.000000000 -0500
34357 @@ -0,0 +1,17 @@
34358 +#include "linux/module.h"
34359 +#include "linux/in6.h"
34360 +#include "linux/rwsem.h"
34361 +#include "asm/byteorder.h"
34362 +#include "asm/semaphore.h"
34363 +#include "asm/uaccess.h"
34364 +#include "asm/checksum.h"
34365 +#include "asm/errno.h"
34366 +
34367 +EXPORT_SYMBOL(__down_failed);
34368 +EXPORT_SYMBOL(__down_failed_interruptible);
34369 +EXPORT_SYMBOL(__down_failed_trylock);
34370 +EXPORT_SYMBOL(__up_wakeup);
34371 +
34372 +/* Networking helper routines. */
34373 +EXPORT_SYMBOL(csum_partial_copy_from);
34374 +EXPORT_SYMBOL(csum_partial_copy_to);
34375 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ldt.c um/arch/um/sys-i386/ldt.c
34376 --- orig/arch/um/sys-i386/ldt.c 1969-12-31 19:00:00.000000000 -0500
34377 +++ um/arch/um/sys-i386/ldt.c   2002-11-13 12:43:04.000000000 -0500
34378 @@ -0,0 +1,92 @@
34379 +/*
34380 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34381 + * Licensed under the GPL
34382 + */
34383 +
34384 +#include "linux/config.h"
34385 +#include "linux/slab.h"
34386 +#include "asm/uaccess.h"
34387 +#include "asm/ptrace.h"
34388 +#include "choose-mode.h"
34389 +#include "kern.h"
34390 +
34391 +#ifdef CONFIG_MODE_TT
34392 +extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
34393 +
34394 +int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
34395 +{
34396 +       if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
34397 +       return(modify_ldt(func, ptr, bytecount));
34398 +}
34399 +#endif
34400 +
34401 +#ifdef CONFIG_MODE_SKAS
34402 +extern int userspace_pid;
34403 +
34404 +int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
34405 +{
34406 +       struct ptrace_ldt ldt;
34407 +       void *buf;
34408 +       int res, n;
34409 +
34410 +       buf = kmalloc(bytecount, GFP_KERNEL);
34411 +       if(buf == NULL)
34412 +               return(-ENOMEM);
34413 +
34414 +       res = 0;
34415 +
34416 +       switch(func){
34417 +       case 1:
34418 +       case 0x11:
34419 +               res = copy_from_user(buf, ptr, bytecount);
34420 +               break;
34421 +       }
34422 +
34423 +       if(res != 0){
34424 +               res = -EFAULT;
34425 +               goto out;
34426 +       }
34427 +
34428 +       ldt = ((struct ptrace_ldt) { .func      = func,
34429 +                                    .ptr       = buf,
34430 +                                    .bytecount = bytecount });
34431 +       res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
34432 +       if(res < 0)
34433 +               goto out;
34434 +
34435 +       switch(func){
34436 +       case 0:
34437 +       case 2:
34438 +               n = res;
34439 +               res = copy_to_user(ptr, buf, n);
34440 +               if(res != 0)
34441 +                       res = -EFAULT;
34442 +               else 
34443 +                       res = n;
34444 +               break;
34445 +       }
34446 +
34447 + out:
34448 +       kfree(buf);
34449 +       return(res);
34450 +}
34451 +#endif
34452 +
34453 +int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
34454 +{
34455 +       return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, 
34456 +                               ptr, bytecount));
34457 +}
34458 +
34459 +
34460 +
34461 +/*
34462 + * Overrides for Emacs so that we follow Linus's tabbing style.
34463 + * Emacs will notice this stuff at the end of the file and automatically
34464 + * adjust the settings for this buffer only.  This must remain at the end
34465 + * of the file.
34466 + * ---------------------------------------------------------------------------
34467 + * Local variables:
34468 + * c-file-style: "linux"
34469 + * End:
34470 + */
34471 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/Makefile um/arch/um/sys-i386/Makefile
34472 --- orig/arch/um/sys-i386/Makefile      1969-12-31 19:00:00.000000000 -0500
34473 +++ um/arch/um/sys-i386/Makefile        2002-11-23 23:34:24.000000000 -0500
34474 @@ -0,0 +1,46 @@
34475 +# 
34476 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34477 +# Licensed under the GPL
34478 +#
34479 +
34480 +O_TARGET = built-in.o
34481 +
34482 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
34483 +       ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
34484 +export-objs = ksyms.o
34485 +
34486 +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o
34487 +
34488 +SYMLINKS = semaphore.c extable.c
34489 +
34490 +semaphore.c-dir = kernel
34491 +extable.c-dir = mm
34492 +
34493 +include $(TOPDIR)/Rules.make
34494 +
34495 +$(USER_OBJS) : %.o: %.c
34496 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
34497 +
34498 +define make_link
34499 +       -rm -f $1
34500 +       ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1
34501 +endef
34502 +
34503 +$(SYMLINKS): 
34504 +       $(call make_link,$@)
34505 +
34506 +clean:
34507 +       $(MAKE) -C util clean
34508 +       rm -f $(SYMLINKS)
34509 +
34510 +fastdep:
34511 +
34512 +dep:
34513 +
34514 +archmrproper:
34515 +
34516 +archclean:
34517 +
34518 +archdep:
34519 +
34520 +modules:
34521 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace.c um/arch/um/sys-i386/ptrace.c
34522 --- orig/arch/um/sys-i386/ptrace.c      1969-12-31 19:00:00.000000000 -0500
34523 +++ um/arch/um/sys-i386/ptrace.c        2002-10-27 16:49:35.000000000 -0500
34524 @@ -0,0 +1,365 @@
34525 +/* 
34526 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
34527 + * Licensed under the GPL
34528 + */
34529 +
34530 +#include "linux/sched.h"
34531 +#include "asm/elf.h"
34532 +#include "asm/ptrace.h"
34533 +#include "asm/uaccess.h"
34534 +#include "ptrace_user.h"
34535 +#include "sysdep/sigcontext.h"
34536 +#include "sysdep/sc.h"
34537 +
34538 +void arch_switch(void)
34539 +{
34540 +       update_debugregs(current->thread.arch.debugregs_seq);
34541 +}
34542 +
34543 +int is_syscall(unsigned long addr)
34544 +{
34545 +       unsigned short instr;
34546 +       int n;
34547 +
34548 +       n = copy_from_user(&instr, (void *) addr, sizeof(instr));
34549 +       if(n){
34550 +               printk("is_syscall : failed to read instruction from 0x%lu\n", 
34551 +                      addr);
34552 +               return(0);
34553 +       }
34554 +       return(instr == 0x80cd);
34555 +}
34556 +
34557 +/* determines which flags the user has access to. */
34558 +/* 1 = access 0 = no access */
34559 +#define FLAG_MASK 0x00044dd5
34560 +
34561 +int putreg(struct task_struct *child, int regno, unsigned long value)
34562 +{
34563 +       regno >>= 2;
34564 +       switch (regno) {
34565 +       case FS:
34566 +               if (value && (value & 3) != 3)
34567 +                       return -EIO;
34568 +               PT_REGS_FS(&child->thread.regs) = value;
34569 +               return 0;
34570 +       case GS:
34571 +               if (value && (value & 3) != 3)
34572 +                       return -EIO;
34573 +               PT_REGS_GS(&child->thread.regs) = value;
34574 +               return 0;
34575 +       case DS:
34576 +       case ES:
34577 +               if (value && (value & 3) != 3)
34578 +                       return -EIO;
34579 +               value &= 0xffff;
34580 +               break;
34581 +       case SS:
34582 +       case CS:
34583 +               if ((value & 3) != 3)
34584 +                       return -EIO;
34585 +               value &= 0xffff;
34586 +               break;
34587 +       case EFL:
34588 +               value &= FLAG_MASK;
34589 +               value |= PT_REGS_EFLAGS(&child->thread.regs);
34590 +               break;
34591 +       }
34592 +       PT_REGS_SET(&child->thread.regs, regno, value);
34593 +       return 0;
34594 +}
34595 +
34596 +unsigned long getreg(struct task_struct *child, int regno)
34597 +{
34598 +       unsigned long retval = ~0UL;
34599 +
34600 +       regno >>= 2;
34601 +       switch (regno) {
34602 +       case FS:
34603 +       case GS:
34604 +       case DS:
34605 +       case ES:
34606 +       case SS:
34607 +       case CS:
34608 +               retval = 0xffff;
34609 +               /* fall through */
34610 +       default:
34611 +               retval &= PT_REG(&child->thread.regs, regno);
34612 +       }
34613 +       return retval;
34614 +}
34615 +
34616 +struct i387_fxsave_struct {
34617 +       unsigned short  cwd;
34618 +       unsigned short  swd;
34619 +       unsigned short  twd;
34620 +       unsigned short  fop;
34621 +       long    fip;
34622 +       long    fcs;
34623 +       long    foo;
34624 +       long    fos;
34625 +       long    mxcsr;
34626 +       long    reserved;
34627 +       long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
34628 +       long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
34629 +       long    padding[56];
34630 +};
34631 +
34632 +/*
34633 + * FPU tag word conversions.
34634 + */
34635 +
34636 +static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
34637 +{
34638 +       unsigned int tmp; /* to avoid 16 bit prefixes in the code */
34639
34640 +       /* Transform each pair of bits into 01 (valid) or 00 (empty) */
34641 +        tmp = ~twd;
34642 +        tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
34643 +        /* and move the valid bits to the lower byte. */
34644 +        tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
34645 +        tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
34646 +        tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
34647 +        return tmp;
34648 +}
34649 +
34650 +static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
34651 +{
34652 +       struct _fpxreg *st = NULL;
34653 +       unsigned long twd = (unsigned long) fxsave->twd;
34654 +       unsigned long tag;
34655 +       unsigned long ret = 0xffff0000;
34656 +       int i;
34657 +
34658 +#define FPREG_ADDR(f, n)       ((char *)&(f)->st_space + (n) * 16);
34659 +
34660 +       for ( i = 0 ; i < 8 ; i++ ) {
34661 +               if ( twd & 0x1 ) {
34662 +                       st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
34663 +
34664 +                       switch ( st->exponent & 0x7fff ) {
34665 +                       case 0x7fff:
34666 +                               tag = 2;                /* Special */
34667 +                               break;
34668 +                       case 0x0000:
34669 +                               if ( !st->significand[0] &&
34670 +                                    !st->significand[1] &&
34671 +                                    !st->significand[2] &&
34672 +                                    !st->significand[3] ) {
34673 +                                       tag = 1;        /* Zero */
34674 +                               } else {
34675 +                                       tag = 2;        /* Special */
34676 +                               }
34677 +                               break;
34678 +                       default:
34679 +                               if ( st->significand[3] & 0x8000 ) {
34680 +                                       tag = 0;        /* Valid */
34681 +                               } else {
34682 +                                       tag = 2;        /* Special */
34683 +                               }
34684 +                               break;
34685 +                       }
34686 +               } else {
34687 +                       tag = 3;                        /* Empty */
34688 +               }
34689 +               ret |= (tag << (2 * i));
34690 +               twd = twd >> 1;
34691 +       }
34692 +       return ret;
34693 +}
34694 +
34695 +/*
34696 + * FXSR floating point environment conversions.
34697 + */
34698 +
34699 +#ifdef CONFIG_MODE_TT
34700 +static inline int convert_fxsr_to_user_tt(struct _fpstate *buf, 
34701 +                                         struct pt_regs *regs)
34702 +{
34703 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34704 +       unsigned long env[7];
34705 +       struct _fpreg *to;
34706 +       struct _fpxreg *from;
34707 +       int i;
34708 +
34709 +       env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
34710 +       env[1] = (unsigned long)fxsave->swd | 0xffff0000;
34711 +       env[2] = twd_fxsr_to_i387(fxsave);
34712 +       env[3] = fxsave->fip;
34713 +       env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
34714 +       env[5] = fxsave->foo;
34715 +       env[6] = fxsave->fos;
34716 +
34717 +       if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
34718 +               return 1;
34719 +
34720 +       to = &buf->_st[0];
34721 +       from = (struct _fpxreg *) &fxsave->st_space[0];
34722 +       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
34723 +               if ( __copy_to_user( to, from, sizeof(*to) ) )
34724 +                       return 1;
34725 +       }
34726 +       return 0;
34727 +}
34728 +#endif
34729 +
34730 +static inline int convert_fxsr_to_user(struct _fpstate *buf, 
34731 +                                      struct pt_regs *regs)
34732 +{
34733 +       return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
34734 +}
34735 +
34736 +#ifdef CONFIG_MODE_TT
34737 +static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
34738 +                                           struct _fpstate *buf)
34739 +{
34740 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34741 +       unsigned long env[7];
34742 +       struct _fpxreg *to;
34743 +       struct _fpreg *from;
34744 +       int i;
34745 +
34746 +       if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
34747 +               return 1;
34748 +
34749 +       fxsave->cwd = (unsigned short)(env[0] & 0xffff);
34750 +       fxsave->swd = (unsigned short)(env[1] & 0xffff);
34751 +       fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
34752 +       fxsave->fip = env[3];
34753 +       fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
34754 +       fxsave->fcs = (env[4] & 0xffff);
34755 +       fxsave->foo = env[5];
34756 +       fxsave->fos = env[6];
34757 +
34758 +       to = (struct _fpxreg *) &fxsave->st_space[0];
34759 +       from = &buf->_st[0];
34760 +       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
34761 +               if ( __copy_from_user( to, from, sizeof(*from) ) )
34762 +                       return 1;
34763 +       }
34764 +       return 0;
34765 +}
34766 +#endif
34767 +
34768 +static inline int convert_fxsr_from_user(struct pt_regs *regs, 
34769 +                                        struct _fpstate *buf)
34770 +{
34771 +       return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
34772 +}
34773 +
34774 +int get_fpregs(unsigned long buf, struct task_struct *child)
34775 +{
34776 +       int err;
34777 +
34778 +       err = convert_fxsr_to_user((struct _fpstate *) buf, 
34779 +                                  &child->thread.regs);
34780 +       if(err) return(-EFAULT);
34781 +       else return(0);
34782 +}
34783 +
34784 +int set_fpregs(unsigned long buf, struct task_struct *child)
34785 +{
34786 +       int err;
34787 +
34788 +       err = convert_fxsr_from_user(&child->thread.regs, 
34789 +                                    (struct _fpstate *) buf);
34790 +       if(err) return(-EFAULT);
34791 +       else return(0);
34792 +}
34793 +
34794 +#ifdef CONFIG_MODE_TT
34795 +int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
34796 +{
34797 +       struct pt_regs *regs = &tsk->thread.regs;
34798 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34799 +       int err;
34800 +
34801 +       err = __copy_to_user((void *) buf, fxsave,
34802 +                            sizeof(struct user_fxsr_struct));
34803 +       if(err) return -EFAULT;
34804 +       else return 0;
34805 +}
34806 +#endif
34807 +
34808 +int get_fpxregs(unsigned long buf, struct task_struct *tsk)
34809 +{
34810 +       return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
34811 +}
34812 +
34813 +#ifdef CONFIG_MODE_TT
34814 +int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
34815 +{
34816 +       struct pt_regs *regs = &tsk->thread.regs;
34817 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
34818 +       int err;
34819 +
34820 +       err = __copy_from_user(fxsave, (void *) buf,
34821 +                              sizeof(struct user_fxsr_struct) );
34822 +       if(err) return -EFAULT;
34823 +       else return 0;
34824 +}
34825 +#endif
34826 +
34827 +int set_fpxregs(unsigned long buf, struct task_struct *tsk)
34828 +{
34829 +       return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
34830 +}
34831 +
34832 +#ifdef notdef
34833 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
34834 +{
34835 +       fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
34836 +                   (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
34837 +       fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
34838 +       fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
34839 +       fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
34840 +       fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
34841 +       fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
34842 +       fpu->fos = 0;
34843 +       memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
34844 +              sizeof(fpu->st_space));
34845 +       return(1);
34846 +}
34847 +#endif
34848 +
34849 +#ifdef CONFIG_MODE_TT
34850 +static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
34851 +                                     struct user_i387_struct *buf)
34852 +{
34853 +       struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
34854 +       unsigned short *to;
34855 +       unsigned short *from;
34856 +       int i;
34857 +
34858 +       memcpy( buf, fpu, 7 * sizeof(long) );
34859 +
34860 +       to = (unsigned short *) &buf->st_space[0];
34861 +       from = (unsigned short *) &fpu->st_space[0];
34862 +       for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
34863 +               memcpy( to, from, 5 * sizeof(unsigned short) );
34864 +       }
34865 +}
34866 +#endif
34867 +
34868 +static inline void copy_fpu_fxsave(struct pt_regs *regs,
34869 +                                  struct user_i387_struct *buf)
34870 +{
34871 +       (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
34872 +}
34873 +
34874 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
34875 +{
34876 +       copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
34877 +       return(1);
34878 +}
34879 +
34880 +/*
34881 + * Overrides for Emacs so that we follow Linus's tabbing style.
34882 + * Emacs will notice this stuff at the end of the file and automatically
34883 + * adjust the settings for this buffer only.  This must remain at the end
34884 + * of the file.
34885 + * ---------------------------------------------------------------------------
34886 + * Local variables:
34887 + * c-file-style: "linux"
34888 + * End:
34889 + */
34890 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace_user.c um/arch/um/sys-i386/ptrace_user.c
34891 --- orig/arch/um/sys-i386/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500
34892 +++ um/arch/um/sys-i386/ptrace_user.c   2002-10-23 21:08:04.000000000 -0400
34893 @@ -0,0 +1,117 @@
34894 +/* 
34895 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34896 + * Licensed under the GPL
34897 + */
34898 +
34899 +#include <stdio.h>
34900 +#include <errno.h>
34901 +#include <unistd.h>
34902 +#include <linux/stddef.h>
34903 +#include <sys/ptrace.h>
34904 +#include <asm/ptrace.h>
34905 +#include <asm/user.h>
34906 +#include "kern_util.h"
34907 +#include "sysdep/thread.h"
34908 +#include "user.h"
34909 +#include "os.h"
34910 +
34911 +int ptrace_getregs(long pid, unsigned long *regs_out)
34912 +{
34913 +       return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
34914 +}
34915 +
34916 +int ptrace_setregs(long pid, unsigned long *regs)
34917 +{
34918 +       return(ptrace(PTRACE_SETREGS, pid, 0, regs));
34919 +}
34920 +
34921 +int ptrace_getfpregs(long pid, unsigned long *regs)
34922 +{
34923 +       return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
34924 +}
34925 +
34926 +static void write_debugregs(int pid, unsigned long *regs)
34927 +{
34928 +       struct user *dummy;
34929 +       int nregs, i;
34930 +
34931 +       dummy = NULL;
34932 +       nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
34933 +       for(i = 0; i < nregs; i++){
34934 +               if((i == 4) || (i == 5)) continue;
34935 +               if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
34936 +                         regs[i]) < 0)
34937 +                       printk("write_debugregs - ptrace failed, "
34938 +                              "errno = %d\n", errno);
34939 +       }
34940 +}
34941 +
34942 +static void read_debugregs(int pid, unsigned long *regs)
34943 +{
34944 +       struct user *dummy;
34945 +       int nregs, i;
34946 +
34947 +       dummy = NULL;
34948 +       nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
34949 +       for(i = 0; i < nregs; i++){
34950 +               regs[i] = ptrace(PTRACE_PEEKUSR, pid, 
34951 +                                &dummy->u_debugreg[i], 0);
34952 +       }
34953 +}
34954 +
34955 +/* Accessed only by the tracing thread */
34956 +static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
34957 +static int debugregs_seq = 0;
34958 +
34959 +void arch_enter_kernel(void *task, int pid)
34960 +{
34961 +       read_debugregs(pid, TASK_DEBUGREGS(task));
34962 +       write_debugregs(pid, kernel_debugregs);
34963 +}
34964 +
34965 +void arch_leave_kernel(void *task, int pid)
34966 +{
34967 +       read_debugregs(pid, kernel_debugregs);
34968 +       write_debugregs(pid, TASK_DEBUGREGS(task));
34969 +}
34970 +
34971 +void ptrace_pokeuser(unsigned long addr, unsigned long data)
34972 +{
34973 +       if((addr < offsetof(struct user, u_debugreg[0])) ||
34974 +          (addr > offsetof(struct user, u_debugreg[7])))
34975 +               return;
34976 +       addr -= offsetof(struct user, u_debugreg[0]);
34977 +       addr = addr >> 2;
34978 +       if(kernel_debugregs[addr] == data) return;
34979 +
34980 +       kernel_debugregs[addr] = data;
34981 +       debugregs_seq++;
34982 +}
34983 +
34984 +static void update_debugregs_cb(void *arg)
34985 +{
34986 +       int pid = *((int *) arg);
34987 +
34988 +       write_debugregs(pid, kernel_debugregs);
34989 +}
34990 +
34991 +void update_debugregs(int seq)
34992 +{
34993 +       int me;
34994 +
34995 +       if(seq == debugregs_seq) return;
34996 +
34997 +       me = os_getpid();
34998 +       initial_thread_cb(update_debugregs_cb, &me);
34999 +}
35000 +
35001 +/*
35002 + * Overrides for Emacs so that we follow Linus's tabbing style.
35003 + * Emacs will notice this stuff at the end of the file and automatically
35004 + * adjust the settings for this buffer only.  This must remain at the end
35005 + * of the file.
35006 + * ---------------------------------------------------------------------------
35007 + * Local variables:
35008 + * c-file-style: "linux"
35009 + * End:
35010 + */
35011 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sigcontext.c um/arch/um/sys-i386/sigcontext.c
35012 --- orig/arch/um/sys-i386/sigcontext.c  1969-12-31 19:00:00.000000000 -0500
35013 +++ um/arch/um/sys-i386/sigcontext.c    2002-12-02 23:20:13.000000000 -0500
35014 @@ -0,0 +1,80 @@
35015 +/* 
35016 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
35017 + * Licensed under the GPL
35018 + */
35019 +
35020 +#include <stddef.h>
35021 +#include <string.h>
35022 +#include <asm/ptrace.h>
35023 +#include <asm/sigcontext.h>
35024 +#include "sysdep/ptrace.h"
35025 +#include "kern_util.h"
35026 +#include "frame_user.h"
35027 +
35028 +int sc_size(void *data)
35029 +{
35030 +       struct arch_frame_data *arch = data;
35031 +
35032 +       return(sizeof(struct sigcontext) + arch->fpstate_size);
35033 +}
35034 +
35035 +void sc_to_sc(void *to_ptr, void *from_ptr)
35036 +{
35037 +       struct sigcontext *to = to_ptr, *from = from_ptr;
35038 +       int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
35039 +
35040 +       memcpy(to, from, size);
35041 +       if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
35042 +}
35043 +
35044 +unsigned long *sc_sigmask(void *sc_ptr)
35045 +{
35046 +       struct sigcontext *sc = sc_ptr;
35047 +
35048 +       return(&sc->oldmask);
35049 +}
35050 +
35051 +int sc_get_fpregs(unsigned long buf, void *sc_ptr)
35052 +{
35053 +       struct sigcontext *sc = sc_ptr;
35054 +       struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
35055 +       int err = 0;
35056 +
35057 +       if(from == NULL){
35058 +               err |= clear_user_proc(&to->cw, sizeof(to->cw));
35059 +               err |= clear_user_proc(&to->sw, sizeof(to->sw));
35060 +               err |= clear_user_proc(&to->tag, sizeof(to->tag));
35061 +               err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
35062 +               err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
35063 +               err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
35064 +               err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
35065 +               err |= clear_user_proc(&to->_st, sizeof(to->_st));
35066 +       }
35067 +       else {
35068 +               err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
35069 +               err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
35070 +               err |= copy_to_user_proc(&to->tag, &from->tag, 
35071 +                                        sizeof(to->tag));
35072 +               err |= copy_to_user_proc(&to->ipoff, &from->ipoff, 
35073 +                                        sizeof(to->ipoff));
35074 +               err |= copy_to_user_proc(&to->cssel,& from->cssel, 
35075 +                                        sizeof(to->cssel));
35076 +               err |= copy_to_user_proc(&to->dataoff, &from->dataoff, 
35077 +                                   sizeof(to->dataoff));
35078 +               err |= copy_to_user_proc(&to->datasel, &from->datasel, 
35079 +                                   sizeof(to->datasel));
35080 +               err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
35081 +       }
35082 +       return(err);
35083 +}
35084 +
35085 +/*
35086 + * Overrides for Emacs so that we follow Linus's tabbing style.
35087 + * Emacs will notice this stuff at the end of the file and automatically
35088 + * adjust the settings for this buffer only.  This must remain at the end
35089 + * of the file.
35090 + * ---------------------------------------------------------------------------
35091 + * Local variables:
35092 + * c-file-style: "linux"
35093 + * End:
35094 + */
35095 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/syscalls.c um/arch/um/sys-i386/syscalls.c
35096 --- orig/arch/um/sys-i386/syscalls.c    1969-12-31 19:00:00.000000000 -0500
35097 +++ um/arch/um/sys-i386/syscalls.c      2002-10-23 21:08:04.000000000 -0400
35098 @@ -0,0 +1,68 @@
35099 +/* 
35100 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
35101 + * Licensed under the GPL
35102 + */
35103 +
35104 +#include "asm/mman.h"
35105 +#include "asm/uaccess.h"
35106 +#include "asm/unistd.h"
35107 +
35108 +/*
35109 + * Perform the select(nd, in, out, ex, tv) and mmap() system
35110 + * calls. Linux/i386 didn't use to be able to handle more than
35111 + * 4 system call parameters, so these system calls used a memory
35112 + * block for parameter passing..
35113 + */
35114 +
35115 +struct mmap_arg_struct {
35116 +       unsigned long addr;
35117 +       unsigned long len;
35118 +       unsigned long prot;
35119 +       unsigned long flags;
35120 +       unsigned long fd;
35121 +       unsigned long offset;
35122 +};
35123 +
35124 +extern int old_mmap(unsigned long addr, unsigned long len,
35125 +                   unsigned long prot, unsigned long flags,
35126 +                   unsigned long fd, unsigned long offset);
35127 +
35128 +int old_mmap_i386(struct mmap_arg_struct *arg)
35129 +{
35130 +       struct mmap_arg_struct a;
35131 +       int err = -EFAULT;
35132 +
35133 +       if (copy_from_user(&a, arg, sizeof(a)))
35134 +               goto out;
35135 +
35136 +       err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
35137 + out:
35138 +       return err;
35139 +}
35140 +
35141 +struct sel_arg_struct {
35142 +       unsigned long n;
35143 +       fd_set *inp, *outp, *exp;
35144 +       struct timeval *tvp;
35145 +};
35146 +
35147 +int old_select(struct sel_arg_struct *arg)
35148 +{
35149 +       struct sel_arg_struct a;
35150 +
35151 +       if (copy_from_user(&a, arg, sizeof(a)))
35152 +               return -EFAULT;
35153 +       /* sys_select() does the appropriate kernel locking */
35154 +       return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
35155 +}
35156 +
35157 +/*
35158 + * Overrides for Emacs so that we follow Linus's tabbing style.
35159 + * Emacs will notice this stuff at the end of the file and automatically
35160 + * adjust the settings for this buffer only.  This must remain at the end
35161 + * of the file.
35162 + * ---------------------------------------------------------------------------
35163 + * Local variables:
35164 + * c-file-style: "linux"
35165 + * End:
35166 + */
35167 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sysrq.c um/arch/um/sys-i386/sysrq.c
35168 --- orig/arch/um/sys-i386/sysrq.c       1969-12-31 19:00:00.000000000 -0500
35169 +++ um/arch/um/sys-i386/sysrq.c 2002-10-23 21:08:04.000000000 -0400
35170 @@ -0,0 +1,30 @@
35171 +#include "linux/kernel.h"
35172 +#include "linux/smp.h"
35173 +#include "linux/sched.h"
35174 +#include "asm/ptrace.h"
35175 +#include "sysrq.h"
35176 +
35177 +void show_regs(struct pt_regs *regs)
35178 +{
35179 +        printk("\n");
35180 +        printk("EIP: %04lx:[<%08lx>] CPU: %d %s", 
35181 +              0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs),
35182 +              smp_processor_id(), print_tainted());
35183 +        if (PT_REGS_CS(regs) & 3)
35184 +                printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs),
35185 +                      PT_REGS_SP(regs));
35186 +        printk(" EFLAGS: %08lx\n    %s\n", PT_REGS_EFLAGS(regs),
35187 +              print_tainted());
35188 +        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
35189 +                PT_REGS_EAX(regs), PT_REGS_EBX(regs), 
35190 +              PT_REGS_ECX(regs), 
35191 +              PT_REGS_EDX(regs));
35192 +        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
35193 +              PT_REGS_ESI(regs), PT_REGS_EDI(regs), 
35194 +              PT_REGS_EBP(regs));
35195 +        printk(" DS: %04lx ES: %04lx\n",
35196 +              0xffff & PT_REGS_DS(regs), 
35197 +              0xffff & PT_REGS_ES(regs));
35198 +
35199 +        show_trace((unsigned long *) &regs);
35200 +}
35201 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/Makefile um/arch/um/sys-i386/util/Makefile
35202 --- orig/arch/um/sys-i386/util/Makefile 1969-12-31 19:00:00.000000000 -0500
35203 +++ um/arch/um/sys-i386/util/Makefile   2002-10-23 21:08:04.000000000 -0400
35204 @@ -0,0 +1,28 @@
35205 +EXE = mk_sc mk_thread
35206 +
35207 +include $(TOPDIR)/Rules.make
35208 +
35209 +all : $(EXE)
35210 +
35211 +mk_sc : mk_sc.o
35212 +       $(CC) -o mk_sc mk_sc.o
35213 +
35214 +mk_sc.o : mk_sc.c
35215 +       $(CC) -c $< 
35216 +
35217 +mk_thread : mk_thread_user.o mk_thread_kern.o
35218 +       $(CC) -o mk_thread mk_thread_user.o mk_thread_kern.o
35219 +
35220 +mk_thread_user.o : mk_thread_user.c
35221 +       $(CC) -c $< 
35222 +
35223 +mk_thread_kern.o : mk_thread_kern.c
35224 +       $(CC) $(CFLAGS) -c $< 
35225 +
35226 +clean :
35227 +       $(RM) $(EXE) *.o
35228 +
35229 +archmrproper : clean
35230 +
35231 +fastdep :
35232 +
35233 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_sc.c um/arch/um/sys-i386/util/mk_sc.c
35234 --- orig/arch/um/sys-i386/util/mk_sc.c  1969-12-31 19:00:00.000000000 -0500
35235 +++ um/arch/um/sys-i386/util/mk_sc.c    2002-10-23 21:08:04.000000000 -0400
35236 @@ -0,0 +1,51 @@
35237 +#include <stdio.h>
35238 +#include <signal.h>
35239 +#include <linux/stddef.h>
35240 +
35241 +#define SC_OFFSET(name, field) \
35242 +  printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
35243 +        offsetof(struct sigcontext, field))
35244 +
35245 +#define SC_FP_OFFSET(name, field) \
35246 +  printf("#define " name \
35247 +        "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
35248 +        offsetof(struct _fpstate, field))
35249 +
35250 +#define SC_FP_OFFSET_PTR(name, field, type) \
35251 +  printf("#define " name \
35252 +        "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
35253 +        offsetof(struct _fpstate, field))
35254 +
35255 +int main(int argc, char **argv)
35256 +{
35257 +  SC_OFFSET("SC_IP", eip);
35258 +  SC_OFFSET("SC_SP", esp);
35259 +  SC_OFFSET("SC_FS", fs);
35260 +  SC_OFFSET("SC_GS", gs);
35261 +  SC_OFFSET("SC_DS", ds);
35262 +  SC_OFFSET("SC_ES", es);
35263 +  SC_OFFSET("SC_SS", ss);
35264 +  SC_OFFSET("SC_CS", cs);
35265 +  SC_OFFSET("SC_EFLAGS", eflags);
35266 +  SC_OFFSET("SC_EAX", eax);
35267 +  SC_OFFSET("SC_EBX", ebx);
35268 +  SC_OFFSET("SC_ECX", ecx);
35269 +  SC_OFFSET("SC_EDX", edx);
35270 +  SC_OFFSET("SC_EDI", edi);
35271 +  SC_OFFSET("SC_ESI", esi);
35272 +  SC_OFFSET("SC_EBP", ebp);
35273 +  SC_OFFSET("SC_TRAPNO", trapno);
35274 +  SC_OFFSET("SC_ERR", err);
35275 +  SC_OFFSET("SC_CR2", cr2);
35276 +  SC_OFFSET("SC_FPSTATE", fpstate);
35277 +  SC_FP_OFFSET("SC_FP_CW", cw);
35278 +  SC_FP_OFFSET("SC_FP_SW", sw);
35279 +  SC_FP_OFFSET("SC_FP_TAG", tag);
35280 +  SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
35281 +  SC_FP_OFFSET("SC_FP_CSSEL", cssel);
35282 +  SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
35283 +  SC_FP_OFFSET("SC_FP_DATASEL", datasel);
35284 +  SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
35285 +  SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
35286 +  return(0);
35287 +}
35288 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_thread_kern.c um/arch/um/sys-i386/util/mk_thread_kern.c
35289 --- orig/arch/um/sys-i386/util/mk_thread_kern.c 1969-12-31 19:00:00.000000000 -0500
35290 +++ um/arch/um/sys-i386/util/mk_thread_kern.c   2002-12-09 23:24:38.000000000 -0500
35291 @@ -0,0 +1,22 @@
35292 +#include "linux/config.h"
35293 +#include "linux/stddef.h"
35294 +#include "linux/sched.h"
35295 +
35296 +extern void print_head(void);
35297 +extern void print_constant_ptr(char *name, int value);
35298 +extern void print_constant(char *name, char *type, int value);
35299 +extern void print_tail(void);
35300 +
35301 +#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
35302 +
35303 +int main(int argc, char **argv)
35304 +{
35305 +  print_head();
35306 +  print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
35307 +#ifdef CONFIG_MODE_TT
35308 +  print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
35309 +#endif
35310 +  print_tail();
35311 +  return(0);
35312 +}
35313 +
35314 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_thread_user.c um/arch/um/sys-i386/util/mk_thread_user.c
35315 --- orig/arch/um/sys-i386/util/mk_thread_user.c 1969-12-31 19:00:00.000000000 -0500
35316 +++ um/arch/um/sys-i386/util/mk_thread_user.c   2002-10-23 21:08:04.000000000 -0400
35317 @@ -0,0 +1,30 @@
35318 +#include <stdio.h>
35319 +
35320 +void print_head(void)
35321 +{
35322 +  printf("/*\n");
35323 +  printf(" * Generated by mk_thread\n");
35324 +  printf(" */\n");
35325 +  printf("\n");
35326 +  printf("#ifndef __UM_THREAD_H\n");
35327 +  printf("#define __UM_THREAD_H\n");
35328 +  printf("\n");
35329 +}
35330 +
35331 +void print_constant_ptr(char *name, int value)
35332 +{
35333 +  printf("#define %s(task) ((unsigned long *) "
35334 +        "&(((char *) (task))[%d]))\n", name, value);
35335 +}
35336 +
35337 +void print_constant(char *name, char *type, int value)
35338 +{
35339 +  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, 
35340 +        value);
35341 +}
35342 +
35343 +void print_tail(void)
35344 +{
35345 +  printf("\n");
35346 +  printf("#endif\n");
35347 +}
35348 diff -Naur -X ../exclude-files orig/arch/um/sys-ia64/Makefile um/arch/um/sys-ia64/Makefile
35349 --- orig/arch/um/sys-ia64/Makefile      1969-12-31 19:00:00.000000000 -0500
35350 +++ um/arch/um/sys-ia64/Makefile        2002-10-23 21:08:04.000000000 -0400
35351 @@ -0,0 +1,26 @@
35352 +OBJ = sys.o
35353 +
35354 +OBJS =
35355 +
35356 +all: $(OBJ)
35357 +
35358 +$(OBJ): $(OBJS)
35359 +       rm -f $@
35360 +       $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
35361 +clean:
35362 +       rm -f $(OBJS)
35363 +
35364 +fastdep:
35365 +
35366 +archmrproper:
35367 +
35368 +archclean:
35369 +       rm -f link.ld
35370 +       @$(MAKEBOOT) clean
35371 +
35372 +archdep:
35373 +       @$(MAKEBOOT) dep
35374 +
35375 +modules:
35376 +
35377 +include $(TOPDIR)/Rules.make
35378 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/Makefile um/arch/um/sys-ppc/Makefile
35379 --- orig/arch/um/sys-ppc/Makefile       1969-12-31 19:00:00.000000000 -0500
35380 +++ um/arch/um/sys-ppc/Makefile 2002-10-23 21:08:04.000000000 -0400
35381 @@ -0,0 +1,80 @@
35382 +OBJ = sys.o
35383 +
35384 +.S.o:
35385 +       $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35386 +
35387 +OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
35388 +       ptrace_user.o sysrq.o
35389 +
35390 +EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
35391 +
35392 +all: $(OBJ)
35393 +
35394 +$(OBJ): $(OBJS)
35395 +       rm -f $@
35396 +       $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
35397 +
35398 +ptrace_user.o: ptrace_user.c
35399 +       $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
35400 +
35401 +sigcontext.o: sigcontext.c
35402 +       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
35403 +
35404 +semaphore.c:
35405 +       rm -f $@
35406 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35407 +
35408 +checksum.S:
35409 +       rm -f $@
35410 +       ln -s $(TOPDIR)/arch/ppc/lib/$@ $@
35411 +
35412 +mk_defs.c:
35413 +       rm -f $@
35414 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35415 +
35416 +ppc_defs.head:
35417 +       rm -f $@
35418 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
35419 +
35420 +ppc_defs.h: mk_defs.c ppc_defs.head \
35421 +               $(TOPDIR)/include/asm-ppc/mmu.h \
35422 +               $(TOPDIR)/include/asm-ppc/processor.h \
35423 +               $(TOPDIR)/include/asm-ppc/pgtable.h \
35424 +               $(TOPDIR)/include/asm-ppc/ptrace.h
35425 +#      $(CC) $(CFLAGS) -S mk_defs.c
35426 +       cp ppc_defs.head ppc_defs.h
35427 +# for bk, this way we can write to the file even if it's not checked out
35428 +       echo '#define THREAD 608' >> ppc_defs.h
35429 +       echo '#define PT_REGS 8' >> ppc_defs.h
35430 +       echo '#define CLONE_VM 256' >> ppc_defs.h
35431 +#      chmod u+w ppc_defs.h
35432 +#      grep '^#define' mk_defs.s >> ppc_defs.h
35433 +#      rm mk_defs.s
35434 +
35435 +# the asm link is horrible, and breaks the other targets.  This is also
35436 +# not going to work with parallel makes.
35437 +
35438 +checksum.o: checksum.S
35439 +       rm -f asm
35440 +       ln -s $(TOPDIR)/include/asm-ppc asm
35441 +       $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35442 +       rm -f asm
35443 +
35444 +misc.o: misc.S ppc_defs.h
35445 +       rm -f asm
35446 +       ln -s $(TOPDIR)/include/asm-ppc asm
35447 +       $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
35448 +       rm -f asm
35449 +
35450 +clean:
35451 +       rm -f $(OBJS)
35452 +       rm -f ppc_defs.h
35453 +       rm -f checksum.S semaphore.c mk_defs.c
35454 +
35455 +fastdep:
35456 +
35457 +dep:
35458 +
35459 +modules:
35460 +
35461 +include $(TOPDIR)/Rules.make
35462 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/misc.S um/arch/um/sys-ppc/misc.S
35463 --- orig/arch/um/sys-ppc/misc.S 1969-12-31 19:00:00.000000000 -0500
35464 +++ um/arch/um/sys-ppc/misc.S   2002-10-23 21:08:04.000000000 -0400
35465 @@ -0,0 +1,116 @@
35466 +/*
35467 + * This file contains miscellaneous low-level functions.
35468 + *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
35469 + *
35470 + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
35471 + * and Paul Mackerras.
35472 + *
35473 + * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
35474 + * by Chris Emerson.
35475 + *
35476 + * This program is free software; you can redistribute it and/or
35477 + * modify it under the terms of the GNU General Public License
35478 + * as published by the Free Software Foundation; either version
35479 + * 2 of the License, or (at your option) any later version.
35480 + *
35481 + */
35482 +
35483 +#include <linux/config.h>
35484 +#include <asm/processor.h>
35485 +#include "ppc_asm.h"
35486 +
35487 +#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
35488 +#define CACHE_LINE_SIZE                16
35489 +#define LG_CACHE_LINE_SIZE     4
35490 +#define MAX_COPY_PREFETCH      1
35491 +#elif !defined(CONFIG_PPC64BRIDGE)
35492 +#define CACHE_LINE_SIZE                32
35493 +#define LG_CACHE_LINE_SIZE     5
35494 +#define MAX_COPY_PREFETCH      4
35495 +#else
35496 +#define CACHE_LINE_SIZE                128
35497 +#define LG_CACHE_LINE_SIZE     7
35498 +#define MAX_COPY_PREFETCH      1
35499 +#endif /* CONFIG_4xx || CONFIG_8xx */
35500 +
35501 +       .text
35502 +
35503 +/*
35504 + * Clear a page using the dcbz instruction, which doesn't cause any
35505 + * memory traffic (except to write out any cache lines which get
35506 + * displaced).  This only works on cacheable memory.
35507 + */
35508 +_GLOBAL(clear_page)
35509 +       li      r0,4096/CACHE_LINE_SIZE
35510 +       mtctr   r0
35511 +#ifdef CONFIG_8xx
35512 +       li      r4, 0
35513 +1:     stw     r4, 0(r3)
35514 +       stw     r4, 4(r3)
35515 +       stw     r4, 8(r3)
35516 +       stw     r4, 12(r3)
35517 +#else
35518 +1:     dcbz    0,r3
35519 +#endif
35520 +       addi    r3,r3,CACHE_LINE_SIZE
35521 +       bdnz    1b
35522 +       blr
35523 +
35524 +/*
35525 + * Copy a whole page.  We use the dcbz instruction on the destination
35526 + * to reduce memory traffic (it eliminates the unnecessary reads of
35527 + * the destination into cache).  This requires that the destination
35528 + * is cacheable.
35529 + */
35530 +#define COPY_16_BYTES          \
35531 +       lwz     r6,4(r4);       \
35532 +       lwz     r7,8(r4);       \
35533 +       lwz     r8,12(r4);      \
35534 +       lwzu    r9,16(r4);      \
35535 +       stw     r6,4(r3);       \
35536 +       stw     r7,8(r3);       \
35537 +       stw     r8,12(r3);      \
35538 +       stwu    r9,16(r3)
35539 +
35540 +_GLOBAL(copy_page)
35541 +       addi    r3,r3,-4
35542 +       addi    r4,r4,-4
35543 +       li      r5,4
35544 +
35545 +#ifndef CONFIG_8xx
35546 +#if MAX_COPY_PREFETCH > 1
35547 +       li      r0,MAX_COPY_PREFETCH
35548 +       li      r11,4
35549 +       mtctr   r0
35550 +11:    dcbt    r11,r4
35551 +       addi    r11,r11,CACHE_LINE_SIZE
35552 +       bdnz    11b
35553 +#else /* MAX_COPY_PREFETCH == 1 */
35554 +       dcbt    r5,r4
35555 +       li      r11,CACHE_LINE_SIZE+4
35556 +#endif /* MAX_COPY_PREFETCH */
35557 +#endif /* CONFIG_8xx */
35558 +
35559 +       li      r0,4096/CACHE_LINE_SIZE
35560 +       mtctr   r0
35561 +1:
35562 +#ifndef CONFIG_8xx
35563 +       dcbt    r11,r4
35564 +       dcbz    r5,r3
35565 +#endif
35566 +       COPY_16_BYTES
35567 +#if CACHE_LINE_SIZE >= 32
35568 +       COPY_16_BYTES
35569 +#if CACHE_LINE_SIZE >= 64
35570 +       COPY_16_BYTES
35571 +       COPY_16_BYTES
35572 +#if CACHE_LINE_SIZE >= 128
35573 +       COPY_16_BYTES
35574 +       COPY_16_BYTES
35575 +       COPY_16_BYTES
35576 +       COPY_16_BYTES
35577 +#endif
35578 +#endif
35579 +#endif
35580 +       bdnz    1b
35581 +       blr
35582 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/miscthings.c um/arch/um/sys-ppc/miscthings.c
35583 --- orig/arch/um/sys-ppc/miscthings.c   1969-12-31 19:00:00.000000000 -0500
35584 +++ um/arch/um/sys-ppc/miscthings.c     2002-10-23 21:08:04.000000000 -0400
35585 @@ -0,0 +1,53 @@
35586 +#include "linux/threads.h"
35587 +#include "linux/stddef.h"  // for NULL
35588 +#include "linux/elf.h"  // for AT_NULL
35589 +
35590 +/* The following function nicked from arch/ppc/kernel/process.c and
35591 + * adapted slightly */
35592 +/*
35593 + * XXX ld.so expects the auxiliary table to start on
35594 + * a 16-byte boundary, so we have to find it and
35595 + * move it up. :-(
35596 + */
35597 +void shove_aux_table(unsigned long sp)
35598 +{
35599 +       int argc;
35600 +       char *p;
35601 +       unsigned long e;
35602 +       unsigned long aux_start, offset;
35603 +
35604 +       argc = *(int *)sp;
35605 +       sp += sizeof(int) + (argc + 1) * sizeof(char *);
35606 +       /* skip over the environment pointers */
35607 +       do {
35608 +               p = *(char **)sp;
35609 +               sp += sizeof(char *);
35610 +       } while (p != NULL);
35611 +       aux_start = sp;
35612 +       /* skip to the end of the auxiliary table */
35613 +       do {
35614 +               e = *(unsigned long *)sp;
35615 +               sp += 2 * sizeof(unsigned long);
35616 +       } while (e != AT_NULL);
35617 +       offset = ((aux_start + 15) & ~15) - aux_start;
35618 +       if (offset != 0) {
35619 +               do {
35620 +                       sp -= sizeof(unsigned long);
35621 +                       e = *(unsigned long *)sp;
35622 +                       *(unsigned long *)(sp + offset) = e;
35623 +               } while (sp > aux_start);
35624 +       }
35625 +}
35626 +/* END stuff taken from arch/ppc/kernel/process.c */
35627 +
35628 +
35629 +/*
35630 + * Overrides for Emacs so that we follow Linus's tabbing style.
35631 + * Emacs will notice this stuff at the end of the file and automatically
35632 + * adjust the settings for this buffer only.  This must remain at the end
35633 + * of the file.
35634 + * ---------------------------------------------------------------------------
35635 + * Local variables:
35636 + * c-file-style: "linux"
35637 + * End:
35638 + */
35639 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace.c um/arch/um/sys-ppc/ptrace.c
35640 --- orig/arch/um/sys-ppc/ptrace.c       1969-12-31 19:00:00.000000000 -0500
35641 +++ um/arch/um/sys-ppc/ptrace.c 2002-10-23 21:08:04.000000000 -0400
35642 @@ -0,0 +1,28 @@
35643 +#include "linux/sched.h"
35644 +#include "asm/ptrace.h"
35645 +
35646 +int putreg(struct task_struct *child, unsigned long regno, 
35647 +                 unsigned long value)
35648 +{
35649 +       child->thread.process_regs.regs[regno >> 2] = value;
35650 +       return 0;
35651 +}
35652 +
35653 +unsigned long getreg(struct task_struct *child, unsigned long regno)
35654 +{
35655 +       unsigned long retval = ~0UL;
35656 +
35657 +       retval &= child->thread.process_regs.regs[regno >> 2];
35658 +       return retval;
35659 +}
35660 +
35661 +/*
35662 + * Overrides for Emacs so that we follow Linus's tabbing style.
35663 + * Emacs will notice this stuff at the end of the file and automatically
35664 + * adjust the settings for this buffer only.  This must remain at the end
35665 + * of the file.
35666 + * ---------------------------------------------------------------------------
35667 + * Local variables:
35668 + * c-file-style: "linux"
35669 + * End:
35670 + */
35671 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace_user.c um/arch/um/sys-ppc/ptrace_user.c
35672 --- orig/arch/um/sys-ppc/ptrace_user.c  1969-12-31 19:00:00.000000000 -0500
35673 +++ um/arch/um/sys-ppc/ptrace_user.c    2002-10-23 21:08:04.000000000 -0400
35674 @@ -0,0 +1,40 @@
35675 +#include <sys/ptrace.h>
35676 +#include <errno.h>
35677 +#include <asm/ptrace.h>
35678 +#include "sysdep/ptrace.h"
35679 +
35680 +int ptrace_getregs(long pid, unsigned long *regs_out)
35681 +{
35682 +    int i;
35683 +    for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
35684 +       errno = 0;
35685 +       regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0);
35686 +       if (errno) {
35687 +           return -errno;
35688 +       }
35689 +    }
35690 +    return 0;
35691 +}
35692 +
35693 +int ptrace_setregs(long pid, unsigned long *regs_in)
35694 +{
35695 +    int i;
35696 +    for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
35697 +       if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) {
35698 +           if (ptrace(PTRACE_POKEUSER, pid, i*4, regs_in->regs[i]) < 0) {
35699 +               return -errno;
35700 +           }
35701 +       }
35702 +    }
35703 +    return 0;
35704 +}
35705 +/*
35706 + * Overrides for Emacs so that we follow Linus's tabbing style.
35707 + * Emacs will notice this stuff at the end of the file and automatically
35708 + * adjust the settings for this buffer only.  This must remain at the end
35709 + * of the file.
35710 + * ---------------------------------------------------------------------------
35711 + * Local variables:
35712 + * c-file-style: "linux"
35713 + * End:
35714 + */
35715 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sigcontext.c um/arch/um/sys-ppc/sigcontext.c
35716 --- orig/arch/um/sys-ppc/sigcontext.c   1969-12-31 19:00:00.000000000 -0500
35717 +++ um/arch/um/sys-ppc/sigcontext.c     2002-10-23 21:08:04.000000000 -0400
35718 @@ -0,0 +1,15 @@
35719 +#include "asm/ptrace.h"
35720 +#include "asm/sigcontext.h"
35721 +#include "sysdep/ptrace.h"
35722 +#include "user_util.h"
35723 +
35724 +/*
35725 + * Overrides for Emacs so that we follow Linus's tabbing style.
35726 + * Emacs will notice this stuff at the end of the file and automatically
35727 + * adjust the settings for this buffer only.  This must remain at the end
35728 + * of the file.
35729 + * ---------------------------------------------------------------------------
35730 + * Local variables:
35731 + * c-file-style: "linux"
35732 + * End:
35733 + */
35734 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sysrq.c um/arch/um/sys-ppc/sysrq.c
35735 --- orig/arch/um/sys-ppc/sysrq.c        1969-12-31 19:00:00.000000000 -0500
35736 +++ um/arch/um/sys-ppc/sysrq.c  2002-10-23 21:08:04.000000000 -0400
35737 @@ -0,0 +1,43 @@
35738 +/* 
35739 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
35740 + * Licensed under the GPL
35741 + */
35742 +
35743 +#include "linux/kernel.h"
35744 +#include "linux/smp.h"
35745 +#include "asm/ptrace.h"
35746 +#include "sysrq.h"
35747 +
35748 +void show_regs(struct pt_regs_subarch *regs)
35749 +{
35750 +       printk("\n");
35751 +       printk("show_regs(): insert regs here.\n");
35752 +#if 0
35753 +        printk("\n");
35754 +        printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip,
35755 +              smp_processor_id());
35756 +        if (regs->xcs & 3)
35757 +                printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp);
35758 +        printk(" EFLAGS: %08lx\n", regs->eflags);
35759 +        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
35760 +                regs->eax, regs->ebx, regs->ecx, regs->edx);
35761 +        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
35762 +                regs->esi, regs->edi, regs->ebp);
35763 +        printk(" DS: %04x ES: %04x\n",
35764 +                0xffff & regs->xds, 0xffff & regs->xes);
35765 +#endif
35766 +
35767 +        show_trace(&regs->gpr[1]);
35768 +}
35769 +
35770 +
35771 +/*
35772 + * Overrides for Emacs so that we follow Linus's tabbing style.
35773 + * Emacs will notice this stuff at the end of the file and automatically
35774 + * adjust the settings for this buffer only.  This must remain at the end
35775 + * of the file.
35776 + * ---------------------------------------------------------------------------
35777 + * Local variables:
35778 + * c-file-style: "linux"
35779 + * End:
35780 + */
35781 diff -Naur -X ../exclude-files orig/arch/um/util/Makefile um/arch/um/util/Makefile
35782 --- orig/arch/um/util/Makefile  1969-12-31 19:00:00.000000000 -0500
35783 +++ um/arch/um/util/Makefile    2002-10-23 21:09:14.000000000 -0400
35784 @@ -0,0 +1,26 @@
35785 +ALL = mk_task mk_constants
35786 +
35787 +all : $(ALL)
35788 +
35789 +mk_task : mk_task_user.o mk_task_kern.o
35790 +       $(CC) -o mk_task mk_task_user.o mk_task_kern.o
35791 +
35792 +mk_task_user.o : mk_task_user.c
35793 +       $(CC) -c $< 
35794 +
35795 +mk_task_kern.o : mk_task_kern.c
35796 +       $(CC) $(CFLAGS) -c $< 
35797 +
35798 +mk_constants : mk_constants_user.o mk_constants_kern.o
35799 +       $(CC) -o mk_constants mk_constants_user.o mk_constants_kern.o
35800 +
35801 +mk_constants_user.o : mk_constants_user.c
35802 +       $(CC) -c $< 
35803 +
35804 +mk_constants_kern.o : mk_constants_kern.c
35805 +       $(CC) $(CFLAGS) -c $< 
35806 +
35807 +clean :
35808 +       $(RM) $(ALL) *.o *~
35809 +
35810 +archmrproper : clean
35811 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_kern.c um/arch/um/util/mk_constants_kern.c
35812 --- orig/arch/um/util/mk_constants_kern.c       1969-12-31 19:00:00.000000000 -0500
35813 +++ um/arch/um/util/mk_constants_kern.c 2002-10-23 21:08:04.000000000 -0400
35814 @@ -0,0 +1,24 @@
35815 +#include "linux/kernel.h"
35816 +#include "linux/stringify.h"
35817 +#include "asm/page.h"
35818 +
35819 +extern void print_head(void);
35820 +extern void print_constant_str(char *name, char *value);
35821 +extern void print_constant_int(char *name, int value);
35822 +extern void print_tail(void);
35823 +
35824 +int main(int argc, char **argv)
35825 +{
35826 +  print_head();
35827 +  print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
35828 +  print_constant_str("UM_KERN_EMERG", KERN_EMERG);
35829 +  print_constant_str("UM_KERN_ALERT", KERN_ALERT);
35830 +  print_constant_str("UM_KERN_CRIT", KERN_CRIT);
35831 +  print_constant_str("UM_KERN_ERR", KERN_ERR);
35832 +  print_constant_str("UM_KERN_WARNING", KERN_WARNING);
35833 +  print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
35834 +  print_constant_str("UM_KERN_INFO", KERN_INFO);
35835 +  print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
35836 +  print_tail();
35837 +  return(0);
35838 +}
35839 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_user.c um/arch/um/util/mk_constants_user.c
35840 --- orig/arch/um/util/mk_constants_user.c       1969-12-31 19:00:00.000000000 -0500
35841 +++ um/arch/um/util/mk_constants_user.c 2002-10-23 21:08:04.000000000 -0400
35842 @@ -0,0 +1,28 @@
35843 +#include <stdio.h>
35844 +
35845 +void print_head(void)
35846 +{
35847 +  printf("/*\n");
35848 +  printf(" * Generated by mk_constants\n");
35849 +  printf(" */\n");
35850 +  printf("\n");
35851 +  printf("#ifndef __UM_CONSTANTS_H\n");
35852 +  printf("#define __UM_CONSTANTS_H\n");
35853 +  printf("\n");
35854 +}
35855 +
35856 +void print_constant_str(char *name, char *value)
35857 +{
35858 +  printf("#define %s \"%s\"\n", name, value);
35859 +}
35860 +
35861 +void print_constant_int(char *name, int value)
35862 +{
35863 +  printf("#define %s %d\n", name, value);
35864 +}
35865 +
35866 +void print_tail(void)
35867 +{
35868 +  printf("\n");
35869 +  printf("#endif\n");
35870 +}
35871 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_kern.c um/arch/um/util/mk_task_kern.c
35872 --- orig/arch/um/util/mk_task_kern.c    1969-12-31 19:00:00.000000000 -0500
35873 +++ um/arch/um/util/mk_task_kern.c      2002-12-08 21:03:34.000000000 -0500
35874 @@ -0,0 +1,17 @@
35875 +#include "linux/sched.h"
35876 +#include "linux/stddef.h"
35877 +
35878 +extern void print(char *name, char *type, int offset);
35879 +extern void print_ptr(char *name, char *type, int offset);
35880 +extern void print_head(void);
35881 +extern void print_tail(void);
35882 +
35883 +int main(int argc, char **argv)
35884 +{
35885 +  print_head();
35886 +  print_ptr("TASK_REGS", "union uml_pt_regs", 
35887 +           offsetof(struct task_struct, thread.regs));
35888 +  print("TASK_PID", "int", offsetof(struct task_struct, pid));
35889 +  print_tail();
35890 +  return(0);
35891 +}
35892 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_user.c um/arch/um/util/mk_task_user.c
35893 --- orig/arch/um/util/mk_task_user.c    1969-12-31 19:00:00.000000000 -0500
35894 +++ um/arch/um/util/mk_task_user.c      2002-10-23 21:08:04.000000000 -0400
35895 @@ -0,0 +1,30 @@
35896 +#include <stdio.h>
35897 +
35898 +void print(char *name, char *type, int offset)
35899 +{
35900 +  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
35901 +        offset);
35902 +}
35903 +
35904 +void print_ptr(char *name, char *type, int offset)
35905 +{
35906 +  printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
35907 +        offset);
35908 +}
35909 +
35910 +void print_head(void)
35911 +{
35912 +  printf("/*\n");
35913 +  printf(" * Generated by mk_task\n");
35914 +  printf(" */\n");
35915 +  printf("\n");
35916 +  printf("#ifndef __TASK_H\n");
35917 +  printf("#define __TASK_H\n");
35918 +  printf("\n");
35919 +}
35920 +
35921 +void print_tail(void)
35922 +{
35923 +  printf("\n");
35924 +  printf("#endif\n");
35925 +}
35926 diff -Naur -X ../exclude-files orig/CREDITS um/CREDITS
35927 --- orig/CREDITS        2003-02-27 13:04:11.000000000 -0500
35928 +++ um/CREDITS  2003-02-27 13:05:17.000000000 -0500
35929 @@ -432,6 +432,7 @@
35930  E: lars@nocrew.org
35931  W: http://lars.nocrew.org/
35932  D: dsp56k device driver
35933 +D: ptrace proxy in user mode kernel port
35934  S: Kopmansg 2
35935  S: 411 13  Goteborg
35936  S: Sweden
35937 @@ -721,7 +722,7 @@
35938  E: jdike@karaya.com
35939  W: http://user-mode-linux.sourceforge.net
35940  D: User mode kernel port
35941 -S: RR1 Box 67C
35942 +S: 375 Tubbs Hill Rd
35943  S: Deering NH 03244
35944  S: USA
35945  
35946 diff -Naur -X ../exclude-files orig/Documentation/Configure.help um/Documentation/Configure.help
35947 --- orig/Documentation/Configure.help   2003-02-27 13:04:11.000000000 -0500
35948 +++ um/Documentation/Configure.help     2003-02-27 13:05:17.000000000 -0500
35949 @@ -14690,19 +14690,23 @@
35950    The module will be called dsbr100.o. If you want to compile it as a
35951    module, say M here and read <file:Documentation/modules.txt>.
35952  
35953 -Always do synchronous disk IO for UBD
35954 -CONFIG_BLK_DEV_UBD_SYNC
35955 +CONFIG_BLK_DEV_UBD
35956    The User-Mode Linux port includes a driver called UBD which will let
35957    you access arbitrary files on the host computer as block devices.
35958 -  Writes to such a block device are not immediately written to the
35959 -  host's disk; this may cause problems if, for example, the User-Mode
35960 -  Linux 'Virtual Machine' uses a journalling file system and the host
35961 -  computer crashes.
35962 +  Unless you know that you do not need such virtual block devices say
35963 +  Y here.
35964 +
35965 +Always do synchronous disk IO for UBD
35966 +CONFIG_BLK_DEV_UBD_SYNC
35967 +  Writes to the virtual block device are not immediately written to the host's
35968 +  disk; this may cause problems if, for example, the User-Mode Linux
35969 +  'Virtual Machine' uses a journalling filesystem and the host computer
35970 +  crashes.
35971  
35972    Synchronous operation (i.e. always writing data to the host's disk
35973    immediately) is configurable on a per-UBD basis by using a special
35974    kernel command line option.  Alternatively, you can say Y here to
35975 -  turn on synchronous operation by default for all block.
35976 +  turn on synchronous operation by default for all block devices.
35977  
35978    If you're running a journalling file system (like reiserfs, for
35979    example) in your virtual machine, you will want to say Y here.  If
35980 @@ -14714,6 +14718,7 @@
35981  CONFIG_PT_PROXY
35982    This option enables a debugging interface which allows gdb to debug
35983    the kernel without needing to actually attach to kernel threads.
35984 +  CONFIG_XTERM_CHAN must be enabled in order to enable CONFIG_PT_PROXY.
35985    If you want to do kernel debugging, say Y here; otherwise say N.
35986  
35987  Management console
35988 @@ -14908,26 +14913,174 @@
35989  
35990  SLIP transport
35991  CONFIG_UML_NET_SLIP
35992 -  The Slip User-Mode Linux network transport allows a running UML to
35993 +  The slip User-Mode Linux network transport allows a running UML to
35994    network with its host over a point-to-point link.  Unlike Ethertap,
35995    which can carry any Ethernet frame (and hence even non-IP packets),
35996 -  the Slip transport can only carry IP packets.
35997 +  the slip transport can only carry IP packets.
35998  
35999 -  To use this, your host must support Slip devices.
36000 +  To use this, your host must support slip devices.
36001  
36002    For more information, see
36003    <http://user-mode-linux.sourceforge.net/networking.html>.  That site
36004 -  has examples of the UML command line to use to enable Slip
36005 +  has examples of the UML command line to use to enable slip
36006    networking, and details of a few quirks with it.
36007  
36008 -  The Ethertap Transport is preferred over Slip because of its
36009 -  limitation.  If you prefer Slip, however, say Y here.  Otherwise
36010 +  The Ethertap Transport is preferred over slip because of its
36011 +  limitations.  If you prefer slip, however, say Y here.  Otherwise
36012    choose the Multicast transport (to network multiple UMLs on 
36013    multiple hosts), Ethertap (to network with the host and the
36014    outside world), and/or the Daemon transport (to network multiple
36015    UMLs on a single host).  You may choose more than one without
36016    conflict.  If you don't need UML networking, say N.
36017  
36018 +SLiRP transport
36019 +CONFIG_UML_NET_SLIRP
36020 +  The SLiRP User-Mode Linux network transport allows a running UML
36021 +  to network by invoking a program that can handle SLIP encapsulated
36022 +  packets.  This is commonly (but not limited to) the application
36023 +  known as SLiRP, a program that can re-socket IP packets back onto
36024 +  the host on which it is run.  Only IP packets are supported,
36025 +  unlike other network transports that can handle all Ethernet
36026 +  frames.  In general, slirp allows the UML the same IP connectivity
36027 +  to the outside world that the host user is permitted, and unlike
36028 +  other transports, SLiRP works without the need of root level
36029 +  privleges, setuid binaries, or SLIP devices on the host.  This
36030 +  also means not every type of connection is possible, but most
36031 +  situations can be accomodated with carefully crafted slirp
36032 +  commands that can be passed along as part of the network device's
36033 +  setup string.  The effect of this transport on the UML is similar
36034 +  that of a host behind a firewall that masquerades all network
36035 +  connections passing through it (but is less secure).
36036 +
36037 +  To use this you should first have slirp compiled somewhere
36038 +  accessible on the host, and have read its documentation.  If you
36039 +  don't need UML networking, say N.
36040 +
36041 +  Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
36042 +
36043 +Default main console channel initialization
36044 +CONFIG_CON_ZERO_CHAN
36045 +  This is the string describing the channel to which the main console
36046 +  will be attached by default.  This value can be overridden from the
36047 +  command line.  The default value is "fd:0,fd:1", which attaches the
36048 +  main console to stdin and stdout.
36049 +  It is safe to leave this unchanged.
36050 +
36051 +Default console channel initialization
36052 +CONFIG_CON_CHAN
36053 +  This is the string describing the channel to which all consoles
36054 +  except the main console will be attached by default.  This value can
36055 +  be overridden from the command line.  The default value is "xterm",
36056 +  which brings them up in xterms.
36057 +  It is safe to leave this unchanged, although you may wish to change
36058 +  this if you expect the UML that you build to be run in environments
36059 +  which don't have X or xterm available.
36060 +
36061 +Default serial line channel initialization
36062 +CONFIG_SSL_CHAN
36063 +  This is the string describing the channel to which the serial lines
36064 +  will be attached by default.  This value can be overridden from the
36065 +  command line.  The default value is "pty", which attaches them to
36066 +  traditional pseudo-terminals.
36067 +  It is safe to leave this unchanged, although you may wish to change
36068 +  this if you expect the UML that you build to be run in environments
36069 +  which don't have a set of /dev/pty* devices.
36070 +
36071 +Nesting level
36072 +CONFIG_NEST_LEVEL
36073 +  This is set to the number of layers of UMLs that this UML will be run
36074 +  in.  Normally, this is zero, meaning that it will run directly on the
36075 +  host.  Setting it to one will build a UML that can run inside a UML
36076 +  that is running on the host.  Generally, if you intend this UML to run
36077 +  inside another UML, set CONFIG_NEST_LEVEL to one more than the host UML.
36078 +  Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to 
36079 +  greater than one, then the guest UML should have its CONFIG_NEST_LEVEL 
36080 +  set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
36081 +  Only change this if you are running nested UMLs.
36082 +
36083 +Kernel address space size (in .5G units)
36084 +CONFIG_KERNEL_HALF_GIGS
36085 +  This determines the amount of address space that UML will allocate for
36086 +  its own, measured in half Gigabyte units.  The default is 1.
36087 +  Change this only if you need to boot UML with an unusually large amount
36088 +  of physical memory.
36089 +
36090 +UML sound support
36091 +CONFIG_UML_SOUND
36092 +  This option enables UML sound support.  If enabled, it will pull in
36093 +  soundcore and the UML hostaudio relay, which acts as a intermediary
36094 +  between the host's dsp and mixer devices and the UML sound system.
36095 +  It is safe to say 'Y' here.
36096 +
36097 +UML SMP support
36098 +CONFIG_UML_SMP
36099 +  This option enables UML SMP support.  UML implements virtual SMP by
36100 +  allowing as many processes to run simultaneously on the host as
36101 +  there are virtual processors configured.  Obviously, if the host is
36102 +  a uniprocessor, those processes will timeshare, but, inside UML,
36103 +  will appear to be running simultaneously.  If the host is a
36104 +  multiprocessor, then UML processes may run simultaneously, depending
36105 +  on the host scheduler.
36106 +  CONFIG_SMP will be set to whatever this option is set to.
36107 +  It is safe to leave this unchanged.
36108 +
36109 +file descriptor channel support
36110 +CONFIG_FD_CHAN
36111 +  This option enables support for attaching UML consoles and serial
36112 +  lines to already set up file descriptors.  Generally, the main
36113 +  console is attached to file descriptors 0 and 1 (stdin and stdout),
36114 +  so it would be wise to leave this enabled unless you intend to
36115 +  attach it to some other host device.
36116 +
36117 +null device channel support
36118 +CONFIG_NULL_CHAN
36119 +  This option enables support for attaching UML consoles and serial
36120 +  lines to a device similar to /dev/null.  Data written to it disappears
36121 +  and there is never any data to be read.
36122 +
36123 +port channel support
36124 +CONFIG_PORT_CHAN
36125 +  This option enables support for attaching UML consoles and serial
36126 +  lines to host portals.  They may be accessed with 'telnet <host>
36127 +  <port number>'.  Any number of consoles and serial lines may be
36128 +  attached to a single portal, although what UML device you get when
36129 +  you telnet to that portal will be unpredictable.
36130 +  It is safe to say 'Y' here.
36131 +
36132 +pty channel support
36133 +CONFIG_PTY_CHAN
36134 +  This option enables support for attaching UML consoles and serial
36135 +  lines to host pseudo-terminals.  Access to both traditional
36136 +  pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
36137 +  with this option.  The assignment of UML devices to host devices
36138 +  will be announced in the kernel message log.
36139 +  It is safe to say 'Y' here.
36140 +
36141 +tty channel support
36142 +CONFIG_TTY_CHAN
36143 +  This option enables support for attaching UML consoles and serial
36144 +  lines to host terminals.  Access to both virtual consoles
36145 +  (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
36146 +  /dev/pts/*) are controlled by this option.
36147 +  It is safe to say 'Y' here.
36148 +
36149 +xterm channel support
36150 +CONFIG_XTERM_CHAN
36151 +  This option enables support for attaching UML consoles and serial
36152 +  lines to xterms.  Each UML device so assigned will be brought up in
36153 +  its own xterm.
36154 +  If you disable this option, then CONFIG_PT_PROXY will be disabled as
36155 +  well, since UML's gdb currently requires an xterm.
36156 +  It is safe to say 'Y' here.
36157 +
36158 +tty logging
36159 +CONFIG_TTY_LOG
36160 +  This option enables logging of all data going through pseudo-terminals
36161 +  to the host.  This is primarily useful for honeypots, where you want
36162 +  secure keystroke logging that can't be detected or disabled by root.
36163 +  Say 'N' unless you are setting up a UML honeypot or otherwise know that
36164 +  you want this option.
36165 +
36166  Microtek USB scanner support
36167  CONFIG_USB_MICROTEK
36168    Say Y here if you want support for the Microtek X6USB and
36169 diff -Naur -X ../exclude-files orig/drivers/char/Makefile um/drivers/char/Makefile
36170 --- orig/drivers/char/Makefile  2003-02-27 13:04:15.000000000 -0500
36171 +++ um/drivers/char/Makefile    2003-02-27 13:05:21.000000000 -0500
36172 @@ -95,6 +95,12 @@
36173    endif
36174  endif
36175  
36176 +ifeq ($(ARCH),um)
36177 +  KEYMAP   =
36178 +  KEYBD    =
36179 +  CONSOLE  =
36180 +endif
36181 +
36182  ifeq ($(ARCH),sh)
36183    KEYMAP   =
36184    KEYBD    =
36185 diff -Naur -X ../exclude-files orig/drivers/char/tty_io.c um/drivers/char/tty_io.c
36186 --- orig/drivers/char/tty_io.c  2003-02-27 13:04:15.000000000 -0500
36187 +++ um/drivers/char/tty_io.c    2003-02-27 13:05:21.000000000 -0500
36188 @@ -637,6 +637,9 @@
36189         wake_up_interruptible(&tty->write_wait);
36190  }
36191  
36192 +extern int write_tty_log(int fd, const unsigned char *buf, int len, void *tty,
36193 +                        int direction);
36194 +
36195  static ssize_t tty_read(struct file * file, char * buf, size_t count, 
36196                         loff_t *ppos)
36197  {
36198 @@ -677,8 +680,13 @@
36199         else
36200                 i = -EIO;
36201         unlock_kernel();
36202 -       if (i > 0)
36203 +       if (i > 0){
36204                 inode->i_atime = CURRENT_TIME;
36205 +#ifdef CONFIG_TTY_LOG
36206 +               if(tty->log_fd >= 0) 
36207 +                 write_tty_log(tty->log_fd, buf, i, tty, 1);
36208 +#endif
36209 +       }
36210         return i;
36211  }
36212  
36213 @@ -732,6 +740,10 @@
36214         if (written) {
36215                 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
36216                 ret = written;
36217 +#ifdef CONFIG_TTY_LOG
36218 +               if(tty->log_fd >= 0) 
36219 +                 write_tty_log(tty->log_fd, buf - ret, ret, tty, 0);
36220 +#endif
36221         }
36222         up(&tty->atomic_write);
36223         return ret;
36224 @@ -945,6 +957,9 @@
36225                         goto release_mem_out;
36226                 }
36227         }
36228 +#ifdef CONFIG_TTY_LOG
36229 +       tty->log_fd = -1;
36230 +#endif
36231         goto success;
36232  
36233         /*
36234 @@ -1039,6 +1054,8 @@
36235         free_tty_struct(tty);
36236  }
36237  
36238 +extern int close_tty_log(int fd, void *tty);
36239 +
36240  /*
36241   * Even releasing the tty structures is a tricky business.. We have
36242   * to be very careful that the structures are all released at the
36243 @@ -1267,6 +1284,10 @@
36244         run_task_queue(&tq_timer);
36245         flush_scheduled_tasks();
36246  
36247 +#ifdef CONFIG_TTY_LOG
36248 +       if(tty->log_fd >= 0) close_tty_log(tty->log_fd, tty);
36249 +#endif
36250 +
36251         /* 
36252          * The release_mem function takes care of the details of clearing
36253          * the slots and preserving the termios structure.
36254 @@ -1274,6 +1295,8 @@
36255         release_mem(tty, idx);
36256  }
36257  
36258 +extern int open_tty_log(void *tty, void *current_tty); 
36259 +
36260  /*
36261   * tty_open and tty_release keep up the tty count that contains the
36262   * number of opens done on a tty. We cannot use the inode-count, as
36263 @@ -1425,6 +1448,11 @@
36264                         nr_warns++;
36265                 }
36266         }
36267 +
36268 +#ifdef CONFIG_TTY_LOG
36269 +       if(tty->log_fd < 0)
36270 +              tty->log_fd = open_tty_log(tty, current->tty);
36271 +#endif
36272         return 0;
36273  }
36274  
36275 diff -Naur -X ../exclude-files orig/drivers/net/setup.c um/drivers/net/setup.c
36276 --- orig/drivers/net/setup.c    2002-09-15 12:13:19.000000000 -0400
36277 +++ um/drivers/net/setup.c      2002-10-23 21:08:05.000000000 -0400
36278 @@ -28,7 +28,6 @@
36279  extern int lmc_setup(void);
36280  
36281  extern int madgemc_probe(void);
36282 -extern int uml_net_probe(void);
36283  
36284  /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
36285  #define __PAD6 "\0\0\0\0\0\0\0\0\0"
36286 @@ -103,9 +102,6 @@
36287  #ifdef CONFIG_MADGEMC
36288         {madgemc_probe, 0},
36289  #endif
36290 -#ifdef CONFIG_UML_NET
36291 -       {uml_net_probe, 0},
36292 -#endif
36293   
36294         {NULL, 0},
36295  };
36296 diff -Naur -X ../exclude-files orig/include/asm-i386/hardirq.h um/include/asm-i386/hardirq.h
36297 --- orig/include/asm-i386/hardirq.h     2002-09-15 12:13:19.000000000 -0400
36298 +++ um/include/asm-i386/hardirq.h       2003-05-28 11:02:07.000000000 -0400
36299 @@ -4,6 +4,7 @@
36300  #include <linux/config.h>
36301  #include <linux/threads.h>
36302  #include <linux/irq.h>
36303 +#include <asm/processor.h>             /* for cpu_relax */
36304  
36305  /* assembly code in softirq.h is sensitive to the offsets of these fields */
36306  typedef struct {
36307 diff -Naur -X ../exclude-files orig/include/asm-um/a.out.h um/include/asm-um/a.out.h
36308 --- orig/include/asm-um/a.out.h 1969-12-31 19:00:00.000000000 -0500
36309 +++ um/include/asm-um/a.out.h   2002-10-27 11:54:50.000000000 -0500
36310 @@ -0,0 +1,20 @@
36311 +#ifndef __UM_A_OUT_H
36312 +#define __UM_A_OUT_H
36313 +
36314 +#include "linux/config.h"
36315 +#include "asm/arch/a.out.h"
36316 +#include "choose-mode.h"
36317 +
36318 +#undef STACK_TOP
36319 +
36320 +extern unsigned long stacksizelim;
36321 +
36322 +extern unsigned long host_task_size;
36323 +
36324 +#define STACK_ROOM (stacksizelim)
36325 +
36326 +extern int honeypot;
36327 +#define STACK_TOP \
36328 +       CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
36329 +
36330 +#endif
36331 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-i386.h um/include/asm-um/archparam-i386.h
36332 --- orig/include/asm-um/archparam-i386.h        1969-12-31 19:00:00.000000000 -0500
36333 +++ um/include/asm-um/archparam-i386.h  2002-12-08 20:09:11.000000000 -0500
36334 @@ -0,0 +1,80 @@
36335 +/* 
36336 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
36337 + * Licensed under the GPL
36338 + */
36339 +
36340 +#ifndef __UM_ARCHPARAM_I386_H
36341 +#define __UM_ARCHPARAM_I386_H
36342 +
36343 +/********* Bits for asm-um/elf.h ************/
36344 +
36345 +#include "user.h"
36346 +
36347 +#define ELF_PLATFORM "i586"
36348 +
36349 +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
36350 +
36351 +typedef struct user_i387_struct elf_fpregset_t;
36352 +typedef unsigned long elf_greg_t;
36353 +
36354 +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
36355 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
36356 +
36357 +#define ELF_DATA        ELFDATA2LSB
36358 +#define ELF_ARCH        EM_386
36359 +
36360 +#define ELF_PLAT_INIT(regs) do { \
36361 +       PT_REGS_EBX(regs) = 0; \
36362 +       PT_REGS_ECX(regs) = 0; \
36363 +       PT_REGS_EDX(regs) = 0; \
36364 +       PT_REGS_ESI(regs) = 0; \
36365 +       PT_REGS_EDI(regs) = 0; \
36366 +       PT_REGS_EBP(regs) = 0; \
36367 +       PT_REGS_EAX(regs) = 0; \
36368 +} while(0)
36369 +
36370 +/* Shamelessly stolen from include/asm-i386/elf.h */
36371 +
36372 +#define ELF_CORE_COPY_REGS(pr_reg, regs) do {  \
36373 +       pr_reg[0] = PT_REGS_EBX(regs);          \
36374 +       pr_reg[1] = PT_REGS_ECX(regs);          \
36375 +       pr_reg[2] = PT_REGS_EDX(regs);          \
36376 +       pr_reg[3] = PT_REGS_ESI(regs);          \
36377 +       pr_reg[4] = PT_REGS_EDI(regs);          \
36378 +       pr_reg[5] = PT_REGS_EBP(regs);          \
36379 +       pr_reg[6] = PT_REGS_EAX(regs);          \
36380 +       pr_reg[7] = PT_REGS_DS(regs);           \
36381 +       pr_reg[8] = PT_REGS_ES(regs);           \
36382 +       /* fake once used fs and gs selectors? */       \
36383 +       pr_reg[9] = PT_REGS_DS(regs);           \
36384 +       pr_reg[10] = PT_REGS_DS(regs);          \
36385 +       pr_reg[11] = PT_REGS_SYSCALL_NR(regs);  \
36386 +       pr_reg[12] = PT_REGS_IP(regs);          \
36387 +       pr_reg[13] = PT_REGS_CS(regs);          \
36388 +       pr_reg[14] = PT_REGS_EFLAGS(regs);      \
36389 +       pr_reg[15] = PT_REGS_SP(regs);          \
36390 +       pr_reg[16] = PT_REGS_SS(regs);          \
36391 +} while(0);
36392 +
36393 +/********* Bits for asm-um/delay.h **********/
36394 +
36395 +typedef unsigned long um_udelay_t;
36396 +
36397 +/********* Nothing for asm-um/hardirq.h **********/
36398 +
36399 +/********* Nothing for asm-um/hw_irq.h **********/
36400 +
36401 +/********* Nothing for asm-um/string.h **********/
36402 +
36403 +#endif
36404 +
36405 +/*
36406 + * Overrides for Emacs so that we follow Linus's tabbing style.
36407 + * Emacs will notice this stuff at the end of the file and automatically
36408 + * adjust the settings for this buffer only.  This must remain at the end
36409 + * of the file.
36410 + * ---------------------------------------------------------------------------
36411 + * Local variables:
36412 + * c-file-style: "linux"
36413 + * End:
36414 + */
36415 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-ppc.h um/include/asm-um/archparam-ppc.h
36416 --- orig/include/asm-um/archparam-ppc.h 1969-12-31 19:00:00.000000000 -0500
36417 +++ um/include/asm-um/archparam-ppc.h   2002-10-23 21:08:05.000000000 -0400
36418 @@ -0,0 +1,41 @@
36419 +#ifndef __UM_ARCHPARAM_PPC_H
36420 +#define __UM_ARCHPARAM_PPC_H
36421 +
36422 +/********* Bits for asm-um/elf.h ************/
36423 +
36424 +#define ELF_PLATFORM (0)
36425 +
36426 +#define ELF_ET_DYN_BASE (0x08000000)
36427 +
36428 +/* the following stolen from asm-ppc/elf.h */
36429 +#define ELF_NGREG      48      /* includes nip, msr, lr, etc. */
36430 +#define ELF_NFPREG     33      /* includes fpscr */
36431 +/* General registers */
36432 +typedef unsigned long elf_greg_t;
36433 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
36434 +
36435 +/* Floating point registers */
36436 +typedef double elf_fpreg_t;
36437 +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
36438 +
36439 +#define ELF_DATA        ELFDATA2MSB
36440 +#define ELF_ARCH       EM_PPC
36441 +
36442 +/********* Bits for asm-um/delay.h **********/
36443 +
36444 +typedef unsigned int um_udelay_t;
36445 +
36446 +/********* Bits for asm-um/hw_irq.h **********/
36447 +
36448 +struct hw_interrupt_type;
36449 +
36450 +/********* Bits for asm-um/hardirq.h **********/
36451 +
36452 +#define irq_enter(cpu, irq) hardirq_enter(cpu)
36453 +#define irq_exit(cpu, irq) hardirq_exit(cpu)
36454 +
36455 +/********* Bits for asm-um/string.h **********/
36456 +
36457 +#define __HAVE_ARCH_STRRCHR
36458 +
36459 +#endif
36460 diff -Naur -X ../exclude-files orig/include/asm-um/arch-signal-i386.h um/include/asm-um/arch-signal-i386.h
36461 --- orig/include/asm-um/arch-signal-i386.h      1969-12-31 19:00:00.000000000 -0500
36462 +++ um/include/asm-um/arch-signal-i386.h        2002-10-23 21:08:05.000000000 -0400
36463 @@ -0,0 +1,24 @@
36464 +/* 
36465 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36466 + * Licensed under the GPL
36467 + */
36468 +
36469 +#ifndef __UM_ARCH_SIGNAL_I386_H
36470 +#define __UM_ARCH_SIGNAL_I386_H
36471 +
36472 +struct arch_signal_context {
36473 +       unsigned long extrasigs[_NSIG_WORDS];
36474 +};
36475 +
36476 +#endif
36477 +
36478 +/*
36479 + * Overrides for Emacs so that we follow Linus's tabbing style.
36480 + * Emacs will notice this stuff at the end of the file and automatically
36481 + * adjust the settings for this buffer only.  This must remain at the end
36482 + * of the file.
36483 + * ---------------------------------------------------------------------------
36484 + * Local variables:
36485 + * c-file-style: "linux"
36486 + * End:
36487 + */
36488 diff -Naur -X ../exclude-files orig/include/asm-um/atomic.h um/include/asm-um/atomic.h
36489 --- orig/include/asm-um/atomic.h        1969-12-31 19:00:00.000000000 -0500
36490 +++ um/include/asm-um/atomic.h  2003-05-28 11:02:07.000000000 -0400
36491 @@ -0,0 +1,6 @@
36492 +#ifndef __UM_ATOMIC_H
36493 +#define __UM_ATOMIC_H
36494 +
36495 +#include "asm/arch/atomic.h"
36496 +
36497 +#endif
36498 diff -Naur -X ../exclude-files orig/include/asm-um/bitops.h um/include/asm-um/bitops.h
36499 --- orig/include/asm-um/bitops.h        1969-12-31 19:00:00.000000000 -0500
36500 +++ um/include/asm-um/bitops.h  2003-05-28 11:02:07.000000000 -0400
36501 @@ -0,0 +1,6 @@
36502 +#ifndef __UM_BITOPS_H
36503 +#define __UM_BITOPS_H
36504 +
36505 +#include "asm/arch/bitops.h"
36506 +
36507 +#endif
36508 diff -Naur -X ../exclude-files orig/include/asm-um/boot.h um/include/asm-um/boot.h
36509 --- orig/include/asm-um/boot.h  1969-12-31 19:00:00.000000000 -0500
36510 +++ um/include/asm-um/boot.h    2002-10-23 21:08:05.000000000 -0400
36511 @@ -0,0 +1,6 @@
36512 +#ifndef __UM_BOOT_H
36513 +#define __UM_BOOT_H
36514 +
36515 +#include "asm/arch/boot.h"
36516 +
36517 +#endif
36518 diff -Naur -X ../exclude-files orig/include/asm-um/bugs.h um/include/asm-um/bugs.h
36519 --- orig/include/asm-um/bugs.h  1969-12-31 19:00:00.000000000 -0500
36520 +++ um/include/asm-um/bugs.h    2002-10-23 21:08:05.000000000 -0400
36521 @@ -0,0 +1,6 @@
36522 +#ifndef __UM_BUGS_H
36523 +#define __UM_BUGS_H
36524 +
36525 +void check_bugs(void);
36526 +
36527 +#endif
36528 diff -Naur -X ../exclude-files orig/include/asm-um/byteorder.h um/include/asm-um/byteorder.h
36529 --- orig/include/asm-um/byteorder.h     1969-12-31 19:00:00.000000000 -0500
36530 +++ um/include/asm-um/byteorder.h       2003-02-27 13:20:12.000000000 -0500
36531 @@ -0,0 +1,6 @@
36532 +#ifndef __UM_BYTEORDER_H
36533 +#define __UM_BYTEORDER_H
36534 +
36535 +#include "asm/arch/byteorder.h"
36536 +
36537 +#endif
36538 diff -Naur -X ../exclude-files orig/include/asm-um/cache.h um/include/asm-um/cache.h
36539 --- orig/include/asm-um/cache.h 1969-12-31 19:00:00.000000000 -0500
36540 +++ um/include/asm-um/cache.h   2002-10-23 21:08:05.000000000 -0400
36541 @@ -0,0 +1,6 @@
36542 +#ifndef __UM_CACHE_H
36543 +#define __UM_CACHE_H
36544 +
36545 +#define        L1_CACHE_BYTES  32
36546 +
36547 +#endif
36548 diff -Naur -X ../exclude-files orig/include/asm-um/checksum.h um/include/asm-um/checksum.h
36549 --- orig/include/asm-um/checksum.h      1969-12-31 19:00:00.000000000 -0500
36550 +++ um/include/asm-um/checksum.h        2002-10-29 17:25:12.000000000 -0500
36551 @@ -0,0 +1,6 @@
36552 +#ifndef __UM_CHECKSUM_H
36553 +#define __UM_CHECKSUM_H
36554 +
36555 +#include "sysdep/checksum.h"
36556 +
36557 +#endif
36558 diff -Naur -X ../exclude-files orig/include/asm-um/cobalt.h um/include/asm-um/cobalt.h
36559 --- orig/include/asm-um/cobalt.h        1969-12-31 19:00:00.000000000 -0500
36560 +++ um/include/asm-um/cobalt.h  2002-10-23 21:08:05.000000000 -0400
36561 @@ -0,0 +1,6 @@
36562 +#ifndef __UM_COBALT_H
36563 +#define __UM_COBALT_H
36564 +
36565 +#include "asm/arch/cobalt.h"
36566 +
36567 +#endif
36568 diff -Naur -X ../exclude-files orig/include/asm-um/current.h um/include/asm-um/current.h
36569 --- orig/include/asm-um/current.h       1969-12-31 19:00:00.000000000 -0500
36570 +++ um/include/asm-um/current.h 2003-05-28 11:02:07.000000000 -0400
36571 @@ -0,0 +1,34 @@
36572 +/* 
36573 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
36574 + * Licensed under the GPL
36575 + */
36576 +
36577 +#ifndef __UM_CURRENT_H
36578 +#define __UM_CURRENT_H
36579 +
36580 +#ifndef __ASSEMBLY__
36581 +
36582 +#include "linux/config.h"
36583 +#include "asm/page.h"
36584 +
36585 +struct task_struct;
36586 +
36587 +#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \
36588 +                            (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
36589 +
36590 +#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); })
36591 +
36592 +#endif /* __ASSEMBLY__ */
36593 +
36594 +#endif
36595 +
36596 +/*
36597 + * Overrides for Emacs so that we follow Linus's tabbing style.
36598 + * Emacs will notice this stuff at the end of the file and automatically
36599 + * adjust the settings for this buffer only.  This must remain at the end
36600 + * of the file.
36601 + * ---------------------------------------------------------------------------
36602 + * Local variables:
36603 + * c-file-style: "linux"
36604 + * End:
36605 + */
36606 diff -Naur -X ../exclude-files orig/include/asm-um/delay.h um/include/asm-um/delay.h
36607 --- orig/include/asm-um/delay.h 1969-12-31 19:00:00.000000000 -0500
36608 +++ um/include/asm-um/delay.h   2002-12-08 20:09:15.000000000 -0500
36609 @@ -0,0 +1,7 @@
36610 +#ifndef __UM_DELAY_H
36611 +#define __UM_DELAY_H
36612 +
36613 +#include "asm/arch/delay.h"
36614 +#include "asm/archparam.h"
36615 +
36616 +#endif
36617 diff -Naur -X ../exclude-files orig/include/asm-um/desc.h um/include/asm-um/desc.h
36618 --- orig/include/asm-um/desc.h  1969-12-31 19:00:00.000000000 -0500
36619 +++ um/include/asm-um/desc.h    2002-10-23 21:08:05.000000000 -0400
36620 @@ -0,0 +1,6 @@
36621 +#ifndef __UM_DESC_H
36622 +#define __UM_DESC_H
36623 +
36624 +#include "asm/arch/desc.h"
36625 +
36626 +#endif
36627 diff -Naur -X ../exclude-files orig/include/asm-um/div64.h um/include/asm-um/div64.h
36628 --- orig/include/asm-um/div64.h 1969-12-31 19:00:00.000000000 -0500
36629 +++ um/include/asm-um/div64.h   2002-10-23 21:08:05.000000000 -0400
36630 @@ -0,0 +1,6 @@
36631 +#ifndef _UM_DIV64_H
36632 +#define _UM_DIV64_H
36633 +
36634 +#include "asm/arch/div64.h"
36635 +
36636 +#endif
36637 diff -Naur -X ../exclude-files orig/include/asm-um/dma.h um/include/asm-um/dma.h
36638 --- orig/include/asm-um/dma.h   1969-12-31 19:00:00.000000000 -0500
36639 +++ um/include/asm-um/dma.h     2002-10-27 16:53:42.000000000 -0500
36640 @@ -0,0 +1,10 @@
36641 +#ifndef __UM_DMA_H
36642 +#define __UM_DMA_H
36643 +
36644 +#include "asm/io.h"
36645 +
36646 +extern unsigned long uml_physmem;
36647 +
36648 +#define MAX_DMA_ADDRESS (uml_physmem)
36649 +
36650 +#endif
36651 diff -Naur -X ../exclude-files orig/include/asm-um/elf.h um/include/asm-um/elf.h
36652 --- orig/include/asm-um/elf.h   1969-12-31 19:00:00.000000000 -0500
36653 +++ um/include/asm-um/elf.h     2002-12-08 20:13:07.000000000 -0500
36654 @@ -0,0 +1,18 @@
36655 +#ifndef __UM_ELF_H
36656 +#define __UM_ELF_H
36657 +
36658 +#include "asm/archparam.h"
36659 +
36660 +#define ELF_HWCAP (0)
36661 +
36662 +#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
36663 +
36664 +#define ELF_EXEC_PAGESIZE 4096
36665 +
36666 +#define elf_check_arch(x) (1)
36667 +
36668 +#define ELF_CLASS ELFCLASS32
36669 +
36670 +#define USE_ELF_CORE_DUMP
36671 +
36672 +#endif
36673 diff -Naur -X ../exclude-files orig/include/asm-um/errno.h um/include/asm-um/errno.h
36674 --- orig/include/asm-um/errno.h 1969-12-31 19:00:00.000000000 -0500
36675 +++ um/include/asm-um/errno.h   2002-10-23 21:08:05.000000000 -0400
36676 @@ -0,0 +1,6 @@
36677 +#ifndef __UM_ERRNO_H
36678 +#define __UM_ERRNO_H
36679 +
36680 +#include "asm/arch/errno.h"
36681 +
36682 +#endif
36683 diff -Naur -X ../exclude-files orig/include/asm-um/fcntl.h um/include/asm-um/fcntl.h
36684 --- orig/include/asm-um/fcntl.h 1969-12-31 19:00:00.000000000 -0500
36685 +++ um/include/asm-um/fcntl.h   2002-10-23 21:08:05.000000000 -0400
36686 @@ -0,0 +1,6 @@
36687 +#ifndef __UM_FCNTL_H
36688 +#define __UM_FCNTL_H
36689 +
36690 +#include "asm/arch/fcntl.h"
36691 +
36692 +#endif
36693 diff -Naur -X ../exclude-files orig/include/asm-um/fixmap.h um/include/asm-um/fixmap.h
36694 --- orig/include/asm-um/fixmap.h        1969-12-31 19:00:00.000000000 -0500
36695 +++ um/include/asm-um/fixmap.h  2003-05-28 11:02:08.000000000 -0400
36696 @@ -0,0 +1,89 @@
36697 +#ifndef __UM_FIXMAP_H
36698 +#define __UM_FIXMAP_H
36699 +
36700 +#include <linux/config.h>
36701 +#include <asm/kmap_types.h>
36702 +
36703 +/*
36704 + * Here we define all the compile-time 'special' virtual
36705 + * addresses. The point is to have a constant address at
36706 + * compile time, but to set the physical address only
36707 + * in the boot process. We allocate these special  addresses
36708 + * from the end of virtual memory (0xfffff000) backwards.
36709 + * Also this lets us do fail-safe vmalloc(), we
36710 + * can guarantee that these special addresses and
36711 + * vmalloc()-ed addresses never overlap.
36712 + *
36713 + * these 'compile-time allocated' memory buffers are
36714 + * fixed-size 4k pages. (or larger if used with an increment
36715 + * highger than 1) use fixmap_set(idx,phys) to associate
36716 + * physical memory with fixmap indices.
36717 + *
36718 + * TLB entries of such buffers will not be flushed across
36719 + * task switches.
36720 + */
36721 +
36722 +/*
36723 + * on UP currently we will have no trace of the fixmap mechanizm,
36724 + * no page table allocations, etc. This might change in the
36725 + * future, say framebuffers for the console driver(s) could be
36726 + * fix-mapped?
36727 + */
36728 +enum fixed_addresses {
36729 +#ifdef CONFIG_HIGHMEM
36730 +       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
36731 +       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
36732 +#endif
36733 +       __end_of_fixed_addresses
36734 +};
36735 +
36736 +extern void __set_fixmap (enum fixed_addresses idx,
36737 +                         unsigned long phys, pgprot_t flags);
36738 +
36739 +#define set_fixmap(idx, phys) \
36740 +               __set_fixmap(idx, phys, PAGE_KERNEL)
36741 +/*
36742 + * Some hardware wants to get fixmapped without caching.
36743 + */
36744 +#define set_fixmap_nocache(idx, phys) \
36745 +               __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
36746 +/*
36747 + * used by vmalloc.c.
36748 + *
36749 + * Leave one empty page between vmalloc'ed areas and
36750 + * the start of the fixmap, and leave one page empty
36751 + * at the top of mem..
36752 + */
36753 +extern unsigned long get_kmem_end(void);
36754 +
36755 +#define FIXADDR_TOP    (get_kmem_end() - 0x2000)
36756 +#define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
36757 +#define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
36758 +
36759 +#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
36760 +
36761 +extern void __this_fixmap_does_not_exist(void);
36762 +
36763 +/*
36764 + * 'index to address' translation. If anyone tries to use the idx
36765 + * directly without tranlation, we catch the bug with a NULL-deference
36766 + * kernel oops. Illegal ranges of incoming indices are caught too.
36767 + */
36768 +static inline unsigned long fix_to_virt(const unsigned int idx)
36769 +{
36770 +       /*
36771 +        * this branch gets completely eliminated after inlining,
36772 +        * except when someone tries to use fixaddr indices in an
36773 +        * illegal way. (such as mixing up address types or using
36774 +        * out-of-range indices).
36775 +        *
36776 +        * If it doesn't get removed, the linker will complain
36777 +        * loudly with a reasonably clear error message..
36778 +        */
36779 +       if (idx >= __end_of_fixed_addresses)
36780 +               __this_fixmap_does_not_exist();
36781 +
36782 +        return __fix_to_virt(idx);
36783 +}
36784 +
36785 +#endif
36786 diff -Naur -X ../exclude-files orig/include/asm-um/floppy.h um/include/asm-um/floppy.h
36787 --- orig/include/asm-um/floppy.h        1969-12-31 19:00:00.000000000 -0500
36788 +++ um/include/asm-um/floppy.h  2002-10-23 21:08:05.000000000 -0400
36789 @@ -0,0 +1,6 @@
36790 +#ifndef __UM_FLOPPY_H
36791 +#define __UM_FLOPPY_H
36792 +
36793 +#include "asm/arch/floppy.h"
36794 +
36795 +#endif
36796 diff -Naur -X ../exclude-files orig/include/asm-um/hardirq.h um/include/asm-um/hardirq.h
36797 --- orig/include/asm-um/hardirq.h       1969-12-31 19:00:00.000000000 -0500
36798 +++ um/include/asm-um/hardirq.h 2003-05-28 11:02:07.000000000 -0400
36799 @@ -0,0 +1,6 @@
36800 +#ifndef __UM_HARDIRQ_H
36801 +#define __UM_HARDIRQ_H
36802 +
36803 +#include "asm/arch/hardirq.h"
36804 +
36805 +#endif
36806 diff -Naur -X ../exclude-files orig/include/asm-um/hdreg.h um/include/asm-um/hdreg.h
36807 --- orig/include/asm-um/hdreg.h 1969-12-31 19:00:00.000000000 -0500
36808 +++ um/include/asm-um/hdreg.h   2002-10-23 21:08:05.000000000 -0400
36809 @@ -0,0 +1,6 @@
36810 +#ifndef __UM_HDREG_H
36811 +#define __UM_HDREG_H
36812 +
36813 +#include "asm/arch/hdreg.h"
36814 +
36815 +#endif
36816 diff -Naur -X ../exclude-files orig/include/asm-um/highmem.h um/include/asm-um/highmem.h
36817 --- orig/include/asm-um/highmem.h       1969-12-31 19:00:00.000000000 -0500
36818 +++ um/include/asm-um/highmem.h 2003-05-28 11:02:08.000000000 -0400
36819 @@ -0,0 +1,12 @@
36820 +#ifndef __UM_HIGHMEM_H
36821 +#define __UM_HIGHMEM_H
36822 +
36823 +#include "asm/page.h"
36824 +#include "asm/fixmap.h"
36825 +#include "asm/arch/highmem.h"
36826 +
36827 +#undef PKMAP_BASE
36828 +
36829 +#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
36830 +
36831 +#endif
36832 diff -Naur -X ../exclude-files orig/include/asm-um/hw_irq.h um/include/asm-um/hw_irq.h
36833 --- orig/include/asm-um/hw_irq.h        1969-12-31 19:00:00.000000000 -0500
36834 +++ um/include/asm-um/hw_irq.h  2003-05-11 18:31:58.000000000 -0400
36835 @@ -0,0 +1,10 @@
36836 +#ifndef _ASM_UM_HW_IRQ_H
36837 +#define _ASM_UM_HW_IRQ_H
36838 +
36839 +#include "asm/irq.h"
36840 +#include "asm/archparam.h"
36841 +
36842 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
36843 +{}
36844 +
36845 +#endif
36846 diff -Naur -X ../exclude-files orig/include/asm-um/ide.h um/include/asm-um/ide.h
36847 --- orig/include/asm-um/ide.h   1969-12-31 19:00:00.000000000 -0500
36848 +++ um/include/asm-um/ide.h     2002-10-23 21:08:05.000000000 -0400
36849 @@ -0,0 +1,6 @@
36850 +#ifndef __UM_IDE_H
36851 +#define __UM_IDE_H
36852 +
36853 +#include "asm/arch/ide.h"
36854 +
36855 +#endif
36856 diff -Naur -X ../exclude-files orig/include/asm-um/init.h um/include/asm-um/init.h
36857 --- orig/include/asm-um/init.h  1969-12-31 19:00:00.000000000 -0500
36858 +++ um/include/asm-um/init.h    2002-10-23 21:08:05.000000000 -0400
36859 @@ -0,0 +1,11 @@
36860 +#ifndef _UM_INIT_H
36861 +#define _UM_INIT_H
36862 +
36863 +#ifdef notdef
36864 +#define __init
36865 +#define __initdata
36866 +#define __initfunc(__arginit) __arginit
36867 +#define __cacheline_aligned 
36868 +#endif
36869 +
36870 +#endif
36871 diff -Naur -X ../exclude-files orig/include/asm-um/ioctl.h um/include/asm-um/ioctl.h
36872 --- orig/include/asm-um/ioctl.h 1969-12-31 19:00:00.000000000 -0500
36873 +++ um/include/asm-um/ioctl.h   2002-10-23 21:08:05.000000000 -0400
36874 @@ -0,0 +1,6 @@
36875 +#ifndef __UM_IOCTL_H
36876 +#define __UM_IOCTL_H
36877 +
36878 +#include "asm/arch/ioctl.h"
36879 +
36880 +#endif
36881 diff -Naur -X ../exclude-files orig/include/asm-um/ioctls.h um/include/asm-um/ioctls.h
36882 --- orig/include/asm-um/ioctls.h        1969-12-31 19:00:00.000000000 -0500
36883 +++ um/include/asm-um/ioctls.h  2002-10-23 21:11:14.000000000 -0400
36884 @@ -0,0 +1,6 @@
36885 +#ifndef __UM_IOCTLS_H
36886 +#define __UM_IOCTLS_H
36887 +
36888 +#include "asm/arch/ioctls.h"
36889 +
36890 +#endif
36891 diff -Naur -X ../exclude-files orig/include/asm-um/io.h um/include/asm-um/io.h
36892 --- orig/include/asm-um/io.h    1969-12-31 19:00:00.000000000 -0500
36893 +++ um/include/asm-um/io.h      2002-10-27 16:53:42.000000000 -0500
36894 @@ -0,0 +1,25 @@
36895 +#ifndef __UM_IO_H
36896 +#define __UM_IO_H
36897 +
36898 +#include "asm/page.h"
36899 +
36900 +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
36901 +
36902 +static inline int inb(unsigned long i) { return(0); }
36903 +static inline void outb(char c, unsigned long i) { }
36904 +
36905 +/*
36906 + * Change virtual addresses to physical addresses and vv.
36907 + * These are pretty trivial
36908 + */
36909 +static inline unsigned long virt_to_phys(volatile void * address)
36910 +{
36911 +       return __pa((void *) address);
36912 +}
36913 +
36914 +static inline void * phys_to_virt(unsigned long address)
36915 +{
36916 +       return __va(address);
36917 +}
36918 +
36919 +#endif
36920 diff -Naur -X ../exclude-files orig/include/asm-um/ipcbuf.h um/include/asm-um/ipcbuf.h
36921 --- orig/include/asm-um/ipcbuf.h        1969-12-31 19:00:00.000000000 -0500
36922 +++ um/include/asm-um/ipcbuf.h  2002-10-23 21:08:05.000000000 -0400
36923 @@ -0,0 +1,6 @@
36924 +#ifndef __UM_IPCBUF_H
36925 +#define __UM_IPCBUF_H
36926 +
36927 +#include "asm/arch/ipcbuf.h"
36928 +
36929 +#endif
36930 diff -Naur -X ../exclude-files orig/include/asm-um/ipc.h um/include/asm-um/ipc.h
36931 --- orig/include/asm-um/ipc.h   1969-12-31 19:00:00.000000000 -0500
36932 +++ um/include/asm-um/ipc.h     2002-10-23 21:08:05.000000000 -0400
36933 @@ -0,0 +1,6 @@
36934 +#ifndef __UM_IPC_H
36935 +#define __UM_IPC_H
36936 +
36937 +#include "asm/arch/ipc.h"
36938 +
36939 +#endif
36940 diff -Naur -X ../exclude-files orig/include/asm-um/irq.h um/include/asm-um/irq.h
36941 --- orig/include/asm-um/irq.h   1969-12-31 19:00:00.000000000 -0500
36942 +++ um/include/asm-um/irq.h     2003-05-03 11:03:52.000000000 -0400
36943 @@ -0,0 +1,22 @@
36944 +#ifndef __UM_IRQ_H
36945 +#define __UM_IRQ_H
36946 +
36947 +#define TIMER_IRQ              0
36948 +#define UMN_IRQ                        1
36949 +#define CONSOLE_IRQ            2
36950 +#define CONSOLE_WRITE_IRQ      3
36951 +#define UBD_IRQ                        4
36952 +#define UM_ETH_IRQ             5
36953 +#define SSL_IRQ                        6
36954 +#define SSL_WRITE_IRQ          7
36955 +#define ACCEPT_IRQ             8
36956 +#define MCONSOLE_IRQ           9
36957 +#define WINCH_IRQ              10
36958 +#define SIGIO_WRITE_IRQ        11
36959 +#define TELNETD_IRQ            12
36960 +#define XTERM_IRQ              13
36961 +
36962 +#define LAST_IRQ XTERM_IRQ
36963 +#define NR_IRQS (LAST_IRQ + 1)
36964 +
36965 +#endif
36966 diff -Naur -X ../exclude-files orig/include/asm-um/keyboard.h um/include/asm-um/keyboard.h
36967 --- orig/include/asm-um/keyboard.h      1969-12-31 19:00:00.000000000 -0500
36968 +++ um/include/asm-um/keyboard.h        2002-10-23 21:08:05.000000000 -0400
36969 @@ -0,0 +1,6 @@
36970 +#ifndef __UM_KEYBOARD_H
36971 +#define __UM_KEYBOARD_H
36972 +
36973 +#include "asm/arch/keyboard.h"
36974 +
36975 +#endif
36976 diff -Naur -X ../exclude-files orig/include/asm-um/kmap_types.h um/include/asm-um/kmap_types.h
36977 --- orig/include/asm-um/kmap_types.h    1969-12-31 19:00:00.000000000 -0500
36978 +++ um/include/asm-um/kmap_types.h      2003-02-27 13:20:14.000000000 -0500
36979 @@ -0,0 +1,11 @@
36980 +/* 
36981 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36982 + * Licensed under the GPL
36983 + */
36984 +
36985 +#ifndef __UM_KMAP_TYPES_H
36986 +#define __UM_KMAP_TYPES_H
36987 +
36988 +#include "asm/arch/kmap_types.h"
36989 +
36990 +#endif
36991 diff -Naur -X ../exclude-files orig/include/asm-um/linux_logo.h um/include/asm-um/linux_logo.h
36992 --- orig/include/asm-um/linux_logo.h    1969-12-31 19:00:00.000000000 -0500
36993 +++ um/include/asm-um/linux_logo.h      2002-10-23 21:08:05.000000000 -0400
36994 @@ -0,0 +1,6 @@
36995 +#ifndef __UM_LINUX_LOGO_H
36996 +#define __UM_LINUX_LOGO_H
36997 +
36998 +#include "asm/arch/linux_logo.h"
36999 +
37000 +#endif
37001 diff -Naur -X ../exclude-files orig/include/asm-um/locks.h um/include/asm-um/locks.h
37002 --- orig/include/asm-um/locks.h 1969-12-31 19:00:00.000000000 -0500
37003 +++ um/include/asm-um/locks.h   2002-10-23 21:08:05.000000000 -0400
37004 @@ -0,0 +1,6 @@
37005 +#ifndef __UM_LOCKS_H
37006 +#define __UM_LOCKS_H
37007 +
37008 +#include "asm/arch/locks.h"
37009 +
37010 +#endif
37011 diff -Naur -X ../exclude-files orig/include/asm-um/mca_dma.h um/include/asm-um/mca_dma.h
37012 --- orig/include/asm-um/mca_dma.h       1969-12-31 19:00:00.000000000 -0500
37013 +++ um/include/asm-um/mca_dma.h 2002-10-23 21:08:05.000000000 -0400
37014 @@ -0,0 +1,6 @@
37015 +#ifndef mca___UM_DMA_H
37016 +#define mca___UM_DMA_H
37017 +
37018 +#include "asm/arch/mca_dma.h"
37019 +
37020 +#endif
37021 diff -Naur -X ../exclude-files orig/include/asm-um/mman.h um/include/asm-um/mman.h
37022 --- orig/include/asm-um/mman.h  1969-12-31 19:00:00.000000000 -0500
37023 +++ um/include/asm-um/mman.h    2002-10-23 21:08:05.000000000 -0400
37024 @@ -0,0 +1,6 @@
37025 +#ifndef __UM_MMAN_H
37026 +#define __UM_MMAN_H
37027 +
37028 +#include "asm/arch/mman.h"
37029 +
37030 +#endif
37031 diff -Naur -X ../exclude-files orig/include/asm-um/mmu_context.h um/include/asm-um/mmu_context.h
37032 --- orig/include/asm-um/mmu_context.h   1969-12-31 19:00:00.000000000 -0500
37033 +++ um/include/asm-um/mmu_context.h     2003-05-28 11:02:07.000000000 -0400
37034 @@ -0,0 +1,72 @@
37035 +/* 
37036 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37037 + * Licensed under the GPL
37038 + */
37039 +
37040 +#ifndef __UM_MMU_CONTEXT_H
37041 +#define __UM_MMU_CONTEXT_H
37042 +
37043 +#include "linux/sched.h"
37044 +#include "choose-mode.h"
37045 +
37046 +#define get_mmu_context(task) do ; while(0)
37047 +#define activate_context(tsk) do ; while(0)
37048 +
37049 +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
37050 +{
37051 +}
37052 +
37053 +extern void switch_mm_skas(int mm_fd);
37054 +
37055 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
37056 +                            struct task_struct *tsk, unsigned cpu)
37057 +{
37058 +       if(prev != next){
37059 +               clear_bit(cpu, &prev->cpu_vm_mask);
37060 +               set_bit(cpu, &next->cpu_vm_mask);
37061 +               if(next != &init_mm)
37062 +                       CHOOSE_MODE((void) 0, 
37063 +                                   switch_mm_skas(next->context.skas.mm_fd));
37064 +       }
37065 +}
37066 +
37067 +static inline void enter_lazy_tlb(struct mm_struct *mm, 
37068 +                                 struct task_struct *tsk, unsigned cpu)
37069 +{
37070 +}
37071 +
37072 +extern int init_new_context_skas(struct task_struct *task, 
37073 +                                struct mm_struct *mm);
37074 +
37075 +static inline int init_new_context_tt(struct task_struct *task, 
37076 +                                     struct mm_struct *mm)
37077 +{
37078 +       return(0);
37079 +}
37080 +
37081 +static inline int init_new_context(struct task_struct *task, 
37082 +                                  struct mm_struct *mm)
37083 +{
37084 +       return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas, 
37085 +                               task, mm));
37086 +}
37087 +
37088 +extern void destroy_context_skas(struct mm_struct *mm);
37089 +
37090 +static inline void destroy_context(struct mm_struct *mm)
37091 +{
37092 +       CHOOSE_MODE((void) 0, destroy_context_skas(mm));
37093 +}
37094 +
37095 +#endif
37096 +
37097 +/*
37098 + * Overrides for Emacs so that we follow Linus's tabbing style.
37099 + * Emacs will notice this stuff at the end of the file and automatically
37100 + * adjust the settings for this buffer only.  This must remain at the end
37101 + * of the file.
37102 + * ---------------------------------------------------------------------------
37103 + * Local variables:
37104 + * c-file-style: "linux"
37105 + * End:
37106 + */
37107 diff -Naur -X ../exclude-files orig/include/asm-um/mmu.h um/include/asm-um/mmu.h
37108 --- orig/include/asm-um/mmu.h   1969-12-31 19:00:00.000000000 -0500
37109 +++ um/include/asm-um/mmu.h     2002-11-09 12:51:11.000000000 -0500
37110 @@ -0,0 +1,22 @@
37111 +/* 
37112 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
37113 + * Licensed under the GPL
37114 + */
37115 +
37116 +#ifndef __MMU_H
37117 +#define __MMU_H
37118 +
37119 +#include "um_mmu.h"
37120 +
37121 +#endif
37122 +
37123 +/*
37124 + * Overrides for Emacs so that we follow Linus's tabbing style.
37125 + * Emacs will notice this stuff at the end of the file and automatically
37126 + * adjust the settings for this buffer only.  This must remain at the end
37127 + * of the file.
37128 + * ---------------------------------------------------------------------------
37129 + * Local variables:
37130 + * c-file-style: "linux"
37131 + * End:
37132 + */
37133 diff -Naur -X ../exclude-files orig/include/asm-um/module.h um/include/asm-um/module.h
37134 --- orig/include/asm-um/module.h        1969-12-31 19:00:00.000000000 -0500
37135 +++ um/include/asm-um/module.h  2002-10-23 21:08:05.000000000 -0400
37136 @@ -0,0 +1,6 @@
37137 +#ifndef __UM_MODULE_H
37138 +#define __UM_MODULE_H
37139 +
37140 +#include "asm/arch/module.h"
37141 +
37142 +#endif
37143 diff -Naur -X ../exclude-files orig/include/asm-um/msgbuf.h um/include/asm-um/msgbuf.h
37144 --- orig/include/asm-um/msgbuf.h        1969-12-31 19:00:00.000000000 -0500
37145 +++ um/include/asm-um/msgbuf.h  2002-10-23 21:08:05.000000000 -0400
37146 @@ -0,0 +1,6 @@
37147 +#ifndef __UM_MSGBUF_H
37148 +#define __UM_MSGBUF_H
37149 +
37150 +#include "asm/arch/msgbuf.h"
37151 +
37152 +#endif
37153 diff -Naur -X ../exclude-files orig/include/asm-um/mtrr.h um/include/asm-um/mtrr.h
37154 --- orig/include/asm-um/mtrr.h  1969-12-31 19:00:00.000000000 -0500
37155 +++ um/include/asm-um/mtrr.h    2003-05-29 13:46:27.000000000 -0400
37156 @@ -0,0 +1,6 @@
37157 +#ifndef __UM_MTRR_H
37158 +#define __UM_MTRR_H
37159 +
37160 +#include "asm/arch/mtrr.h"
37161 +
37162 +#endif
37163 diff -Naur -X ../exclude-files orig/include/asm-um/namei.h um/include/asm-um/namei.h
37164 --- orig/include/asm-um/namei.h 1969-12-31 19:00:00.000000000 -0500
37165 +++ um/include/asm-um/namei.h   2002-10-23 21:08:05.000000000 -0400
37166 @@ -0,0 +1,6 @@
37167 +#ifndef __UM_NAMEI_H
37168 +#define __UM_NAMEI_H
37169 +
37170 +#include "asm/arch/namei.h"
37171 +
37172 +#endif
37173 diff -Naur -X ../exclude-files orig/include/asm-um/page.h um/include/asm-um/page.h
37174 --- orig/include/asm-um/page.h  1969-12-31 19:00:00.000000000 -0500
37175 +++ um/include/asm-um/page.h    2002-10-27 16:49:35.000000000 -0500
37176 @@ -0,0 +1,53 @@
37177 +#ifndef __UM_PAGE_H
37178 +#define __UM_PAGE_H
37179 +
37180 +struct page;
37181 +
37182 +#include "asm/arch/page.h"
37183 +
37184 +#undef BUG
37185 +#undef PAGE_BUG
37186 +#undef __pa
37187 +#undef __va
37188 +#undef virt_to_page
37189 +#undef VALID_PAGE
37190 +#undef PAGE_OFFSET
37191 +#undef KERNELBASE
37192 +
37193 +extern unsigned long uml_physmem;
37194 +
37195 +#define PAGE_OFFSET (uml_physmem)
37196 +#define KERNELBASE PAGE_OFFSET
37197 +
37198 +#ifndef __ASSEMBLY__
37199 +
37200 +extern void stop(void);
37201 +
37202 +#define BUG() do { \
37203 +       panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
37204 +} while (0)
37205 +
37206 +#define PAGE_BUG(page) do { \
37207 +       BUG(); \
37208 +} while (0)
37209 +
37210 +#endif /* __ASSEMBLY__ */
37211 +
37212 +#define __va_space (8*1024*1024)
37213 +
37214 +extern unsigned long region_pa(void *virt);
37215 +extern void *region_va(unsigned long phys);
37216 +
37217 +#define __pa(virt) region_pa((void *) (virt))
37218 +#define __va(phys) region_va((unsigned long) (phys))
37219 +
37220 +extern struct page *page_mem_map(struct page *page);
37221 +
37222 +extern struct page *pfn_to_page(unsigned long pfn);
37223 +
37224 +#define VALID_PAGE(page) (page_mem_map(page) != NULL)
37225 +
37226 +extern struct page *arch_validate(struct page *page, int mask, int order);
37227 +#define HAVE_ARCH_VALIDATE
37228 +
37229 +#endif
37230 diff -Naur -X ../exclude-files orig/include/asm-um/page_offset.h um/include/asm-um/page_offset.h
37231 --- orig/include/asm-um/page_offset.h   1969-12-31 19:00:00.000000000 -0500
37232 +++ um/include/asm-um/page_offset.h     2002-10-23 21:08:05.000000000 -0400
37233 @@ -0,0 +1 @@
37234 +#define PAGE_OFFSET_RAW (uml_physmem)
37235 diff -Naur -X ../exclude-files orig/include/asm-um/param.h um/include/asm-um/param.h
37236 --- orig/include/asm-um/param.h 1969-12-31 19:00:00.000000000 -0500
37237 +++ um/include/asm-um/param.h   2002-10-23 21:08:05.000000000 -0400
37238 @@ -0,0 +1,24 @@
37239 +#ifndef _UM_PARAM_H
37240 +#define _UM_PARAM_H
37241 +
37242 +#ifndef HZ
37243 +#define HZ 52
37244 +#endif
37245 +
37246 +#define EXEC_PAGESIZE   4096
37247 +
37248 +#ifndef NGROUPS
37249 +#define NGROUPS         32
37250 +#endif
37251 +
37252 +#ifndef NOGROUP
37253 +#define NOGROUP         (-1)
37254 +#endif
37255 +
37256 +#define MAXHOSTNAMELEN  64      /* max length of hostname */
37257 +
37258 +#ifdef __KERNEL__
37259 +# define CLOCKS_PER_SEC 100    /* frequency at which times() counts */
37260 +#endif
37261 +
37262 +#endif
37263 diff -Naur -X ../exclude-files orig/include/asm-um/pci.h um/include/asm-um/pci.h
37264 --- orig/include/asm-um/pci.h   1969-12-31 19:00:00.000000000 -0500
37265 +++ um/include/asm-um/pci.h     2002-10-23 21:08:05.000000000 -0400
37266 @@ -0,0 +1,6 @@
37267 +#ifndef __UM_PCI_H
37268 +#define __UM_PCI_H
37269 +
37270 +#define PCI_DMA_BUS_IS_PHYS     (1)
37271 +
37272 +#endif
37273 diff -Naur -X ../exclude-files orig/include/asm-um/pgalloc.h um/include/asm-um/pgalloc.h
37274 --- orig/include/asm-um/pgalloc.h       1969-12-31 19:00:00.000000000 -0500
37275 +++ um/include/asm-um/pgalloc.h 2003-05-28 11:02:08.000000000 -0400
37276 @@ -0,0 +1,162 @@
37277 +/* 
37278 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37279 + * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
37280 + * Licensed under the GPL
37281 + */
37282 +
37283 +#ifndef __UM_PGALLOC_H
37284 +#define __UM_PGALLOC_H
37285 +
37286 +#include "linux/config.h"
37287 +#include "linux/mm.h"
37288 +#include "asm/fixmap.h"
37289 +#include "choose-mode.h"
37290 +
37291 +#define pgd_quicklist (current_cpu_data.pgd_quick)
37292 +#define pmd_quicklist (current_cpu_data.pmd_quick)
37293 +#define pte_quicklist (current_cpu_data.pte_quick)
37294 +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
37295 +
37296 +#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
37297 +
37298 +/*
37299 + * Allocate and free page tables.
37300 + */
37301 +
37302 +static inline pgd_t *get_pgd_slow_tt(void)
37303 +{
37304 +       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
37305 +
37306 +       if (pgd) {
37307 +               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
37308 +               memcpy(pgd + USER_PTRS_PER_PGD, 
37309 +                      swapper_pg_dir + USER_PTRS_PER_PGD, 
37310 +                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
37311 +       }
37312 +       return pgd;
37313 +}
37314 +
37315 +static inline pgd_t *get_pgd_slow_skas(void)
37316 +{
37317 +       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
37318 +
37319 +       if (pgd)
37320 +               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
37321 +       return pgd;
37322 +}
37323 +
37324 +static inline pgd_t *get_pgd_slow(void)
37325 +{
37326 +       return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas()));
37327 +}
37328 +
37329 +static inline pgd_t *get_pgd_fast(void)
37330 +{
37331 +       unsigned long *ret;
37332 +
37333 +       if ((ret = pgd_quicklist) != NULL) {
37334 +               pgd_quicklist = (unsigned long *)(*ret);
37335 +               ret[0] = 0;
37336 +               pgtable_cache_size--;
37337 +       } else
37338 +               ret = (unsigned long *)get_pgd_slow();
37339 +       return (pgd_t *)ret;
37340 +}
37341 +
37342 +static inline void free_pgd_fast(pgd_t *pgd)
37343 +{
37344 +       *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
37345 +       pgd_quicklist = (unsigned long *) pgd;
37346 +       pgtable_cache_size++;
37347 +}
37348 +
37349 +static inline void free_pgd_slow(pgd_t *pgd)
37350 +{
37351 +       free_page((unsigned long)pgd);
37352 +}
37353 +
37354 +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
37355 +{
37356 +       pte_t *pte;
37357 +
37358 +       pte = (pte_t *) __get_free_page(GFP_KERNEL);
37359 +       if (pte)
37360 +               clear_page(pte);
37361 +       return pte;
37362 +}
37363 +
37364 +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
37365 +{
37366 +       unsigned long *ret;
37367 +
37368 +       if ((ret = (unsigned long *)pte_quicklist) != NULL) {
37369 +               pte_quicklist = (unsigned long *)(*ret);
37370 +               ret[0] = ret[1];
37371 +               pgtable_cache_size--;
37372 +       }
37373 +       return (pte_t *)ret;
37374 +}
37375 +
37376 +static inline void pte_free_fast(pte_t *pte)
37377 +{
37378 +       *(unsigned long *)pte = (unsigned long) pte_quicklist;
37379 +       pte_quicklist = (unsigned long *) pte;
37380 +       pgtable_cache_size++;
37381 +}
37382 +
37383 +static inline void pte_free_slow(pte_t *pte)
37384 +{
37385 +       free_page((unsigned long)pte);
37386 +}
37387 +
37388 +#define pte_free(pte)           pte_free_fast(pte)
37389 +#define pgd_free(pgd)           free_pgd_slow(pgd)
37390 +#define pgd_alloc(mm)           get_pgd_fast()
37391 +
37392 +/*
37393 + * allocating and freeing a pmd is trivial: the 1-entry pmd is
37394 + * inside the pgd, so has no extra memory associated with it.
37395 + */
37396 +
37397 +#define pmd_alloc_one_fast(mm, addr)   ({ BUG(); ((pmd_t *)1); })
37398 +#define pmd_alloc_one(mm, addr)                ({ BUG(); ((pmd_t *)2); })
37399 +#define pmd_free_slow(x)               do { } while (0)
37400 +#define pmd_free_fast(x)               do { } while (0)
37401 +#define pmd_free(x)                    do { } while (0)
37402 +#define pgd_populate(mm, pmd, pte)     BUG()
37403 +
37404 +/*
37405 + * TLB flushing:
37406 + *
37407 + *  - flush_tlb() flushes the current mm struct TLBs
37408 + *  - flush_tlb_all() flushes all processes TLBs
37409 + *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
37410 + *  - flush_tlb_page(vma, vmaddr) flushes one page
37411 + *  - flush_tlb_kernel_vm() flushes the kernel vm area
37412 + *  - flush_tlb_range(mm, start, end) flushes a range of pages
37413 + *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
37414 + */
37415 +
37416 +extern void flush_tlb_all(void);
37417 +extern void flush_tlb_mm(struct mm_struct *mm);
37418 +extern void flush_tlb_range(struct mm_struct *mm, unsigned long start, 
37419 +                           unsigned long end);
37420 +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
37421 +extern void flush_tlb_kernel_vm(void);
37422 +
37423 +static inline void flush_tlb_pgtables(struct mm_struct *mm,
37424 +                                     unsigned long start, unsigned long end)
37425 +{
37426 +}
37427 +
37428 +#endif
37429 +/*
37430 + * Overrides for Emacs so that we follow Linus's tabbing style.
37431 + * Emacs will notice this stuff at the end of the file and automatically
37432 + * adjust the settings for this buffer only.  This must remain at the end
37433 + * of the file.
37434 + * ---------------------------------------------------------------------------
37435 + * Local variables:
37436 + * c-file-style: "linux"
37437 + * End:
37438 + */
37439 diff -Naur -X ../exclude-files orig/include/asm-um/pgtable.h um/include/asm-um/pgtable.h
37440 --- orig/include/asm-um/pgtable.h       1969-12-31 19:00:00.000000000 -0500
37441 +++ um/include/asm-um/pgtable.h 2003-05-28 11:02:07.000000000 -0400
37442 @@ -0,0 +1,428 @@
37443 +/* 
37444 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37445 + * Derived from include/asm-i386/pgtable.h
37446 + * Licensed under the GPL
37447 + */
37448 +
37449 +#ifndef __UM_PGTABLE_H
37450 +#define __UM_PGTABLE_H
37451 +
37452 +#include "linux/sched.h"
37453 +#include "asm/processor.h"
37454 +#include "asm/page.h"
37455 +
37456 +extern pgd_t swapper_pg_dir[1024];
37457 +
37458 +#define flush_cache_all() do ; while (0)
37459 +#define flush_cache_mm(mm) do ; while (0)
37460 +#define flush_cache_range(vma, start, end) do ; while (0)
37461 +#define flush_cache_page(vma, vmaddr) do ; while (0)
37462 +#define flush_page_to_ram(page) do ; while (0)
37463 +#define flush_dcache_page(page)        do ; while (0)
37464 +#define flush_icache_range(from, to) do ; while (0)
37465 +#define flush_icache_page(vma,pg) do ; while (0)
37466 +#define flush_icache_user_range(vma,pg,adr,len)        do ; while (0)
37467 +
37468 +extern void __flush_tlb_one(unsigned long addr);
37469 +
37470 +extern void pte_free(pte_t *pte);
37471 +
37472 +extern void pgd_free(pgd_t *pgd);
37473 +
37474 +extern int do_check_pgt_cache(int, int);
37475 +
37476 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
37477 +                            pte_t *pte_out);
37478 +
37479 +/* zero page used for uninitialized stuff */
37480 +extern unsigned long *empty_zero_page;
37481 +
37482 +#define pgtable_cache_init() do ; while (0)
37483 +
37484 +/* PMD_SHIFT determines the size of the area a second-level page table can map */
37485 +#define PMD_SHIFT      22
37486 +#define PMD_SIZE       (1UL << PMD_SHIFT)
37487 +#define PMD_MASK       (~(PMD_SIZE-1))
37488 +
37489 +/* PGDIR_SHIFT determines what a third-level page table entry can map */
37490 +#define PGDIR_SHIFT    22
37491 +#define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
37492 +#define PGDIR_MASK     (~(PGDIR_SIZE-1))
37493 +
37494 +/*
37495 + * entries per page directory level: the i386 is two-level, so
37496 + * we don't really have any PMD directory physically.
37497 + */
37498 +#define PTRS_PER_PTE   1024
37499 +#define PTRS_PER_PMD   1
37500 +#define PTRS_PER_PGD   1024
37501 +#define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
37502 +#define FIRST_USER_PGD_NR       0
37503 +
37504 +#define pte_ERROR(e) \
37505 +        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
37506 +#define pmd_ERROR(e) \
37507 +        printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
37508 +#define pgd_ERROR(e) \
37509 +        printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
37510 +
37511 +/*
37512 + * pgd entries used up by user/kernel:
37513 + */
37514 +
37515 +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT)
37516 +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
37517 +
37518 +#ifndef __ASSEMBLY__
37519 +/* Just any arbitrary offset to the start of the vmalloc VM area: the
37520 + * current 8MB value just means that there will be a 8MB "hole" after the
37521 + * physical memory until the kernel virtual memory starts.  That means that
37522 + * any out-of-bounds memory accesses will hopefully be caught.
37523 + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
37524 + * area for the same reason. ;)
37525 + */
37526 +
37527 +extern unsigned long high_physmem;
37528 +
37529 +#define VMALLOC_OFFSET (__va_space)
37530 +#define VMALLOC_START  (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
37531 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
37532 +
37533 +#if CONFIG_HIGHMEM
37534 +# define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
37535 +#else
37536 +# define VMALLOC_END   (FIXADDR_START-2*PAGE_SIZE)
37537 +#endif
37538 +
37539 +#define _PAGE_PRESENT  0x001
37540 +#define _PAGE_NEWPAGE  0x002
37541 +#define _PAGE_PROTNONE 0x004   /* If not present */
37542 +#define _PAGE_RW       0x008
37543 +#define _PAGE_USER     0x010
37544 +#define _PAGE_ACCESSED 0x020
37545 +#define _PAGE_DIRTY    0x040
37546 +#define _PAGE_NEWPROT   0x080
37547 +
37548 +#define REGION_MASK    0xf0000000
37549 +#define REGION_SHIFT   28
37550 +
37551 +#define _PAGE_TABLE    (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
37552 +#define _KERNPG_TABLE  (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
37553 +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
37554 +
37555 +#define PAGE_NONE      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
37556 +#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
37557 +#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
37558 +#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
37559 +#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
37560 +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
37561 +
37562 +/*
37563 + * The i386 can't do page protection for execute, and considers that the same are read.
37564 + * Also, write permissions imply read permissions. This is the closest we can get..
37565 + */
37566 +#define __P000 PAGE_NONE
37567 +#define __P001 PAGE_READONLY
37568 +#define __P010 PAGE_COPY
37569 +#define __P011 PAGE_COPY
37570 +#define __P100 PAGE_READONLY
37571 +#define __P101 PAGE_READONLY
37572 +#define __P110 PAGE_COPY
37573 +#define __P111 PAGE_COPY
37574 +
37575 +#define __S000 PAGE_NONE
37576 +#define __S001 PAGE_READONLY
37577 +#define __S010 PAGE_SHARED
37578 +#define __S011 PAGE_SHARED
37579 +#define __S100 PAGE_READONLY
37580 +#define __S101 PAGE_READONLY
37581 +#define __S110 PAGE_SHARED
37582 +#define __S111 PAGE_SHARED
37583 +
37584 +/*
37585 + * Define this if things work differently on an i386 and an i486:
37586 + * it will (on an i486) warn about kernel memory accesses that are
37587 + * done without a 'verify_area(VERIFY_WRITE,..)'
37588 + */
37589 +#undef TEST_VERIFY_AREA
37590 +
37591 +/* page table for 0-4MB for everybody */
37592 +extern unsigned long pg0[1024];
37593 +
37594 +/*
37595 + * BAD_PAGETABLE is used when we need a bogus page-table, while
37596 + * BAD_PAGE is used for a bogus page.
37597 + *
37598 + * ZERO_PAGE is a global shared page that is always zero: used
37599 + * for zero-mapped memory areas etc..
37600 + */
37601 +extern pte_t __bad_page(void);
37602 +extern pte_t * __bad_pagetable(void);
37603 +
37604 +#define BAD_PAGETABLE __bad_pagetable()
37605 +#define BAD_PAGE __bad_page()
37606 +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
37607 +
37608 +/* number of bits that fit into a memory pointer */
37609 +#define BITS_PER_PTR                   (8*sizeof(unsigned long))
37610 +
37611 +/* to align the pointer to a pointer address */
37612 +#define PTR_MASK                       (~(sizeof(void*)-1))
37613 +
37614 +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
37615 +/* 64-bit machines, beware!  SRB. */
37616 +#define SIZEOF_PTR_LOG2                        2
37617 +
37618 +/* to find an entry in a page-table */
37619 +#define PAGE_PTR(address) \
37620 +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
37621 +
37622 +#define pte_none(x)    !(pte_val(x) & ~_PAGE_NEWPAGE)
37623 +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
37624 +
37625 +#define pte_clear(xp)  do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
37626 +
37627 +#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
37628 +#define pte_region_index(x) phys_region_index(pte_val(x))
37629 +
37630 +#define pmd_none(x)    (!(pmd_val(x) & ~_PAGE_NEWPAGE))
37631 +#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
37632 +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
37633 +#define pmd_clear(xp)  do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
37634 +
37635 +#define pmd_newpage(x)  (pmd_val(x) & _PAGE_NEWPAGE)
37636 +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
37637 +
37638 +/*
37639 + * The "pgd_xxx()" functions here are trivial for a folded two-level
37640 + * setup: the pgd is never bad, and a pmd always exists (as it's folded
37641 + * into the pgd entry)
37642 + */
37643 +static inline int pgd_none(pgd_t pgd)          { return 0; }
37644 +static inline int pgd_bad(pgd_t pgd)           { return 0; }
37645 +static inline int pgd_present(pgd_t pgd)       { return 1; }
37646 +static inline void pgd_clear(pgd_t * pgdp)     { }
37647 +
37648 +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
37649 +
37650 +extern struct page *pte_mem_map(pte_t pte);
37651 +extern struct page *phys_mem_map(unsigned long phys);
37652 +extern unsigned long phys_to_pfn(unsigned long p);
37653 +
37654 +#define pte_page(x) pfn_to_page(pte_pfn(x))
37655 +#define pte_address(x) (__va(pte_val(x) & PAGE_MASK))
37656 +#define mk_phys(a, r) ((a) + (r << REGION_SHIFT))
37657 +#define phys_addr(p) ((p) & ~REGION_MASK)
37658 +#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT))
37659 +#define virt_to_page(kaddr) \
37660 +       (phys_mem_map(__pa(kaddr)) + (phys_addr(__pa(kaddr)) >> PAGE_SHIFT))
37661 +#define pte_pfn(x) phys_to_pfn(pte_val(x))
37662 +
37663 +static inline pte_t pte_mknewprot(pte_t pte)
37664 +{
37665 +       pte_val(pte) |= _PAGE_NEWPROT;
37666 +       return(pte);
37667 +}
37668 +
37669 +static inline pte_t pte_mknewpage(pte_t pte)
37670 +{
37671 +       pte_val(pte) |= _PAGE_NEWPAGE;
37672 +       return(pte);
37673 +}
37674 +
37675 +static inline void set_pte(pte_t *pteptr, pte_t pteval)
37676 +{
37677 +       /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
37678 +        * fix_range knows to unmap it.  _PAGE_NEWPROT is specific to
37679 +        * mapped pages.
37680 +        */
37681 +       *pteptr = pte_mknewpage(pteval);
37682 +       if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
37683 +}
37684 +
37685 +/*
37686 + * (pmds are folded into pgds so this doesnt get actually called,
37687 + * but the define is needed for a generic inline function.)
37688 + */
37689 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
37690 +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
37691 +
37692 +/*
37693 + * The following only work if pte_present() is true.
37694 + * Undefined behaviour if not..
37695 + */
37696 +static inline int pte_read(pte_t pte)
37697 +{ 
37698 +       return((pte_val(pte) & _PAGE_USER) && 
37699 +              !(pte_val(pte) & _PAGE_PROTNONE));
37700 +}
37701 +
37702 +static inline int pte_exec(pte_t pte){
37703 +       return((pte_val(pte) & _PAGE_USER) &&
37704 +              !(pte_val(pte) & _PAGE_PROTNONE));
37705 +}
37706 +
37707 +static inline int pte_write(pte_t pte)
37708 +{
37709 +       return((pte_val(pte) & _PAGE_RW) &&
37710 +              !(pte_val(pte) & _PAGE_PROTNONE));
37711 +}
37712 +
37713 +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
37714 +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
37715 +static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
37716 +static inline int pte_newprot(pte_t pte)
37717 +{ 
37718 +       return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT)); 
37719 +}
37720 +
37721 +static inline pte_t pte_rdprotect(pte_t pte)
37722 +{ 
37723 +       pte_val(pte) &= ~_PAGE_USER; 
37724 +       return(pte_mknewprot(pte));
37725 +}
37726 +
37727 +static inline pte_t pte_exprotect(pte_t pte)
37728 +{ 
37729 +       pte_val(pte) &= ~_PAGE_USER;
37730 +       return(pte_mknewprot(pte));
37731 +}
37732 +
37733 +static inline pte_t pte_mkclean(pte_t pte)
37734 +{
37735 +       pte_val(pte) &= ~_PAGE_DIRTY; 
37736 +       return(pte);
37737 +}
37738 +
37739 +static inline pte_t pte_mkold(pte_t pte)       
37740 +{ 
37741 +       pte_val(pte) &= ~_PAGE_ACCESSED; 
37742 +       return(pte);
37743 +}
37744 +
37745 +static inline pte_t pte_wrprotect(pte_t pte)
37746 +{ 
37747 +       pte_val(pte) &= ~_PAGE_RW; 
37748 +       return(pte_mknewprot(pte)); 
37749 +}
37750 +
37751 +static inline pte_t pte_mkread(pte_t pte)
37752 +{ 
37753 +       pte_val(pte) |= _PAGE_USER; 
37754 +       return(pte_mknewprot(pte)); 
37755 +}
37756 +
37757 +static inline pte_t pte_mkexec(pte_t pte)
37758 +{ 
37759 +       pte_val(pte) |= _PAGE_USER; 
37760 +       return(pte_mknewprot(pte)); 
37761 +}
37762 +
37763 +static inline pte_t pte_mkdirty(pte_t pte)
37764 +{ 
37765 +       pte_val(pte) |= _PAGE_DIRTY; 
37766 +       return(pte);
37767 +}
37768 +
37769 +static inline pte_t pte_mkyoung(pte_t pte)
37770 +{
37771 +       pte_val(pte) |= _PAGE_ACCESSED; 
37772 +       return(pte);
37773 +}
37774 +
37775 +static inline pte_t pte_mkwrite(pte_t pte)     
37776 +{
37777 +       pte_val(pte) |= _PAGE_RW; 
37778 +       return(pte_mknewprot(pte)); 
37779 +}
37780 +
37781 +static inline pte_t pte_mkuptodate(pte_t pte)  
37782 +{
37783 +       pte_val(pte) &= ~_PAGE_NEWPAGE;
37784 +       if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
37785 +       return(pte); 
37786 +}
37787 +
37788 +extern unsigned long page_to_phys(struct page *page);
37789 +
37790 +/*
37791 + * Conversion functions: convert a page and protection to a page entry,
37792 + * and a page entry and page directory to the page they refer to.
37793 + */
37794 +
37795 +#define mk_pte(page, pgprot) \
37796 +({                                     \
37797 +       pte_t __pte;                    \
37798 +                                        \
37799 +       pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
37800 +       if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
37801 +       __pte;                          \
37802 +})
37803 +
37804 +/* This takes a physical page address that is used by the remapping functions */
37805 +#define mk_pte_phys(physpage, pgprot) \
37806 +       pte_mknewpage(mk_pte(phys_page(physpage), pgprot))
37807 +
37808 +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
37809 +{
37810 +       pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
37811 +       if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
37812 +       return pte; 
37813 +}
37814 +
37815 +#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
37816 +
37817 +/* to find an entry in a page-table-directory. */
37818 +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
37819 +#define __pgd_offset(address) pgd_index(address)
37820 +
37821 +/* to find an entry in a page-table-directory */
37822 +#define pgd_offset(mm, address) \
37823 +((mm)->pgd + ((address) >> PGDIR_SHIFT))
37824 +
37825 +/* to find an entry in a kernel page-table-directory */
37826 +#define pgd_offset_k(address) pgd_offset(&init_mm, address)
37827 +
37828 +#define __pmd_offset(address) \
37829 +               (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
37830 +
37831 +/* Find an entry in the second-level page table.. */
37832 +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
37833 +{
37834 +       return (pmd_t *) dir;
37835 +}
37836 +
37837 +/* Find an entry in the third-level page table.. */ 
37838 +#define pte_offset(pmd, address) \
37839 +((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2))))
37840 +
37841 +#define update_mmu_cache(vma,address,pte) do ; while (0)
37842 +
37843 +/* Encode and de-code a swap entry */
37844 +#define SWP_TYPE(x)                    (((x).val >> 3) & 0x7f)
37845 +#define SWP_OFFSET(x)                  ((x).val >> 10)
37846 +
37847 +#define SWP_ENTRY(type, offset) \
37848 +       ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
37849 +#define pte_to_swp_entry(pte) \
37850 +       ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
37851 +#define swp_entry_to_pte(x)            ((pte_t) { (x).val })
37852 +
37853 +#define PageSkip(x) (0)
37854 +#define kern_addr_valid(addr) (1)
37855 +
37856 +#include <asm-generic/pgtable.h>
37857 +
37858 +#endif
37859 +
37860 +#endif
37861 +/*
37862 + * Overrides for Emacs so that we follow Linus's tabbing style.
37863 + * Emacs will notice this stuff at the end of the file and automatically
37864 + * adjust the settings for this buffer only.  This must remain at the end
37865 + * of the file.
37866 + * ---------------------------------------------------------------------------
37867 + * Local variables:
37868 + * c-file-style: "linux"
37869 + * End:
37870 + */
37871 diff -Naur -X ../exclude-files orig/include/asm-um/poll.h um/include/asm-um/poll.h
37872 --- orig/include/asm-um/poll.h  1969-12-31 19:00:00.000000000 -0500
37873 +++ um/include/asm-um/poll.h    2002-10-23 21:08:05.000000000 -0400
37874 @@ -0,0 +1,6 @@
37875 +#ifndef __UM_POLL_H
37876 +#define __UM_POLL_H
37877 +
37878 +#include "asm/arch/poll.h"
37879 +
37880 +#endif
37881 diff -Naur -X ../exclude-files orig/include/asm-um/posix_types.h um/include/asm-um/posix_types.h
37882 --- orig/include/asm-um/posix_types.h   1969-12-31 19:00:00.000000000 -0500
37883 +++ um/include/asm-um/posix_types.h     2002-10-23 21:08:05.000000000 -0400
37884 @@ -0,0 +1,6 @@
37885 +#ifndef __UM_POSIX_TYPES_H
37886 +#define __UM_POSIX_TYPES_H
37887 +
37888 +#include "asm/arch/posix_types.h"
37889 +
37890 +#endif
37891 diff -Naur -X ../exclude-files orig/include/asm-um/processor-generic.h um/include/asm-um/processor-generic.h
37892 --- orig/include/asm-um/processor-generic.h     1969-12-31 19:00:00.000000000 -0500
37893 +++ um/include/asm-um/processor-generic.h       2003-05-28 11:02:07.000000000 -0400
37894 @@ -0,0 +1,182 @@
37895 +/* 
37896 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
37897 + * Licensed under the GPL
37898 + */
37899 +
37900 +#ifndef __UM_PROCESSOR_GENERIC_H
37901 +#define __UM_PROCESSOR_GENERIC_H
37902 +
37903 +struct pt_regs;
37904 +
37905 +struct task_struct;
37906 +
37907 +#include "linux/config.h"
37908 +#include "linux/signal.h"
37909 +#include "asm/ptrace.h"
37910 +#include "asm/siginfo.h"
37911 +#include "choose-mode.h"
37912 +
37913 +struct mm_struct;
37914 +
37915 +#define current_text_addr() ((void *) 0)
37916 +
37917 +#define cpu_relax()    do ; while (0)
37918 +
37919 +#ifdef CONFIG_MODE_TT
37920 +struct proc_tt_mode {
37921 +       int extern_pid;
37922 +       int tracing;
37923 +       int switch_pipe[2];
37924 +       int singlestep_syscall;
37925 +       int vm_seq;
37926 +};
37927 +#endif
37928 +
37929 +#ifdef CONFIG_MODE_SKAS
37930 +struct proc_skas_mode {
37931 +       void *switch_buf;
37932 +       void *fork_buf;
37933 +};
37934 +#endif
37935 +
37936 +struct thread_struct {
37937 +       int forking;
37938 +       unsigned long kernel_stack;
37939 +       int nsyscalls;
37940 +       struct pt_regs regs;
37941 +       unsigned long cr2;
37942 +       int err;
37943 +       void *fault_addr;
37944 +       void *fault_catcher;
37945 +       struct task_struct *prev_sched;
37946 +       unsigned long temp_stack;
37947 +       void *exec_buf;
37948 +       struct arch_thread arch;
37949 +       union {
37950 +#ifdef CONFIG_MODE_TT
37951 +               struct proc_tt_mode tt;
37952 +#endif
37953 +#ifdef CONFIG_MODE_SKAS
37954 +               struct proc_skas_mode skas;
37955 +#endif
37956 +       } mode;
37957 +       struct {
37958 +               int op;
37959 +               union {
37960 +                       struct {
37961 +                               int pid;
37962 +                       } fork, exec;
37963 +                       struct {
37964 +                               int (*proc)(void *);
37965 +                               void *arg;
37966 +                       } thread;
37967 +                       struct {
37968 +                               void (*proc)(void *);
37969 +                               void *arg;
37970 +                       } cb;
37971 +               } u;
37972 +       } request;
37973 +};
37974 +
37975 +#define INIT_THREAD \
37976 +{ \
37977 +       .forking                = 0, \
37978 +       .kernel_stack           = 0, \
37979 +       .nsyscalls              = 0, \
37980 +        .regs                  = EMPTY_REGS, \
37981 +       .cr2                    = 0, \
37982 +       .err                    = 0, \
37983 +       .fault_addr             = NULL, \
37984 +       .prev_sched             = NULL, \
37985 +       .temp_stack             = 0, \
37986 +       .exec_buf               = NULL, \
37987 +       .arch                   = INIT_ARCH_THREAD, \
37988 +       .request                = { 0 } \
37989 +}
37990 +
37991 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
37992 +
37993 +typedef struct {
37994 +       unsigned long seg;
37995 +} mm_segment_t;
37996 +
37997 +extern struct task_struct *alloc_task_struct(void);
37998 +extern void free_task_struct(struct task_struct *task);
37999 +
38000 +#define get_task_struct(tsk)      atomic_inc(&virt_to_page(tsk)->count)
38001 +
38002 +extern void release_thread(struct task_struct *);
38003 +extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
38004 +extern void dump_thread(struct pt_regs *regs, struct user *u);
38005 +
38006 +extern unsigned long thread_saved_pc(struct thread_struct *t);
38007 +
38008 +static inline void mm_copy_segments(struct mm_struct *from_mm, 
38009 +                                   struct mm_struct *new_mm)
38010 +{
38011 +}
38012 +
38013 +static inline void copy_segments(struct task_struct *p, 
38014 +                                struct mm_struct *new_mm)
38015 +{
38016 +}
38017 +
38018 +static inline void release_segments(struct mm_struct *mm)
38019 +{
38020 +}
38021 +
38022 +#define init_task      (init_task_union.task)
38023 +#define init_stack     (init_task_union.stack)
38024 +
38025 +/*
38026 + * User space process size: 3GB (default).
38027 + */
38028 +extern unsigned long task_size;
38029 +
38030 +#define TASK_SIZE      (task_size)
38031 +
38032 +/* This decides where the kernel will search for a free chunk of vm
38033 + * space during mmap's.
38034 + */
38035 +#define TASK_UNMAPPED_BASE     (0x40000000)
38036 +
38037 +extern void start_thread(struct pt_regs *regs, unsigned long entry, 
38038 +                        unsigned long stack);
38039 +
38040 +struct cpuinfo_um {
38041 +       unsigned long loops_per_jiffy;
38042 +       unsigned long *pgd_quick;
38043 +       unsigned long *pmd_quick;
38044 +       unsigned long *pte_quick;
38045 +       unsigned long pgtable_cache_sz;  
38046 +       int ipi_pipe[2];
38047 +};
38048 +
38049 +extern struct cpuinfo_um boot_cpu_data;
38050 +
38051 +#define my_cpu_data            cpu_data[smp_processor_id()]
38052 +
38053 +#ifdef CONFIG_SMP
38054 +extern struct cpuinfo_um cpu_data[];
38055 +#define current_cpu_data cpu_data[smp_processor_id()]
38056 +#else
38057 +#define cpu_data (&boot_cpu_data)
38058 +#define current_cpu_data boot_cpu_data
38059 +#endif
38060 +
38061 +#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
38062 +#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
38063 +#define get_wchan(p) (0)
38064 +
38065 +#endif
38066 +
38067 +/*
38068 + * Overrides for Emacs so that we follow Linus's tabbing style.
38069 + * Emacs will notice this stuff at the end of the file and automatically
38070 + * adjust the settings for this buffer only.  This must remain at the end
38071 + * of the file.
38072 + * ---------------------------------------------------------------------------
38073 + * Local variables:
38074 + * c-file-style: "linux"
38075 + * End:
38076 + */
38077 diff -Naur -X ../exclude-files orig/include/asm-um/processor-i386.h um/include/asm-um/processor-i386.h
38078 --- orig/include/asm-um/processor-i386.h        1969-12-31 19:00:00.000000000 -0500
38079 +++ um/include/asm-um/processor-i386.h  2003-05-28 11:02:07.000000000 -0400
38080 @@ -0,0 +1,35 @@
38081 +/* 
38082 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38083 + * Licensed under the GPL
38084 + */
38085 +
38086 +#ifndef __UM_PROCESSOR_I386_H
38087 +#define __UM_PROCESSOR_I386_H
38088 +
38089 +extern int cpu_has_xmm;
38090 +extern int cpu_has_cmov;
38091 +
38092 +struct arch_thread {
38093 +       unsigned long debugregs[8];
38094 +       int debugregs_seq;
38095 +};
38096 +
38097 +#define INIT_ARCH_THREAD { .debugregs                  = { [ 0 ... 7 ] = 0 }, \
38098 +                           .debugregs_seq      = 0 }
38099 +
38100 +#include "asm/arch/user.h"
38101 +
38102 +#include "asm/processor-generic.h"
38103 +
38104 +#endif
38105 +
38106 +/*
38107 + * Overrides for Emacs so that we follow Linus's tabbing style.
38108 + * Emacs will notice this stuff at the end of the file and automatically
38109 + * adjust the settings for this buffer only.  This must remain at the end
38110 + * of the file.
38111 + * ---------------------------------------------------------------------------
38112 + * Local variables:
38113 + * c-file-style: "linux"
38114 + * End:
38115 + */
38116 diff -Naur -X ../exclude-files orig/include/asm-um/processor-ppc.h um/include/asm-um/processor-ppc.h
38117 --- orig/include/asm-um/processor-ppc.h 1969-12-31 19:00:00.000000000 -0500
38118 +++ um/include/asm-um/processor-ppc.h   2002-10-23 21:08:05.000000000 -0400
38119 @@ -0,0 +1,15 @@
38120 +#ifndef __UM_PROCESSOR_PPC_H
38121 +#define __UM_PROCESSOR_PPC_H
38122 +
38123 +#if defined(__ASSEMBLY__)
38124 +
38125 +#define CONFIG_ALL_PPC
38126 +#include "arch/processor.h"
38127 +
38128 +#else
38129 +
38130 +#include "asm/processor-generic.h"
38131 +
38132 +#endif
38133 +
38134 +#endif
38135 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-generic.h um/include/asm-um/ptrace-generic.h
38136 --- orig/include/asm-um/ptrace-generic.h        1969-12-31 19:00:00.000000000 -0500
38137 +++ um/include/asm-um/ptrace-generic.h  2003-05-28 11:02:07.000000000 -0400
38138 @@ -0,0 +1,74 @@
38139 +/* 
38140 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
38141 + * Licensed under the GPL
38142 + */
38143 +
38144 +#ifndef __UM_PTRACE_GENERIC_H
38145 +#define __UM_PTRACE_GENERIC_H
38146 +
38147 +#ifndef __ASSEMBLY__
38148 +
38149 +#include "linux/config.h"
38150 +
38151 +#include "asm/current.h"
38152 +
38153 +#define pt_regs pt_regs_subarch
38154 +#define show_regs show_regs_subarch
38155 +
38156 +#include "asm/arch/ptrace.h"
38157 +
38158 +#undef pt_regs
38159 +#undef show_regs
38160 +#undef user_mode
38161 +#undef instruction_pointer
38162 +
38163 +#include "sysdep/ptrace.h"
38164 +#include "skas_ptrace.h"
38165 +
38166 +struct pt_regs {
38167 +       union uml_pt_regs regs;
38168 +};
38169 +
38170 +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
38171 +
38172 +#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
38173 +#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
38174 +
38175 +#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
38176 +#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
38177 +
38178 +#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
38179 +       UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
38180 +#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
38181 +
38182 +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
38183 +
38184 +#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
38185 +
38186 +struct task_struct;
38187 +
38188 +extern unsigned long getreg(struct task_struct *child, int regno);
38189 +extern int putreg(struct task_struct *child, int regno, unsigned long value);
38190 +extern int get_fpregs(unsigned long buf, struct task_struct *child);
38191 +extern int set_fpregs(unsigned long buf, struct task_struct *child);
38192 +extern int get_fpxregs(unsigned long buf, struct task_struct *child);
38193 +extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
38194 +
38195 +extern void show_regs(struct pt_regs *regs);
38196 +
38197 +#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
38198 +
38199 +#endif
38200 +
38201 +#endif
38202 +
38203 +/*
38204 + * Overrides for Emacs so that we follow Linus's tabbing style.
38205 + * Emacs will notice this stuff at the end of the file and automatically
38206 + * adjust the settings for this buffer only.  This must remain at the end
38207 + * of the file.
38208 + * ---------------------------------------------------------------------------
38209 + * Local variables:
38210 + * c-file-style: "linux"
38211 + * End:
38212 + */
38213 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-i386.h um/include/asm-um/ptrace-i386.h
38214 --- orig/include/asm-um/ptrace-i386.h   1969-12-31 19:00:00.000000000 -0500
38215 +++ um/include/asm-um/ptrace-i386.h     2003-05-28 11:02:07.000000000 -0400
38216 @@ -0,0 +1,46 @@
38217 +/* 
38218 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
38219 + * Licensed under the GPL
38220 + */
38221 +
38222 +#ifndef __UM_PTRACE_I386_H
38223 +#define __UM_PTRACE_I386_H
38224 +
38225 +#include "sysdep/ptrace.h"
38226 +#include "asm/ptrace-generic.h"
38227 +
38228 +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
38229 +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
38230 +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs)
38231 +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs)
38232 +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs)
38233 +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs)
38234 +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs)
38235 +
38236 +#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
38237 +#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
38238 +#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
38239 +#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
38240 +#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
38241 +#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
38242 +
38243 +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
38244 +
38245 +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r)
38246 +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
38247 +#define PT_FIX_EXEC_STACK(sp) do ; while(0)
38248 +
38249 +#define user_mode(r) UPT_IS_USER(&(r)->regs)
38250 +
38251 +#endif
38252 +
38253 +/*
38254 + * Overrides for Emacs so that we follow Linus's tabbing style.
38255 + * Emacs will notice this stuff at the end of the file and automatically
38256 + * adjust the settings for this buffer only.  This must remain at the end
38257 + * of the file.
38258 + * ---------------------------------------------------------------------------
38259 + * Local variables:
38260 + * c-file-style: "linux"
38261 + * End:
38262 + */
38263 diff -Naur -X ../exclude-files orig/include/asm-um/resource.h um/include/asm-um/resource.h
38264 --- orig/include/asm-um/resource.h      1969-12-31 19:00:00.000000000 -0500
38265 +++ um/include/asm-um/resource.h        2002-10-23 21:08:05.000000000 -0400
38266 @@ -0,0 +1,6 @@
38267 +#ifndef __UM_RESOURCE_H
38268 +#define __UM_RESOURCE_H
38269 +
38270 +#include "asm/arch/resource.h"
38271 +
38272 +#endif
38273 diff -Naur -X ../exclude-files orig/include/asm-um/rwlock.h um/include/asm-um/rwlock.h
38274 --- orig/include/asm-um/rwlock.h        1969-12-31 19:00:00.000000000 -0500
38275 +++ um/include/asm-um/rwlock.h  2002-10-23 21:08:05.000000000 -0400
38276 @@ -0,0 +1,6 @@
38277 +#ifndef __UM_RWLOCK_H
38278 +#define __UM_RWLOCK_H
38279 +
38280 +#include "asm/arch/rwlock.h"
38281 +
38282 +#endif
38283 diff -Naur -X ../exclude-files orig/include/asm-um/rwsem.h um/include/asm-um/rwsem.h
38284 --- orig/include/asm-um/rwsem.h 1969-12-31 19:00:00.000000000 -0500
38285 +++ um/include/asm-um/rwsem.h   2003-05-28 11:02:07.000000000 -0400
38286 @@ -0,0 +1,10 @@
38287 +#ifndef __UM_RWSEM_H__
38288 +#define __UM_RWSEM_H__
38289 +
38290 +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
38291 +#define __builtin_expect(exp,c) (exp)
38292 +#endif
38293 +
38294 +#include "asm/arch/rwsem.h"
38295 +
38296 +#endif
38297 diff -Naur -X ../exclude-files orig/include/asm-um/scatterlist.h um/include/asm-um/scatterlist.h
38298 --- orig/include/asm-um/scatterlist.h   1969-12-31 19:00:00.000000000 -0500
38299 +++ um/include/asm-um/scatterlist.h     2003-02-27 13:21:49.000000000 -0500
38300 @@ -0,0 +1,6 @@
38301 +#ifndef __UM_SCATTERLIST_H
38302 +#define __UM_SCATTERLIST_H
38303 +
38304 +#include "asm/arch/scatterlist.h"
38305 +
38306 +#endif
38307 diff -Naur -X ../exclude-files orig/include/asm-um/segment.h um/include/asm-um/segment.h
38308 --- orig/include/asm-um/segment.h       1969-12-31 19:00:00.000000000 -0500
38309 +++ um/include/asm-um/segment.h 2002-11-01 19:45:34.000000000 -0500
38310 @@ -0,0 +1,4 @@
38311 +#ifndef __UM_SEGMENT_H
38312 +#define __UM_SEGMENT_H
38313 +
38314 +#endif
38315 diff -Naur -X ../exclude-files orig/include/asm-um/semaphore.h um/include/asm-um/semaphore.h
38316 --- orig/include/asm-um/semaphore.h     1969-12-31 19:00:00.000000000 -0500
38317 +++ um/include/asm-um/semaphore.h       2003-05-28 11:02:07.000000000 -0400
38318 @@ -0,0 +1,6 @@
38319 +#ifndef __UM_SEMAPHORE_H
38320 +#define __UM_SEMAPHORE_H
38321 +
38322 +#include "asm/arch/semaphore.h"
38323 +
38324 +#endif
38325 diff -Naur -X ../exclude-files orig/include/asm-um/sembuf.h um/include/asm-um/sembuf.h
38326 --- orig/include/asm-um/sembuf.h        1969-12-31 19:00:00.000000000 -0500
38327 +++ um/include/asm-um/sembuf.h  2002-10-23 21:08:05.000000000 -0400
38328 @@ -0,0 +1,6 @@
38329 +#ifndef __UM_SEMBUF_H
38330 +#define __UM_SEMBUF_H
38331 +
38332 +#include "asm/arch/sembuf.h"
38333 +
38334 +#endif
38335 diff -Naur -X ../exclude-files orig/include/asm-um/serial.h um/include/asm-um/serial.h
38336 --- orig/include/asm-um/serial.h        1969-12-31 19:00:00.000000000 -0500
38337 +++ um/include/asm-um/serial.h  2002-10-23 21:08:05.000000000 -0400
38338 @@ -0,0 +1,6 @@
38339 +#ifndef __UM_SERIAL_H
38340 +#define __UM_SERIAL_H
38341 +
38342 +#include "asm/arch/serial.h"
38343 +
38344 +#endif
38345 diff -Naur -X ../exclude-files orig/include/asm-um/shmbuf.h um/include/asm-um/shmbuf.h
38346 --- orig/include/asm-um/shmbuf.h        1969-12-31 19:00:00.000000000 -0500
38347 +++ um/include/asm-um/shmbuf.h  2002-10-23 21:08:05.000000000 -0400
38348 @@ -0,0 +1,6 @@
38349 +#ifndef __UM_SHMBUF_H
38350 +#define __UM_SHMBUF_H
38351 +
38352 +#include "asm/arch/shmbuf.h"
38353 +
38354 +#endif
38355 diff -Naur -X ../exclude-files orig/include/asm-um/shmparam.h um/include/asm-um/shmparam.h
38356 --- orig/include/asm-um/shmparam.h      1969-12-31 19:00:00.000000000 -0500
38357 +++ um/include/asm-um/shmparam.h        2002-10-23 21:08:05.000000000 -0400
38358 @@ -0,0 +1,6 @@
38359 +#ifndef __UM_SHMPARAM_H
38360 +#define __UM_SHMPARAM_H
38361 +
38362 +#include "asm/arch/shmparam.h"
38363 +
38364 +#endif
38365 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-generic.h um/include/asm-um/sigcontext-generic.h
38366 --- orig/include/asm-um/sigcontext-generic.h    1969-12-31 19:00:00.000000000 -0500
38367 +++ um/include/asm-um/sigcontext-generic.h      2002-10-23 21:08:05.000000000 -0400
38368 @@ -0,0 +1,6 @@
38369 +#ifndef __UM_SIGCONTEXT_GENERIC_H
38370 +#define __UM_SIGCONTEXT_GENERIC_H
38371 +
38372 +#include "asm/arch/sigcontext.h"
38373 +
38374 +#endif
38375 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-i386.h um/include/asm-um/sigcontext-i386.h
38376 --- orig/include/asm-um/sigcontext-i386.h       1969-12-31 19:00:00.000000000 -0500
38377 +++ um/include/asm-um/sigcontext-i386.h 2002-10-23 21:08:05.000000000 -0400
38378 @@ -0,0 +1,6 @@
38379 +#ifndef __UM_SIGCONTEXT_I386_H
38380 +#define __UM_SIGCONTEXT_I386_H
38381 +
38382 +#include "asm/sigcontext-generic.h"
38383 +
38384 +#endif
38385 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-ppc.h um/include/asm-um/sigcontext-ppc.h
38386 --- orig/include/asm-um/sigcontext-ppc.h        1969-12-31 19:00:00.000000000 -0500
38387 +++ um/include/asm-um/sigcontext-ppc.h  2002-10-23 21:08:05.000000000 -0400
38388 @@ -0,0 +1,10 @@
38389 +#ifndef __UM_SIGCONTEXT_PPC_H
38390 +#define __UM_SIGCONTEXT_PPC_H
38391 +
38392 +#define pt_regs sys_pt_regs
38393 +
38394 +#include "asm/sigcontext-generic.h"
38395 +
38396 +#undef pt_regs
38397 +
38398 +#endif
38399 diff -Naur -X ../exclude-files orig/include/asm-um/siginfo.h um/include/asm-um/siginfo.h
38400 --- orig/include/asm-um/siginfo.h       1969-12-31 19:00:00.000000000 -0500
38401 +++ um/include/asm-um/siginfo.h 2003-05-28 11:02:07.000000000 -0400
38402 @@ -0,0 +1,6 @@
38403 +#ifndef __UM_SIGINFO_H
38404 +#define __UM_SIGINFO_H
38405 +
38406 +#include "asm/arch/siginfo.h"
38407 +
38408 +#endif
38409 diff -Naur -X ../exclude-files orig/include/asm-um/signal.h um/include/asm-um/signal.h
38410 --- orig/include/asm-um/signal.h        1969-12-31 19:00:00.000000000 -0500
38411 +++ um/include/asm-um/signal.h  2003-05-28 11:02:07.000000000 -0400
38412 @@ -0,0 +1,22 @@
38413 +/* 
38414 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38415 + * Licensed under the GPL
38416 + */
38417 +
38418 +#ifndef __UM_SIGNAL_H
38419 +#define __UM_SIGNAL_H
38420 +
38421 +#include "asm/arch/signal.h"
38422 +
38423 +#endif
38424 +
38425 +/*
38426 + * Overrides for Emacs so that we follow Linus's tabbing style.
38427 + * Emacs will notice this stuff at the end of the file and automatically
38428 + * adjust the settings for this buffer only.  This must remain at the end
38429 + * of the file.
38430 + * ---------------------------------------------------------------------------
38431 + * Local variables:
38432 + * c-file-style: "linux"
38433 + * End:
38434 + */
38435 diff -Naur -X ../exclude-files orig/include/asm-um/smp.h um/include/asm-um/smp.h
38436 --- orig/include/asm-um/smp.h   1969-12-31 19:00:00.000000000 -0500
38437 +++ um/include/asm-um/smp.h     2003-05-28 11:02:07.000000000 -0400
38438 @@ -0,0 +1,19 @@
38439 +#ifndef __UM_SMP_H
38440 +#define __UM_SMP_H
38441 +
38442 +#ifdef CONFIG_SMP
38443 +
38444 +#include "linux/config.h"
38445 +#include "asm/current.h"
38446 +
38447 +#define smp_processor_id() (current->processor)
38448 +#define cpu_logical_map(n) (n)
38449 +#define cpu_number_map(n) (n)
38450 +#define PROC_CHANGE_PENALTY    15 /* Pick a number, any number */
38451 +extern int hard_smp_processor_id(void);
38452 +extern unsigned long cpu_online_map;
38453 +#define NO_PROC_ID -1
38454 +
38455 +#endif
38456 +
38457 +#endif
38458 diff -Naur -X ../exclude-files orig/include/asm-um/smplock.h um/include/asm-um/smplock.h
38459 --- orig/include/asm-um/smplock.h       1969-12-31 19:00:00.000000000 -0500
38460 +++ um/include/asm-um/smplock.h 2003-05-28 11:02:07.000000000 -0400
38461 @@ -0,0 +1,6 @@
38462 +#ifndef __UM_SMPLOCK_H
38463 +#define __UM_SMPLOCK_H
38464 +
38465 +#include "asm/arch/smplock.h"
38466 +
38467 +#endif
38468 diff -Naur -X ../exclude-files orig/include/asm-um/socket.h um/include/asm-um/socket.h
38469 --- orig/include/asm-um/socket.h        1969-12-31 19:00:00.000000000 -0500
38470 +++ um/include/asm-um/socket.h  2003-02-27 13:20:13.000000000 -0500
38471 @@ -0,0 +1,6 @@
38472 +#ifndef __UM_SOCKET_H
38473 +#define __UM_SOCKET_H
38474 +
38475 +#include "asm/arch/socket.h"
38476 +
38477 +#endif
38478 diff -Naur -X ../exclude-files orig/include/asm-um/sockios.h um/include/asm-um/sockios.h
38479 --- orig/include/asm-um/sockios.h       1969-12-31 19:00:00.000000000 -0500
38480 +++ um/include/asm-um/sockios.h 2002-10-23 21:08:05.000000000 -0400
38481 @@ -0,0 +1,6 @@
38482 +#ifndef __UM_SOCKIOS_H
38483 +#define __UM_SOCKIOS_H
38484 +
38485 +#include "asm/arch/sockios.h"
38486 +
38487 +#endif
38488 diff -Naur -X ../exclude-files orig/include/asm-um/softirq.h um/include/asm-um/softirq.h
38489 --- orig/include/asm-um/softirq.h       1969-12-31 19:00:00.000000000 -0500
38490 +++ um/include/asm-um/softirq.h 2003-05-28 11:02:07.000000000 -0400
38491 @@ -0,0 +1,13 @@
38492 +#ifndef __UM_SOFTIRQ_H
38493 +#define __UM_SOFTIRQ_H
38494 +
38495 +#include "linux/smp.h"
38496 +#include "asm/system.h"
38497 +#include "asm/processor.h"
38498 +
38499 +/* A gratuitous name change */
38500 +#define i386_bh_lock um_bh_lock
38501 +#include "asm/arch/softirq.h"
38502 +#undef i386_bh_lock
38503 +
38504 +#endif
38505 diff -Naur -X ../exclude-files orig/include/asm-um/spinlock.h um/include/asm-um/spinlock.h
38506 --- orig/include/asm-um/spinlock.h      1969-12-31 19:00:00.000000000 -0500
38507 +++ um/include/asm-um/spinlock.h        2003-05-28 11:02:07.000000000 -0400
38508 @@ -0,0 +1,10 @@
38509 +#ifndef __UM_SPINLOCK_H
38510 +#define __UM_SPINLOCK_H
38511 +
38512 +#include "linux/config.h"
38513 +
38514 +#ifdef CONFIG_SMP
38515 +#include "asm/arch/spinlock.h"
38516 +#endif
38517 +
38518 +#endif
38519 diff -Naur -X ../exclude-files orig/include/asm-um/statfs.h um/include/asm-um/statfs.h
38520 --- orig/include/asm-um/statfs.h        1969-12-31 19:00:00.000000000 -0500
38521 +++ um/include/asm-um/statfs.h  2003-05-28 11:02:07.000000000 -0400
38522 @@ -0,0 +1,6 @@
38523 +#ifndef _UM_STATFS_H
38524 +#define _UM_STATFS_H
38525 +
38526 +#include "asm/arch/statfs.h"
38527 +
38528 +#endif
38529 diff -Naur -X ../exclude-files orig/include/asm-um/stat.h um/include/asm-um/stat.h
38530 --- orig/include/asm-um/stat.h  1969-12-31 19:00:00.000000000 -0500
38531 +++ um/include/asm-um/stat.h    2002-10-23 21:08:05.000000000 -0400
38532 @@ -0,0 +1,6 @@
38533 +#ifndef __UM_STAT_H
38534 +#define __UM_STAT_H
38535 +
38536 +#include "asm/arch/stat.h"
38537 +
38538 +#endif
38539 diff -Naur -X ../exclude-files orig/include/asm-um/string.h um/include/asm-um/string.h
38540 --- orig/include/asm-um/string.h        1969-12-31 19:00:00.000000000 -0500
38541 +++ um/include/asm-um/string.h  2003-02-24 22:52:09.000000000 -0500
38542 @@ -0,0 +1,7 @@
38543 +#ifndef __UM_STRING_H
38544 +#define __UM_STRING_H
38545 +
38546 +#include "asm/arch/string.h"
38547 +#include "asm/archparam.h"
38548 +
38549 +#endif
38550 diff -Naur -X ../exclude-files orig/include/asm-um/system-generic.h um/include/asm-um/system-generic.h
38551 --- orig/include/asm-um/system-generic.h        1969-12-31 19:00:00.000000000 -0500
38552 +++ um/include/asm-um/system-generic.h  2003-05-28 11:02:07.000000000 -0400
38553 @@ -0,0 +1,50 @@
38554 +#ifndef __UM_SYSTEM_GENERIC_H
38555 +#define __UM_SYSTEM_GENERIC_H
38556 +
38557 +#include "asm/arch/system.h"
38558 +
38559 +#undef prepare_to_switch
38560 +#undef switch_to
38561 +#undef __save_flags
38562 +#undef save_flags
38563 +#undef __restore_flags
38564 +#undef restore_flags
38565 +#undef __cli
38566 +#undef __sti
38567 +#undef cli
38568 +#undef sti
38569 +#undef local_irq_save
38570 +#undef local_irq_restore
38571 +#undef local_irq_disable
38572 +#undef local_irq_enable
38573 +
38574 +#define prepare_to_switch() do ; while(0)
38575 +
38576 +void *_switch_to(void *prev, void *next);
38577 +
38578 +#define switch_to(prev, next, last) prev = _switch_to(prev, next)
38579 +
38580 +extern int get_signals(void);
38581 +extern int set_signals(int enable);
38582 +extern void block_signals(void);
38583 +extern void unblock_signals(void);
38584 +
38585 +#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0)
38586 +
38587 +#define local_irq_restore(flags) do { set_signals(flags); } while(0)
38588 +
38589 +#define local_irq_enable() unblock_signals()
38590 +#define local_irq_disable() block_signals()
38591 +
38592 +#define __sti() unblock_signals()
38593 +#define sti() unblock_signals()
38594 +#define __cli() block_signals()
38595 +#define cli() block_signals()
38596 +
38597 +#define __save_flags(x) do { (flags) = get_signals(); } while(0)
38598 +#define save_flags(x) __save_flags(x)
38599 +
38600 +#define __restore_flags(x) local_irq_restore(x)
38601 +#define restore_flags(x) __restore_flags(x)
38602 +
38603 +#endif
38604 diff -Naur -X ../exclude-files orig/include/asm-um/system-i386.h um/include/asm-um/system-i386.h
38605 --- orig/include/asm-um/system-i386.h   1969-12-31 19:00:00.000000000 -0500
38606 +++ um/include/asm-um/system-i386.h     2003-05-28 11:02:07.000000000 -0400
38607 @@ -0,0 +1,39 @@
38608 +#ifndef __UM_SYSTEM_I386_H
38609 +#define __UM_SYSTEM_I386_H
38610 +
38611 +#include "asm/system-generic.h"
38612 +
38613 +#define __HAVE_ARCH_CMPXCHG 1
38614 +
38615 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
38616 +                                     unsigned long new, int size)
38617 +{
38618 +       unsigned long prev;
38619 +       switch (size) {
38620 +       case 1:
38621 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
38622 +                                    : "=a"(prev)
38623 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
38624 +                                    : "memory");
38625 +               return prev;
38626 +       case 2:
38627 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
38628 +                                    : "=a"(prev)
38629 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
38630 +                                    : "memory");
38631 +               return prev;
38632 +       case 4:
38633 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
38634 +                                    : "=a"(prev)
38635 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
38636 +                                    : "memory");
38637 +               return prev;
38638 +       }
38639 +       return old;
38640 +}
38641 +
38642 +#define cmpxchg(ptr,o,n)\
38643 +       ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
38644 +                                       (unsigned long)(n),sizeof(*(ptr))))
38645 +    
38646 +#endif
38647 diff -Naur -X ../exclude-files orig/include/asm-um/system-ppc.h um/include/asm-um/system-ppc.h
38648 --- orig/include/asm-um/system-ppc.h    1969-12-31 19:00:00.000000000 -0500
38649 +++ um/include/asm-um/system-ppc.h      2002-10-23 21:08:05.000000000 -0400
38650 @@ -0,0 +1,12 @@
38651 +#ifndef __UM_SYSTEM_PPC_H
38652 +#define __UM_SYSTEM_PPC_H
38653 +
38654 +#define _switch_to _ppc_switch_to
38655 +
38656 +#include "asm/arch/system.h"
38657 +
38658 +#undef _switch_to
38659
38660 +#include "asm/system-generic.h"
38661 +
38662 +#endif
38663 diff -Naur -X ../exclude-files orig/include/asm-um/termbits.h um/include/asm-um/termbits.h
38664 --- orig/include/asm-um/termbits.h      1969-12-31 19:00:00.000000000 -0500
38665 +++ um/include/asm-um/termbits.h        2002-10-23 21:11:14.000000000 -0400
38666 @@ -0,0 +1,6 @@
38667 +#ifndef __UM_TERMBITS_H
38668 +#define __UM_TERMBITS_H
38669 +
38670 +#include "asm/arch/termbits.h"
38671 +
38672 +#endif
38673 diff -Naur -X ../exclude-files orig/include/asm-um/termios.h um/include/asm-um/termios.h
38674 --- orig/include/asm-um/termios.h       1969-12-31 19:00:00.000000000 -0500
38675 +++ um/include/asm-um/termios.h 2003-02-27 13:20:13.000000000 -0500
38676 @@ -0,0 +1,6 @@
38677 +#ifndef __UM_TERMIOS_H
38678 +#define __UM_TERMIOS_H
38679 +
38680 +#include "asm/arch/termios.h"
38681 +
38682 +#endif
38683 diff -Naur -X ../exclude-files orig/include/asm-um/timex.h um/include/asm-um/timex.h
38684 --- orig/include/asm-um/timex.h 1969-12-31 19:00:00.000000000 -0500
38685 +++ um/include/asm-um/timex.h   2003-05-28 11:02:07.000000000 -0400
38686 @@ -0,0 +1,18 @@
38687 +#ifndef __UM_TIMEX_H
38688 +#define __UM_TIMEX_H
38689 +
38690 +#include "linux/time.h"
38691 +
38692 +typedef unsigned long cycles_t;
38693 +
38694 +#define cacheflush_time (0)
38695 +
38696 +static inline cycles_t get_cycles (void)
38697 +{
38698 +       return 0;
38699 +}
38700 +
38701 +#define vxtime_lock()          do ; while (0)
38702 +#define vxtime_unlock()                do ; while (0)
38703 +
38704 +#endif
38705 diff -Naur -X ../exclude-files orig/include/asm-um/tlb.h um/include/asm-um/tlb.h
38706 --- orig/include/asm-um/tlb.h   1969-12-31 19:00:00.000000000 -0500
38707 +++ um/include/asm-um/tlb.h     2002-10-23 21:08:05.000000000 -0400
38708 @@ -0,0 +1 @@
38709 +#include <asm-generic/tlb.h>
38710 diff -Naur -X ../exclude-files orig/include/asm-um/types.h um/include/asm-um/types.h
38711 --- orig/include/asm-um/types.h 1969-12-31 19:00:00.000000000 -0500
38712 +++ um/include/asm-um/types.h   2002-10-23 21:08:05.000000000 -0400
38713 @@ -0,0 +1,6 @@
38714 +#ifndef __UM_TYPES_H
38715 +#define __UM_TYPES_H
38716 +
38717 +#include "asm/arch/types.h"
38718 +
38719 +#endif
38720 diff -Naur -X ../exclude-files orig/include/asm-um/uaccess.h um/include/asm-um/uaccess.h
38721 --- orig/include/asm-um/uaccess.h       1969-12-31 19:00:00.000000000 -0500
38722 +++ um/include/asm-um/uaccess.h 2002-10-23 21:08:05.000000000 -0400
38723 @@ -0,0 +1,97 @@
38724 +/* 
38725 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38726 + * Licensed under the GPL
38727 + */
38728 +
38729 +#ifndef __UM_UACCESS_H
38730 +#define __UM_UACCESS_H
38731 +
38732 +#define VERIFY_READ 0
38733 +#define VERIFY_WRITE 1
38734 +
38735 +/*
38736 + * The fs value determines whether argument validity checking should be
38737 + * performed or not.  If get_fs() == USER_DS, checking is performed, with
38738 + * get_fs() == KERNEL_DS, checking is bypassed.
38739 + *
38740 + * For historical reasons, these macros are grossly misnamed.
38741 + */
38742 +
38743 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
38744 +
38745 +#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFF)
38746 +#define USER_DS                MAKE_MM_SEG(TASK_SIZE)
38747 +
38748 +#define get_ds()       (KERNEL_DS)
38749 +#define get_fs()       (current->addr_limit)
38750 +#define set_fs(x)      (current->addr_limit = (x))
38751 +
38752 +#define segment_eq(a, b) ((a).seg == (b).seg)
38753 +
38754 +#include "um_uaccess.h"
38755 +
38756 +#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
38757 +
38758 +#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
38759 +
38760 +#define __get_user(x, ptr) \
38761 +({ \
38762 +        const __typeof__(ptr) __private_ptr = ptr; \
38763 +        __typeof__(*(__private_ptr)) __private_val; \
38764 +        int __private_ret = -EFAULT; \
38765 +        (x) = 0; \
38766 +       if (__copy_from_user(&__private_val, (__private_ptr), \
38767 +           sizeof(*(__private_ptr))) == 0) {\
38768 +               (x) = (__typeof__(*(__private_ptr))) __private_val; \
38769 +               __private_ret = 0; \
38770 +       } \
38771 +        __private_ret; \
38772 +}) 
38773 +
38774 +#define get_user(x, ptr) \
38775 +({ \
38776 +        const __typeof__((*ptr)) *private_ptr = (ptr); \
38777 +        (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
38778 +        __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \
38779 +})
38780 +
38781 +#define __put_user(x, ptr) \
38782 +({ \
38783 +        __typeof__(ptr) __private_ptr = ptr; \
38784 +        __typeof__(*(__private_ptr)) __private_val; \
38785 +        int __private_ret = -EFAULT; \
38786 +        __private_val = (__typeof__(*(__private_ptr))) (x); \
38787 +        if (__copy_to_user((__private_ptr), &__private_val, \
38788 +                          sizeof(*(__private_ptr))) == 0) { \
38789 +               __private_ret = 0; \
38790 +       } \
38791 +        __private_ret; \
38792 +})
38793 +
38794 +#define put_user(x, ptr) \
38795 +({ \
38796 +        __typeof__(*(ptr)) *private_ptr = (ptr); \
38797 +        (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
38798 +        __put_user(x, private_ptr) : -EFAULT); \
38799 +})
38800 +
38801 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
38802 +
38803 +struct exception_table_entry
38804 +{
38805 +        unsigned long insn;
38806 +       unsigned long fixup;
38807 +};
38808 +
38809 +#endif
38810 +
38811 +/*
38812 + * Overrides for Emacs so that we follow Linus's tabbing style.
38813 + * Emacs will notice this stuff at the end of the file and automatically
38814 + * adjust the settings for this buffer only.  This must remain at the end
38815 + * of the file.
38816 + * ---------------------------------------------------------------------------
38817 + * Local variables:
38818 + * c-file-style: "linux"
38819 + * End:
38820 + */
38821 diff -Naur -X ../exclude-files orig/include/asm-um/ucontext.h um/include/asm-um/ucontext.h
38822 --- orig/include/asm-um/ucontext.h      1969-12-31 19:00:00.000000000 -0500
38823 +++ um/include/asm-um/ucontext.h        2002-12-01 13:20:58.000000000 -0500
38824 @@ -0,0 +1,6 @@
38825 +#ifndef _ASM_UM_UCONTEXT_H
38826 +#define _ASM_UM_UCONTEXT_H
38827 +
38828 +#include "asm/arch/ucontext.h"
38829 +
38830 +#endif
38831 diff -Naur -X ../exclude-files orig/include/asm-um/unaligned.h um/include/asm-um/unaligned.h
38832 --- orig/include/asm-um/unaligned.h     1969-12-31 19:00:00.000000000 -0500
38833 +++ um/include/asm-um/unaligned.h       2002-10-23 21:08:05.000000000 -0400
38834 @@ -0,0 +1,6 @@
38835 +#ifndef __UM_UNALIGNED_H
38836 +#define __UM_UNALIGNED_H
38837 +
38838 +#include "asm/arch/unaligned.h"
38839 +
38840 +#endif
38841 diff -Naur -X ../exclude-files orig/include/asm-um/unistd.h um/include/asm-um/unistd.h
38842 --- orig/include/asm-um/unistd.h        1969-12-31 19:00:00.000000000 -0500
38843 +++ um/include/asm-um/unistd.h  2003-05-28 11:02:08.000000000 -0400
38844 @@ -0,0 +1,118 @@
38845 +/* 
38846 + * Copyright (C) 2000, 2001  Jeff Dike (jdike@karaya.com)
38847 + * Licensed under the GPL
38848 + */
38849 +
38850 +#ifndef _UM_UNISTD_H_
38851 +#define _UM_UNISTD_H_
38852 +
38853 +#include "linux/resource.h"
38854 +#include "asm/uaccess.h"
38855 +
38856 +extern long sys_open(const char *filename, int flags, int mode);
38857 +extern long sys_dup(unsigned int fildes);
38858 +extern long sys_close(unsigned int fd);
38859 +extern int um_execve(const char *file, char *const argv[], char *const env[]);
38860 +extern long sys_setsid(void);
38861 +extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
38862 +extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options, 
38863 +                     struct rusage *ru);
38864 +extern long sys_mount(char *dev_name, char *dir_name, char *type, 
38865 +                     unsigned long flags, void *data);
38866 +extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, 
38867 +                      struct timeval *tvp);
38868 +extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence);
38869 +extern long sys_read(unsigned int fildes, char *buf, int len);
38870 +extern long sys_write(unsigned int fildes, char *buf, int len);
38871 +
38872 +#ifdef __KERNEL_SYSCALLS__
38873 +
38874 +#define KERNEL_CALL(ret_t, sys, args...)       \
38875 +       mm_segment_t fs = get_fs();             \
38876 +       ret_t ret;                              \
38877 +       set_fs(KERNEL_DS);                      \
38878 +       ret = sys(args);                        \
38879 +       set_fs(fs);                             \
38880 +       return ret;
38881 +
38882 +static inline long open(const char *pathname, int flags, int mode) 
38883 +{
38884 +       KERNEL_CALL(int, sys_open, pathname, flags, mode)
38885 +}
38886 +
38887 +static inline long dup(unsigned int fd)
38888 +{
38889 +       KERNEL_CALL(int, sys_dup, fd);
38890 +}
38891 +
38892 +static inline long close(unsigned int fd)
38893 +{
38894 +       KERNEL_CALL(int, sys_close, fd);
38895 +}
38896 +
38897 +static inline int execve(const char *filename, char *const argv[], 
38898 +                        char *const envp[])
38899 +{
38900 +       KERNEL_CALL(int, um_execve, filename, argv, envp);
38901 +}
38902 +
38903 +static inline long waitpid(pid_t pid, unsigned int *status, int options)
38904 +{
38905 +       KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
38906 +}
38907 +
38908 +static inline pid_t wait(int *status)
38909 +{
38910 +       KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL)
38911 +}
38912 +
38913 +static inline pid_t setsid(void)
38914 +{
38915 +       KERNEL_CALL(pid_t, sys_setsid)
38916 +}
38917 +
38918 +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence)
38919 +{
38920 +       KERNEL_CALL(long, sys_lseek, fd, offset, whence)
38921 +}
38922 +
38923 +static inline int read(unsigned int fd, char * buf, int len)
38924 +{
38925 +       KERNEL_CALL(int, sys_read, fd, buf, len)
38926 +}
38927 +
38928 +static inline int write(unsigned int fd, char * buf, int len)
38929 +{
38930 +       KERNEL_CALL(int, sys_write, fd, buf, len)
38931 +}
38932 +
38933 +#endif
38934 +
38935 +/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying
38936 + * arch's unistd.h for the system call numbers, and restore the old 
38937 + * __KERNEL_SYSCALLS__.
38938 + */
38939 +
38940 +#ifdef __KERNEL_SYSCALLS__
38941 +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
38942 +#endif
38943 +
38944 +#undef __KERNEL_SYSCALLS__
38945 +#include "asm/arch/unistd.h"
38946 +
38947 +#ifdef __KERNEL_SYSCALLS__
38948 +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
38949 +#endif
38950 +
38951 +#endif
38952 +
38953 +/*
38954 + * Overrides for Emacs so that we follow Linus's tabbing style.
38955 + * Emacs will notice this stuff at the end of the file and automatically
38956 + * adjust the settings for this buffer only.  This must remain at the end
38957 + * of the file.
38958 + * ---------------------------------------------------------------------------
38959 + * Local variables:
38960 + * c-file-style: "linux"
38961 + * End:
38962 + */
38963 diff -Naur -X ../exclude-files orig/include/asm-um/user.h um/include/asm-um/user.h
38964 --- orig/include/asm-um/user.h  1969-12-31 19:00:00.000000000 -0500
38965 +++ um/include/asm-um/user.h    2003-05-28 11:04:47.000000000 -0400
38966 @@ -0,0 +1,6 @@
38967 +#ifndef __UM_USER_H
38968 +#define __UM_USER_H
38969 +
38970 +#include "asm/arch/user.h"
38971 +
38972 +#endif
38973 diff -Naur -X ../exclude-files orig/include/asm-um/vga.h um/include/asm-um/vga.h
38974 --- orig/include/asm-um/vga.h   1969-12-31 19:00:00.000000000 -0500
38975 +++ um/include/asm-um/vga.h     2002-10-23 21:08:05.000000000 -0400
38976 @@ -0,0 +1,6 @@
38977 +#ifndef __UM_VGA_H
38978 +#define __UM_VGA_H
38979 +
38980 +#include "asm/arch/vga.h"
38981 +
38982 +#endif
38983 diff -Naur -X ../exclude-files orig/include/asm-um/xor.h um/include/asm-um/xor.h
38984 --- orig/include/asm-um/xor.h   1969-12-31 19:00:00.000000000 -0500
38985 +++ um/include/asm-um/xor.h     2002-10-23 21:08:05.000000000 -0400
38986 @@ -0,0 +1,6 @@
38987 +#ifndef __UM_XOR_H
38988 +#define __UM_XOR_H
38989 +
38990 +#include "asm-generic/xor.h"
38991 +
38992 +#endif
38993 diff -Naur -X ../exclude-files orig/include/linux/blk.h um/include/linux/blk.h
38994 --- orig/include/linux/blk.h    2002-09-15 12:13:19.000000000 -0400
38995 +++ um/include/linux/blk.h      2003-05-28 11:02:34.000000000 -0400
38996 @@ -320,6 +320,15 @@
38997  #define DEVICE_REQUEST do_ida_request
38998  #define DEVICE_NR(device) (MINOR(device) >> 4)
38999  
39000 +#elif (MAJOR_NR == UBD_MAJOR)
39001 +
39002 +#define DEVICE_NAME "User-mode block device"
39003 +#define DEVICE_INTR do_ubd
39004 +#define DEVICE_REQUEST do_ubd_request
39005 +#define DEVICE_NR(device) (MINOR(device) >> UBD_SHIFT)
39006 +#define DEVICE_ON(device)
39007 +#define DEVICE_OFF(device)
39008 +
39009  #endif /* MAJOR_NR == whatever */
39010  
39011  /* provide DEVICE_xxx defaults, if not explicitly defined
39012 diff -Naur -X ../exclude-files orig/include/linux/fs.h um/include/linux/fs.h
39013 --- orig/include/linux/fs.h     2003-02-27 13:04:27.000000000 -0500
39014 +++ um/include/linux/fs.h       2003-05-28 11:02:07.000000000 -0400
39015 @@ -318,6 +318,8 @@
39016  #include <linux/ncp_fs_i.h>
39017  #include <linux/proc_fs_i.h>
39018  #include <linux/usbdev_fs_i.h>
39019 +#include <linux/hostfs_fs_i.h>
39020 +#include <linux/hppfs_fs_i.h>
39021  #include <linux/jffs2_fs_i.h>
39022  #include <linux/cramfs_fs_sb.h>
39023  
39024 @@ -509,7 +511,9 @@
39025                 struct proc_inode_info          proc_i;
39026                 struct socket                   socket_i;
39027                 struct usbdev_inode_info        usbdev_i;
39028 -               struct jffs2_inode_info         jffs2_i;
39029 +               struct hostfs_inode_info        hostfs_i;
39030 +               struct hppfs_inode_info         hppfs_i;
39031 +               struct jffs2_inode_info         jffs2_i;
39032                 void                            *generic_ip;
39033         } u;
39034  };
39035 diff -Naur -X ../exclude-files orig/include/linux/hostfs_fs_i.h um/include/linux/hostfs_fs_i.h
39036 --- orig/include/linux/hostfs_fs_i.h    1969-12-31 19:00:00.000000000 -0500
39037 +++ um/include/linux/hostfs_fs_i.h      2002-10-23 21:08:05.000000000 -0400
39038 @@ -0,0 +1,21 @@
39039 +#ifndef _HOSTFS_FS_I
39040 +#define _HOSTFS_FS_I
39041 +
39042 +struct hostfs_inode_info {
39043 +       char *host_filename;
39044 +       int fd;
39045 +       int mode;
39046 +};
39047 +
39048 +#endif
39049 +
39050 +/*
39051 + * Overrides for Emacs so that we follow Linus's tabbing style.
39052 + * Emacs will notice this stuff at the end of the file and automatically
39053 + * adjust the settings for this buffer only.  This must remain at the end
39054 + * of the file.
39055 + * ---------------------------------------------------------------------------
39056 + * Local variables:
39057 + * c-file-style: "linux"
39058 + * End:
39059 + */
39060 diff -Naur -X ../exclude-files orig/include/linux/hppfs_fs_i.h um/include/linux/hppfs_fs_i.h
39061 --- orig/include/linux/hppfs_fs_i.h     1969-12-31 19:00:00.000000000 -0500
39062 +++ um/include/linux/hppfs_fs_i.h       2002-10-23 21:08:05.000000000 -0400
39063 @@ -0,0 +1,19 @@
39064 +#ifndef _HPPFS_FS_I
39065 +#define _HPPFS_FS_I
39066 +
39067 +struct hppfs_inode_info {
39068 +       struct dentry *proc_dentry;
39069 +};
39070 +
39071 +#endif
39072 +
39073 +/*
39074 + * Overrides for Emacs so that we follow Linus's tabbing style.
39075 + * Emacs will notice this stuff at the end of the file and automatically
39076 + * adjust the settings for this buffer only.  This must remain at the end
39077 + * of the file.
39078 + * ---------------------------------------------------------------------------
39079 + * Local variables:
39080 + * c-file-style: "linux"
39081 + * End:
39082 + */
39083 diff -Naur -X ../exclude-files orig/include/linux/kernel.h um/include/linux/kernel.h
39084 --- orig/include/linux/kernel.h 2003-02-27 13:04:27.000000000 -0500
39085 +++ um/include/linux/kernel.h   2003-05-28 11:02:07.000000000 -0400
39086 @@ -49,7 +49,7 @@
39087  # define ATTRIB_NORET  __attribute__((noreturn))
39088  # define NORET_AND     noreturn,
39089  
39090 -#ifdef __i386__
39091 +#if defined(__i386__) || defined(UM_FASTCALL)
39092  #define FASTCALL(x)    x __attribute__((regparm(3)))
39093  #else
39094  #define FASTCALL(x)    x
39095 diff -Naur -X ../exclude-files orig/include/linux/kernel_stat.h um/include/linux/kernel_stat.h
39096 --- orig/include/linux/kernel_stat.h    2003-02-27 13:04:27.000000000 -0500
39097 +++ um/include/linux/kernel_stat.h      2003-05-28 11:02:07.000000000 -0400
39098 @@ -12,7 +12,7 @@
39099   * used by rstatd/perfmeter
39100   */
39101  
39102 -#define DK_MAX_MAJOR 16
39103 +#define DK_MAX_MAJOR 99
39104  #define DK_MAX_DISK 16
39105  
39106  struct kernel_stat {
39107 diff -Naur -X ../exclude-files orig/include/linux/mm.h um/include/linux/mm.h
39108 --- orig/include/linux/mm.h     2002-09-15 12:13:19.000000000 -0400
39109 +++ um/include/linux/mm.h       2003-05-28 11:02:07.000000000 -0400
39110 @@ -425,6 +425,14 @@
39111  extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist));
39112  extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
39113  
39114 +#ifndef HAVE_ARCH_VALIDATE
39115 +static inline struct page *arch_validate(struct page *page, 
39116 +                                        unsigned int gfp_mask, int order)
39117 +{
39118 +        return(page);
39119 +}
39120 +#endif
39121 +
39122  static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
39123  {
39124         /*
39125 @@ -432,7 +440,7 @@
39126          */
39127         if (order >= MAX_ORDER)
39128                 return NULL;
39129 -       return _alloc_pages(gfp_mask, order);
39130 +       return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order);
39131  }
39132  
39133  #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
39134 @@ -492,6 +500,9 @@
39135  int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
39136                 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
39137  
39138 +extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
39139 +                       size_t len, unsigned long prot);
39140 +
39141  /*
39142   * On a two-level page table, this ends up being trivial. Thus the
39143   * inlining and the symmetry break with pte_alloc() that does all
39144 @@ -539,9 +550,10 @@
39145  
39146  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
39147  
39148 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
39149 -       unsigned long len, unsigned long prot,
39150 -       unsigned long flag, unsigned long pgoff);
39151 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
39152 +                                  unsigned long addr, unsigned long len,
39153 +                                  unsigned long prot, unsigned long flag,
39154 +                                  unsigned long pgoff);
39155  
39156  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
39157         unsigned long len, unsigned long prot,
39158 @@ -551,7 +563,8 @@
39159         if ((offset + PAGE_ALIGN(len)) < offset)
39160                 goto out;
39161         if (!(offset & ~PAGE_MASK))
39162 -               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
39163 +               ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
39164 +                                   offset >> PAGE_SHIFT);
39165  out:
39166         return ret;
39167  }
39168 diff -Naur -X ../exclude-files orig/include/linux/proc_mm.h um/include/linux/proc_mm.h
39169 --- orig/include/linux/proc_mm.h        1969-12-31 19:00:00.000000000 -0500
39170 +++ um/include/linux/proc_mm.h  2003-05-28 11:03:43.000000000 -0400
39171 @@ -0,0 +1,48 @@
39172 +/* 
39173 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39174 + * Licensed under the GPL
39175 + */
39176 +
39177 +#ifndef __PROC_MM_H
39178 +#define __PROC_MM_H
39179 +
39180 +#include "linux/sched.h"
39181 +
39182 +#define MM_MMAP 54
39183 +#define MM_MUNMAP 55
39184 +#define MM_MPROTECT 56
39185 +#define MM_COPY_SEGMENTS 57
39186 +
39187 +struct mm_mmap {
39188 +       unsigned long addr;
39189 +       unsigned long len;
39190 +       unsigned long prot;
39191 +       unsigned long flags;
39192 +       unsigned long fd;
39193 +       unsigned long offset;
39194 +};
39195 +
39196 +struct mm_munmap {
39197 +       unsigned long addr;
39198 +       unsigned long len;      
39199 +};
39200 +
39201 +struct mm_mprotect {
39202 +       unsigned long addr;
39203 +       unsigned long len;
39204 +        unsigned int prot;
39205 +};
39206 +
39207 +struct proc_mm_op {
39208 +       int op;
39209 +       union {
39210 +               struct mm_mmap mmap;
39211 +               struct mm_munmap munmap;
39212 +               struct mm_mprotect mprotect;
39213 +               int copy_segments;
39214 +       } u;
39215 +};
39216 +
39217 +extern struct mm_struct *proc_mm_get_mm(int fd);
39218 +
39219 +#endif
39220 diff -Naur -X ../exclude-files orig/include/linux/tty.h um/include/linux/tty.h
39221 --- orig/include/linux/tty.h    2003-02-27 13:04:28.000000000 -0500
39222 +++ um/include/linux/tty.h      2003-05-28 11:02:07.000000000 -0400
39223 @@ -309,6 +309,9 @@
39224         spinlock_t read_lock;
39225         /* If the tty has a pending do_SAK, queue it here - akpm */
39226         struct tq_struct SAK_tq;
39227 +#ifdef CONFIG_TTY_LOG
39228 +        int log_fd;
39229 +#endif
39230  };
39231  
39232  /* tty magic number */
39233 @@ -366,6 +369,7 @@
39234  extern int specialix_init(void);
39235  extern int espserial_init(void);
39236  extern int macserial_init(void);
39237 +extern int stdio_init(void);
39238  extern int a2232board_init(void);
39239  
39240  extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
39241 @@ -421,5 +425,7 @@
39242  extern int vt_ioctl(struct tty_struct *tty, struct file * file,
39243                     unsigned int cmd, unsigned long arg);
39244  
39245 +extern void stdio_console_init(void);
39246 +
39247  #endif /* __KERNEL__ */
39248  #endif
39249 diff -Naur -X ../exclude-files orig/init/do_mounts.c um/init/do_mounts.c
39250 --- orig/init/do_mounts.c       2003-02-27 13:04:28.000000000 -0500
39251 +++ um/init/do_mounts.c 2003-02-27 13:05:27.000000000 -0500
39252 @@ -153,6 +153,22 @@
39253         { "pf",         0x2f00 },
39254         { "apblock", APBLOCK_MAJOR << 8},
39255         { "ddv", DDV_MAJOR << 8},
39256 +       { "ubd0", UBD_MAJOR << 8 | 0 << 4},
39257 +       { "ubda", UBD_MAJOR << 8 | 0 << 4},
39258 +       { "ubd1", UBD_MAJOR << 8 | 1 << 4},
39259 +       { "ubdb", UBD_MAJOR << 8 | 1 << 4},
39260 +       { "ubd2", UBD_MAJOR << 8 | 2 << 4},
39261 +       { "ubdc", UBD_MAJOR << 8 | 2 << 4},
39262 +       { "ubd3", UBD_MAJOR << 8 | 3 << 4},
39263 +       { "ubdd", UBD_MAJOR << 8 | 3 << 4},
39264 +       { "ubd4", UBD_MAJOR << 8 | 4 << 4},
39265 +       { "ubde", UBD_MAJOR << 8 | 4 << 4},
39266 +       { "ubd5", UBD_MAJOR << 8 | 5 << 4},
39267 +       { "ubdf", UBD_MAJOR << 8 | 5 << 4},
39268 +       { "ubd6", UBD_MAJOR << 8 | 6 << 4},
39269 +       { "ubdg", UBD_MAJOR << 8 | 6 << 4},
39270 +       { "ubd7", UBD_MAJOR << 8 | 7 << 4},
39271 +       { "ubdh", UBD_MAJOR << 8 | 7 << 4},
39272         { "jsfd",    JSFD_MAJOR << 8},
39273  #if defined(CONFIG_ARCH_S390)
39274         { "dasda", (DASD_MAJOR << MINORBITS) },
39275 diff -Naur -X ../exclude-files orig/kernel/panic.c um/kernel/panic.c
39276 --- orig/kernel/panic.c 2003-02-27 13:04:29.000000000 -0500
39277 +++ um/kernel/panic.c   2003-02-27 13:05:27.000000000 -0500
39278 @@ -66,7 +66,7 @@
39279         smp_send_stop();
39280  #endif
39281  
39282 -       notifier_call_chain(&panic_notifier_list, 0, NULL);
39283 +       notifier_call_chain(&panic_notifier_list, 0, buf);
39284  
39285         if (panic_timeout > 0)
39286         {
39287 diff -Naur -X ../exclude-files orig/MAINTAINERS um/MAINTAINERS
39288 --- orig/MAINTAINERS    2003-02-27 13:04:12.000000000 -0500
39289 +++ um/MAINTAINERS      2003-02-27 13:05:17.000000000 -0500
39290 @@ -1841,6 +1841,14 @@
39291  L:     linux-usb-devel@lists.sourceforge.net
39292  W:     http://usb.in.tum.de
39293  S:     Maintained
39294 +
39295 +USER-MODE PORT
39296 +P:     Jeff Dike
39297 +M:     jdike@karaya.com
39298 +L:     user-mode-linux-devel@lists.sourceforge.net
39299 +L:     user-mode-linux-user@lists.sourceforge.net
39300 +W:     http://user-mode-linux.sourceforge.net
39301 +S:     Maintained
39302         
39303  USB "USBNET" DRIVER
39304  P:     David Brownell
39305 diff -Naur -X ../exclude-files orig/Makefile um/Makefile
39306 --- orig/Makefile       2003-02-27 13:04:12.000000000 -0500
39307 +++ um/Makefile 2003-02-27 13:05:17.000000000 -0500
39308 @@ -5,7 +5,15 @@
39309  
39310  KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
39311  
39312 -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
39313 +# SUBARCH tells the usermode build what the underlying arch is.  That is set
39314 +# first, and if a usermode build is happening, the "ARCH=um" on the command
39315 +# line overrides the setting of ARCH below.  If a native build is happening,
39316 +# then ARCH is assigned, getting whatever value it gets normally, and 
39317 +# SUBARCH is subsequently ignored.
39318 +
39319 +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
39320 +ARCH := $(SUBARCH)
39321 +
39322  KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
39323  
39324  CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
39325 diff -Naur -X ../exclude-files orig/mm/Makefile um/mm/Makefile
39326 --- orig/mm/Makefile    2002-08-21 11:47:43.000000000 -0400
39327 +++ um/mm/Makefile      2002-11-08 14:21:36.000000000 -0500
39328 @@ -17,5 +17,6 @@
39329             shmem.o
39330  
39331  obj-$(CONFIG_HIGHMEM) += highmem.o
39332 +obj-$(CONFIG_PROC_MM) += proc_mm.o
39333  
39334  include $(TOPDIR)/Rules.make
39335 diff -Naur -X ../exclude-files orig/mm/mmap.c um/mm/mmap.c
39336 --- orig/mm/mmap.c      2003-02-27 13:04:29.000000000 -0500
39337 +++ um/mm/mmap.c        2003-02-27 13:05:27.000000000 -0500
39338 @@ -390,10 +390,11 @@
39339         return 0;
39340  }
39341  
39342 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
39343 -       unsigned long prot, unsigned long flags, unsigned long pgoff)
39344 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
39345 +                           unsigned long addr, unsigned long len,
39346 +                           unsigned long prot, unsigned long flags, 
39347 +                           unsigned long pgoff)
39348  {
39349 -       struct mm_struct * mm = current->mm;
39350         struct vm_area_struct * vma, * prev;
39351         unsigned int vm_flags;
39352         int correct_wcount = 0;
39353 diff -Naur -X ../exclude-files orig/mm/mprotect.c um/mm/mprotect.c
39354 --- orig/mm/mprotect.c  2002-08-21 11:47:43.000000000 -0400
39355 +++ um/mm/mprotect.c    2002-11-10 20:24:32.000000000 -0500
39356 @@ -264,7 +264,8 @@
39357         return 0;
39358  }
39359  
39360 -asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39361 +long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
39362 +                unsigned long prot)
39363  {
39364         unsigned long nstart, end, tmp;
39365         struct vm_area_struct * vma, * next, * prev;
39366 @@ -281,9 +282,9 @@
39367         if (end == start)
39368                 return 0;
39369  
39370 -       down_write(&current->mm->mmap_sem);
39371 +       down_write(&mm->mmap_sem);
39372  
39373 -       vma = find_vma_prev(current->mm, start, &prev);
39374 +       vma = find_vma_prev(mm, start, &prev);
39375         error = -ENOMEM;
39376         if (!vma || vma->vm_start > start)
39377                 goto out;
39378 @@ -332,6 +333,11 @@
39379                 prev->vm_mm->map_count--;
39380         }
39381  out:
39382 -       up_write(&current->mm->mmap_sem);
39383 +       up_write(&mm->mmap_sem);
39384         return error;
39385  }
39386 +
39387 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39388 +{
39389 +        return(do_mprotect(current->mm, start, len, prot));
39390 +}
39391 diff -Naur -X ../exclude-files orig/mm/proc_mm.c um/mm/proc_mm.c
39392 --- orig/mm/proc_mm.c   1969-12-31 19:00:00.000000000 -0500
39393 +++ um/mm/proc_mm.c     2002-11-19 14:20:26.000000000 -0500
39394 @@ -0,0 +1,173 @@
39395 +/* 
39396 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39397 + * Licensed under the GPL
39398 + */
39399 +
39400 +#include "linux/init.h"
39401 +#include "linux/proc_fs.h"
39402 +#include "linux/proc_mm.h"
39403 +#include "linux/file.h"
39404 +#include "asm/uaccess.h"
39405 +#include "asm/mmu_context.h"
39406 +
39407 +static struct file_operations proc_mm_fops;
39408 +
39409 +struct mm_struct *proc_mm_get_mm(int fd)
39410 +{
39411 +       struct mm_struct *ret = ERR_PTR(-EBADF);
39412 +       struct file *file;
39413 +
39414 +       file = fget(fd);
39415 +       if (!file)
39416 +               goto out;
39417 +
39418 +       ret = ERR_PTR(-EINVAL);
39419 +       if(file->f_op != &proc_mm_fops)
39420 +               goto out_fput;
39421 +
39422 +       ret = file->private_data;
39423 + out_fput:
39424 +       fput(file);
39425 + out:
39426 +       return(ret);
39427 +}
39428 +
39429 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
39430 +                    unsigned long len, unsigned long prot, 
39431 +                    unsigned long flags, unsigned long fd,
39432 +                    unsigned long pgoff);
39433 +
39434 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
39435 +                            size_t count, loff_t *ppos)
39436 +{
39437 +       struct mm_struct *mm = file->private_data;
39438 +       struct proc_mm_op req;
39439 +       int n, ret;
39440 +
39441 +       if(count > sizeof(req))
39442 +               return(-EINVAL);
39443 +
39444 +       n = copy_from_user(&req, buffer, count);
39445 +       if(n != 0)
39446 +               return(-EFAULT);
39447 +
39448 +       ret = count;
39449 +       switch(req.op){
39450 +       case MM_MMAP: {
39451 +               struct mm_mmap *map = &req.u.mmap;
39452 +
39453 +               ret = do_mmap2(mm, map->addr, map->len, map->prot, 
39454 +                              map->flags, map->fd, map->offset >> PAGE_SHIFT);
39455 +               if((ret & ~PAGE_MASK) == 0)
39456 +                       ret = count;
39457 +       
39458 +               break;
39459 +       }
39460 +       case MM_MUNMAP: {
39461 +               struct mm_munmap *unmap = &req.u.munmap;
39462 +
39463 +               down_write(&mm->mmap_sem);
39464 +               ret = do_munmap(mm, unmap->addr, unmap->len);
39465 +               up_write(&mm->mmap_sem);
39466 +
39467 +               if(ret == 0)
39468 +                       ret = count;
39469 +               break;
39470 +       }
39471 +       case MM_MPROTECT: {
39472 +               struct mm_mprotect *protect = &req.u.mprotect;
39473 +
39474 +               ret = do_mprotect(mm, protect->addr, protect->len, 
39475 +                                 protect->prot);
39476 +               if(ret == 0)
39477 +                       ret = count;
39478 +               break;
39479 +       }
39480 +
39481 +       case MM_COPY_SEGMENTS: {
39482 +               struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
39483 +
39484 +               if(IS_ERR(from)){
39485 +                       ret = PTR_ERR(from);
39486 +                       break;
39487 +               }
39488 +
39489 +               mm_copy_segments(from, mm);
39490 +               break;
39491 +       }
39492 +       default:
39493 +               ret = -EINVAL;
39494 +               break;
39495 +       }
39496 +
39497 +       return(ret);
39498 +}
39499 +
39500 +static int open_proc_mm(struct inode *inode, struct file *file)
39501 +{
39502 +       struct mm_struct *mm = mm_alloc();
39503 +       int ret;
39504 +
39505 +       ret = -ENOMEM;
39506 +       if(mm == NULL)
39507 +               goto out_mem;
39508 +
39509 +       ret = init_new_context(current, mm);
39510 +       if(ret)
39511 +               goto out_free;
39512 +
39513 +       spin_lock(&mmlist_lock);
39514 +       list_add(&mm->mmlist, &current->mm->mmlist);
39515 +       mmlist_nr++;
39516 +       spin_unlock(&mmlist_lock);
39517 +
39518 +       file->private_data = mm;
39519 +
39520 +       return(0);
39521 +
39522 + out_free:
39523 +       mmput(mm);
39524 + out_mem:
39525 +       return(ret);
39526 +}
39527 +
39528 +static int release_proc_mm(struct inode *inode, struct file *file)
39529 +{
39530 +       struct mm_struct *mm = file->private_data;
39531 +
39532 +       mmput(mm);
39533 +       return(0);
39534 +}
39535 +
39536 +static struct file_operations proc_mm_fops = {
39537 +       .open           = open_proc_mm,
39538 +       .release        = release_proc_mm,
39539 +       .write          = write_proc_mm,
39540 +};
39541 +
39542 +static int make_proc_mm(void)
39543 +{
39544 +       struct proc_dir_entry *ent;
39545 +
39546 +       ent = create_proc_entry("mm", 0222, &proc_root);
39547 +       if(ent == NULL){
39548 +               printk("make_proc_mm : Failed to register /proc/mm\n");
39549 +               return(0);
39550 +       }
39551 +       ent->proc_fops = &proc_mm_fops;
39552 +
39553 +       return(0);
39554 +}
39555 +
39556 +__initcall(make_proc_mm);
39557 +
39558 +/*
39559 + * Overrides for Emacs so that we follow Linus's tabbing style.
39560 + * Emacs will notice this stuff at the end of the file and automatically
39561 + * adjust the settings for this buffer only.  This must remain at the end
39562 + * of the file.
39563 + * ---------------------------------------------------------------------------
39564 + * Local variables:
39565 + * c-file-style: "linux"
39566 + * End:
39567 + */
39568 diff -Naur -X ../exclude-files orig/mm/slab.c um/mm/slab.c
39569 --- orig/mm/slab.c      2003-02-27 13:04:29.000000000 -0500
39570 +++ um/mm/slab.c        2003-02-27 13:05:27.000000000 -0500
39571 @@ -1946,10 +1946,14 @@
39572  
39573         name = cachep->name; 
39574         {
39575 +        mm_segment_t fs;
39576         char tmp; 
39577 +       fs = get_fs();
39578 +       set_fs(KERNEL_DS);
39579         if (__get_user(tmp, name)) 
39580                 name = "broken"; 
39581 -       }       
39582 +       set_fs(fs);
39583 +       }
39584  
39585         seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
39586                 name, active_objs, num_objs, cachep->objsize,