Whamcloud - gitweb
smash the HEAD with the contents of b_cmd. HEAD_PRE_CMD_SMASH and
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-patch-2.4.23-1.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-10-21 03:26:06.000000000 -0400
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  2003-10-21 03:26:06.000000000 -0400
61 @@ -0,0 +1,22 @@
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 +bool 'COW device' CONFIG_COW
68 +
69 +if [ "$CONFIG_BLK_DEV_UBD" = "y" -o "$CONFIG_COW" = "y" ] ; then
70 +       define_bool CONFIG_COW_COMMON y
71 +fi
72 +
73 +tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
74 +dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
75 +tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
76 +if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
77 +       int '   Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
78 +fi
79 +dep_bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
80 +
81 +tristate 'Example IO memory driver' CONFIG_MMAPPER
82 +
83 +endmenu
84 diff -Naur -X ../exclude-files orig/arch/um/config_char.in um/arch/um/config_char.in
85 --- orig/arch/um/config_char.in 1969-12-31 19:00:00.000000000 -0500
86 +++ um/arch/um/config_char.in   2003-10-21 03:26:06.000000000 -0400
87 @@ -0,0 +1,37 @@
88 +mainmenu_option next_comment
89 +comment 'Character Devices'
90 +
91 +define_bool CONFIG_STDIO_CONSOLE y
92 +
93 +bool 'Virtual serial line' CONFIG_SSL
94 +
95 +bool 'file descriptor channel support' CONFIG_FD_CHAN
96 +bool 'null channel support' CONFIG_NULL_CHAN
97 +bool 'port channel support' CONFIG_PORT_CHAN
98 +bool 'pty channel support' CONFIG_PTY_CHAN
99 +bool 'tty channel support' CONFIG_TTY_CHAN
100 +bool 'xterm channel support' CONFIG_XTERM_CHAN
101 +string 'Default main console channel initialization' CONFIG_CON_ZERO_CHAN \
102 +            "fd:0,fd:1"
103 +string 'Default console channel initialization' CONFIG_CON_CHAN "xterm"
104 +string 'Default serial line channel initialization' CONFIG_SSL_CHAN "pty"
105 +
106 +
107 +bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
108 +if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
109 +   int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
110 +fi
111 +
112 +bool 'Watchdog Timer Support' CONFIG_WATCHDOG
113 +dep_bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT \
114 +       $CONFIG_WATCHDOG
115 +dep_tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG $CONFIG_WATCHDOG
116 +dep_tristate '  UML watchdog' CONFIG_UML_WATCHDOG $CONFIG_WATCHDOG
117 +
118 +tristate 'Sound support' CONFIG_UML_SOUND
119 +define_tristate CONFIG_SOUND $CONFIG_UML_SOUND
120 +define_tristate CONFIG_HOSTAUDIO $CONFIG_UML_SOUND
121 +
122 +bool 'Enable tty logging' CONFIG_TTY_LOG
123 +
124 +endmenu
125 diff -Naur -X ../exclude-files orig/arch/um/config.in um/arch/um/config.in
126 --- orig/arch/um/config.in      1969-12-31 19:00:00.000000000 -0500
127 +++ um/arch/um/config.in        2003-12-14 11:34:02.000000000 -0500
128 @@ -0,0 +1,105 @@
129 +define_bool CONFIG_USERMODE y
130 +
131 +mainmenu_name "Linux/Usermode Kernel Configuration"
132 +
133 +define_bool CONFIG_ISA n
134 +define_bool CONFIG_SBUS n
135 +define_bool CONFIG_PCI n
136 +
137 +define_bool CONFIG_UID16 y
138 +
139 +define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
140 +
141 +mainmenu_option next_comment
142 +comment 'Code maturity level options'
143 +bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
144 +endmenu
145 +
146 +mainmenu_option next_comment
147 +comment 'General Setup'
148 +
149 +bool 'Separate kernel address space support' CONFIG_MODE_SKAS
150 +
151 +# This is to ensure that at least one of the modes is enabled.  When neither
152 +# is present in defconfig, they default to N, which is bad.
153 +if [ "$CONFIG_MODE_SKAS" != "y" ]; then
154 +   define_bool CONFIG_MODE_TT y
155 +fi
156 +
157 +bool 'Tracing thread support' CONFIG_MODE_TT
158 +if [ "$CONFIG_MODE_TT" != "y" ]; then
159 +   bool 'Statically linked binary when CONFIG_MODE_TT is disabled' CONFIG_STATIC_LINK
160 +fi
161 +bool 'Networking support' CONFIG_NET
162 +bool 'System V IPC' CONFIG_SYSVIPC
163 +bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
164 +bool 'Sysctl support' CONFIG_SYSCTL
165 +tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
166 +tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
167 +tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
168 +tristate 'Host filesystem' CONFIG_HOSTFS
169 +tristate 'Honeypot proc filesystem' CONFIG_HPPFS
170 +bool 'Management console' CONFIG_MCONSOLE
171 +dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_MCONSOLE
172 +bool '2G/2G host address space split' CONFIG_HOST_2G_2G
173 +bool 'Symmetric multi-processing support' CONFIG_UML_SMP
174 +define_bool CONFIG_SMP $CONFIG_UML_SMP
175 +int 'Nesting level' CONFIG_NEST_LEVEL 0
176 +int 'Kernel address space size (in .5G units)' CONFIG_KERNEL_HALF_GIGS 1
177 +bool 'Highmem support' CONFIG_HIGHMEM
178 +bool '/proc/mm' CONFIG_PROC_MM
179 +int 'Kernel stack size order' CONFIG_KERNEL_STACK_ORDER 2
180 +bool 'Real-time Clock' CONFIG_UML_REAL_TIME_CLOCK
181 +endmenu
182 +
183 +mainmenu_option next_comment
184 +comment 'Loadable module support'
185 +bool 'Enable loadable module support' CONFIG_MODULES
186 +if [ "$CONFIG_MODULES" = "y" ]; then
187 +# MODVERSIONS does not yet work in this architecture
188 +#   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
189 +    bool '  Kernel module loader' CONFIG_KMOD
190 +fi
191 +endmenu
192 +
193 +source arch/um/config_char.in
194 +
195 +source arch/um/config_block.in
196 +
197 +define_bool CONFIG_NETDEVICES $CONFIG_NET
198 +
199 +if [ "$CONFIG_NET" = "y" ]; then
200 +   source arch/um/config_net.in
201 +   source net/Config.in
202 +fi
203 +
204 +source fs/Config.in
205 +
206 +mainmenu_option next_comment
207 +comment 'SCSI support'
208 +
209 +tristate 'SCSI support' CONFIG_SCSI
210 +
211 +if [ "$CONFIG_SCSI" != "n" ]; then
212 +   source arch/um/config_scsi.in
213 +fi
214 +endmenu
215 +
216 +source drivers/md/Config.in
217 +
218 +source drivers/mtd/Config.in
219 +
220 +source lib/Config.in
221 +
222 +mainmenu_option next_comment
223 +comment 'Kernel hacking'
224 +bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
225 +bool 'Enable kernel debugging symbols' CONFIG_DEBUGSYM
226 +if [ "$CONFIG_XTERM_CHAN" = "y" ]; then
227 +   dep_bool 'Enable ptrace proxy' CONFIG_PT_PROXY $CONFIG_DEBUGSYM
228 +else 
229 +   define_bool CONFIG_PT_PROXY n
230 +fi
231 +dep_bool 'Enable gprof support' CONFIG_GPROF $CONFIG_DEBUGSYM
232 +dep_bool 'Enable gcov support' CONFIG_GCOV $CONFIG_DEBUGSYM
233 +endmenu
234 diff -Naur -X ../exclude-files orig/arch/um/config_net.in um/arch/um/config_net.in
235 --- orig/arch/um/config_net.in  1969-12-31 19:00:00.000000000 -0500
236 +++ um/arch/um/config_net.in    2003-10-21 03:26:06.000000000 -0400
237 @@ -0,0 +1,47 @@
238 +mainmenu_option next_comment
239 +comment 'Network Devices'
240 +
241 +# UML virtual driver
242 +bool 'Virtual network device' CONFIG_UML_NET
243 +
244 +dep_bool '  Ethertap transport' CONFIG_UML_NET_ETHERTAP $CONFIG_UML_NET
245 +dep_bool '  TUN/TAP transport' CONFIG_UML_NET_TUNTAP $CONFIG_UML_NET
246 +dep_bool '  SLIP transport' CONFIG_UML_NET_SLIP $CONFIG_UML_NET
247 +dep_bool '  SLiRP transport' CONFIG_UML_NET_SLIRP $CONFIG_UML_NET
248 +dep_bool '  Daemon transport' CONFIG_UML_NET_DAEMON $CONFIG_UML_NET
249 +dep_bool '  Multicast transport' CONFIG_UML_NET_MCAST $CONFIG_UML_NET
250 +dep_bool '  pcap transport' CONFIG_UML_NET_PCAP $CONFIG_UML_NET
251 +
252 +# Below are hardware-independent drivers mirrored from
253 +# drivers/net/Config.in. It would be nice if Linux
254 +# had HW independent drivers separated from the other
255 +# but it does not. Until then each non-ISA/PCI arch
256 +# needs to provide it's own menu of network drivers
257 +
258 +tristate 'Dummy net driver support' CONFIG_DUMMY
259 +tristate 'Bonding driver support' CONFIG_BONDING
260 +tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
261 +tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
262 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
263 +   if [ "$CONFIG_NETLINK" = "y" ]; then
264 +      tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
265 +   fi
266 +fi
267 +
268 +tristate 'PPP (point-to-point protocol) support' CONFIG_PPP
269 +if [ ! "$CONFIG_PPP" = "n" ]; then
270 +   dep_bool '  PPP multilink support (EXPERIMENTAL)' CONFIG_PPP_MULTILINK $CONFIG_EXPERIMENTAL
271 +   dep_bool '  PPP filtering' CONFIG_PPP_FILTER $CONFIG_FILTER
272 +   dep_tristate '  PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
273 +   dep_tristate '  PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
274 +   dep_tristate '  PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
275 +   dep_tristate '  PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
276 +   dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP $CONFIG_EXPERIMENTAL
277 +fi
278 +
279 +tristate 'SLIP (serial line) support' CONFIG_SLIP
280 +dep_bool '  CSLIP compressed headers' CONFIG_SLIP_COMPRESSED $CONFIG_SLIP
281 +dep_bool '  Keepalive and linefill' CONFIG_SLIP_SMART $CONFIG_SLIP
282 +dep_bool '  Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 $CONFIG_SLIP
283 +
284 +endmenu
285 diff -Naur -X ../exclude-files orig/arch/um/config.release um/arch/um/config.release
286 --- orig/arch/um/config.release 1969-12-31 19:00:00.000000000 -0500
287 +++ um/arch/um/config.release   2003-10-21 03:26:06.000000000 -0400
288 @@ -0,0 +1,302 @@
289 +#
290 +# Automatically generated make config: don't edit
291 +#
292 +CONFIG_USERMODE=y
293 +# CONFIG_ISA is not set
294 +# CONFIG_SBUS is not set
295 +# CONFIG_PCI is not set
296 +CONFIG_UID16=y
297 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
298 +
299 +#
300 +# Code maturity level options
301 +#
302 +CONFIG_EXPERIMENTAL=y
303 +
304 +#
305 +# General Setup
306 +#
307 +CONFIG_NET=y
308 +CONFIG_SYSVIPC=y
309 +CONFIG_BSD_PROCESS_ACCT=y
310 +CONFIG_SYSCTL=y
311 +CONFIG_BINFMT_AOUT=y
312 +CONFIG_BINFMT_ELF=y
313 +CONFIG_BINFMT_MISC=y
314 +CONFIG_HOSTFS=y
315 +# CONFIG_HPPFS is not set
316 +CONFIG_MCONSOLE=y
317 +CONFIG_MAGIC_SYSRQ=y
318 +# CONFIG_HOST_2G_2G is not set
319 +# CONFIG_UML_SMP is not set
320 +# CONFIG_SMP is not set
321 +CONFIG_NEST_LEVEL=0
322 +CONFIG_KERNEL_HALF_GIGS=1
323 +
324 +#
325 +# Loadable module support
326 +#
327 +CONFIG_MODULES=y
328 +CONFIG_KMOD=y
329 +
330 +#
331 +# Character Devices
332 +#
333 +CONFIG_STDIO_CONSOLE=y
334 +CONFIG_SSL=y
335 +CONFIG_FD_CHAN=y
336 +# CONFIG_NULL_CHAN is not set
337 +CONFIG_PORT_CHAN=y
338 +CONFIG_PTY_CHAN=y
339 +CONFIG_TTY_CHAN=y
340 +CONFIG_XTERM_CHAN=y
341 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
342 +CONFIG_CON_CHAN="xterm"
343 +CONFIG_SSL_CHAN="pty"
344 +CONFIG_UNIX98_PTYS=y
345 +CONFIG_UNIX98_PTY_COUNT=256
346 +# CONFIG_WATCHDOG is not set
347 +CONFIG_UML_SOUND=y
348 +CONFIG_SOUND=y
349 +CONFIG_HOSTAUDIO=y
350 +# CONFIG_TTY_LOG is not set
351 +
352 +#
353 +# Block Devices
354 +#
355 +CONFIG_BLK_DEV_UBD=y
356 +# CONFIG_BLK_DEV_UBD_SYNC is not set
357 +CONFIG_BLK_DEV_LOOP=y
358 +CONFIG_BLK_DEV_NBD=y
359 +CONFIG_BLK_DEV_RAM=y
360 +CONFIG_BLK_DEV_RAM_SIZE=4096
361 +CONFIG_BLK_DEV_INITRD=y
362 +# CONFIG_MMAPPER is not set
363 +CONFIG_NETDEVICES=y
364 +
365 +#
366 +# Network Devices
367 +#
368 +CONFIG_UML_NET=y
369 +CONFIG_UML_NET_ETHERTAP=y
370 +CONFIG_UML_NET_TUNTAP=y
371 +CONFIG_UML_NET_SLIP=y
372 +CONFIG_UML_NET_DAEMON=y
373 +CONFIG_UML_NET_MCAST=y
374 +CONFIG_DUMMY=y
375 +CONFIG_BONDING=m
376 +CONFIG_EQUALIZER=m
377 +CONFIG_TUN=y
378 +CONFIG_PPP=m
379 +CONFIG_PPP_MULTILINK=y
380 +# CONFIG_PPP_ASYNC is not set
381 +CONFIG_PPP_SYNC_TTY=m
382 +CONFIG_PPP_DEFLATE=m
383 +CONFIG_PPP_BSDCOMP=m
384 +CONFIG_PPPOE=m
385 +CONFIG_SLIP=m
386 +
387 +#
388 +# Networking options
389 +#
390 +CONFIG_PACKET=y
391 +CONFIG_PACKET_MMAP=y
392 +# CONFIG_NETLINK_DEV is not set
393 +# CONFIG_NETFILTER is not set
394 +# CONFIG_FILTER is not set
395 +CONFIG_UNIX=y
396 +CONFIG_INET=y
397 +# CONFIG_IP_MULTICAST is not set
398 +# CONFIG_IP_ADVANCED_ROUTER is not set
399 +# CONFIG_IP_PNP is not set
400 +# CONFIG_NET_IPIP is not set
401 +# CONFIG_NET_IPGRE is not set
402 +# CONFIG_ARPD is not set
403 +# CONFIG_INET_ECN is not set
404 +# CONFIG_SYN_COOKIES is not set
405 +# CONFIG_IPV6 is not set
406 +# CONFIG_KHTTPD is not set
407 +# CONFIG_ATM is not set
408 +# CONFIG_VLAN_8021Q is not set
409 +
410 +#
411 +#  
412 +#
413 +# CONFIG_IPX is not set
414 +# CONFIG_ATALK is not set
415 +
416 +#
417 +# Appletalk devices
418 +#
419 +# CONFIG_DECNET is not set
420 +# CONFIG_BRIDGE is not set
421 +# CONFIG_X25 is not set
422 +# CONFIG_LAPB is not set
423 +# CONFIG_LLC is not set
424 +# CONFIG_NET_DIVERT is not set
425 +# CONFIG_ECONET is not set
426 +# CONFIG_WAN_ROUTER is not set
427 +# CONFIG_NET_FASTROUTE is not set
428 +# CONFIG_NET_HW_FLOWCONTROL is not set
429 +
430 +#
431 +# QoS and/or fair queueing
432 +#
433 +# CONFIG_NET_SCHED is not set
434 +
435 +#
436 +# Network testing
437 +#
438 +# CONFIG_NET_PKTGEN is not set
439 +
440 +#
441 +# File systems
442 +#
443 +CONFIG_QUOTA=y
444 +CONFIG_AUTOFS_FS=m
445 +CONFIG_AUTOFS4_FS=m
446 +CONFIG_REISERFS_FS=m
447 +# CONFIG_REISERFS_CHECK is not set
448 +# CONFIG_REISERFS_PROC_INFO is not set
449 +CONFIG_ADFS_FS=m
450 +# CONFIG_ADFS_FS_RW is not set
451 +CONFIG_AFFS_FS=m
452 +CONFIG_HFS_FS=m
453 +CONFIG_BFS_FS=m
454 +CONFIG_EXT3_FS=y
455 +CONFIG_JBD=y
456 +# CONFIG_JBD_DEBUG is not set
457 +CONFIG_FAT_FS=y
458 +CONFIG_MSDOS_FS=y
459 +CONFIG_UMSDOS_FS=y
460 +CONFIG_VFAT_FS=y
461 +CONFIG_EFS_FS=m
462 +CONFIG_CRAMFS=m
463 +CONFIG_TMPFS=y
464 +CONFIG_RAMFS=y
465 +CONFIG_ISO9660_FS=y
466 +# CONFIG_JOLIET is not set
467 +# CONFIG_ZISOFS is not set
468 +CONFIG_MINIX_FS=m
469 +CONFIG_VXFS_FS=m
470 +# CONFIG_NTFS_FS is not set
471 +CONFIG_HPFS_FS=m
472 +CONFIG_PROC_FS=y
473 +CONFIG_DEVFS_FS=y
474 +CONFIG_DEVFS_MOUNT=y
475 +# CONFIG_DEVFS_DEBUG is not set
476 +CONFIG_DEVPTS_FS=y
477 +CONFIG_QNX4FS_FS=m
478 +# CONFIG_QNX4FS_RW is not set
479 +CONFIG_ROMFS_FS=m
480 +CONFIG_EXT2_FS=y
481 +CONFIG_SYSV_FS=m
482 +CONFIG_UDF_FS=m
483 +# CONFIG_UDF_RW is not set
484 +CONFIG_UFS_FS=m
485 +# CONFIG_UFS_FS_WRITE is not set
486 +
487 +#
488 +# Network File Systems
489 +#
490 +# CONFIG_CODA_FS is not set
491 +# CONFIG_INTERMEZZO_FS is not set
492 +CONFIG_NFS_FS=y
493 +CONFIG_NFS_V3=y
494 +CONFIG_NFSD=y
495 +CONFIG_NFSD_V3=y
496 +CONFIG_SUNRPC=y
497 +CONFIG_LOCKD=y
498 +CONFIG_LOCKD_V4=y
499 +# CONFIG_SMB_FS is not set
500 +# CONFIG_NCP_FS is not set
501 +# CONFIG_ZISOFS_FS is not set
502 +CONFIG_ZLIB_FS_INFLATE=m
503 +
504 +#
505 +# Partition Types
506 +#
507 +# CONFIG_PARTITION_ADVANCED is not set
508 +CONFIG_MSDOS_PARTITION=y
509 +# CONFIG_SMB_NLS is not set
510 +CONFIG_NLS=y
511 +
512 +#
513 +# Native Language Support
514 +#
515 +CONFIG_NLS_DEFAULT="iso8859-1"
516 +# CONFIG_NLS_CODEPAGE_437 is not set
517 +# CONFIG_NLS_CODEPAGE_737 is not set
518 +# CONFIG_NLS_CODEPAGE_775 is not set
519 +# CONFIG_NLS_CODEPAGE_850 is not set
520 +# CONFIG_NLS_CODEPAGE_852 is not set
521 +# CONFIG_NLS_CODEPAGE_855 is not set
522 +# CONFIG_NLS_CODEPAGE_857 is not set
523 +# CONFIG_NLS_CODEPAGE_860 is not set
524 +# CONFIG_NLS_CODEPAGE_861 is not set
525 +# CONFIG_NLS_CODEPAGE_862 is not set
526 +# CONFIG_NLS_CODEPAGE_863 is not set
527 +# CONFIG_NLS_CODEPAGE_864 is not set
528 +# CONFIG_NLS_CODEPAGE_865 is not set
529 +# CONFIG_NLS_CODEPAGE_866 is not set
530 +# CONFIG_NLS_CODEPAGE_869 is not set
531 +# CONFIG_NLS_CODEPAGE_936 is not set
532 +# CONFIG_NLS_CODEPAGE_950 is not set
533 +# CONFIG_NLS_CODEPAGE_932 is not set
534 +# CONFIG_NLS_CODEPAGE_949 is not set
535 +# CONFIG_NLS_CODEPAGE_874 is not set
536 +# CONFIG_NLS_ISO8859_8 is not set
537 +# CONFIG_NLS_CODEPAGE_1250 is not set
538 +# CONFIG_NLS_CODEPAGE_1251 is not set
539 +# CONFIG_NLS_ISO8859_1 is not set
540 +# CONFIG_NLS_ISO8859_2 is not set
541 +# CONFIG_NLS_ISO8859_3 is not set
542 +# CONFIG_NLS_ISO8859_4 is not set
543 +# CONFIG_NLS_ISO8859_5 is not set
544 +# CONFIG_NLS_ISO8859_6 is not set
545 +# CONFIG_NLS_ISO8859_7 is not set
546 +# CONFIG_NLS_ISO8859_9 is not set
547 +# CONFIG_NLS_ISO8859_13 is not set
548 +# CONFIG_NLS_ISO8859_14 is not set
549 +# CONFIG_NLS_ISO8859_15 is not set
550 +# CONFIG_NLS_KOI8_R is not set
551 +# CONFIG_NLS_KOI8_U is not set
552 +# CONFIG_NLS_UTF8 is not set
553 +
554 +#
555 +# SCSI support
556 +#
557 +CONFIG_SCSI=y
558 +
559 +#
560 +# SCSI support type (disk, tape, CD-ROM)
561 +#
562 +# CONFIG_BLK_DEV_SD is not set
563 +# CONFIG_CHR_DEV_ST is not set
564 +# CONFIG_BLK_DEV_SR is not set
565 +# CONFIG_CHR_DEV_SG is not set
566 +
567 +#
568 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
569 +#
570 +# CONFIG_SCSI_DEBUG_QUEUES is not set
571 +# CONFIG_SCSI_MULTI_LUN is not set
572 +# CONFIG_SCSI_CONSTANTS is not set
573 +# CONFIG_SCSI_LOGGING is not set
574 +CONFIG_SCSI_DEBUG=m
575 +
576 +#
577 +# Multi-device support (RAID and LVM)
578 +#
579 +# CONFIG_MD is not set
580 +
581 +#
582 +# Memory Technology Devices (MTD)
583 +#
584 +# CONFIG_MTD is not set
585 +
586 +#
587 +# Kernel hacking
588 +#
589 +# CONFIG_DEBUG_SLAB is not set
590 +# CONFIG_DEBUGSYM is not set
591 diff -Naur -X ../exclude-files orig/arch/um/config_scsi.in um/arch/um/config_scsi.in
592 --- orig/arch/um/config_scsi.in 1969-12-31 19:00:00.000000000 -0500
593 +++ um/arch/um/config_scsi.in   2003-10-21 03:26:06.000000000 -0400
594 @@ -0,0 +1,30 @@
595 +comment 'SCSI support type (disk, tape, CD-ROM)'
596 +
597 +dep_tristate '  SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
598 +
599 +if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
600 +   int  'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
601 +fi
602 +
603 +dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
604 +
605 +dep_tristate '  SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
606 +
607 +if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
608 +   bool '    Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
609 +   int  'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2
610 +fi
611 +dep_tristate '  SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
612 +
613 +comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
614 +
615 +#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
616 +   bool '  Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES
617 +#fi
618 +
619 +bool '  Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
620 +  
621 +bool '  Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
622 +bool '  SCSI logging facility' CONFIG_SCSI_LOGGING
623 +
624 +dep_tristate 'SCSI debugging host simulator (EXPERIMENTAL)' CONFIG_SCSI_DEBUG $CONFIG_SCSI
625 diff -Naur -X ../exclude-files orig/arch/um/defconfig um/arch/um/defconfig
626 --- orig/arch/um/defconfig      1969-12-31 19:00:00.000000000 -0500
627 +++ um/arch/um/defconfig        2003-12-17 02:15:39.000000000 -0500
628 @@ -0,0 +1,423 @@
629 +#
630 +# Automatically generated make config: don't edit
631 +#
632 +CONFIG_USERMODE=y
633 +# CONFIG_ISA is not set
634 +# CONFIG_SBUS is not set
635 +# CONFIG_PCI is not set
636 +CONFIG_UID16=y
637 +CONFIG_RWSEM_XCHGADD_ALGORITHM=y
638 +
639 +#
640 +# Code maturity level options
641 +#
642 +CONFIG_EXPERIMENTAL=y
643 +
644 +#
645 +# General Setup
646 +#
647 +CONFIG_MODE_SKAS=y
648 +CONFIG_MODE_TT=y
649 +CONFIG_NET=y
650 +CONFIG_SYSVIPC=y
651 +CONFIG_BSD_PROCESS_ACCT=y
652 +CONFIG_SYSCTL=y
653 +CONFIG_BINFMT_AOUT=y
654 +CONFIG_BINFMT_ELF=y
655 +CONFIG_BINFMT_MISC=y
656 +CONFIG_HOSTFS=y
657 +CONFIG_HPPFS=y
658 +CONFIG_MCONSOLE=y
659 +CONFIG_MAGIC_SYSRQ=y
660 +# CONFIG_HOST_2G_2G is not set
661 +# CONFIG_UML_SMP is not set
662 +# CONFIG_SMP is not set
663 +CONFIG_NEST_LEVEL=0
664 +CONFIG_KERNEL_HALF_GIGS=1
665 +# CONFIG_HIGHMEM is not set
666 +CONFIG_PROC_MM=y
667 +CONFIG_KERNEL_STACK_ORDER=2
668 +CONFIG_UML_REAL_TIME_CLOCK=y
669 +
670 +#
671 +# Loadable module support
672 +#
673 +CONFIG_MODULES=y
674 +# CONFIG_KMOD is not set
675 +
676 +#
677 +# Character Devices
678 +#
679 +CONFIG_STDIO_CONSOLE=y
680 +CONFIG_SSL=y
681 +CONFIG_FD_CHAN=y
682 +CONFIG_NULL_CHAN=y
683 +CONFIG_PORT_CHAN=y
684 +CONFIG_PTY_CHAN=y
685 +CONFIG_TTY_CHAN=y
686 +CONFIG_XTERM_CHAN=y
687 +CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
688 +CONFIG_CON_CHAN="xterm"
689 +CONFIG_SSL_CHAN="pty"
690 +CONFIG_UNIX98_PTYS=y
691 +CONFIG_UNIX98_PTY_COUNT=256
692 +# CONFIG_WATCHDOG is not set
693 +# CONFIG_WATCHDOG_NOWAYOUT is not set
694 +# CONFIG_SOFT_WATCHDOG is not set
695 +# CONFIG_UML_WATCHDOG is not set
696 +CONFIG_UML_SOUND=y
697 +CONFIG_SOUND=y
698 +CONFIG_HOSTAUDIO=y
699 +# CONFIG_TTY_LOG is not set
700 +
701 +#
702 +# Block Devices
703 +#
704 +CONFIG_BLK_DEV_UBD=y
705 +# CONFIG_BLK_DEV_UBD_SYNC is not set
706 +# CONFIG_COW is not set
707 +CONFIG_COW_COMMON=y
708 +CONFIG_BLK_DEV_LOOP=y
709 +CONFIG_BLK_DEV_NBD=y
710 +CONFIG_BLK_DEV_RAM=y
711 +CONFIG_BLK_DEV_RAM_SIZE=4096
712 +CONFIG_BLK_DEV_INITRD=y
713 +# CONFIG_MMAPPER is not set
714 +CONFIG_NETDEVICES=y
715 +
716 +#
717 +# Network Devices
718 +#
719 +CONFIG_UML_NET=y
720 +CONFIG_UML_NET_ETHERTAP=y
721 +CONFIG_UML_NET_TUNTAP=y
722 +CONFIG_UML_NET_SLIP=y
723 +CONFIG_UML_NET_SLIRP=y
724 +CONFIG_UML_NET_DAEMON=y
725 +CONFIG_UML_NET_MCAST=y
726 +# CONFIG_UML_NET_PCAP is not set
727 +CONFIG_DUMMY=y
728 +# CONFIG_BONDING is not set
729 +# CONFIG_EQUALIZER is not set
730 +CONFIG_TUN=y
731 +CONFIG_PPP=y
732 +# CONFIG_PPP_MULTILINK is not set
733 +# CONFIG_PPP_FILTER is not set
734 +# CONFIG_PPP_ASYNC is not set
735 +# CONFIG_PPP_SYNC_TTY is not set
736 +# CONFIG_PPP_DEFLATE is not set
737 +# CONFIG_PPP_BSDCOMP is not set
738 +# CONFIG_PPPOE is not set
739 +CONFIG_SLIP=y
740 +# CONFIG_SLIP_COMPRESSED is not set
741 +# CONFIG_SLIP_SMART is not set
742 +# CONFIG_SLIP_MODE_SLIP6 is not set
743 +
744 +#
745 +# Networking options
746 +#
747 +CONFIG_PACKET=y
748 +CONFIG_PACKET_MMAP=y
749 +# CONFIG_NETLINK_DEV is not set
750 +# CONFIG_NETFILTER is not set
751 +# CONFIG_FILTER is not set
752 +CONFIG_UNIX=y
753 +CONFIG_INET=y
754 +# CONFIG_IP_MULTICAST is not set
755 +# CONFIG_IP_ADVANCED_ROUTER is not set
756 +# CONFIG_IP_PNP is not set
757 +# CONFIG_NET_IPIP is not set
758 +# CONFIG_NET_IPGRE is not set
759 +# CONFIG_ARPD is not set
760 +# CONFIG_INET_ECN is not set
761 +# CONFIG_SYN_COOKIES is not set
762 +# CONFIG_IPV6 is not set
763 +# CONFIG_KHTTPD is not set
764 +
765 +#
766 +#    SCTP Configuration (EXPERIMENTAL)
767 +#
768 +CONFIG_IPV6_SCTP__=y
769 +# CONFIG_IP_SCTP is not set
770 +# CONFIG_ATM is not set
771 +# CONFIG_VLAN_8021Q is not set
772 +
773 +#
774 +#  
775 +#
776 +# CONFIG_IPX is not set
777 +# CONFIG_ATALK is not set
778 +
779 +#
780 +# Appletalk devices
781 +#
782 +# CONFIG_DEV_APPLETALK is not set
783 +# CONFIG_DECNET is not set
784 +# CONFIG_BRIDGE is not set
785 +# CONFIG_X25 is not set
786 +# CONFIG_LAPB is not set
787 +# CONFIG_LLC is not set
788 +# CONFIG_NET_DIVERT is not set
789 +# CONFIG_ECONET is not set
790 +# CONFIG_WAN_ROUTER is not set
791 +# CONFIG_NET_FASTROUTE is not set
792 +# CONFIG_NET_HW_FLOWCONTROL is not set
793 +
794 +#
795 +# QoS and/or fair queueing
796 +#
797 +# CONFIG_NET_SCHED is not set
798 +
799 +#
800 +# Network testing
801 +#
802 +# CONFIG_NET_PKTGEN is not set
803 +
804 +#
805 +# File systems
806 +#
807 +CONFIG_QUOTA=y
808 +# CONFIG_QFMT_V2 is not set
809 +CONFIG_AUTOFS_FS=y
810 +CONFIG_AUTOFS4_FS=y
811 +CONFIG_REISERFS_FS=y
812 +# CONFIG_REISERFS_CHECK is not set
813 +# CONFIG_REISERFS_PROC_INFO is not set
814 +# CONFIG_ADFS_FS is not set
815 +# CONFIG_ADFS_FS_RW is not set
816 +# CONFIG_AFFS_FS is not set
817 +# CONFIG_HFS_FS is not set
818 +# CONFIG_HFSPLUS_FS is not set
819 +# CONFIG_BEFS_FS is not set
820 +# CONFIG_BEFS_DEBUG is not set
821 +# CONFIG_BFS_FS is not set
822 +# CONFIG_EXT3_FS is not set
823 +# CONFIG_JBD is not set
824 +# CONFIG_JBD_DEBUG is not set
825 +CONFIG_FAT_FS=y
826 +CONFIG_MSDOS_FS=y
827 +CONFIG_UMSDOS_FS=y
828 +CONFIG_VFAT_FS=y
829 +# CONFIG_EFS_FS is not set
830 +CONFIG_JFFS_FS=y
831 +CONFIG_JFFS_FS_VERBOSE=0
832 +CONFIG_JFFS_PROC_FS=y
833 +CONFIG_JFFS2_FS=y
834 +CONFIG_JFFS2_FS_DEBUG=0
835 +# CONFIG_CRAMFS is not set
836 +# CONFIG_TMPFS is not set
837 +CONFIG_RAMFS=y
838 +CONFIG_ISO9660_FS=y
839 +# CONFIG_JOLIET is not set
840 +# CONFIG_ZISOFS is not set
841 +# CONFIG_JFS_FS is not set
842 +# CONFIG_JFS_DEBUG is not set
843 +# CONFIG_JFS_STATISTICS is not set
844 +CONFIG_MINIX_FS=y
845 +# CONFIG_VXFS_FS is not set
846 +# CONFIG_NTFS_FS is not set
847 +# CONFIG_NTFS_RW is not set
848 +# CONFIG_HPFS_FS is not set
849 +CONFIG_PROC_FS=y
850 +CONFIG_DEVFS_FS=y
851 +CONFIG_DEVFS_MOUNT=y
852 +# CONFIG_DEVFS_DEBUG is not set
853 +CONFIG_DEVPTS_FS=y
854 +# CONFIG_QNX4FS_FS is not set
855 +# CONFIG_QNX4FS_RW is not set
856 +# CONFIG_ROMFS_FS is not set
857 +CONFIG_EXT2_FS=y
858 +# CONFIG_SYSV_FS is not set
859 +# CONFIG_UDF_FS is not set
860 +# CONFIG_UDF_RW is not set
861 +# CONFIG_UFS_FS is not set
862 +# CONFIG_UFS_FS_WRITE is not set
863 +
864 +#
865 +# Network File Systems
866 +#
867 +# CONFIG_CODA_FS is not set
868 +# CONFIG_INTERMEZZO_FS is not set
869 +# CONFIG_NFS_FS is not set
870 +# CONFIG_NFS_V3 is not set
871 +# CONFIG_NFS_DIRECTIO is not set
872 +# CONFIG_ROOT_NFS is not set
873 +# CONFIG_NFSD is not set
874 +# CONFIG_NFSD_V3 is not set
875 +# CONFIG_NFSD_TCP is not set
876 +# CONFIG_SUNRPC is not set
877 +# CONFIG_LOCKD is not set
878 +# CONFIG_SMB_FS is not set
879 +# CONFIG_NCP_FS is not set
880 +# CONFIG_NCPFS_PACKET_SIGNING is not set
881 +# CONFIG_NCPFS_IOCTL_LOCKING is not set
882 +# CONFIG_NCPFS_STRONG is not set
883 +# CONFIG_NCPFS_NFS_NS is not set
884 +# CONFIG_NCPFS_OS2_NS is not set
885 +# CONFIG_NCPFS_SMALLDOS is not set
886 +# CONFIG_NCPFS_NLS is not set
887 +# CONFIG_NCPFS_EXTRAS is not set
888 +# CONFIG_ZISOFS_FS is not set
889 +
890 +#
891 +# Partition Types
892 +#
893 +# CONFIG_PARTITION_ADVANCED is not set
894 +CONFIG_MSDOS_PARTITION=y
895 +# CONFIG_SMB_NLS is not set
896 +CONFIG_NLS=y
897 +
898 +#
899 +# Native Language Support
900 +#
901 +CONFIG_NLS_DEFAULT="iso8859-1"
902 +# CONFIG_NLS_CODEPAGE_437 is not set
903 +# CONFIG_NLS_CODEPAGE_737 is not set
904 +# CONFIG_NLS_CODEPAGE_775 is not set
905 +# CONFIG_NLS_CODEPAGE_850 is not set
906 +# CONFIG_NLS_CODEPAGE_852 is not set
907 +# CONFIG_NLS_CODEPAGE_855 is not set
908 +# CONFIG_NLS_CODEPAGE_857 is not set
909 +# CONFIG_NLS_CODEPAGE_860 is not set
910 +# CONFIG_NLS_CODEPAGE_861 is not set
911 +# CONFIG_NLS_CODEPAGE_862 is not set
912 +# CONFIG_NLS_CODEPAGE_863 is not set
913 +# CONFIG_NLS_CODEPAGE_864 is not set
914 +# CONFIG_NLS_CODEPAGE_865 is not set
915 +# CONFIG_NLS_CODEPAGE_866 is not set
916 +# CONFIG_NLS_CODEPAGE_869 is not set
917 +# CONFIG_NLS_CODEPAGE_936 is not set
918 +# CONFIG_NLS_CODEPAGE_950 is not set
919 +# CONFIG_NLS_CODEPAGE_932 is not set
920 +# CONFIG_NLS_CODEPAGE_949 is not set
921 +# CONFIG_NLS_CODEPAGE_874 is not set
922 +# CONFIG_NLS_ISO8859_8 is not set
923 +# CONFIG_NLS_CODEPAGE_1250 is not set
924 +# CONFIG_NLS_CODEPAGE_1251 is not set
925 +# CONFIG_NLS_ISO8859_1 is not set
926 +# CONFIG_NLS_ISO8859_2 is not set
927 +# CONFIG_NLS_ISO8859_3 is not set
928 +# CONFIG_NLS_ISO8859_4 is not set
929 +# CONFIG_NLS_ISO8859_5 is not set
930 +# CONFIG_NLS_ISO8859_6 is not set
931 +# CONFIG_NLS_ISO8859_7 is not set
932 +# CONFIG_NLS_ISO8859_9 is not set
933 +# CONFIG_NLS_ISO8859_13 is not set
934 +# CONFIG_NLS_ISO8859_14 is not set
935 +# CONFIG_NLS_ISO8859_15 is not set
936 +# CONFIG_NLS_KOI8_R is not set
937 +# CONFIG_NLS_KOI8_U is not set
938 +# CONFIG_NLS_UTF8 is not set
939 +
940 +#
941 +# SCSI support
942 +#
943 +CONFIG_SCSI=y
944 +
945 +#
946 +# SCSI support type (disk, tape, CD-ROM)
947 +#
948 +# CONFIG_BLK_DEV_SD is not set
949 +# CONFIG_CHR_DEV_ST is not set
950 +# CONFIG_BLK_DEV_SR is not set
951 +# CONFIG_CHR_DEV_SG is not set
952 +
953 +#
954 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
955 +#
956 +# CONFIG_SCSI_DEBUG_QUEUES is not set
957 +# CONFIG_SCSI_MULTI_LUN is not set
958 +# CONFIG_SCSI_CONSTANTS is not set
959 +# CONFIG_SCSI_LOGGING is not set
960 +CONFIG_SCSI_DEBUG=y
961 +
962 +#
963 +# Multi-device support (RAID and LVM)
964 +#
965 +# CONFIG_MD is not set
966 +# CONFIG_BLK_DEV_MD is not set
967 +# CONFIG_MD_LINEAR is not set
968 +# CONFIG_MD_RAID0 is not set
969 +# CONFIG_MD_RAID1 is not set
970 +# CONFIG_MD_RAID5 is not set
971 +# CONFIG_MD_MULTIPATH is not set
972 +# CONFIG_BLK_DEV_LVM is not set
973 +
974 +#
975 +# Memory Technology Devices (MTD)
976 +#
977 +CONFIG_MTD=y
978 +# CONFIG_MTD_DEBUG is not set
979 +# CONFIG_MTD_PARTITIONS is not set
980 +# CONFIG_MTD_CONCAT is not set
981 +# CONFIG_MTD_REDBOOT_PARTS is not set
982 +# CONFIG_MTD_CMDLINE_PARTS is not set
983 +
984 +#
985 +# User Modules And Translation Layers
986 +#
987 +CONFIG_MTD_CHAR=y
988 +CONFIG_MTD_BLOCK=y
989 +# CONFIG_FTL is not set
990 +# CONFIG_NFTL is not set
991 +
992 +#
993 +# RAM/ROM/Flash chip drivers
994 +#
995 +# CONFIG_MTD_CFI is not set
996 +# CONFIG_MTD_JEDECPROBE is not set
997 +# CONFIG_MTD_GEN_PROBE is not set
998 +# CONFIG_MTD_CFI_INTELEXT is not set
999 +# CONFIG_MTD_CFI_AMDSTD is not set
1000 +# CONFIG_MTD_CFI_STAA is not set
1001 +# CONFIG_MTD_RAM is not set
1002 +# CONFIG_MTD_ROM is not set
1003 +# CONFIG_MTD_ABSENT is not set
1004 +# CONFIG_MTD_OBSOLETE_CHIPS is not set
1005 +# CONFIG_MTD_AMDSTD is not set
1006 +# CONFIG_MTD_SHARP is not set
1007 +# CONFIG_MTD_JEDEC is not set
1008 +
1009 +#
1010 +# Mapping drivers for chip access
1011 +#
1012 +# CONFIG_MTD_PHYSMAP is not set
1013 +# CONFIG_MTD_PCI is not set
1014 +# CONFIG_MTD_PCMCIA is not set
1015 +
1016 +#
1017 +# Self-contained MTD device drivers
1018 +#
1019 +# CONFIG_MTD_PMC551 is not set
1020 +# CONFIG_MTD_SLRAM is not set
1021 +# CONFIG_MTD_MTDRAM is not set
1022 +CONFIG_MTD_BLKMTD=y
1023 +
1024 +#
1025 +# Disk-On-Chip Device Drivers
1026 +#
1027 +# CONFIG_MTD_DOC1000 is not set
1028 +# CONFIG_MTD_DOC2000 is not set
1029 +# CONFIG_MTD_DOC2001 is not set
1030 +# CONFIG_MTD_DOCPROBE is not set
1031 +
1032 +#
1033 +# NAND Flash Device Drivers
1034 +#
1035 +# CONFIG_MTD_NAND is not set
1036 +
1037 +#
1038 +# Library routines
1039 +#
1040 +# CONFIG_CRC32 is not set
1041 +CONFIG_ZLIB_INFLATE=y
1042 +CONFIG_ZLIB_DEFLATE=y
1043 +
1044 +#
1045 +# Kernel hacking
1046 +#
1047 +# CONFIG_DEBUG_SLAB is not set
1048 +CONFIG_DEBUGSYM=y
1049 +CONFIG_PT_PROXY=y
1050 +# CONFIG_GPROF is not set
1051 +# CONFIG_GCOV is not set
1052 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_kern.c um/arch/um/drivers/chan_kern.c
1053 --- orig/arch/um/drivers/chan_kern.c    1969-12-31 19:00:00.000000000 -0500
1054 +++ um/arch/um/drivers/chan_kern.c      2003-11-07 07:25:34.000000000 -0500
1055 @@ -0,0 +1,519 @@
1056 +/* 
1057 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
1058 + * Licensed under the GPL
1059 + */
1060 +
1061 +#include <linux/stddef.h>
1062 +#include <linux/kernel.h>
1063 +#include <linux/list.h>
1064 +#include <linux/slab.h>
1065 +#include <linux/tty.h>
1066 +#include <linux/string.h>
1067 +#include <linux/tty_flip.h>
1068 +#include <asm/irq.h>
1069 +#include "chan_kern.h"
1070 +#include "user_util.h"
1071 +#include "kern.h"
1072 +#include "irq_user.h"
1073 +#include "sigio.h"
1074 +#include "line.h"
1075 +
1076 +static void *not_configged_init(char *str, int device, struct chan_opts *opts)
1077 +{
1078 +       printk(KERN_ERR "Using a channel type which is configured out of "
1079 +              "UML\n");
1080 +       return(NULL);
1081 +}
1082 +
1083 +static int not_configged_open(int input, int output, int primary, void *data,
1084 +                             char **dev_out)
1085 +{
1086 +       printk(KERN_ERR "Using a channel type which is configured out of "
1087 +              "UML\n");
1088 +       return(-ENODEV);
1089 +}
1090 +
1091 +static void not_configged_close(int fd, void *data)
1092 +{
1093 +       printk(KERN_ERR "Using a channel type which is configured out of "
1094 +              "UML\n");
1095 +}
1096 +
1097 +static int not_configged_read(int fd, char *c_out, void *data)
1098 +{
1099 +       printk(KERN_ERR "Using a channel type which is configured out of "
1100 +              "UML\n");
1101 +       return(-EIO);
1102 +}
1103 +
1104 +static int not_configged_write(int fd, const char *buf, int len, void *data)
1105 +{
1106 +       printk(KERN_ERR "Using a channel type which is configured out of "
1107 +              "UML\n");
1108 +       return(-EIO);
1109 +}
1110 +
1111 +static int not_configged_console_write(int fd, const char *buf, int len,
1112 +                                      void *data)
1113 +{
1114 +       printk(KERN_ERR "Using a channel type which is configured out of "
1115 +              "UML\n");
1116 +       return(-EIO);
1117 +}
1118 +
1119 +static int not_configged_window_size(int fd, void *data, unsigned short *rows,
1120 +                                    unsigned short *cols)
1121 +{
1122 +       printk(KERN_ERR "Using a channel type which is configured out of "
1123 +              "UML\n");
1124 +       return(-ENODEV);
1125 +}
1126 +
1127 +static void not_configged_free(void *data)
1128 +{
1129 +       printk(KERN_ERR "Using a channel type which is configured out of "
1130 +              "UML\n");
1131 +}
1132 +
1133 +static struct chan_ops not_configged_ops = {
1134 +       .init           = not_configged_init,
1135 +       .open           = not_configged_open,
1136 +       .close          = not_configged_close,
1137 +       .read           = not_configged_read,
1138 +       .write          = not_configged_write,
1139 +       .console_write  = not_configged_console_write,
1140 +       .window_size    = not_configged_window_size,
1141 +       .free           = not_configged_free,
1142 +       .winch          = 0,
1143 +};
1144 +
1145 +static void tty_receive_char(struct tty_struct *tty, char ch)
1146 +{
1147 +       if(tty == NULL) return;
1148 +
1149 +       if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
1150 +               if(ch == STOP_CHAR(tty)){
1151 +                       stop_tty(tty);
1152 +                       return;
1153 +               }
1154 +               else if(ch == START_CHAR(tty)){
1155 +                       start_tty(tty);
1156 +                       return;
1157 +               }
1158 +       }
1159 +
1160 +       if((tty->flip.flag_buf_ptr == NULL) || 
1161 +          (tty->flip.char_buf_ptr == NULL))
1162 +               return;
1163 +       tty_insert_flip_char(tty, ch, TTY_NORMAL);
1164 +}
1165 +
1166 +static int open_one_chan(struct chan *chan, int input, int output, int primary)
1167 +{
1168 +       int fd;
1169 +
1170 +       if(chan->opened) return(0);
1171 +       if(chan->ops->open == NULL) fd = 0;
1172 +       else fd = (*chan->ops->open)(input, output, primary, chan->data,
1173 +                                    &chan->dev);
1174 +       if(fd < 0) return(fd);
1175 +       chan->fd = fd;
1176 +
1177 +       chan->opened = 1;
1178 +       return(0);
1179 +}
1180 +
1181 +int open_chan(struct list_head *chans)
1182 +{
1183 +       struct list_head *ele;
1184 +       struct chan *chan;
1185 +       int ret, err = 0;
1186 +
1187 +       list_for_each(ele, chans){
1188 +               chan = list_entry(ele, struct chan, list);
1189 +               ret = open_one_chan(chan, chan->input, chan->output,
1190 +                                   chan->primary);
1191 +               if(chan->primary) err = ret;
1192 +       }
1193 +       return(err);
1194 +}
1195 +
1196 +void chan_enable_winch(struct list_head *chans, void *line)
1197 +{
1198 +       struct list_head *ele;
1199 +       struct chan *chan;
1200 +
1201 +       list_for_each(ele, chans){
1202 +               chan = list_entry(ele, struct chan, list);
1203 +               if(chan->primary && chan->output && chan->ops->winch){
1204 +                       register_winch(chan->fd, line);
1205 +                       return;
1206 +               }
1207 +       }
1208 +}
1209 +
1210 +void enable_chan(struct list_head *chans, void *data)
1211 +{
1212 +       struct list_head *ele;
1213 +       struct chan *chan;
1214 +
1215 +       list_for_each(ele, chans){
1216 +               chan = list_entry(ele, struct chan, list);
1217 +               if(!chan->opened) continue;
1218 +
1219 +               line_setup_irq(chan->fd, chan->input, chan->output, data);
1220 +       }
1221 +}
1222 +
1223 +void close_chan(struct list_head *chans)
1224 +{
1225 +       struct list_head *ele;
1226 +       struct chan *chan;
1227 +
1228 +       /* Close in reverse order as open in case more than one of them
1229 +        * refers to the same device and they save and restore that device's
1230 +        * state.  Then, the first one opened will have the original state,
1231 +        * so it must be the last closed.
1232 +        */
1233 +        for(ele = chans->prev; ele != chans; ele = ele->prev){
1234 +                chan = list_entry(ele, struct chan, list);
1235 +               if(!chan->opened) continue;
1236 +               if(chan->ops->close != NULL)
1237 +                       (*chan->ops->close)(chan->fd, chan->data);
1238 +               chan->opened = 0;
1239 +               chan->fd = -1;
1240 +       }
1241 +}
1242 +
1243 +int write_chan(struct list_head *chans, const char *buf, int len, 
1244 +              int write_irq)
1245 +{
1246 +       struct list_head *ele;
1247 +       struct chan *chan;
1248 +       int n, ret = 0;
1249 +
1250 +       list_for_each(ele, chans){
1251 +               chan = list_entry(ele, struct chan, list);
1252 +               if(!chan->output || (chan->ops->write == NULL)) continue;
1253 +               n = chan->ops->write(chan->fd, buf, len, chan->data);
1254 +               if(chan->primary){
1255 +                       ret = n;
1256 +                       if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){
1257 +                               reactivate_fd(chan->fd, write_irq);
1258 +                               if(ret == -EAGAIN) ret = 0;
1259 +                       }
1260 +               }
1261 +       }
1262 +       return(ret);
1263 +}
1264 +
1265 +int console_write_chan(struct list_head *chans, const char *buf, int len)
1266 +{
1267 +       struct list_head *ele;
1268 +       struct chan *chan;
1269 +       int n, ret = 0;
1270 +
1271 +       list_for_each(ele, chans){
1272 +               chan = list_entry(ele, struct chan, list);
1273 +               if(!chan->output || (chan->ops->console_write == NULL))
1274 +                       continue;
1275 +               n = chan->ops->console_write(chan->fd, buf, len, chan->data);
1276 +               if(chan->primary) ret = n;
1277 +       }
1278 +       return(ret);
1279 +}
1280 +
1281 +int chan_window_size(struct list_head *chans, unsigned short *rows_out,
1282 +                     unsigned short *cols_out)
1283 +{
1284 +       struct list_head *ele;
1285 +       struct chan *chan;
1286 +
1287 +       list_for_each(ele, chans){
1288 +               chan = list_entry(ele, struct chan, list);
1289 +               if(chan->primary){
1290 +                       if(chan->ops->window_size == NULL) return(0);
1291 +                       return(chan->ops->window_size(chan->fd, chan->data,
1292 +                                                     rows_out, cols_out));
1293 +               }
1294 +       }
1295 +       return(0);
1296 +}
1297 +
1298 +void free_one_chan(struct chan *chan)
1299 +{
1300 +       list_del(&chan->list);
1301 +       if(chan->ops->free != NULL)
1302 +               (*chan->ops->free)(chan->data);
1303 +       free_irq_by_fd(chan->fd);
1304 +       if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
1305 +       kfree(chan);
1306 +}
1307 +
1308 +void free_chan(struct list_head *chans)
1309 +{
1310 +       struct list_head *ele, *next;
1311 +       struct chan *chan;
1312 +
1313 +       list_for_each_safe(ele, next, chans){
1314 +               chan = list_entry(ele, struct chan, list);
1315 +               free_one_chan(chan);
1316 +       }
1317 +}
1318 +
1319 +static int one_chan_config_string(struct chan *chan, char *str, int size,
1320 +                                 char **error_out)
1321 +{
1322 +       int n = 0;
1323 +
1324 +       if(chan == NULL){
1325 +               CONFIG_CHUNK(str, size, n, "none", 1);
1326 +               return(n);
1327 +       }
1328 +
1329 +       CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
1330 +
1331 +       if(chan->dev == NULL){
1332 +               CONFIG_CHUNK(str, size, n, "", 1);
1333 +               return(n);
1334 +       }
1335 +
1336 +       CONFIG_CHUNK(str, size, n, ":", 0);
1337 +       CONFIG_CHUNK(str, size, n, chan->dev, 0);
1338 +
1339 +       return(n);
1340 +}
1341 +
1342 +static int chan_pair_config_string(struct chan *in, struct chan *out, 
1343 +                                  char *str, int size, char **error_out)
1344 +{
1345 +       int n;
1346 +
1347 +       n = one_chan_config_string(in, str, size, error_out);
1348 +       str += n;
1349 +       size -= n;
1350 +
1351 +       if(in == out){
1352 +               CONFIG_CHUNK(str, size, n, "", 1);
1353 +               return(n);
1354 +       }
1355 +
1356 +       CONFIG_CHUNK(str, size, n, ",", 1);
1357 +       n = one_chan_config_string(out, str, size, error_out);
1358 +       str += n;
1359 +       size -= n;
1360 +       CONFIG_CHUNK(str, size, n, "", 1);
1361 +
1362 +       return(n);
1363 +}
1364 +
1365 +int chan_config_string(struct list_head *chans, char *str, int size, 
1366 +                      char **error_out)
1367 +{
1368 +       struct list_head *ele;
1369 +       struct chan *chan, *in = NULL, *out = NULL;
1370 +
1371 +       list_for_each(ele, chans){
1372 +               chan = list_entry(ele, struct chan, list);
1373 +               if(!chan->primary)
1374 +                       continue;
1375 +               if(chan->input)
1376 +                       in = chan;
1377 +               if(chan->output)
1378 +                       out = chan;
1379 +       }
1380 +
1381 +       return(chan_pair_config_string(in, out, str, size, error_out));
1382 +}
1383 +
1384 +struct chan_type {
1385 +       char *key;
1386 +       struct chan_ops *ops;
1387 +};
1388 +
1389 +struct chan_type chan_table[] = {
1390 +#ifdef CONFIG_FD_CHAN
1391 +       { "fd", &fd_ops },
1392 +#else
1393 +       { "fd", &not_configged_ops },
1394 +#endif
1395 +
1396 +#ifdef CONFIG_NULL_CHAN
1397 +       { "null", &null_ops },
1398 +#else
1399 +       { "null", &not_configged_ops },
1400 +#endif
1401 +
1402 +#ifdef CONFIG_PORT_CHAN
1403 +       { "port", &port_ops },
1404 +#else
1405 +       { "port", &not_configged_ops },
1406 +#endif
1407 +
1408 +#ifdef CONFIG_PTY_CHAN
1409 +       { "pty", &pty_ops },
1410 +       { "pts", &pts_ops },
1411 +#else
1412 +       { "pty", &not_configged_ops },
1413 +       { "pts", &not_configged_ops },
1414 +#endif
1415 +
1416 +#ifdef CONFIG_TTY_CHAN
1417 +       { "tty", &tty_ops },
1418 +#else
1419 +       { "tty", &not_configged_ops },
1420 +#endif
1421 +
1422 +#ifdef CONFIG_XTERM_CHAN
1423 +       { "xterm", &xterm_ops },
1424 +#else
1425 +       { "xterm", &not_configged_ops },
1426 +#endif
1427 +};
1428 +
1429 +static struct chan *parse_chan(char *str, int pri, int device, 
1430 +                              struct chan_opts *opts)
1431 +{
1432 +       struct chan_type *entry;
1433 +       struct chan_ops *ops;
1434 +       struct chan *chan;
1435 +       void *data;
1436 +       int i;
1437 +
1438 +       ops = NULL;
1439 +       data = NULL;
1440 +       for(i = 0; i < sizeof(chan_table)/sizeof(chan_table[0]); i++){
1441 +               entry = &chan_table[i];
1442 +               if(!strncmp(str, entry->key, strlen(entry->key))){
1443 +                       ops = entry->ops;
1444 +                       str += strlen(entry->key);
1445 +                       break;
1446 +               }
1447 +       }
1448 +       if(ops == NULL){
1449 +               printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n", 
1450 +                      str);
1451 +               return(NULL);
1452 +       }
1453 +       if(ops->init == NULL) return(NULL); 
1454 +       data = (*ops->init)(str, device, opts);
1455 +       if(data == NULL) return(NULL);
1456 +
1457 +       chan = kmalloc(sizeof(*chan), GFP_KERNEL);
1458 +       if(chan == NULL) return(NULL);
1459 +       *chan = ((struct chan) { .list          = LIST_HEAD_INIT(chan->list),
1460 +                                .primary       = 1,
1461 +                                .input         = 0,
1462 +                                .output        = 0,
1463 +                                .opened        = 0,
1464 +                                .fd            = -1,
1465 +                                .pri           = pri,
1466 +                                .ops           = ops,
1467 +                                .data          = data });
1468 +       return(chan);
1469 +}
1470 +
1471 +int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
1472 +                   struct chan_opts *opts)
1473 +{
1474 +       struct chan *new, *chan;
1475 +       char *in, *out;
1476 +
1477 +       if(!list_empty(chans)){
1478 +               chan = list_entry(chans->next, struct chan, list);
1479 +               if(chan->pri >= pri) return(0);
1480 +               free_chan(chans);
1481 +               INIT_LIST_HEAD(chans);
1482 +       }
1483 +
1484 +       out = strchr(str, ',');
1485 +       if(out != NULL){
1486 +               in = str;
1487 +               *out = '\0';
1488 +               out++;
1489 +               new = parse_chan(in, pri, device, opts);
1490 +               if(new == NULL) return(-1);
1491 +               new->input = 1;
1492 +               list_add(&new->list, chans);
1493 +
1494 +               new = parse_chan(out, pri, device, opts);
1495 +               if(new == NULL) return(-1);
1496 +               list_add(&new->list, chans);
1497 +               new->output = 1;
1498 +       }
1499 +       else {
1500 +               new = parse_chan(str, pri, device, opts);
1501 +               if(new == NULL) return(-1);
1502 +               list_add(&new->list, chans);
1503 +               new->input = 1;
1504 +               new->output = 1;
1505 +       }
1506 +       return(0);
1507 +}
1508 +
1509 +int chan_out_fd(struct list_head *chans)
1510 +{
1511 +       struct list_head *ele;
1512 +       struct chan *chan;
1513 +
1514 +       list_for_each(ele, chans){
1515 +               chan = list_entry(ele, struct chan, list);
1516 +               if(chan->primary && chan->output)
1517 +                       return(chan->fd);
1518 +       }
1519 +       return(-1);
1520 +}
1521 +
1522 +void chan_interrupt(struct list_head *chans, struct tq_struct *task,
1523 +                   struct tty_struct *tty, int irq, void *dev)
1524 +{
1525 +       struct list_head *ele, *next;
1526 +       struct chan *chan;
1527 +       int err;
1528 +       char c;
1529 +
1530 +       list_for_each_safe(ele, next, chans){
1531 +               chan = list_entry(ele, struct chan, list);
1532 +               if(!chan->input || (chan->ops->read == NULL)) continue;
1533 +               do {
1534 +                       if((tty != NULL) && 
1535 +                          (tty->flip.count >= TTY_FLIPBUF_SIZE)){
1536 +                               queue_task(task, &tq_timer);
1537 +                               goto out;
1538 +                       }
1539 +                       err = chan->ops->read(chan->fd, &c, chan->data);
1540 +                       if(err > 0) 
1541 +                               tty_receive_char(tty, c);
1542 +               } while(err > 0);
1543 +
1544 +               if(err == 0) reactivate_fd(chan->fd, irq);
1545 +               if(err == -EIO){
1546 +                       if(chan->primary){
1547 +                               if(tty != NULL) 
1548 +                                       tty_hangup(tty);
1549 +                               line_disable(dev, irq);
1550 +                               close_chan(chans);
1551 +                               free_chan(chans);
1552 +                               return;
1553 +                       }
1554 +                       else {
1555 +                               if(chan->ops->close != NULL)
1556 +                                       chan->ops->close(chan->fd, chan->data);
1557 +                               free_one_chan(chan);
1558 +                       }
1559 +               }
1560 +       }
1561 + out:
1562 +       if(tty) tty_flip_buffer_push(tty);
1563 +}
1564 +
1565 +/*
1566 + * Overrides for Emacs so that we follow Linus's tabbing style.
1567 + * Emacs will notice this stuff at the end of the file and automatically
1568 + * adjust the settings for this buffer only.  This must remain at the end
1569 + * of the file.
1570 + * ---------------------------------------------------------------------------
1571 + * Local variables:
1572 + * c-file-style: "linux"
1573 + * End:
1574 + */
1575 diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_user.c um/arch/um/drivers/chan_user.c
1576 --- orig/arch/um/drivers/chan_user.c    1969-12-31 19:00:00.000000000 -0500
1577 +++ um/arch/um/drivers/chan_user.c      2003-11-07 07:23:45.000000000 -0500
1578 @@ -0,0 +1,217 @@
1579 +/* 
1580 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
1581 + * Licensed under the GPL
1582 + */
1583 +
1584 +#include <unistd.h>
1585 +#include <stdlib.h>
1586 +#include <errno.h>
1587 +#include <termios.h>
1588 +#include <string.h>
1589 +#include <signal.h>
1590 +#include <sys/stat.h>
1591 +#include <sys/ioctl.h>
1592 +#include <sys/socket.h>
1593 +#include "kern_util.h"
1594 +#include "user_util.h"
1595 +#include "chan_user.h"
1596 +#include "user.h"
1597 +#include "helper.h"
1598 +#include "os.h"
1599 +#include "choose-mode.h"
1600 +#include "mode.h"
1601 +
1602 +void generic_close(int fd, void *unused)
1603 +{
1604 +       os_close_file(fd);
1605 +}
1606 +
1607 +int generic_read(int fd, char *c_out, void *unused)
1608 +{
1609 +       int n;
1610 +
1611 +       n = os_read_file(fd, c_out, sizeof(*c_out));
1612 +
1613 +       if(n == -EAGAIN) 
1614 +               return(0);
1615 +       else if(n == 0) 
1616 +               return(-EIO);
1617 +       return(n);
1618 +}
1619 +
1620 +/* XXX Trivial wrapper around os_write_file */
1621 +
1622 +int generic_write(int fd, const char *buf, int n, void *unused)
1623 +{
1624 +       return(os_write_file(fd, buf, n));
1625 +}
1626 +
1627 +int generic_console_write(int fd, const char *buf, int n, void *unused)
1628 +{
1629 +       struct termios save, new;
1630 +       int err;
1631 +
1632 +       if(isatty(fd)){
1633 +               tcgetattr(fd, &save);
1634 +               new = save;
1635 +               new.c_oflag |= OPOST;
1636 +               tcsetattr(fd, TCSAFLUSH, &new);
1637 +       }
1638 +       err = generic_write(fd, buf, n, NULL);
1639 +       if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
1640 +       return(err);
1641 +}
1642 +
1643 +int generic_window_size(int fd, void *unused, unsigned short *rows_out,
1644 +                       unsigned short *cols_out)
1645 +{
1646 +       int rows, cols;
1647 +       int ret;
1648 +
1649 +       ret = os_window_size(fd, &rows, &cols);
1650 +       if(ret < 0)
1651 +               return(ret);
1652 +
1653 +       ret = ((*rows_out != rows) || (*cols_out != cols));
1654 +
1655 +       *rows_out = rows;
1656 +       *cols_out = cols;
1657 +
1658 +       return(ret);
1659 +}
1660 +
1661 +void generic_free(void *data)
1662 +{
1663 +       kfree(data);
1664 +}
1665 +
1666 +static void winch_handler(int sig)
1667 +{
1668 +}
1669 +
1670 +struct winch_data {
1671 +       int pty_fd;
1672 +       int pipe_fd;
1673 +       int close_me;
1674 +};
1675 +
1676 +static int winch_thread(void *arg)
1677 +{
1678 +       struct winch_data *data = arg;
1679 +       sigset_t sigs;
1680 +       int pty_fd, pipe_fd;
1681 +       int count, err;
1682 +       char c = 1;
1683 +
1684 +       os_close_file(data->close_me);
1685 +       pty_fd = data->pty_fd;
1686 +       pipe_fd = data->pipe_fd;
1687 +       count = os_write_file(pipe_fd, &c, sizeof(c));
1688 +       if(count != sizeof(c))
1689 +               printk("winch_thread : failed to write synchronization "
1690 +                      "byte, err = %d\n", -count);
1691 +
1692 +       signal(SIGWINCH, winch_handler);
1693 +       sigfillset(&sigs);
1694 +       sigdelset(&sigs, SIGWINCH);
1695 +       if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
1696 +               printk("winch_thread : sigprocmask failed, errno = %d\n", 
1697 +                      errno);
1698 +               exit(1);
1699 +       }
1700 +
1701 +       if(setsid() < 0){
1702 +               printk("winch_thread : setsid failed, errno = %d\n", errno);
1703 +               exit(1);
1704 +       }
1705 +
1706 +       err = os_new_tty_pgrp(pty_fd, os_getpid());
1707 +       if(err < 0){
1708 +               printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
1709 +               exit(1);
1710 +       }
1711 +
1712 +       count = os_read_file(pipe_fd, &c, sizeof(c));
1713 +       if(count != sizeof(c))
1714 +               printk("winch_thread : failed to read synchronization byte, "
1715 +                      "err = %d\n", -count);
1716 +
1717 +       while(1){
1718 +               pause();
1719 +
1720 +               count = os_write_file(pipe_fd, &c, sizeof(c));
1721 +               if(count != sizeof(c))
1722 +                       printk("winch_thread : write failed, err = %d\n",
1723 +                              -count);
1724 +       }
1725 +}
1726 +
1727 +static int winch_tramp(int fd, void *device_data, int *fd_out)
1728 +{
1729 +       struct winch_data data;
1730 +       unsigned long stack;
1731 +       int fds[2], pid, n, err;
1732 +       char c;
1733 +
1734 +       err = os_pipe(fds, 1, 1);
1735 +       if(err < 0){
1736 +               printk("winch_tramp : os_pipe failed, err = %d\n", -err);
1737 +               return(err);
1738 +       }
1739 +
1740 +       data = ((struct winch_data) { .pty_fd           = fd,
1741 +                                     .pipe_fd          = fds[1],
1742 +                                     .close_me         = fds[0] } );
1743 +       pid = run_helper_thread(winch_thread, &data, 0, &stack, 0);
1744 +       if(pid < 0){
1745 +               printk("fork of winch_thread failed - errno = %d\n", errno);
1746 +               return(pid);
1747 +       }
1748 +
1749 +       os_close_file(fds[1]);
1750 +       *fd_out = fds[0];
1751 +       n = os_read_file(fds[0], &c, sizeof(c));
1752 +       if(n != sizeof(c)){
1753 +               printk("winch_tramp : failed to read synchronization byte\n");
1754 +               printk("read failed, err = %d\n", -n);
1755 +               printk("fd %d will not support SIGWINCH\n", fd);
1756 +               *fd_out = -1;
1757 +       }
1758 +       return(pid);
1759 +}
1760 +
1761 +void register_winch(int fd, void *device_data)
1762 +{
1763 +       int pid, thread, thread_fd;
1764 +       int count;
1765 +       char c = 1;
1766 +
1767 +       if(!isatty(fd)) 
1768 +               return;
1769 +
1770 +       pid = tcgetpgrp(fd);
1771 +       if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
1772 +                            device_data) && (pid == -1)){
1773 +               thread = winch_tramp(fd, device_data, &thread_fd);
1774 +               if(fd != -1){
1775 +                       register_winch_irq(thread_fd, fd, thread, device_data);
1776 +
1777 +                       count = os_write_file(thread_fd, &c, sizeof(c));
1778 +                       if(count != sizeof(c))
1779 +                               printk("register_winch : failed to write "
1780 +                                      "synchronization byte, err = %d\n",
1781 +                                       -count);
1782 +               }
1783 +       }
1784 +}
1785 +
1786 +/*
1787 + * Overrides for Emacs so that we follow Linus's tabbing style.
1788 + * Emacs will notice this stuff at the end of the file and automatically
1789 + * adjust the settings for this buffer only.  This must remain at the end
1790 + * of the file.
1791 + * ---------------------------------------------------------------------------
1792 + * Local variables:
1793 + * c-file-style: "linux"
1794 + * End:
1795 + */
1796 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow.h um/arch/um/drivers/cow.h
1797 --- orig/arch/um/drivers/cow.h  1969-12-31 19:00:00.000000000 -0500
1798 +++ um/arch/um/drivers/cow.h    2003-12-15 00:32:23.000000000 -0500
1799 @@ -0,0 +1,41 @@
1800 +#ifndef __COW_H__
1801 +#define __COW_H__
1802 +
1803 +#include <asm/types.h>
1804 +
1805 +#if __BYTE_ORDER == __BIG_ENDIAN
1806 +# define ntohll(x) (x)
1807 +# define htonll(x) (x)
1808 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
1809 +# define ntohll(x)  bswap_64(x)
1810 +# define htonll(x)  bswap_64(x)
1811 +#else
1812 +#error "__BYTE_ORDER not defined"
1813 +#endif
1814 +
1815 +extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
1816 +                        int sectorsize, int alignment, int *bitmap_offset_out, 
1817 +                        unsigned long *bitmap_len_out, int *data_offset_out);
1818 +
1819 +extern int file_reader(__u64 offset, char *buf, int len, void *arg);
1820 +extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
1821 +                          void *arg, __u32 *version_out, 
1822 +                          char **backing_file_out, time_t *mtime_out, 
1823 +                          __u64 *size_out, int *sectorsize_out, 
1824 +                          __u32 *align_out, int *bitmap_offset_out);
1825 +
1826 +extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
1827 +                           int sectorsize, int alignment, long long *size);
1828 +
1829 +extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
1830 +                     int bitmap_offset, unsigned long *bitmap_len_out, 
1831 +                     int *data_offset_out);
1832 +
1833 +#endif
1834 +
1835 +/*
1836 + * ---------------------------------------------------------------------------
1837 + * Local variables:
1838 + * c-file-style: "linux"
1839 + * End:
1840 + */
1841 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_kern.c um/arch/um/drivers/cow_kern.c
1842 --- orig/arch/um/drivers/cow_kern.c     1969-12-31 19:00:00.000000000 -0500
1843 +++ um/arch/um/drivers/cow_kern.c       2003-10-21 03:26:06.000000000 -0400
1844 @@ -0,0 +1,630 @@
1845 +#define COW_MAJOR 60
1846 +#define MAJOR_NR COW_MAJOR
1847 +
1848 +#include <linux/stddef.h>
1849 +#include <linux/kernel.h>
1850 +#include <linux/ctype.h>
1851 +#include <linux/stat.h>
1852 +#include <linux/vmalloc.h>
1853 +#include <linux/blkdev.h>
1854 +#include <linux/blk.h>
1855 +#include <linux/fs.h>
1856 +#include <linux/genhd.h>
1857 +#include <linux/devfs_fs.h>
1858 +#include <asm/uaccess.h>
1859 +#include "2_5compat.h"
1860 +#include "cow.h"
1861 +#include "ubd_user.h"
1862 +
1863 +#define COW_SHIFT 4
1864 +
1865 +struct cow {
1866 +       int count;
1867 +       char *cow_path;
1868 +       dev_t cow_dev;
1869 +       struct block_device *cow_bdev;
1870 +       char *backing_path;
1871 +       dev_t backing_dev;
1872 +       struct block_device *backing_bdev;
1873 +       int sectorsize;
1874 +       unsigned long *bitmap;
1875 +       unsigned long bitmap_len;
1876 +       int bitmap_offset;
1877 +        int data_offset;
1878 +       devfs_handle_t devfs;
1879 +       struct semaphore sem;
1880 +       struct semaphore io_sem;
1881 +       atomic_t working;
1882 +       spinlock_t io_lock;
1883 +       struct buffer_head *bh;
1884 +       struct buffer_head *bhtail;
1885 +       void *end_io;
1886 +};
1887 +
1888 +#define DEFAULT_COW { \
1889 +       .count                  = 0, \
1890 +       .cow_path               = NULL, \
1891 +       .cow_dev                = 0, \
1892 +       .backing_path           = NULL, \
1893 +       .backing_dev            = 0, \
1894 +        .bitmap                        = NULL, \
1895 +       .bitmap_len             = 0, \
1896 +       .bitmap_offset          = 0, \
1897 +        .data_offset           = 0, \
1898 +       .devfs                  = NULL, \
1899 +       .working                = ATOMIC_INIT(0), \
1900 +       .io_lock                = SPIN_LOCK_UNLOCKED, \
1901 +}
1902 +
1903 +#define MAX_DEV (8)
1904 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
1905 +
1906 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
1907 +
1908 +/* Not modified by this driver */
1909 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
1910 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
1911 +
1912 +/* Protected by cow_lock */
1913 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
1914 +
1915 +static struct hd_struct        cow_part[MAX_MINOR] =
1916 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
1917 +
1918 +/* Protected by io_request_lock */
1919 +static request_queue_t *cow_queue;
1920 +
1921 +static int cow_open(struct inode *inode, struct file *filp);
1922 +static int cow_release(struct inode * inode, struct file * file);
1923 +static int cow_ioctl(struct inode * inode, struct file * file,
1924 +                    unsigned int cmd, unsigned long arg);
1925 +static int cow_revalidate(kdev_t rdev);
1926 +
1927 +static struct block_device_operations cow_blops = {
1928 +        .open          = cow_open,
1929 +        .release       = cow_release,
1930 +        .ioctl         = cow_ioctl,
1931 +        .revalidate    = cow_revalidate,
1932 +};
1933 +
1934 +/* Initialized in an initcall, and unchanged thereafter */
1935 +devfs_handle_t cow_dir_handle;
1936 +
1937 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
1938 +{ \
1939 +       .major          = maj, \
1940 +       .major_name     = name, \
1941 +       .minor_shift    = shift, \
1942 +       .max_p          = 1 << shift, \
1943 +       .part           = parts, \
1944 +       .sizes          = bsizes, \
1945 +       .nr_real        = max, \
1946 +       .real_devices   = NULL, \
1947 +       .next           = NULL, \
1948 +       .fops           = blops, \
1949 +       .de_arr         = NULL, \
1950 +       .flags          = 0 \
1951 +}
1952 +
1953 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
1954 +
1955 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
1956 +                                                COW_SHIFT, sizes, MAX_DEV, 
1957 +                                                &cow_blops);
1958 +
1959 +static int cow_add(int n)
1960 +{
1961 +       struct cow *dev = &cow_dev[n];
1962 +       char name[sizeof("nnnnnn\0")];
1963 +       int err = -ENODEV;
1964 +
1965 +       if(dev->cow_path == NULL)
1966 +               goto out;
1967 +
1968 +       sprintf(name, "%d", n);
1969 +       dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
1970 +                                   MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
1971 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
1972 +                                   &cow_blops, NULL);
1973 +
1974 +       init_MUTEX_LOCKED(&dev->sem);
1975 +       init_MUTEX(&dev->io_sem);
1976 +
1977 +       return(0);
1978 +
1979 + out:
1980 +       return(err);
1981 +}
1982 +
1983 +/*
1984 + * Add buffer_head to back of pending list
1985 + */
1986 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
1987 +{
1988 +       unsigned long flags;
1989 +
1990 +       spin_lock_irqsave(&cow->io_lock, flags);
1991 +       if(cow->bhtail != NULL){
1992 +               cow->bhtail->b_reqnext = bh;
1993 +               cow->bhtail = bh;
1994 +       }
1995 +       else {
1996 +               cow->bh = bh;
1997 +               cow->bhtail = bh;
1998 +       }
1999 +       spin_unlock_irqrestore(&cow->io_lock, flags);
2000 +}
2001 +
2002 +/*
2003 + * Grab first pending buffer
2004 + */
2005 +static struct buffer_head *cow_get_bh(struct cow *cow)
2006 +{
2007 +       struct buffer_head *bh;
2008 +
2009 +       spin_lock_irq(&cow->io_lock);
2010 +       bh = cow->bh;
2011 +       if(bh != NULL){
2012 +               if(bh == cow->bhtail)
2013 +                       cow->bhtail = NULL;
2014 +               cow->bh = bh->b_reqnext;
2015 +               bh->b_reqnext = NULL;
2016 +       }
2017 +       spin_unlock_irq(&cow->io_lock);
2018 +
2019 +       return(bh);
2020 +}
2021 +
2022 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
2023 +                         struct buffer_head **cow_bh, int ncow_bh)
2024 +{
2025 +       int i;
2026 +
2027 +       if(ncow_bh > 0)
2028 +               ll_rw_block(WRITE, ncow_bh, cow_bh);
2029 +
2030 +       for(i = 0; i < ncow_bh ; i++){
2031 +               wait_on_buffer(cow_bh[i]);
2032 +               brelse(cow_bh[i]);
2033 +       }
2034 +
2035 +       ll_rw_block(WRITE, 1, &bh);
2036 +       brelse(bh);
2037 +}
2038 +
2039 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
2040 +{
2041 +       struct buffer_head *bh;
2042 +
2043 +       sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
2044 +       bh = getblk(dev->cow_dev, sector, dev->sectorsize);
2045 +       memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
2046 +              dev->sectorsize);
2047 +       return(bh);
2048 +}
2049 +
2050 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
2051 +
2052 +static int cow_thread(void *data)
2053 +{
2054 +       struct cow *dev = data;
2055 +       struct buffer_head *bh;
2056 +
2057 +       daemonize();
2058 +       exit_files(current);
2059 +
2060 +       sprintf(current->comm, "cow%d", dev - cow_dev);
2061 +
2062 +       spin_lock_irq(&current->sigmask_lock);
2063 +       sigfillset(&current->blocked);
2064 +       flush_signals(current);
2065 +       spin_unlock_irq(&current->sigmask_lock);
2066 +
2067 +       atomic_inc(&dev->working);
2068 +
2069 +       current->policy = SCHED_OTHER;
2070 +       current->nice = -20;
2071 +
2072 +       current->flags |= PF_NOIO;
2073 +
2074 +       /*
2075 +        * up sem, we are running
2076 +        */
2077 +       up(&dev->sem);
2078 +
2079 +       for(;;){
2080 +               int start, len, nbh, i, update_bitmap = 0;
2081 +               struct buffer_head *cow_bh[2];
2082 +
2083 +               down_interruptible(&dev->io_sem);
2084 +               /*
2085 +                * could be upped because of tear-down, not because of
2086 +                * pending work
2087 +                */
2088 +               if(!atomic_read(&dev->working))
2089 +                       break;
2090 +
2091 +               bh = cow_get_bh(dev);
2092 +               if(bh == NULL){
2093 +                       printk(KERN_ERR "cow: missing bh\n");
2094 +                       continue;
2095 +               }
2096 +
2097 +               start = bh->b_blocknr * bh->b_size / dev->sectorsize;
2098 +               len = bh->b_size / dev->sectorsize;
2099 +               for(i = 0; i < len ; i++){
2100 +                       if(ubd_test_bit(start + i, 
2101 +                                       (unsigned char *) dev->bitmap))
2102 +                               continue;
2103 +
2104 +                       update_bitmap = 1;
2105 +                       ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
2106 +               }
2107 +
2108 +               cow_bh[0] = NULL;
2109 +               cow_bh[1] = NULL;
2110 +               nbh = 0;
2111 +               if(update_bitmap){
2112 +                       cow_bh[0] = cow_new_bh(dev, start);
2113 +                       nbh++;
2114 +                       if(start / dev->sectorsize != 
2115 +                          (start + len) / dev->sectorsize){
2116 +                               cow_bh[1] = cow_new_bh(dev, start + len);
2117 +                               nbh++;
2118 +                       }
2119 +               }
2120 +               
2121 +               bh->b_dev = dev->cow_dev;
2122 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
2123 +
2124 +               cow_handle_bh(dev, bh, cow_bh, nbh);
2125 +
2126 +               /*
2127 +                * upped both for pending work and tear-down, lo_pending
2128 +                * will hit zero then
2129 +                */
2130 +               if(atomic_dec_and_test(&dev->working))
2131 +                       break;
2132 +       }
2133 +
2134 +       up(&dev->sem);
2135 +       return(0);
2136 +}
2137 +
2138 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
2139 +{
2140 +       struct cow *dev;
2141 +       int n, minor;
2142 +
2143 +       minor = MINOR(bh->b_rdev);
2144 +       n = minor >> COW_SHIFT;
2145 +       dev = &cow_dev[n];
2146 +
2147 +       dev->end_io = NULL;
2148 +       if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
2149 +               bh->b_rdev = dev->cow_dev;
2150 +               bh->b_rsector += dev->data_offset / dev->sectorsize;
2151 +       }
2152 +       else if(rw == WRITE){
2153 +               bh->b_dev = dev->cow_dev;
2154 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
2155 +
2156 +               cow_add_bh(dev, bh);
2157 +               up(&dev->io_sem);
2158 +               return(0);
2159 +       }
2160 +       else {
2161 +               bh->b_rdev = dev->backing_dev;
2162 +       }
2163 +
2164 +       return(1);
2165 +}
2166 +
2167 +int cow_init(void)
2168 +{
2169 +       int i;
2170 +
2171 +       cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
2172 +       if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
2173 +               printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
2174 +               return -1;
2175 +       }
2176 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
2177 +       blksize_size[MAJOR_NR] = blk_sizes;
2178 +       blk_size[MAJOR_NR] = sizes;
2179 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
2180 +
2181 +       cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
2182 +       blk_init_queue(cow_queue, NULL);
2183 +       INIT_ELV(cow_queue, &cow_queue->elevator);
2184 +       blk_queue_make_request(cow_queue, cow_make_request);
2185 +
2186 +        add_gendisk(&cow_gendisk);
2187 +
2188 +       for(i=0;i<MAX_DEV;i++) 
2189 +               cow_add(i);
2190 +
2191 +       return(0);
2192 +}
2193 +
2194 +__initcall(cow_init);
2195 +
2196 +static int reader(__u64 start, char *buf, int count, void *arg)
2197 +{
2198 +       dev_t dev = *((dev_t *) arg);
2199 +       struct buffer_head *bh;
2200 +       __u64 block;
2201 +       int cur, offset, left, n, blocksize = get_hardsect_size(dev);
2202 +
2203 +       if(blocksize == 0)
2204 +               panic("Zero blocksize");
2205 +
2206 +       block = start / blocksize;
2207 +       offset = start % blocksize;
2208 +       left = count;
2209 +       cur = 0;
2210 +       while(left > 0){
2211 +               n = (left > blocksize) ? blocksize : left;
2212 +
2213 +               bh = bread(dev, block, (n < 512) ? 512 : n);
2214 +               if(bh == NULL)
2215 +                       return(-EIO);
2216 +
2217 +               n -= offset;
2218 +               memcpy(&buf[cur], bh->b_data + offset, n);
2219 +               block++;
2220 +               left -= n;
2221 +               cur += n;
2222 +               offset = 0;
2223 +               brelse(bh);
2224 +       }
2225 +
2226 +       return(count);
2227 +}
2228 +
2229 +static int cow_open(struct inode *inode, struct file *filp)
2230 +{
2231 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
2232 +                        unsigned long);
2233 +       mm_segment_t fs;
2234 +       struct cow *dev;
2235 +       __u64 size;
2236 +       __u32 version, align;
2237 +       time_t mtime;
2238 +       char *backing_file;
2239 +       int n, offset, err = 0;
2240 +
2241 +       n = DEVICE_NR(inode->i_rdev);
2242 +       if(n >= MAX_DEV)
2243 +               return(-ENODEV);
2244 +       dev = &cow_dev[n];
2245 +       offset = n << COW_SHIFT;
2246 +
2247 +       spin_lock(&cow_lock);
2248 +
2249 +       if(dev->count == 0){
2250 +               dev->cow_dev = name_to_kdev_t(dev->cow_path);
2251 +               if(dev->cow_dev == 0){
2252 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
2253 +                              "failed\n", dev->cow_path);
2254 +                       err = -ENODEV;
2255 +               }
2256 +
2257 +               dev->backing_dev = name_to_kdev_t(dev->backing_path);
2258 +               if(dev->backing_dev == 0){
2259 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
2260 +                              "failed\n", dev->backing_path);
2261 +                       err = -ENODEV;
2262 +               }
2263 +
2264 +               if(err) 
2265 +                       goto out;
2266 +
2267 +               dev->cow_bdev = bdget(dev->cow_dev);
2268 +               if(dev->cow_bdev == NULL){
2269 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
2270 +                              dev->cow_path);
2271 +                       err = -ENOMEM;
2272 +               }
2273 +               dev->backing_bdev = bdget(dev->backing_dev);
2274 +               if(dev->backing_bdev == NULL){
2275 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
2276 +                              dev->backing_path);
2277 +                       err = -ENOMEM;
2278 +               }
2279 +
2280 +               if(err) 
2281 +                       goto out;
2282 +
2283 +               err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
2284 +                                BDEV_RAW);
2285 +               if(err){
2286 +                       printk("cow_open - blkdev_get of COW device failed, "
2287 +                              "error = %d\n", err);
2288 +                       goto out;
2289 +               }
2290 +               
2291 +               err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
2292 +               if(err){
2293 +                       printk("cow_open - blkdev_get of backing device "
2294 +                              "failed, error = %d\n", err);
2295 +                       goto out;
2296 +               }
2297 +               
2298 +               err = read_cow_header(reader, &dev->cow_dev, &version, 
2299 +                                     &backing_file, &mtime, &size,
2300 +                                     &dev->sectorsize, &align, 
2301 +                                     &dev->bitmap_offset);
2302 +               if(err){
2303 +                       printk(KERN_ERR "cow_open - read_cow_header failed, "
2304 +                              "err = %d\n", err);
2305 +                       goto out;
2306 +               }
2307 +
2308 +               cow_sizes(version, size, dev->sectorsize, align, 
2309 +                         dev->bitmap_offset, &dev->bitmap_len, 
2310 +                         &dev->data_offset);
2311 +               dev->bitmap = (void *) vmalloc(dev->bitmap_len);
2312 +               if(dev->bitmap == NULL){
2313 +                       err = -ENOMEM;
2314 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
2315 +                       goto out;
2316 +               }
2317 +               flush_tlb_kernel_vm();
2318 +               
2319 +               err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
2320 +                            dev->bitmap_len, &dev->cow_dev);
2321 +               if(err < 0){
2322 +                       printk(KERN_ERR "Failed to read COW bitmap\n");
2323 +                       vfree(dev->bitmap);
2324 +                       goto out;
2325 +               }
2326 +
2327 +               dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2328 +               fs = get_fs();
2329 +               set_fs(KERNEL_DS);
2330 +               err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
2331 +                                  (unsigned long) &sizes[offset]);
2332 +               set_fs(fs);
2333 +               if(err){
2334 +                       printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
2335 +                              "error = %d\n", err);
2336 +                       goto out;
2337 +               }
2338 +
2339 +               kernel_thread(cow_thread, dev, 
2340 +                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
2341 +               down(&dev->sem);
2342 +       }
2343 +       dev->count++;
2344 + out:
2345 +       spin_unlock(&cow_lock);
2346 +       return(err);
2347 +}
2348 +
2349 +static int cow_release(struct inode * inode, struct file * file)
2350 +{
2351 +       struct cow *dev;
2352 +       int n, err;
2353 +
2354 +       n = DEVICE_NR(inode->i_rdev);
2355 +       if(n >= MAX_DEV)
2356 +               return(-ENODEV);
2357 +       dev = &cow_dev[n];
2358 +
2359 +       spin_lock(&cow_lock);
2360 +
2361 +       if(--dev->count > 0)
2362 +               goto out;
2363 +
2364 +       err = blkdev_put(dev->cow_bdev, BDEV_RAW);
2365 +       if(err)
2366 +               printk("cow_release - blkdev_put of cow device failed, "
2367 +                      "error = %d\n", err);
2368 +       bdput(dev->cow_bdev);
2369 +       dev->cow_bdev = 0;
2370 +
2371 +       err = blkdev_put(dev->backing_bdev, BDEV_RAW);
2372 +       if(err)
2373 +               printk("cow_release - blkdev_put of backing device failed, "
2374 +                      "error = %d\n", err);
2375 +       bdput(dev->backing_bdev);
2376 +       dev->backing_bdev = 0;
2377 +
2378 + out:
2379 +       spin_unlock(&cow_lock);
2380 +       return(0);
2381 +}
2382 +
2383 +static int cow_ioctl(struct inode * inode, struct file * file,
2384 +                    unsigned int cmd, unsigned long arg)
2385 +{
2386 +       struct cow *dev;
2387 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
2388 +                        unsigned long);
2389 +       int n;
2390 +
2391 +       n = DEVICE_NR(inode->i_rdev);
2392 +       if(n >= MAX_DEV)
2393 +               return(-ENODEV);
2394 +       dev = &cow_dev[n];
2395 +
2396 +       dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2397 +       return((*dev_ioctl)(inode, file, cmd, arg));
2398 +}
2399 +
2400 +static int cow_revalidate(kdev_t rdev)
2401 +{
2402 +       printk(KERN_ERR "Need to implement cow_revalidate\n");
2403 +       return(0);
2404 +}
2405 +
2406 +static int parse_unit(char **ptr)
2407 +{
2408 +       char *str = *ptr, *end;
2409 +       int n = -1;
2410 +
2411 +       if(isdigit(*str)) {
2412 +               n = simple_strtoul(str, &end, 0);
2413 +               if(end == str)
2414 +                       return(-1);
2415 +               *ptr = end;
2416 +       }
2417 +       else if (('a' <= *str) && (*str <= 'h')) {
2418 +               n = *str - 'a';
2419 +               str++;
2420 +               *ptr = str;
2421 +       }
2422 +       return(n);
2423 +}
2424 +
2425 +static int cow_setup(char *str)
2426 +{
2427 +       struct cow *dev;
2428 +       char *cow_name, *backing_name;
2429 +       int unit;
2430 +
2431 +       unit = parse_unit(&str);
2432 +       if(unit < 0){
2433 +               printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
2434 +               return(1);
2435 +       }
2436 +
2437 +       if(*str != '='){
2438 +               printk(KERN_ERR "cow_setup - Missing '=' after unit "
2439 +                      "number\n");
2440 +               return(1);
2441 +       }
2442 +       str++;
2443 +
2444 +       cow_name = str;
2445 +       backing_name = strchr(str, ',');
2446 +       if(backing_name == NULL){
2447 +               printk(KERN_ERR "cow_setup - missing backing device name\n");
2448 +               return(0);
2449 +       }
2450 +       *backing_name = '\0';
2451 +       backing_name++;
2452 +
2453 +       spin_lock(&cow_lock);
2454 +
2455 +       dev = &cow_dev[unit];
2456 +       dev->cow_path = cow_name;
2457 +       dev->backing_path = backing_name;
2458 +       
2459 +       spin_unlock(&cow_lock);
2460 +       return(0);
2461 +}
2462 +
2463 +__setup("cow", cow_setup);
2464 +
2465 +/*
2466 + * Overrides for Emacs so that we follow Linus's tabbing style.
2467 + * Emacs will notice this stuff at the end of the file and automatically
2468 + * adjust the settings for this buffer only.  This must remain at the end
2469 + * of the file.
2470 + * ---------------------------------------------------------------------------
2471 + * Local variables:
2472 + * c-file-style: "linux"
2473 + * End:
2474 + */
2475 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_sys.h um/arch/um/drivers/cow_sys.h
2476 --- orig/arch/um/drivers/cow_sys.h      1969-12-31 19:00:00.000000000 -0500
2477 +++ um/arch/um/drivers/cow_sys.h        2003-12-17 10:53:03.000000000 -0500
2478 @@ -0,0 +1,48 @@
2479 +#ifndef __COW_SYS_H__
2480 +#define __COW_SYS_H__
2481 +
2482 +#include "kern_util.h"
2483 +#include "user_util.h"
2484 +#include "os.h"
2485 +#include "user.h"
2486 +
2487 +static inline void *cow_malloc(int size)
2488 +{
2489 +       return(um_kmalloc(size));
2490 +}
2491 +
2492 +static inline void cow_free(void *ptr)
2493 +{
2494 +       kfree(ptr);
2495 +}
2496 +
2497 +#define cow_printf printk
2498 +
2499 +static inline char *cow_strdup(char *str)
2500 +{
2501 +       return(uml_strdup(str));
2502 +}
2503 +
2504 +static inline int cow_seek_file(int fd, __u64 offset)
2505 +{
2506 +       return(os_seek_file(fd, offset));
2507 +}
2508 +
2509 +static inline int cow_file_size(char *file, __u64 *size_out)
2510 +{
2511 +       return(os_file_size(file, size_out));
2512 +}
2513 +
2514 +static inline int cow_write_file(int fd, char *buf, int size)
2515 +{
2516 +       return(os_write_file(fd, buf, size));
2517 +}
2518 +
2519 +#endif
2520 +
2521 +/*
2522 + * ---------------------------------------------------------------------------
2523 + * Local variables:
2524 + * c-file-style: "linux"
2525 + * End:
2526 + */
2527 diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_user.c um/arch/um/drivers/cow_user.c
2528 --- orig/arch/um/drivers/cow_user.c     1969-12-31 19:00:00.000000000 -0500
2529 +++ um/arch/um/drivers/cow_user.c       2003-11-08 06:29:47.000000000 -0500
2530 @@ -0,0 +1,375 @@
2531 +#include <stddef.h>
2532 +#include <string.h>
2533 +#include <errno.h>
2534 +#include <unistd.h>
2535 +#include <byteswap.h>
2536 +#include <sys/time.h>
2537 +#include <sys/param.h>
2538 +#include <sys/user.h>
2539 +#include <netinet/in.h>
2540 +
2541 +#include "os.h"
2542 +
2543 +#include "cow.h"
2544 +#include "cow_sys.h"
2545 +
2546 +#define PATH_LEN_V1 256
2547 +
2548 +struct cow_header_v1 {
2549 +       int magic;
2550 +       int version;
2551 +       char backing_file[PATH_LEN_V1];
2552 +       time_t mtime;
2553 +       __u64 size;
2554 +       int sectorsize;
2555 +};
2556 +
2557 +#define PATH_LEN_V2 MAXPATHLEN
2558 +
2559 +struct cow_header_v2 {
2560 +       unsigned long magic;
2561 +       unsigned long version;
2562 +       char backing_file[PATH_LEN_V2];
2563 +       time_t mtime;
2564 +       __u64 size;
2565 +       int sectorsize;
2566 +};
2567 +
2568 +/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in 
2569 + * case other systems have different values for MAXPATHLEN
2570 + */
2571 +#define PATH_LEN_V3 4096
2572 +
2573 +/* Changes from V2 - 
2574 + *     PATH_LEN_V3 as described above
2575 + *     Explicitly specify field bit lengths for systems with different
2576 + *             lengths for the usual C types.  Not sure whether char or
2577 + *             time_t should be changed, this can be changed later without
2578 + *             breaking compatibility
2579 + *     Add alignment field so that different alignments can be used for the
2580 + *             bitmap and data
2581 + *     Add cow_format field to allow for the possibility of different ways
2582 + *             of specifying the COW blocks.  For now, the only value is 0,
2583 + *             for the traditional COW bitmap.
2584 + *     Move the backing_file field to the end of the header.  This allows
2585 + *             for the possibility of expanding it into the padding required
2586 + *             by the bitmap alignment.
2587 + *     The bitmap and data portions of the file will be aligned as specified
2588 + *             by the alignment field.  This is to allow COW files to be
2589 + *             put on devices with restrictions on access alignments, such as
2590 + *             /dev/raw, with a 512 byte alignment restriction.  This also
2591 + *             allows the data to be more aligned more strictly than on
2592 + *             sector boundaries.  This is needed for ubd-mmap, which needs
2593 + *             the data to be page aligned.
2594 + *     Fixed (finally!) the rounding bug
2595 + */
2596 +
2597 +struct cow_header_v3 {
2598 +       __u32 magic;
2599 +       __u32 version;
2600 +       time_t mtime;
2601 +       __u64 size;
2602 +       __u32 sectorsize;
2603 +       __u32 alignment;
2604 +       __u32 cow_format;
2605 +       char backing_file[PATH_LEN_V3];
2606 +};
2607 +
2608 +/* COW format definitions - for now, we have only the usual COW bitmap */
2609 +#define COW_BITMAP 0
2610 +
2611 +union cow_header {
2612 +       struct cow_header_v1 v1;
2613 +       struct cow_header_v2 v2;
2614 +       struct cow_header_v3 v3;
2615 +};
2616 +
2617 +#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
2618 +#define COW_VERSION 3
2619 +
2620 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
2621 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
2622 +
2623 +void cow_sizes(int version, __u64 size, int sectorsize, int align, 
2624 +              int bitmap_offset, unsigned long *bitmap_len_out, 
2625 +              int *data_offset_out)
2626 +{
2627 +       if(version < 3){
2628 +               *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
2629 +
2630 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
2631 +               *data_offset_out = (*data_offset_out + sectorsize - 1) / 
2632 +                       sectorsize;
2633 +               *data_offset_out *= sectorsize;
2634 +       }
2635 +       else {
2636 +               *bitmap_len_out = DIV_ROUND(size, sectorsize);
2637 +               *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
2638 +
2639 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
2640 +               *data_offset_out = ROUND_UP(*data_offset_out, align);
2641 +       }
2642 +}
2643 +
2644 +static int absolutize(char *to, int size, char *from)
2645 +{
2646 +       char save_cwd[256], *slash;
2647 +       int remaining;
2648 +
2649 +       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
2650 +               cow_printf("absolutize : unable to get cwd - errno = %d\n", 
2651 +                          errno);
2652 +               return(-1);
2653 +       }
2654 +       slash = strrchr(from, '/');
2655 +       if(slash != NULL){
2656 +               *slash = '\0';
2657 +               if(chdir(from)){
2658 +                       *slash = '/';
2659 +                       cow_printf("absolutize : Can't cd to '%s' - " 
2660 +                                  "errno = %d\n", from, errno);
2661 +                       return(-1);
2662 +               }
2663 +               *slash = '/';
2664 +               if(getcwd(to, size) == NULL){
2665 +                       cow_printf("absolutize : unable to get cwd of '%s' - "
2666 +                              "errno = %d\n", from, errno);
2667 +                       return(-1);
2668 +               }
2669 +               remaining = size - strlen(to);
2670 +               if(strlen(slash) + 1 > remaining){
2671 +                       cow_printf("absolutize : unable to fit '%s' into %d "
2672 +                              "chars\n", from, size);
2673 +                       return(-1);
2674 +               }
2675 +               strcat(to, slash);
2676 +       }
2677 +       else {
2678 +               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
2679 +                       cow_printf("absolutize : unable to fit '%s' into %d "
2680 +                              "chars\n", from, size);
2681 +                       return(-1);
2682 +               }
2683 +               strcpy(to, save_cwd);
2684 +               strcat(to, "/");
2685 +               strcat(to, from);
2686 +       }
2687 +       chdir(save_cwd);
2688 +       return(0);
2689 +}
2690 +
2691 +int write_cow_header(char *cow_file, int fd, char *backing_file, 
2692 +                    int sectorsize, int alignment, long long *size)
2693 +{
2694 +        struct cow_header_v3 *header;
2695 +       unsigned long modtime;
2696 +       int err;
2697 +
2698 +       err = cow_seek_file(fd, 0);
2699 +       if(err < 0){
2700 +               cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
2701 +               goto out;
2702 +       }
2703 +
2704 +       err = -ENOMEM;
2705 +       header = cow_malloc(sizeof(*header));
2706 +       if(header == NULL){
2707 +               cow_printf("Failed to allocate COW V3 header\n");
2708 +               goto out;
2709 +       }
2710 +       header->magic = htonl(COW_MAGIC);
2711 +       header->version = htonl(COW_VERSION);
2712 +
2713 +       err = -EINVAL;
2714 +       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
2715 +               cow_printf("Backing file name \"%s\" is too long - names are "
2716 +                          "limited to %d characters\n", backing_file, 
2717 +                          sizeof(header->backing_file) - 1);
2718 +               goto out_free;
2719 +       }
2720 +
2721 +       if(absolutize(header->backing_file, sizeof(header->backing_file), 
2722 +                     backing_file))
2723 +               goto out_free;
2724 +
2725 +       err = os_file_modtime(header->backing_file, &modtime);
2726 +       if(err < 0){
2727 +               cow_printf("Backing file '%s' mtime request failed, "
2728 +                          "err = %d\n", header->backing_file, -err);
2729 +               goto out_free;
2730 +       }
2731 +
2732 +       err = cow_file_size(header->backing_file, size);
2733 +       if(err < 0){
2734 +               cow_printf("Couldn't get size of backing file '%s', "
2735 +                          "err = %d\n", header->backing_file, -err);
2736 +               goto out_free;
2737 +       }
2738 +
2739 +       header->mtime = htonl(modtime);
2740 +       header->size = htonll(*size);
2741 +       header->sectorsize = htonl(sectorsize);
2742 +       header->alignment = htonl(alignment);
2743 +       header->cow_format = COW_BITMAP;
2744 +
2745 +       err = os_write_file(fd, header, sizeof(*header));
2746 +       if(err != sizeof(*header)){
2747 +               cow_printf("Write of header to new COW file '%s' failed, "
2748 +                          "err = %d\n", cow_file, -err);
2749 +               goto out_free;
2750 +       }
2751 +       err = 0;
2752 + out_free:
2753 +       cow_free(header);
2754 + out:
2755 +       return(err);
2756 +}
2757 +
2758 +int file_reader(__u64 offset, char *buf, int len, void *arg)
2759 +{
2760 +       int fd = *((int *) arg);
2761 +
2762 +       return(pread(fd, buf, len, offset));
2763 +}
2764 +
2765 +/* XXX Need to sanity-check the values read from the header */
2766 +
2767 +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
2768 +                   __u32 *version_out, char **backing_file_out, 
2769 +                   time_t *mtime_out, __u64 *size_out, 
2770 +                   int *sectorsize_out, __u32 *align_out, 
2771 +                   int *bitmap_offset_out)
2772 +{
2773 +       union cow_header *header;
2774 +       char *file;
2775 +       int err, n;
2776 +       unsigned long version, magic;
2777 +
2778 +       header = cow_malloc(sizeof(*header));
2779 +       if(header == NULL){
2780 +               cow_printf("read_cow_header - Failed to allocate header\n");
2781 +               return(-ENOMEM);
2782 +       }
2783 +       err = -EINVAL;
2784 +       n = (*reader)(0, (char *) header, sizeof(*header), arg);
2785 +       if(n < offsetof(typeof(header->v1), backing_file)){
2786 +               cow_printf("read_cow_header - short header\n");
2787 +               goto out;
2788 +       }
2789 +
2790 +       magic = header->v1.magic;
2791 +       if(magic == COW_MAGIC) {
2792 +               version = header->v1.version;
2793 +       }
2794 +       else if(magic == ntohl(COW_MAGIC)){
2795 +               version = ntohl(header->v1.version);
2796 +       }
2797 +       /* No error printed because the non-COW case comes through here */
2798 +       else goto out;
2799 +
2800 +       *version_out = version;
2801 +
2802 +       if(version == 1){
2803 +               if(n < sizeof(header->v1)){
2804 +                       cow_printf("read_cow_header - failed to read V1 "
2805 +                                  "header\n");
2806 +                       goto out;
2807 +               }
2808 +               *mtime_out = header->v1.mtime;
2809 +               *size_out = header->v1.size;
2810 +               *sectorsize_out = header->v1.sectorsize;
2811 +               *bitmap_offset_out = sizeof(header->v1);
2812 +               *align_out = *sectorsize_out;
2813 +               file = header->v1.backing_file;
2814 +       }
2815 +       else if(version == 2){
2816 +               if(n < sizeof(header->v2)){
2817 +                       cow_printf("read_cow_header - failed to read V2 "
2818 +                                  "header\n");
2819 +                       goto out;
2820 +               }
2821 +               *mtime_out = ntohl(header->v2.mtime);
2822 +               *size_out = ntohll(header->v2.size);
2823 +               *sectorsize_out = ntohl(header->v2.sectorsize);
2824 +               *bitmap_offset_out = sizeof(header->v2);
2825 +               *align_out = *sectorsize_out;
2826 +               file = header->v2.backing_file;
2827 +       }
2828 +       else if(version == 3){
2829 +               if(n < sizeof(header->v3)){
2830 +                       cow_printf("read_cow_header - failed to read V2 "
2831 +                                  "header\n");
2832 +                       goto out;
2833 +               }
2834 +               *mtime_out = ntohl(header->v3.mtime);
2835 +               *size_out = ntohll(header->v3.size);
2836 +               *sectorsize_out = ntohl(header->v3.sectorsize);
2837 +               *align_out = ntohl(header->v3.alignment);
2838 +               *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
2839 +               file = header->v3.backing_file;
2840 +       }
2841 +       else {
2842 +               cow_printf("read_cow_header - invalid COW version\n");
2843 +               goto out;               
2844 +       }
2845 +       err = -ENOMEM;
2846 +       *backing_file_out = cow_strdup(file);
2847 +       if(*backing_file_out == NULL){
2848 +               cow_printf("read_cow_header - failed to allocate backing "
2849 +                          "file\n");
2850 +               goto out;
2851 +       }
2852 +       err = 0;
2853 + out:
2854 +       cow_free(header);
2855 +       return(err);
2856 +}
2857 +
2858 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
2859 +                 int alignment, int *bitmap_offset_out, 
2860 +                 unsigned long *bitmap_len_out, int *data_offset_out)
2861 +{
2862 +       __u64 size, offset;
2863 +       char zero = 0;
2864 +       int err;
2865 +
2866 +       err = write_cow_header(cow_file, fd, backing_file, sectorsize, 
2867 +                              alignment, &size);
2868 +       if(err) 
2869 +               goto out;
2870 +       
2871 +       *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
2872 +       cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
2873 +                 bitmap_len_out, data_offset_out);
2874 +
2875 +       offset = *data_offset_out + size - sizeof(zero);
2876 +       err = cow_seek_file(fd, offset);
2877 +       if(err < 0){
2878 +               cow_printf("cow bitmap lseek failed : err = %d\n", -err);
2879 +               goto out;
2880 +       }
2881 +
2882 +       /* does not really matter how much we write it is just to set EOF 
2883 +        * this also sets the entire COW bitmap
2884 +        * to zero without having to allocate it 
2885 +        */
2886 +       err = cow_write_file(fd, &zero, sizeof(zero));
2887 +       if(err != sizeof(zero)){
2888 +               cow_printf("Write of bitmap to new COW file '%s' failed, "
2889 +                          "err = %d\n", cow_file, -err);
2890 +               err = -EINVAL;
2891 +               goto out;
2892 +       }
2893 +
2894 +       return(0);
2895 +
2896 + out:
2897 +       return(err);
2898 +}
2899 +
2900 +/*
2901 + * ---------------------------------------------------------------------------
2902 + * Local variables:
2903 + * c-file-style: "linux"
2904 + * End:
2905 + */
2906 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon.h um/arch/um/drivers/daemon.h
2907 --- orig/arch/um/drivers/daemon.h       1969-12-31 19:00:00.000000000 -0500
2908 +++ um/arch/um/drivers/daemon.h 2003-10-21 03:26:06.000000000 -0400
2909 @@ -0,0 +1,35 @@
2910 +/* 
2911 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
2912 + * Licensed under the GPL
2913 + */
2914 +
2915 +#include "net_user.h"
2916 +
2917 +#define SWITCH_VERSION 3
2918 +
2919 +struct daemon_data {
2920 +       char *sock_type;
2921 +       char *ctl_sock;
2922 +       void *ctl_addr;
2923 +       void *data_addr;
2924 +       void *local_addr;
2925 +       int fd;
2926 +       int control;
2927 +       void *dev;
2928 +};
2929 +
2930 +extern struct net_user_info daemon_user_info;
2931 +
2932 +extern int daemon_user_write(int fd, void *buf, int len, 
2933 +                            struct daemon_data *pri);
2934 +
2935 +/*
2936 + * Overrides for Emacs so that we follow Linus's tabbing style.
2937 + * Emacs will notice this stuff at the end of the file and automatically
2938 + * adjust the settings for this buffer only.  This must remain at the end
2939 + * of the file.
2940 + * ---------------------------------------------------------------------------
2941 + * Local variables:
2942 + * c-file-style: "linux"
2943 + * End:
2944 + */
2945 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_kern.c um/arch/um/drivers/daemon_kern.c
2946 --- orig/arch/um/drivers/daemon_kern.c  1969-12-31 19:00:00.000000000 -0500
2947 +++ um/arch/um/drivers/daemon_kern.c    2003-10-21 03:26:06.000000000 -0400
2948 @@ -0,0 +1,113 @@
2949 +/*
2950 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
2951 + * James Leu (jleu@mindspring.net).
2952 + * Copyright (C) 2001 by various other people who didn't put their name here.
2953 + * Licensed under the GPL.
2954 + */
2955 +
2956 +#include "linux/kernel.h"
2957 +#include "linux/init.h"
2958 +#include "linux/netdevice.h"
2959 +#include "linux/etherdevice.h"
2960 +#include "net_kern.h"
2961 +#include "net_user.h"
2962 +#include "daemon.h"
2963 +
2964 +struct daemon_init {
2965 +       char *sock_type;
2966 +       char *ctl_sock;
2967 +};
2968 +
2969 +void daemon_init(struct net_device *dev, void *data)
2970 +{
2971 +       struct uml_net_private *pri;
2972 +       struct daemon_data *dpri;
2973 +       struct daemon_init *init = data;
2974 +
2975 +       init_etherdev(dev, 0);
2976 +       pri = dev->priv;
2977 +       dpri = (struct daemon_data *) pri->user;
2978 +       *dpri = ((struct daemon_data)
2979 +               { .sock_type            = init->sock_type,
2980 +                 .ctl_sock             = init->ctl_sock,
2981 +                 .ctl_addr             = NULL,
2982 +                 .data_addr            = NULL,
2983 +                 .local_addr           = NULL,
2984 +                 .fd                   = -1,
2985 +                 .control              = -1,
2986 +                 .dev                  = dev });
2987 +
2988 +       printk("daemon backend (uml_switch version %d) - %s:%s", 
2989 +              SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
2990 +       printk("\n");
2991 +}
2992 +
2993 +static int daemon_read(int fd, struct sk_buff **skb, 
2994 +                      struct uml_net_private *lp)
2995 +{
2996 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
2997 +       if(*skb == NULL) return(-ENOMEM);
2998 +       return(net_recvfrom(fd, (*skb)->mac.raw, 
2999 +                           (*skb)->dev->mtu + ETH_HEADER_OTHER));
3000 +}
3001 +
3002 +static int daemon_write(int fd, struct sk_buff **skb,
3003 +                       struct uml_net_private *lp)
3004 +{
3005 +       return(daemon_user_write(fd, (*skb)->data, (*skb)->len, 
3006 +                                (struct daemon_data *) &lp->user));
3007 +}
3008 +
3009 +static struct net_kern_info daemon_kern_info = {
3010 +       .init                   = daemon_init,
3011 +       .protocol               = eth_protocol,
3012 +       .read                   = daemon_read,
3013 +       .write                  = daemon_write,
3014 +};
3015 +
3016 +int daemon_setup(char *str, char **mac_out, void *data)
3017 +{
3018 +       struct daemon_init *init = data;
3019 +       char *remain;
3020 +
3021 +       *init = ((struct daemon_init)
3022 +               { .sock_type            = "unix",
3023 +                 .ctl_sock             = "/tmp/uml.ctl" });
3024 +       
3025 +       remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
3026 +                              NULL);
3027 +       if(remain != NULL)
3028 +               printk(KERN_WARNING "daemon_setup : Ignoring data socket "
3029 +                      "specification\n");
3030 +       
3031 +       return(1);
3032 +}
3033 +
3034 +static struct transport daemon_transport = {
3035 +       .list           = LIST_HEAD_INIT(daemon_transport.list),
3036 +       .name           = "daemon",
3037 +       .setup          = daemon_setup,
3038 +       .user           = &daemon_user_info,
3039 +       .kern           = &daemon_kern_info,
3040 +       .private_size   = sizeof(struct daemon_data),
3041 +       .setup_size     = sizeof(struct daemon_init),
3042 +};
3043 +
3044 +static int register_daemon(void)
3045 +{
3046 +       register_transport(&daemon_transport);
3047 +       return(1);
3048 +}
3049 +
3050 +__initcall(register_daemon);
3051 +
3052 +/*
3053 + * Overrides for Emacs so that we follow Linus's tabbing style.
3054 + * Emacs will notice this stuff at the end of the file and automatically
3055 + * adjust the settings for this buffer only.  This must remain at the end
3056 + * of the file.
3057 + * ---------------------------------------------------------------------------
3058 + * Local variables:
3059 + * c-file-style: "linux"
3060 + * End:
3061 + */
3062 diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_user.c um/arch/um/drivers/daemon_user.c
3063 --- orig/arch/um/drivers/daemon_user.c  1969-12-31 19:00:00.000000000 -0500
3064 +++ um/arch/um/drivers/daemon_user.c    2003-10-21 03:26:06.000000000 -0400
3065 @@ -0,0 +1,197 @@
3066 +/*
3067 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
3068 + * James Leu (jleu@mindspring.net).
3069 + * Copyright (C) 2001 by various other people who didn't put their name here.
3070 + * Licensed under the GPL.
3071 + */
3072 +
3073 +#include <errno.h>
3074 +#include <unistd.h>
3075 +#include <stdint.h>
3076 +#include <sys/socket.h>
3077 +#include <sys/un.h>
3078 +#include <sys/time.h>
3079 +#include "net_user.h"
3080 +#include "daemon.h"
3081 +#include "kern_util.h"
3082 +#include "user_util.h"
3083 +#include "user.h"
3084 +#include "os.h"
3085 +
3086 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
3087 +
3088 +enum request_type { REQ_NEW_CONTROL };
3089 +
3090 +#define SWITCH_MAGIC 0xfeedface
3091 +
3092 +struct request_v3 {
3093 +       uint32_t magic;
3094 +       uint32_t version;
3095 +       enum request_type type;
3096 +       struct sockaddr_un sock;
3097 +};
3098 +
3099 +static struct sockaddr_un *new_addr(void *name, int len)
3100 +{
3101 +       struct sockaddr_un *sun;
3102 +
3103 +       sun = um_kmalloc(sizeof(struct sockaddr_un));
3104 +       if(sun == NULL){
3105 +               printk("new_addr: allocation of sockaddr_un failed\n");
3106 +               return(NULL);
3107 +       }
3108 +       sun->sun_family = AF_UNIX;
3109 +       memcpy(sun->sun_path, name, len);
3110 +       return(sun);
3111 +}
3112 +
3113 +static int connect_to_switch(struct daemon_data *pri)
3114 +{
3115 +       struct sockaddr_un *ctl_addr = pri->ctl_addr;
3116 +       struct sockaddr_un *local_addr = pri->local_addr;
3117 +       struct sockaddr_un *sun;
3118 +       struct request_v3 req;
3119 +       int fd, n, err;
3120 +
3121 +       pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
3122 +       if(pri->control < 0){
3123 +               printk("daemon_open : control socket failed, errno = %d\n", 
3124 +                      errno);          
3125 +               return(-errno);
3126 +       }
3127 +
3128 +       if(connect(pri->control, (struct sockaddr *) ctl_addr, 
3129 +                  sizeof(*ctl_addr)) < 0){
3130 +               printk("daemon_open : control connect failed, errno = %d\n",
3131 +                      errno);
3132 +               err = -errno;
3133 +               goto out;
3134 +       }
3135 +
3136 +       fd = socket(AF_UNIX, SOCK_DGRAM, 0);
3137 +       if(fd < 0){
3138 +               printk("daemon_open : data socket failed, errno = %d\n", 
3139 +                      errno);
3140 +               err = -errno;
3141 +               goto out;
3142 +       }
3143 +       if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
3144 +               printk("daemon_open : data bind failed, errno = %d\n", 
3145 +                      errno);
3146 +               err = -errno;
3147 +               goto out_close;
3148 +       }
3149 +
3150 +       sun = um_kmalloc(sizeof(struct sockaddr_un));
3151 +       if(sun == NULL){
3152 +               printk("new_addr: allocation of sockaddr_un failed\n");
3153 +               err = -ENOMEM;
3154 +               goto out_close;
3155 +       }
3156 +
3157 +       req.magic = SWITCH_MAGIC;
3158 +       req.version = SWITCH_VERSION;
3159 +       req.type = REQ_NEW_CONTROL;
3160 +       req.sock = *local_addr;
3161 +       n = os_write_file(pri->control, &req, sizeof(req));
3162 +       if(n != sizeof(req)){
3163 +               printk("daemon_open : control setup request failed, err = %d\n",
3164 +                      -n);
3165 +               err = -ENOTCONN;
3166 +               goto out;               
3167 +       }
3168 +
3169 +       n = os_read_file(pri->control, sun, sizeof(*sun));
3170 +       if(n != sizeof(*sun)){
3171 +               printk("daemon_open : read of data socket failed, err = %d\n", 
3172 +                      -n);
3173 +               err = -ENOTCONN;
3174 +               goto out_close;         
3175 +       }
3176 +
3177 +       pri->data_addr = sun;
3178 +       return(fd);
3179 +
3180 + out_close:
3181 +       os_close_file(fd);
3182 + out:
3183 +       os_close_file(pri->control);
3184 +       return(err);
3185 +}
3186 +
3187 +static void daemon_user_init(void *data, void *dev)
3188 +{
3189 +       struct daemon_data *pri = data;
3190 +       struct timeval tv;
3191 +       struct {
3192 +               char zero;
3193 +               int pid;
3194 +               int usecs;
3195 +       } name;
3196 +
3197 +       if(!strcmp(pri->sock_type, "unix"))
3198 +               pri->ctl_addr = new_addr(pri->ctl_sock, 
3199 +                                        strlen(pri->ctl_sock) + 1);
3200 +       name.zero = 0;
3201 +       name.pid = os_getpid();
3202 +       gettimeofday(&tv, NULL);
3203 +       name.usecs = tv.tv_usec;
3204 +       pri->local_addr = new_addr(&name, sizeof(name));
3205 +       pri->dev = dev;
3206 +       pri->fd = connect_to_switch(pri);
3207 +       if(pri->fd < 0){
3208 +               kfree(pri->local_addr);
3209 +               pri->local_addr = NULL;
3210 +       }
3211 +}
3212 +
3213 +static int daemon_open(void *data)
3214 +{
3215 +       struct daemon_data *pri = data;
3216 +       return(pri->fd);
3217 +}
3218 +
3219 +static void daemon_remove(void *data)
3220 +{
3221 +       struct daemon_data *pri = data;
3222 +
3223 +       os_close_file(pri->fd);
3224 +       os_close_file(pri->control);
3225 +       if(pri->data_addr != NULL) kfree(pri->data_addr);
3226 +       if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
3227 +       if(pri->local_addr != NULL) kfree(pri->local_addr);
3228 +}
3229 +
3230 +int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
3231 +{
3232 +       struct sockaddr_un *data_addr = pri->data_addr;
3233 +
3234 +       return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
3235 +}
3236 +
3237 +static int daemon_set_mtu(int mtu, void *data)
3238 +{
3239 +       return(mtu);
3240 +}
3241 +
3242 +struct net_user_info daemon_user_info = {
3243 +       .init           = daemon_user_init,
3244 +       .open           = daemon_open,
3245 +       .close          = NULL,
3246 +       .remove         = daemon_remove,
3247 +       .set_mtu        = daemon_set_mtu,
3248 +       .add_address    = NULL,
3249 +       .delete_address = NULL,
3250 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
3251 +};
3252 +
3253 +/*
3254 + * Overrides for Emacs so that we follow Linus's tabbing style.
3255 + * Emacs will notice this stuff at the end of the file and automatically
3256 + * adjust the settings for this buffer only.  This must remain at the end
3257 + * of the file.
3258 + * ---------------------------------------------------------------------------
3259 + * Local variables:
3260 + * c-file-style: "linux"
3261 + * End:
3262 + */
3263 diff -Naur -X ../exclude-files orig/arch/um/drivers/fd.c um/arch/um/drivers/fd.c
3264 --- orig/arch/um/drivers/fd.c   1969-12-31 19:00:00.000000000 -0500
3265 +++ um/arch/um/drivers/fd.c     2003-10-21 03:26:06.000000000 -0400
3266 @@ -0,0 +1,97 @@
3267 +/* 
3268 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
3269 + * Licensed under the GPL
3270 + */
3271 +
3272 +#include <stdio.h>
3273 +#include <stdlib.h>
3274 +#include <unistd.h>
3275 +#include <termios.h>
3276 +#include "user.h"
3277 +#include "user_util.h"
3278 +#include "chan_user.h"
3279 +
3280 +struct fd_chan {
3281 +       int fd;
3282 +       int raw;
3283 +       struct termios tt;
3284 +       char str[sizeof("1234567890\0")];
3285 +};
3286 +
3287 +void *fd_init(char *str, int device, struct chan_opts *opts)
3288 +{
3289 +       struct fd_chan *data;
3290 +       char *end;
3291 +       int n;
3292 +
3293 +       if(*str != ':'){
3294 +               printk("fd_init : channel type 'fd' must specify a file "
3295 +                      "descriptor\n");
3296 +               return(NULL);
3297 +       }
3298 +       str++;
3299 +       n = strtoul(str, &end, 0);
3300 +       if((*end != '\0') || (end == str)){
3301 +               printk("fd_init : couldn't parse file descriptor '%s'\n", str);
3302 +               return(NULL);
3303 +       }
3304 +       data = um_kmalloc(sizeof(*data));
3305 +       if(data == NULL) return(NULL);
3306 +       *data = ((struct fd_chan) { .fd         = n,
3307 +                                   .raw        = opts->raw });
3308 +       return(data);
3309 +}
3310 +
3311 +int fd_open(int input, int output, int primary, void *d, char **dev_out)
3312 +{
3313 +       struct fd_chan *data = d;
3314 +
3315 +       if(data->raw && isatty(data->fd)){
3316 +               tcgetattr(data->fd, &data->tt);
3317 +               raw(data->fd, 0);
3318 +       }
3319 +       sprintf(data->str, "%d", data->fd);
3320 +       *dev_out = data->str;
3321 +       return(data->fd);
3322 +}
3323 +
3324 +void fd_close(int fd, void *d)
3325 +{
3326 +       struct fd_chan *data = d;
3327 +
3328 +       if(data->raw && isatty(fd)){
3329 +               tcsetattr(fd, TCSAFLUSH, &data->tt);
3330 +               data->raw = 0;
3331 +       }
3332 +}
3333 +
3334 +int fd_console_write(int fd, const char *buf, int n, void *d)
3335 +{
3336 +       struct fd_chan *data = d;
3337 +
3338 +       return(generic_console_write(fd, buf, n, &data->tt));
3339 +}
3340 +
3341 +struct chan_ops fd_ops = {
3342 +       .type           = "fd",
3343 +       .init           = fd_init,
3344 +       .open           = fd_open,
3345 +       .close          = fd_close,
3346 +       .read           = generic_read,
3347 +       .write          = generic_write,
3348 +       .console_write  = fd_console_write,
3349 +       .window_size    = generic_window_size,
3350 +       .free           = generic_free,
3351 +       .winch          = 1,
3352 +};
3353 +
3354 +/*
3355 + * Overrides for Emacs so that we follow Linus's tabbing style.
3356 + * Emacs will notice this stuff at the end of the file and automatically
3357 + * adjust the settings for this buffer only.  This must remain at the end
3358 + * of the file.
3359 + * ---------------------------------------------------------------------------
3360 + * Local variables:
3361 + * c-file-style: "linux"
3362 + * End:
3363 + */
3364 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_kern.c um/arch/um/drivers/harddog_kern.c
3365 --- orig/arch/um/drivers/harddog_kern.c 1969-12-31 19:00:00.000000000 -0500
3366 +++ um/arch/um/drivers/harddog_kern.c   2003-10-21 03:26:06.000000000 -0400
3367 @@ -0,0 +1,194 @@
3368 +/* UML hardware watchdog, shamelessly stolen from:
3369 + *
3370 + *     SoftDog 0.05:   A Software Watchdog Device
3371 + *
3372 + *     (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
3373 + *                             http://www.redhat.com
3374 + *
3375 + *     This program is free software; you can redistribute it and/or
3376 + *     modify it under the terms of the GNU General Public License
3377 + *     as published by the Free Software Foundation; either version
3378 + *     2 of the License, or (at your option) any later version.
3379 + *     
3380 + *     Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
3381 + *     warranty for any of this software. This material is provided 
3382 + *     "AS-IS" and at no charge.       
3383 + *
3384 + *     (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
3385 + *
3386 + *     Software only watchdog driver. Unlike its big brother the WDT501P
3387 + *     driver this won't always recover a failed machine.
3388 + *
3389 + *  03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
3390 + *     Modularised.
3391 + *     Added soft_margin; use upon insmod to change the timer delay.
3392 + *     NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate
3393 + *         minors.
3394 + *
3395 + *  19980911 Alan Cox
3396 + *     Made SMP safe for 2.3.x
3397 + *
3398 + *  20011127 Joel Becker (jlbec@evilplan.org>
3399 + *     Added soft_noboot; Allows testing the softdog trigger without 
3400 + *     requiring a recompile.
3401 + *     Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
3402 + */
3403
3404 +#include <linux/module.h>
3405 +#include <linux/config.h>
3406 +#include <linux/types.h>
3407 +#include <linux/kernel.h>
3408 +#include <linux/fs.h>
3409 +#include <linux/mm.h>
3410 +#include <linux/miscdevice.h>
3411 +#include <linux/watchdog.h>
3412 +#include <linux/reboot.h>
3413 +#include <linux/smp_lock.h>
3414 +#include <linux/init.h>
3415 +#include <asm/uaccess.h>
3416 +#include "helper.h"
3417 +#include "mconsole.h"
3418 +
3419 +MODULE_LICENSE("GPL");
3420 +
3421 +/* Locked by the BKL in harddog_open and harddog_release */
3422 +static int timer_alive;
3423 +static int harddog_in_fd = -1;
3424 +static int harddog_out_fd = -1;
3425 +
3426 +/*
3427 + *     Allow only one person to hold it open
3428 + */
3429
3430 +extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock);
3431 +
3432 +static int harddog_open(struct inode *inode, struct file *file)
3433 +{
3434 +       int err;
3435 +       char *sock = NULL;
3436 +
3437 +       lock_kernel();
3438 +       if(timer_alive)
3439 +               return -EBUSY;
3440 +#ifdef CONFIG_HARDDOG_NOWAYOUT  
3441 +       MOD_INC_USE_COUNT;
3442 +#endif
3443 +
3444 +#ifdef CONFIG_MCONSOLE
3445 +       sock = mconsole_notify_socket();
3446 +#endif
3447 +       err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock);
3448 +       if(err) return(err);
3449 +
3450 +       timer_alive = 1;
3451 +       unlock_kernel();
3452 +       return 0;
3453 +}
3454 +
3455 +extern void stop_watchdog(int in_fd, int out_fd);
3456 +
3457 +static int harddog_release(struct inode *inode, struct file *file)
3458 +{
3459 +       /*
3460 +        *      Shut off the timer.
3461 +        */
3462 +       lock_kernel();
3463 +
3464 +       stop_watchdog(harddog_in_fd, harddog_out_fd);
3465 +       harddog_in_fd = -1;
3466 +       harddog_out_fd = -1;
3467 +
3468 +       timer_alive=0;
3469 +       unlock_kernel();
3470 +       return 0;
3471 +}
3472 +
3473 +extern int ping_watchdog(int fd);
3474 +
3475 +static ssize_t harddog_write(struct file *file, const char *data, size_t len,
3476 +                            loff_t *ppos)
3477 +{
3478 +       /*  Can't seek (pwrite) on this device  */
3479 +       if (ppos != &file->f_pos)
3480 +               return -ESPIPE;
3481 +
3482 +       /*
3483 +        *      Refresh the timer.
3484 +        */
3485 +       if(len)
3486 +               return(ping_watchdog(harddog_out_fd));
3487 +       return 0;
3488 +}
3489 +
3490 +static int harddog_ioctl(struct inode *inode, struct file *file,
3491 +                        unsigned int cmd, unsigned long arg)
3492 +{
3493 +       static struct watchdog_info ident = {
3494 +               WDIOF_SETTIMEOUT,
3495 +               0,
3496 +               "UML Hardware Watchdog"
3497 +       };
3498 +       switch (cmd) {
3499 +               default:
3500 +                       return -ENOTTY;
3501 +               case WDIOC_GETSUPPORT:
3502 +                       if(copy_to_user((struct harddog_info *)arg, &ident,
3503 +                                       sizeof(ident)))
3504 +                               return -EFAULT;
3505 +                       return 0;
3506 +               case WDIOC_GETSTATUS:
3507 +               case WDIOC_GETBOOTSTATUS:
3508 +                       return put_user(0,(int *)arg);
3509 +               case WDIOC_KEEPALIVE:
3510 +                       return(ping_watchdog(harddog_out_fd));
3511 +       }
3512 +}
3513 +
3514 +static struct file_operations harddog_fops = {
3515 +       .owner          = THIS_MODULE,
3516 +       .write          = harddog_write,
3517 +       .ioctl          = harddog_ioctl,
3518 +       .open           = harddog_open,
3519 +       .release        = harddog_release,
3520 +};
3521 +
3522 +static struct miscdevice harddog_miscdev = {
3523 +       .minor          = WATCHDOG_MINOR,
3524 +       .name           = "watchdog",
3525 +       .fops           = &harddog_fops,
3526 +};
3527 +
3528 +static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n";
3529 +
3530 +static int __init harddog_init(void)
3531 +{
3532 +       int ret;
3533 +
3534 +       ret = misc_register(&harddog_miscdev);
3535 +
3536 +       if (ret)
3537 +               return ret;
3538 +
3539 +       printk(banner);
3540 +
3541 +       return(0);
3542 +}
3543 +
3544 +static void __exit harddog_exit(void)
3545 +{
3546 +       misc_deregister(&harddog_miscdev);
3547 +}
3548 +
3549 +module_init(harddog_init);
3550 +module_exit(harddog_exit);
3551 +
3552 +/*
3553 + * Overrides for Emacs so that we follow Linus's tabbing style.
3554 + * Emacs will notice this stuff at the end of the file and automatically
3555 + * adjust the settings for this buffer only.  This must remain at the end
3556 + * of the file.
3557 + * ---------------------------------------------------------------------------
3558 + * Local variables:
3559 + * c-file-style: "linux"
3560 + * End:
3561 + */
3562 diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_user.c um/arch/um/drivers/harddog_user.c
3563 --- orig/arch/um/drivers/harddog_user.c 1969-12-31 19:00:00.000000000 -0500
3564 +++ um/arch/um/drivers/harddog_user.c   2003-10-21 03:26:06.000000000 -0400
3565 @@ -0,0 +1,143 @@
3566 +/* 
3567 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3568 + * Licensed under the GPL
3569 + */
3570 +
3571 +#include <stdio.h>
3572 +#include <unistd.h>
3573 +#include <errno.h>
3574 +#include "user_util.h"
3575 +#include "user.h"
3576 +#include "helper.h"
3577 +#include "mconsole.h"
3578 +#include "os.h"
3579 +#include "choose-mode.h"
3580 +#include "mode.h"
3581 +
3582 +struct dog_data {
3583 +       int stdin;
3584 +       int stdout;
3585 +       int close_me[2];
3586 +};
3587 +
3588 +static void pre_exec(void *d)
3589 +{
3590 +       struct dog_data *data = d;
3591 +
3592 +       dup2(data->stdin, 0);
3593 +       dup2(data->stdout, 1);
3594 +       dup2(data->stdout, 2);
3595 +       os_close_file(data->stdin);
3596 +       os_close_file(data->stdout);
3597 +       os_close_file(data->close_me[0]);
3598 +       os_close_file(data->close_me[1]);
3599 +}
3600 +
3601 +int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
3602 +{
3603 +       struct dog_data data;
3604 +       int in_fds[2], out_fds[2], pid, n, err;
3605 +       char pid_buf[sizeof("nnnnn\0")], c;
3606 +       char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL };
3607 +       char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, 
3608 +                                 NULL };
3609 +       char **args = NULL;
3610 +
3611 +       err = os_pipe(in_fds, 1, 0);
3612 +       if(err < 0){
3613 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
3614 +               goto out;
3615 +       }
3616 +
3617 +       err = os_pipe(out_fds, 1, 0);
3618 +       if(err < 0){
3619 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
3620 +               goto out_close_in;
3621 +       }
3622 +
3623 +       data.stdin = out_fds[0];
3624 +       data.stdout = in_fds[1];
3625 +       data.close_me[0] = out_fds[1];
3626 +       data.close_me[1] = in_fds[0];
3627 +
3628 +       if(sock != NULL){
3629 +               mconsole_args[2] = sock;
3630 +               args = mconsole_args;
3631 +       }
3632 +       else {
3633 +               /* XXX The os_getpid() is not SMP correct */
3634 +               sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
3635 +               args = pid_args;
3636 +       }
3637 +
3638 +       pid = run_helper(pre_exec, &data, args, NULL);
3639 +
3640 +       os_close_file(out_fds[0]);
3641 +       os_close_file(in_fds[1]);
3642 +
3643 +       if(pid < 0){
3644 +               err = -pid;
3645 +               printk("harddog_open - run_helper failed, errno = %d\n", -err);
3646 +               goto out_close_out;
3647 +       }
3648 +
3649 +       n = os_read_file(in_fds[0], &c, sizeof(c));
3650 +       if(n == 0){
3651 +               printk("harddog_open - EOF on watchdog pipe\n");
3652 +               helper_wait(pid);
3653 +               err = -EIO;
3654 +               goto out_close_out;
3655 +       }
3656 +       else if(n < 0){
3657 +               printk("harddog_open - read of watchdog pipe failed, "
3658 +                      "err = %d\n", -n);
3659 +               helper_wait(pid);
3660 +               err = n;
3661 +               goto out_close_out;
3662 +       }
3663 +       *in_fd_ret = in_fds[0];
3664 +       *out_fd_ret = out_fds[1];
3665 +       return(0);
3666 +
3667 + out_close_in:
3668 +       os_close_file(in_fds[0]);
3669 +       os_close_file(in_fds[1]);
3670 + out_close_out:
3671 +       os_close_file(out_fds[0]);
3672 +       os_close_file(out_fds[1]);
3673 + out:
3674 +       return(err);
3675 +}
3676 +
3677 +void stop_watchdog(int in_fd, int out_fd)
3678 +{
3679 +       os_close_file(in_fd);
3680 +       os_close_file(out_fd);
3681 +}
3682 +
3683 +int ping_watchdog(int fd)
3684 +{
3685 +       int n;
3686 +       char c = '\n';
3687 +
3688 +       n = os_write_file(fd, &c, sizeof(c));
3689 +       if(n != sizeof(c)){
3690 +               printk("ping_watchdog - write failed, err = %d\n", -n);
3691 +               if(n < 0) 
3692 +                       return(n);
3693 +               return(-EIO);
3694 +       }
3695 +       return 1;
3696 +
3697 +}
3698 +
3699 +/*
3700 + * Overrides for Emacs so that we follow Linus's tabbing style.
3701 + * Emacs will notice this stuff at the end of the file and automatically
3702 + * adjust the settings for this buffer only.  This must remain at the end
3703 + * of the file.
3704 + * ---------------------------------------------------------------------------
3705 + * Local variables:
3706 + * c-file-style: "linux"
3707 + * End:
3708 + */
3709 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_kern.c um/arch/um/drivers/hostaudio_kern.c
3710 --- orig/arch/um/drivers/hostaudio_kern.c       1969-12-31 19:00:00.000000000 -0500
3711 +++ um/arch/um/drivers/hostaudio_kern.c 2003-11-10 00:04:23.000000000 -0500
3712 @@ -0,0 +1,339 @@
3713 +/* 
3714 + * Copyright (C) 2002 Steve Schmidtke 
3715 + * Licensed under the GPL
3716 + */
3717 +
3718 +#include "linux/config.h"
3719 +#include "linux/module.h"
3720 +#include "linux/version.h"
3721 +#include "linux/init.h"
3722 +#include "linux/slab.h"
3723 +#include "linux/fs.h"
3724 +#include "linux/sound.h"
3725 +#include "linux/soundcard.h"
3726 +#include "asm/uaccess.h"
3727 +#include "kern_util.h"
3728 +#include "init.h"
3729 +#include "hostaudio.h"
3730 +
3731 +/* Only changed from linux_main at boot time */
3732 +char *dsp = HOSTAUDIO_DEV_DSP;
3733 +char *mixer = HOSTAUDIO_DEV_MIXER;
3734 +
3735 +#define DSP_HELP \
3736 +"    This is used to specify the host dsp device to the hostaudio driver.\n" \
3737 +"    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
3738 +
3739 +#define MIXER_HELP \
3740 +"    This is used to specify the host mixer device to the hostaudio driver.\n" \
3741 +"    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
3742 +
3743 +#ifndef MODULE
3744 +static int set_dsp(char *name, int *add)
3745 +{
3746 +       dsp = name;
3747 +       return(0);
3748 +}
3749 +
3750 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
3751 +
3752 +static int set_mixer(char *name, int *add)
3753 +{
3754 +       mixer = name;
3755 +       return(0);
3756 +}
3757 +
3758 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
3759 +
3760 +#else /*MODULE*/
3761 +
3762 +MODULE_PARM(dsp, "s");
3763 +MODULE_PARM_DESC(dsp, DSP_HELP);
3764 +
3765 +MODULE_PARM(mixer, "s");
3766 +MODULE_PARM_DESC(mixer, MIXER_HELP);
3767 +
3768 +#endif
3769 +
3770 +/* /dev/dsp file operations */
3771 +
3772 +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count, 
3773 +                             loff_t *ppos)
3774 +{
3775 +        struct hostaudio_state *state = file->private_data;
3776 +       void *kbuf;
3777 +       int err;
3778 +
3779 +#ifdef DEBUG
3780 +        printk("hostaudio: read called, count = %d\n", count);
3781 +#endif
3782 +
3783 +       kbuf = kmalloc(count, GFP_KERNEL);
3784 +       if(kbuf == NULL)
3785 +               return(-ENOMEM);
3786 +
3787 +        err = hostaudio_read_user(state, kbuf, count, ppos);
3788 +       if(err < 0)
3789 +               goto out;
3790 +
3791 +       if(copy_to_user(buffer, kbuf, err))
3792 +               err = -EFAULT;
3793 +
3794 + out:
3795 +       kfree(kbuf);
3796 +       return(err);
3797 +}
3798 +
3799 +static ssize_t hostaudio_write(struct file *file, const char *buffer, 
3800 +                              size_t count, loff_t *ppos)
3801 +{
3802 +        struct hostaudio_state *state = file->private_data;
3803 +       void *kbuf;
3804 +       int err;
3805 +
3806 +#ifdef DEBUG
3807 +        printk("hostaudio: write called, count = %d\n", count);
3808 +#endif
3809 +
3810 +       kbuf = kmalloc(count, GFP_KERNEL);
3811 +       if(kbuf == NULL)
3812 +               return(-ENOMEM);
3813 +
3814 +       err = -EFAULT;
3815 +       if(copy_from_user(kbuf, buffer, count))
3816 +               goto out;
3817 +
3818 +        err = hostaudio_write_user(state, kbuf, count, ppos);
3819 +       if(err < 0)
3820 +               goto out;
3821 +
3822 + out:
3823 +       kfree(kbuf);
3824 +       return(err);
3825 +}
3826 +
3827 +static unsigned int hostaudio_poll(struct file *file, 
3828 +                                  struct poll_table_struct *wait)
3829 +{
3830 +        unsigned int mask = 0;
3831 +
3832 +#ifdef DEBUG
3833 +        printk("hostaudio: poll called (unimplemented)\n");
3834 +#endif
3835 +
3836 +        return(mask);
3837 +}
3838 +
3839 +static int hostaudio_ioctl(struct inode *inode, struct file *file, 
3840 +                          unsigned int cmd, unsigned long arg)
3841 +{
3842 +        struct hostaudio_state *state = file->private_data;
3843 +       unsigned long data = 0;
3844 +       int err;
3845 +
3846 +#ifdef DEBUG
3847 +        printk("hostaudio: ioctl called, cmd = %u\n", cmd);
3848 +#endif
3849 +       switch(cmd){
3850 +       case SNDCTL_DSP_SPEED:
3851 +       case SNDCTL_DSP_STEREO:
3852 +       case SNDCTL_DSP_GETBLKSIZE:
3853 +       case SNDCTL_DSP_CHANNELS:
3854 +       case SNDCTL_DSP_SUBDIVIDE:
3855 +       case SNDCTL_DSP_SETFRAGMENT:
3856 +               if(get_user(data, (int *) arg))
3857 +                       return(-EFAULT);
3858 +               break;
3859 +       default:
3860 +               break;
3861 +       }
3862 +
3863 +        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
3864 +
3865 +       switch(cmd){
3866 +       case SNDCTL_DSP_SPEED:
3867 +       case SNDCTL_DSP_STEREO:
3868 +       case SNDCTL_DSP_GETBLKSIZE:
3869 +       case SNDCTL_DSP_CHANNELS:
3870 +       case SNDCTL_DSP_SUBDIVIDE:
3871 +       case SNDCTL_DSP_SETFRAGMENT:
3872 +               if(put_user(data, (int *) arg))
3873 +                       return(-EFAULT);
3874 +               break;
3875 +       default:
3876 +               break;
3877 +       }
3878 +
3879 +       return(err);
3880 +}
3881 +
3882 +static int hostaudio_open(struct inode *inode, struct file *file)
3883 +{
3884 +        struct hostaudio_state *state;
3885 +        int r = 0, w = 0;
3886 +        int ret;
3887 +
3888 +#ifdef DEBUG
3889 +        printk("hostaudio: open called (host: %s)\n", dsp);
3890 +#endif
3891 +
3892 +        state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
3893 +        if(state == NULL) return(-ENOMEM);
3894 +
3895 +        if(file->f_mode & FMODE_READ) r = 1;
3896 +        if(file->f_mode & FMODE_WRITE) w = 1;
3897 +
3898 +        ret = hostaudio_open_user(state, r, w, dsp);
3899 +        if(ret < 0){
3900 +               kfree(state);
3901 +               return(ret);
3902 +        }
3903 +
3904 +        file->private_data = state;
3905 +        return(0);
3906 +}
3907 +
3908 +static int hostaudio_release(struct inode *inode, struct file *file)
3909 +{
3910 +        struct hostaudio_state *state = file->private_data;
3911 +        int ret;
3912 +
3913 +#ifdef DEBUG
3914 +        printk("hostaudio: release called\n");
3915 +#endif
3916 +
3917 +        ret = hostaudio_release_user(state);
3918 +        kfree(state);
3919 +
3920 +        return(ret);
3921 +}
3922 +
3923 +/* /dev/mixer file operations */
3924 +
3925 +static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, 
3926 +                                 unsigned int cmd, unsigned long arg)
3927 +{
3928 +        struct hostmixer_state *state = file->private_data;
3929 +
3930 +#ifdef DEBUG
3931 +        printk("hostmixer: ioctl called\n");
3932 +#endif
3933 +
3934 +        return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
3935 +}
3936 +
3937 +static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
3938 +{
3939 +        struct hostmixer_state *state;
3940 +        int r = 0, w = 0;
3941 +        int ret;
3942 +
3943 +#ifdef DEBUG
3944 +        printk("hostmixer: open called (host: %s)\n", mixer);
3945 +#endif
3946 +
3947 +        state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
3948 +        if(state == NULL) return(-ENOMEM);
3949 +
3950 +        if(file->f_mode & FMODE_READ) r = 1;
3951 +        if(file->f_mode & FMODE_WRITE) w = 1;
3952 +
3953 +        ret = hostmixer_open_mixdev_user(state, r, w, mixer);
3954 +        
3955 +        if(ret < 0){
3956 +               kfree(state);
3957 +               return(ret);
3958 +        }
3959 +
3960 +        file->private_data = state;
3961 +        return(0);
3962 +}
3963 +
3964 +static int hostmixer_release(struct inode *inode, struct file *file)
3965 +{
3966 +        struct hostmixer_state *state = file->private_data;
3967 +       int ret;
3968 +
3969 +#ifdef DEBUG
3970 +        printk("hostmixer: release called\n");
3971 +#endif
3972 +
3973 +        ret = hostmixer_release_mixdev_user(state);
3974 +        kfree(state);
3975 +
3976 +        return(ret);
3977 +}
3978 +
3979 +
3980 +/* kernel module operations */
3981 +
3982 +static struct file_operations hostaudio_fops = {
3983 +        .owner          = THIS_MODULE,
3984 +        .llseek         = no_llseek,
3985 +        .read           = hostaudio_read,
3986 +        .write          = hostaudio_write,
3987 +        .poll           = hostaudio_poll,
3988 +        .ioctl          = hostaudio_ioctl,
3989 +        .mmap           = NULL,
3990 +        .open           = hostaudio_open,
3991 +        .release        = hostaudio_release,
3992 +};
3993 +
3994 +static struct file_operations hostmixer_fops = {
3995 +        .owner          = THIS_MODULE,
3996 +        .llseek         = no_llseek,
3997 +        .ioctl          = hostmixer_ioctl_mixdev,
3998 +        .open           = hostmixer_open_mixdev,
3999 +        .release        = hostmixer_release,
4000 +};
4001 +
4002 +struct {
4003 +       int dev_audio;
4004 +       int dev_mixer;
4005 +} module_data;
4006 +
4007 +MODULE_AUTHOR("Steve Schmidtke");
4008 +MODULE_DESCRIPTION("UML Audio Relay");
4009 +MODULE_LICENSE("GPL");
4010 +
4011 +static int __init hostaudio_init_module(void)
4012 +{
4013 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
4014 +              dsp, mixer);
4015 +
4016 +       module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
4017 +        if(module_data.dev_audio < 0){
4018 +                printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
4019 +                return -ENODEV;
4020 +        }
4021 +
4022 +       module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
4023 +        if(module_data.dev_mixer < 0){
4024 +                printk(KERN_ERR "hostmixer: couldn't register mixer "
4025 +                      "device!\n");
4026 +                unregister_sound_dsp(module_data.dev_audio);
4027 +                return -ENODEV;
4028 +        }
4029 +
4030 +        return 0;
4031 +}
4032 +
4033 +static void __exit hostaudio_cleanup_module (void)
4034 +{
4035 +       unregister_sound_mixer(module_data.dev_mixer);
4036 +       unregister_sound_dsp(module_data.dev_audio);
4037 +}
4038 +
4039 +module_init(hostaudio_init_module);
4040 +module_exit(hostaudio_cleanup_module);
4041 +
4042 +/*
4043 + * Overrides for Emacs so that we follow Linus's tabbing style.
4044 + * Emacs will notice this stuff at the end of the file and automatically
4045 + * adjust the settings for this buffer only.  This must remain at the end
4046 + * of the file.
4047 + * ---------------------------------------------------------------------------
4048 + * Local variables:
4049 + * c-file-style: "linux"
4050 + * End:
4051 + */
4052 diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_user.c um/arch/um/drivers/hostaudio_user.c
4053 --- orig/arch/um/drivers/hostaudio_user.c       1969-12-31 19:00:00.000000000 -0500
4054 +++ um/arch/um/drivers/hostaudio_user.c 2003-10-21 03:26:06.000000000 -0400
4055 @@ -0,0 +1,134 @@
4056 +/* 
4057 + * Copyright (C) 2002 Steve Schmidtke 
4058 + * Licensed under the GPL
4059 + */
4060 +
4061 +#include <sys/types.h>
4062 +#include <unistd.h>
4063 +#include <errno.h>
4064 +#include "hostaudio.h"
4065 +#include "user_util.h"
4066 +#include "kern_util.h"
4067 +#include "user.h"
4068 +#include "os.h"
4069 +
4070 +/* /dev/dsp file operations */
4071 +
4072 +ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, 
4073 +                           size_t count, loff_t *ppos)
4074 +{
4075 +#ifdef DEBUG
4076 +        printk("hostaudio: read_user called, count = %d\n", count);
4077 +#endif
4078 +
4079 +        return(os_read_file(state->fd, buffer, count));
4080 +}
4081 +
4082 +ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
4083 +                            size_t count, loff_t *ppos)
4084 +{
4085 +       ssize_t ret;
4086 +
4087 +#ifdef DEBUG
4088 +        printk("hostaudio: write_user called, count = %d\n", count);
4089 +#endif
4090 +
4091 +        return(os_write_file(state->fd, buffer, count));
4092 +
4093 +        return(ret);
4094 +}
4095 +
4096 +int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, 
4097 +                        unsigned long arg)
4098 +{
4099 +#ifdef DEBUG
4100 +        printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
4101 +#endif
4102 +
4103 +        return(os_ioctl_generic(state->fd, cmd, arg));
4104 +}
4105 +
4106 +int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
4107 +{
4108 +#ifdef DEBUG
4109 +        printk("hostaudio: open_user called\n");
4110 +#endif
4111 +
4112 +        state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
4113 +
4114 +        if(state->fd < 0) {
4115 +               printk("hostaudio_open_user failed to open '%s', err = %d\n",
4116 +                      dsp, -state->fd);
4117 +               return(state->fd); 
4118 +       }
4119 +        
4120 +       return(0);
4121 +}
4122 +
4123 +int hostaudio_release_user(struct hostaudio_state *state)
4124 +{
4125 +#ifdef DEBUG
4126 +        printk("hostaudio: release called\n");
4127 +#endif
4128 +        if(state->fd >= 0){
4129 +               os_close_file(state->fd);
4130 +               state->fd = -1;
4131 +        }
4132 +
4133 +        return(0);
4134 +}
4135 +
4136 +/* /dev/mixer file operations */
4137 +
4138 +int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
4139 +                               unsigned int cmd, unsigned long arg)
4140 +{
4141 +#ifdef DEBUG
4142 +        printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
4143 +#endif
4144 +
4145 +       return(os_ioctl_generic(state->fd, cmd, arg));
4146 +}
4147 +
4148 +int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
4149 +                              char *mixer)
4150 +{
4151 +#ifdef DEBUG
4152 +        printk("hostmixer: open_user called\n");
4153 +#endif
4154 +
4155 +        state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
4156 +
4157 +        if(state->fd < 0) {
4158 +               printk("hostaudio_open_mixdev_user failed to open '%s', "
4159 +                      "err = %d\n", mixer, state->fd);
4160 +               return(state->fd); 
4161 +       }
4162 +        
4163 +       return(0);
4164 +}
4165 +
4166 +int hostmixer_release_mixdev_user(struct hostmixer_state *state)
4167 +{
4168 +#ifdef DEBUG
4169 +        printk("hostmixer: release_user called\n");
4170 +#endif
4171 +
4172 +        if(state->fd >= 0){
4173 +               os_close_file(state->fd);
4174 +               state->fd = -1;
4175 +        }
4176 +
4177 +        return 0;
4178 +}
4179 +
4180 +/*
4181 + * Overrides for Emacs so that we follow Linus's tabbing style.
4182 + * Emacs will notice this stuff at the end of the file and automatically
4183 + * adjust the settings for this buffer only.  This must remain at the end
4184 + * of the file.
4185 + * ---------------------------------------------------------------------------
4186 + * Local variables:
4187 + * c-file-style: "linux"
4188 + * End:
4189 + */
4190 diff -Naur -X ../exclude-files orig/arch/um/drivers/line.c um/arch/um/drivers/line.c
4191 --- orig/arch/um/drivers/line.c 1969-12-31 19:00:00.000000000 -0500
4192 +++ um/arch/um/drivers/line.c   2003-11-07 03:03:57.000000000 -0500
4193 @@ -0,0 +1,610 @@
4194 +/* 
4195 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
4196 + * Licensed under the GPL
4197 + */
4198 +
4199 +#include "linux/sched.h"
4200 +#include "linux/slab.h"
4201 +#include "linux/list.h"
4202 +#include "linux/devfs_fs_kernel.h"
4203 +#include "asm/irq.h"
4204 +#include "asm/uaccess.h"
4205 +#include "chan_kern.h"
4206 +#include "irq_user.h"
4207 +#include "line.h"
4208 +#include "kern.h"
4209 +#include "user_util.h"
4210 +#include "kern_util.h"
4211 +#include "os.h"
4212 +#include "irq_kern.h"
4213 +
4214 +#define LINE_BUFSIZE 4096
4215 +
4216 +static void line_interrupt(int irq, void *data, struct pt_regs *unused)
4217 +{
4218 +       struct line *dev = data;
4219 +
4220 +       if(dev->count > 0) 
4221 +               chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
4222 +                              dev);
4223 +}
4224 +
4225 +static void line_timer_cb(void *arg)
4226 +{
4227 +       struct line *dev = arg;
4228 +
4229 +       line_interrupt(dev->driver->read_irq, dev, NULL);
4230 +}
4231 +
4232 +static int write_room(struct line *dev)
4233 +{
4234 +       int n;
4235 +
4236 +       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
4237 +
4238 +       n = dev->head - dev->tail;
4239 +       if(n <= 0) n = LINE_BUFSIZE + n;
4240 +       return(n - 1);
4241 +}
4242 +
4243 +static int buffer_data(struct line *line, const char *buf, int len)
4244 +{
4245 +       int end, room;
4246 +
4247 +       if(line->buffer == NULL){
4248 +               line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
4249 +               if(line->buffer == NULL){
4250 +                       printk("buffer_data - atomic allocation failed\n");
4251 +                       return(0);
4252 +               }
4253 +               line->head = line->buffer;
4254 +               line->tail = line->buffer;
4255 +       }
4256 +
4257 +       room = write_room(line);
4258 +       len = (len > room) ? room : len;
4259 +
4260 +       end = line->buffer + LINE_BUFSIZE - line->tail;
4261 +       if(len < end){
4262 +               memcpy(line->tail, buf, len);
4263 +               line->tail += len;
4264 +       }
4265 +       else {
4266 +               memcpy(line->tail, buf, end);
4267 +               buf += end;
4268 +               len -= end;
4269 +               memcpy(line->buffer, buf, len);
4270 +               line->tail = line->buffer + len;
4271 +       }
4272 +
4273 +       return(len);
4274 +}
4275 +
4276 +static int flush_buffer(struct line *line)
4277 +{
4278 +       int n, count;
4279 +
4280 +       if((line->buffer == NULL) || (line->head == line->tail)) return(1);
4281 +
4282 +       if(line->tail < line->head){
4283 +               count = line->buffer + LINE_BUFSIZE - line->head;
4284 +               n = write_chan(&line->chan_list, line->head, count,
4285 +                              line->driver->write_irq);
4286 +               if(n < 0) return(n);
4287 +               if(n == count) line->head = line->buffer;
4288 +               else {
4289 +                       line->head += n;
4290 +                       return(0);
4291 +               }
4292 +       }
4293 +
4294 +       count = line->tail - line->head;
4295 +       n = write_chan(&line->chan_list, line->head, count, 
4296 +                      line->driver->write_irq);
4297 +       if(n < 0) return(n);
4298 +
4299 +       line->head += n;
4300 +       return(line->head == line->tail);
4301 +}
4302 +
4303 +int line_write(struct line *lines, struct tty_struct *tty, int from_user,
4304 +              const char *buf, int len)
4305 +{
4306 +       struct line *line;
4307 +       char *new;
4308 +       unsigned long flags;
4309 +       int n, err, i, ret = 0;
4310 +
4311 +       if(tty->stopped) return 0;
4312 +
4313 +       if(from_user){
4314 +               new = kmalloc(len, GFP_KERNEL);
4315 +               if(new == NULL)
4316 +                       return(0);
4317 +               n = copy_from_user(new, buf, len);
4318 +               buf = new;
4319 +               if(n == len){
4320 +                       len = -EFAULT;
4321 +                       goto out_free;
4322 +               }
4323 +
4324 +               len -= n;
4325 +       }
4326 +
4327 +       i = minor(tty->device) - tty->driver.minor_start;
4328 +       line = &lines[i];
4329 +
4330 +       down(&line->sem);
4331 +       if(line->head != line->tail){
4332 +               local_irq_save(flags);
4333 +               ret += buffer_data(line, buf, len);
4334 +               err = flush_buffer(line);
4335 +               local_irq_restore(flags);
4336 +               if(err <= 0)
4337 +                       goto out_up;
4338 +       }
4339 +       else {
4340 +               n = write_chan(&line->chan_list, buf, len, 
4341 +                              line->driver->write_irq);
4342 +               if(n < 0){
4343 +                       ret = n;
4344 +                       goto out_up;
4345 +               }
4346 +
4347 +               len -= n;
4348 +               ret += n;
4349 +               if(len > 0)
4350 +                       ret += buffer_data(line, buf + n, len);
4351 +       }
4352 + out_up:
4353 +       up(&line->sem);
4354 +
4355 + out_free:
4356 +       if(from_user)
4357 +               kfree(buf);
4358 +       return(ret);
4359 +}
4360 +
4361 +static void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
4362 +{
4363 +       struct line *dev = data;
4364 +       struct tty_struct *tty = dev->tty;
4365 +       int err;
4366 +
4367 +       err = flush_buffer(dev);
4368 +       if(err == 0) return;
4369 +       else if(err < 0){
4370 +               dev->head = dev->buffer;
4371 +               dev->tail = dev->buffer;
4372 +       }
4373 +
4374 +       if(tty == NULL) return;
4375 +
4376 +       if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
4377 +          (tty->ldisc.write_wakeup != NULL))
4378 +               (tty->ldisc.write_wakeup)(tty);
4379 +       
4380 +       /* BLOCKING mode
4381 +        * In blocking mode, everything sleeps on tty->write_wait.
4382 +        * Sleeping in the console driver would break non-blocking
4383 +        * writes.
4384 +        */
4385 +
4386 +       if (waitqueue_active(&tty->write_wait))
4387 +               wake_up_interruptible(&tty->write_wait);
4388 +
4389 +}
4390 +
4391 +int line_setup_irq(int fd, int input, int output, void *data)
4392 +{
4393 +       struct line *line = data;
4394 +       struct line_driver *driver = line->driver;
4395 +       int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
4396 +
4397 +       if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, 
4398 +                                      line_interrupt, flags, 
4399 +                                      driver->read_irq_name, line);
4400 +       if(err) return(err);
4401 +       if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 
4402 +                                       line_write_interrupt, flags, 
4403 +                                       driver->write_irq_name, line);
4404 +       line->have_irq = 1;
4405 +       return(err);
4406 +}
4407 +
4408 +void line_disable(struct line *line, int current_irq)
4409 +{
4410 +       if(!line->have_irq) return;
4411 +
4412 +       if(line->driver->read_irq == current_irq)
4413 +               free_irq_later(line->driver->read_irq, line);
4414 +       else
4415 +               free_irq(line->driver->read_irq, line);
4416 +
4417 +       if(line->driver->write_irq == current_irq)
4418 +               free_irq_later(line->driver->write_irq, line);
4419 +       else
4420 +               free_irq(line->driver->write_irq, line);
4421 +
4422 +       line->have_irq = 0;
4423 +}
4424 +
4425 +int line_open(struct line *lines, struct tty_struct *tty,
4426 +             struct chan_opts *opts)
4427 +{
4428 +       struct line *line;
4429 +       int n, err = 0;
4430 +
4431 +       if(tty == NULL) n = 0;
4432 +       else n = minor(tty->device) - tty->driver.minor_start;
4433 +       line = &lines[n];
4434 +
4435 +       down(&line->sem);
4436 +       if(line->count == 0){
4437 +               if(!line->valid){
4438 +                       err = -ENODEV;
4439 +                       goto out;
4440 +               }
4441 +               if(list_empty(&line->chan_list)){
4442 +                       err = parse_chan_pair(line->init_str, &line->chan_list,
4443 +                                             line->init_pri, n, opts);
4444 +                       if(err) goto out;
4445 +                       err = open_chan(&line->chan_list);
4446 +                       if(err) goto out;
4447 +               }
4448 +               enable_chan(&line->chan_list, line);
4449 +               INIT_TQUEUE(&line->task, line_timer_cb, line);
4450 +       }
4451 +
4452 +       if(!line->sigio){
4453 +               chan_enable_winch(&line->chan_list, line);
4454 +               line->sigio = 1;
4455 +       }
4456 +
4457 +       /* This is outside the if because the initial console is opened
4458 +        * with tty == NULL
4459 +        */
4460 +       line->tty = tty;
4461 +
4462 +       if(tty != NULL){
4463 +               tty->driver_data = line;
4464 +               chan_window_size(&line->chan_list, &tty->winsize.ws_row, 
4465 +                                &tty->winsize.ws_col);
4466 +       }
4467 +
4468 +       line->count++;
4469 + out:
4470 +       up(&line->sem);
4471 +       return(err);
4472 +}
4473 +
4474 +void line_close(struct line *lines, struct tty_struct *tty)
4475 +{
4476 +       struct line *line;
4477 +       int n;
4478 +
4479 +       if(tty == NULL) n = 0;
4480 +       else n = minor(tty->device) - tty->driver.minor_start;
4481 +       line = &lines[n];
4482 +
4483 +       down(&line->sem);
4484 +       line->count--;
4485 +
4486 +       /* I don't like this, but I can't think of anything better.  What's
4487 +        * going on is that the tty is in the process of being closed for
4488 +        * the last time.  Its count hasn't been dropped yet, so it's still
4489 +        * at 1.  This may happen when line->count != 0 because of the initial
4490 +        * console open (without a tty) bumping it up to 1.
4491 +        */
4492 +       if((line->tty != NULL) && (line->tty->count == 1))
4493 +               line->tty = NULL;
4494 +       if(line->count == 0)
4495 +               line_disable(line, -1);
4496 +       up(&line->sem);
4497 +}
4498 +
4499 +void close_lines(struct line *lines, int nlines)
4500 +{
4501 +       int i;
4502 +
4503 +       for(i = 0; i < nlines; i++)
4504 +               close_chan(&lines[i].chan_list);
4505 +}
4506 +
4507 +int line_setup(struct line *lines, int num, char *init, int all_allowed)
4508 +{
4509 +       int i, n;
4510 +       char *end;
4511 +
4512 +       if(*init == '=') n = -1;
4513 +       else {
4514 +               n = simple_strtoul(init, &end, 0);
4515 +               if(*end != '='){
4516 +                       printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 
4517 +                              init);
4518 +                       return(0);
4519 +               }
4520 +               init = end;
4521 +       }
4522 +       init++;
4523 +       if((n >= 0) && (n >= num)){
4524 +               printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
4525 +                      n, num);
4526 +               return(0);
4527 +       }
4528 +       else if(n >= 0){
4529 +               if(lines[n].count > 0){
4530 +                       printk("line_setup - device %d is open\n", n);
4531 +                       return(0);
4532 +               }
4533 +               if(lines[n].init_pri <= INIT_ONE){
4534 +                       lines[n].init_pri = INIT_ONE;
4535 +                       if(!strcmp(init, "none")) lines[n].valid = 0;
4536 +                       else {
4537 +                               lines[n].init_str = init;
4538 +                               lines[n].valid = 1;
4539 +                       }       
4540 +               }
4541 +       }
4542 +       else if(!all_allowed){
4543 +               printk("line_setup - can't configure all devices from "
4544 +                      "mconsole\n");
4545 +               return(0);
4546 +       }
4547 +       else {
4548 +               for(i = 0; i < num; i++){
4549 +                       if(lines[i].init_pri <= INIT_ALL){
4550 +                               lines[i].init_pri = INIT_ALL;
4551 +                               if(!strcmp(init, "none")) lines[i].valid = 0;
4552 +                               else {
4553 +                                       lines[i].init_str = init;
4554 +                                       lines[i].valid = 1;
4555 +                               }
4556 +                       }
4557 +               }
4558 +       }
4559 +       return(1);
4560 +}
4561 +
4562 +int line_config(struct line *lines, int num, char *str)
4563 +{
4564 +       char *new = uml_strdup(str);
4565 +
4566 +       if(new == NULL){
4567 +               printk("line_config - uml_strdup failed\n");
4568 +               return(-ENOMEM);
4569 +       }
4570 +       return(!line_setup(lines, num, new, 0));
4571 +}
4572 +
4573 +int line_get_config(char *name, struct line *lines, int num, char *str, 
4574 +                   int size, char **error_out)
4575 +{
4576 +       struct line *line;
4577 +       char *end;
4578 +       int dev, n = 0;
4579 +
4580 +       dev = simple_strtoul(name, &end, 0);
4581 +       if((*end != '\0') || (end == name)){
4582 +               *error_out = "line_get_config failed to parse device number";
4583 +               return(0);
4584 +       }
4585 +
4586 +       if((dev < 0) || (dev >= num)){
4587 +               *error_out = "device number of of range";
4588 +               return(0);
4589 +       }
4590 +
4591 +       line = &lines[dev];
4592 +
4593 +       down(&line->sem);
4594 +       if(!line->valid)
4595 +               CONFIG_CHUNK(str, size, n, "none", 1);
4596 +       else if(line->count == 0)
4597 +               CONFIG_CHUNK(str, size, n, line->init_str, 1);
4598 +       else n = chan_config_string(&line->chan_list, str, size, error_out);
4599 +       up(&line->sem);
4600 +
4601 +       return(n);
4602 +}
4603 +
4604 +int line_remove(struct line *lines, int num, char *str)
4605 +{
4606 +       char config[sizeof("conxxxx=none\0")];
4607 +
4608 +       sprintf(config, "%s=none", str);
4609 +       return(!line_setup(lines, num, config, 0));
4610 +}
4611 +
4612 +static int line_write_room(struct tty_struct *tty)
4613 +{
4614 +       struct line *dev = tty->driver_data;
4615 +
4616 +       return(write_room(dev));
4617 +}
4618 +
4619 +void line_register_devfs(struct lines *set, struct line_driver *line_driver, 
4620 +                        struct tty_driver *driver, struct line *lines,
4621 +                        int nlines)
4622 +{
4623 +       int err, i, n;
4624 +       char *from, *to;
4625 +
4626 +       driver->driver_name = line_driver->name;
4627 +       driver->name = line_driver->devfs_name;
4628 +       driver->major = line_driver->major;
4629 +       driver->minor_start = line_driver->minor_start;
4630 +       driver->type = line_driver->type;
4631 +       driver->subtype = line_driver->subtype;
4632 +       driver->magic = TTY_DRIVER_MAGIC;
4633 +       driver->flags = TTY_DRIVER_REAL_RAW;
4634 +
4635 +       n = set->num;
4636 +       driver->num = n;
4637 +       driver->table = kmalloc(n * sizeof(driver->table[0]), GFP_KERNEL);
4638 +       driver->termios = kmalloc(n * sizeof(driver->termios[0]), GFP_KERNEL);
4639 +       driver->termios_locked = kmalloc(n * sizeof(driver->termios_locked[0]),
4640 +                                        GFP_KERNEL);
4641 +       if((driver->table == NULL) || (driver->termios == NULL) ||
4642 +          (driver->termios_locked == NULL))
4643 +               panic("Failed to allocate driver table");
4644 +
4645 +       memset(driver->table, 0, n * sizeof(driver->table[0]));
4646 +       memset(driver->termios, 0, n * sizeof(driver->termios[0]));
4647 +       memset(driver->termios_locked, 0, 
4648 +              n * sizeof(driver->termios_locked[0]));
4649 +
4650 +       driver->write_room = line_write_room;
4651 +       driver->init_termios = tty_std_termios;
4652 +
4653 +       if (tty_register_driver(driver))
4654 +               panic("line_register_devfs : Couldn't register driver\n");
4655 +
4656 +       from = line_driver->symlink_from;
4657 +       to = line_driver->symlink_to;
4658 +       err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL);
4659 +       if(err) printk("Symlink creation from /dev/%s to /dev/%s "
4660 +                      "returned %d\n", from, to, err);
4661 +
4662 +       for(i = 0; i < nlines; i++){
4663 +               if(!lines[i].valid) 
4664 +                       tty_unregister_devfs(driver, driver->minor_start + i);
4665 +       }
4666 +
4667 +       mconsole_register_dev(&line_driver->mc);
4668 +}
4669 +
4670 +void lines_init(struct line *lines, int nlines)
4671 +{
4672 +       struct line *line;
4673 +       int i;
4674 +
4675 +       for(i = 0; i < nlines; i++){
4676 +               line = &lines[i];
4677 +               INIT_LIST_HEAD(&line->chan_list);
4678 +               sema_init(&line->sem, 1);
4679 +               if(line->init_str != NULL){
4680 +                       line->init_str = uml_strdup(line->init_str);
4681 +                       if(line->init_str == NULL)
4682 +                               printk("lines_init - uml_strdup returned "
4683 +                                      "NULL\n");
4684 +               }
4685 +       }
4686 +}
4687 +
4688 +struct winch {
4689 +       struct list_head list;
4690 +       int fd;
4691 +       int tty_fd;
4692 +       int pid;
4693 +       struct line *line;
4694 +};
4695 +
4696 +void winch_interrupt(int irq, void *data, struct pt_regs *unused)
4697 +{
4698 +       struct winch *winch = data;
4699 +       struct tty_struct *tty;
4700 +       int err;
4701 +       char c;
4702 +
4703 +       if(winch->fd != -1){
4704 +               err = generic_read(winch->fd, &c, NULL);
4705 +               if(err < 0){
4706 +                       if(err != -EAGAIN){
4707 +                               printk("winch_interrupt : read failed, "
4708 +                                      "errno = %d\n", -err);
4709 +                               printk("fd %d is losing SIGWINCH support\n", 
4710 +                                      winch->tty_fd);
4711 +                               return;
4712 +                       }
4713 +                       goto out;
4714 +               }
4715 +       }
4716 +       tty = winch->line->tty;
4717 +       if(tty != NULL){
4718 +               chan_window_size(&winch->line->chan_list, 
4719 +                                &tty->winsize.ws_row, 
4720 +                                &tty->winsize.ws_col);
4721 +               kill_pg(tty->pgrp, SIGWINCH, 1);
4722 +       }
4723 + out:
4724 +       if(winch->fd != -1)
4725 +               reactivate_fd(winch->fd, WINCH_IRQ);
4726 +}
4727 +
4728 +DECLARE_MUTEX(winch_handler_sem);
4729 +LIST_HEAD(winch_handlers);
4730 +
4731 +void register_winch_irq(int fd, int tty_fd, int pid, void *line)
4732 +{
4733 +       struct winch *winch;
4734 +
4735 +       down(&winch_handler_sem);
4736 +       winch = kmalloc(sizeof(*winch), GFP_KERNEL);
4737 +       if(winch == NULL){
4738 +               printk("register_winch_irq - kmalloc failed\n");
4739 +               goto out;
4740 +       }
4741 +       *winch = ((struct winch) { .list        = LIST_HEAD_INIT(winch->list),
4742 +                                  .fd          = fd,
4743 +                                  .tty_fd      = tty_fd,
4744 +                                  .pid         = pid,
4745 +                                  .line        = line });
4746 +       list_add(&winch->list, &winch_handlers);
4747 +       if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 
4748 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
4749 +                         "winch", winch) < 0)
4750 +               printk("register_winch_irq - failed to register IRQ\n");
4751 + out:
4752 +       up(&winch_handler_sem);
4753 +}
4754 +
4755 +static void winch_cleanup(void)
4756 +{
4757 +       struct list_head *ele;
4758 +       struct winch *winch;
4759 +
4760 +       list_for_each(ele, &winch_handlers){
4761 +               winch = list_entry(ele, struct winch, list);
4762 +               if(winch->fd != -1){
4763 +                       deactivate_fd(winch->fd, WINCH_IRQ);
4764 +                       os_close_file(winch->fd);
4765 +               }
4766 +               if(winch->pid != -1) 
4767 +                       os_kill_process(winch->pid, 1);
4768 +       }
4769 +}
4770 +
4771 +__uml_exitcall(winch_cleanup);
4772 +
4773 +char *add_xterm_umid(char *base)
4774 +{
4775 +       char *umid, *title;
4776 +       int len;
4777 +
4778 +       umid = get_umid(1);
4779 +       if(umid == NULL) return(base);
4780 +       
4781 +       len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
4782 +       title = kmalloc(len, GFP_KERNEL);
4783 +       if(title == NULL){
4784 +               printk("Failed to allocate buffer for xterm title\n");
4785 +               return(base);
4786 +       }
4787 +
4788 +       strncpy(title, base, len);
4789 +       len -= strlen(title);
4790 +       snprintf(&title[strlen(title)], len, " (%s)", umid);
4791 +       return(title);
4792 +}
4793 +
4794 +/*
4795 + * Overrides for Emacs so that we follow Linus's tabbing style.
4796 + * Emacs will notice this stuff at the end of the file and automatically
4797 + * adjust the settings for this buffer only.  This must remain at the end
4798 + * of the file.
4799 + * ---------------------------------------------------------------------------
4800 + * Local variables:
4801 + * c-file-style: "linux"
4802 + * End:
4803 + */
4804 diff -Naur -X ../exclude-files orig/arch/um/drivers/Makefile um/arch/um/drivers/Makefile
4805 --- orig/arch/um/drivers/Makefile       1969-12-31 19:00:00.000000000 -0500
4806 +++ um/arch/um/drivers/Makefile 2003-11-08 09:58:54.000000000 -0500
4807 @@ -0,0 +1,97 @@
4808 +# 
4809 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
4810 +# Licensed under the GPL
4811 +#
4812 +
4813 +O_TARGET := built-in.o 
4814 +
4815 +CHAN_OBJS := chan_kern.o chan_user.o line.o 
4816 +
4817 +list-multi := slip.o slirp.o daemon.o mcast.o mconsole.o net.o ubd.o \
4818 +       hostaudio.o pcap.o port.o harddog.o
4819 +
4820 +slip-objs := slip_kern.o slip_user.o
4821 +slirp-objs := slirp_kern.o slirp_user.o
4822 +daemon-objs := daemon_kern.o daemon_user.o
4823 +mcast-objs := mcast_kern.o mcast_user.o
4824 +pcap-objs := pcap_kern.o pcap_user.o
4825 +pcap-libs := -lpcap -L/usr/lib
4826 +net-objs := net_kern.o net_user.o
4827 +mconsole-objs := mconsole_kern.o mconsole_user.o
4828 +hostaudio-objs := hostaudio_kern.o hostaudio_user.o
4829 +ubd-objs := ubd_kern.o ubd_user.o
4830 +port-objs := port_kern.o port_user.o
4831 +harddog-objs := harddog_kern.o harddog_user.o
4832 +
4833 +export-objs := mconsole_kern.o
4834 +
4835 +obj-y = 
4836 +obj-$(CONFIG_SSL) += ssl.o 
4837 +obj-$(CONFIG_UML_NET_SLIP) += slip.o
4838 +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o
4839 +obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
4840 +obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
4841 +obj-$(CONFIG_UML_NET_PCAP) += pcap.o 
4842 +obj-$(CONFIG_UML_NET) += net.o 
4843 +obj-$(CONFIG_MCONSOLE) += mconsole.o
4844 +obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
4845 +obj-$(CONFIG_BLK_DEV_UBD) += ubd.o 
4846 +obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
4847 +obj-$(CONFIG_FD_CHAN) += fd.o 
4848 +obj-$(CONFIG_NULL_CHAN) += null.o 
4849 +obj-$(CONFIG_PORT_CHAN) += port.o
4850 +obj-$(CONFIG_PTY_CHAN) += pty.o
4851 +obj-$(CONFIG_TTY_CHAN) += tty.o 
4852 +obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
4853 +obj-$(CONFIG_UML_WATCHDOG) += harddog.o
4854 +obj-$(CONFIG_COW) += cow_kern.o
4855 +obj-$(CONFIG_COW_COMMON) += cow_user.o
4856 +
4857 +CFLAGS_pcap_user.o = -I/usr/include/pcap
4858 +
4859 +obj-y += stdio_console.o $(CHAN_OBJS)
4860 +
4861 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
4862 +
4863 +USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
4864 +       null.o pty.o tty.o xterm.o
4865 +
4866 +include $(TOPDIR)/Rules.make
4867 +
4868 +$(USER_OBJS) : %.o: %.c
4869 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
4870 +
4871 +clean:
4872 +
4873 +modules:
4874 +
4875 +fastdep:
4876 +
4877 +dep:
4878 +
4879 +archmrproper:
4880 +
4881 +daemon.o : $(daemon-objs)
4882 +
4883 +slip.o : $(slip-objs)
4884 +
4885 +slirp.o : $(slirp-objs)
4886 +
4887 +mcast.o : $(mcast-objs)
4888 +
4889 +pcap.o : $(pcap-objs)
4890 +
4891 +mconsole.o : $(mconsole-objs)
4892 +
4893 +net.o : $(net-objs)
4894 +
4895 +hostaudio.o : $(hostaudio-objs)
4896 +
4897 +ubd.o : $(ubd-objs)
4898 +
4899 +port.o : $(port-objs)
4900 +
4901 +harddog.o : $(harddog-objs)
4902 +
4903 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
4904 +       $(LD) -r -o $@ $($(patsubst %.o,%,$@)-objs) $($(patsubst %.o,%,$@)-libs)
4905 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast.h um/arch/um/drivers/mcast.h
4906 --- orig/arch/um/drivers/mcast.h        1969-12-31 19:00:00.000000000 -0500
4907 +++ um/arch/um/drivers/mcast.h  2003-10-21 03:26:06.000000000 -0400
4908 @@ -0,0 +1,30 @@
4909 +/* 
4910 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4911 + * Licensed under the GPL
4912 + */
4913 +
4914 +#include "net_user.h"
4915 +
4916 +struct mcast_data {
4917 +       char *addr;
4918 +       unsigned short port;
4919 +       void *mcast_addr;
4920 +       int ttl;
4921 +       void *dev;
4922 +};
4923 +
4924 +extern struct net_user_info mcast_user_info;
4925 +
4926 +extern int mcast_user_write(int fd, void *buf, int len, 
4927 +                           struct mcast_data *pri);
4928 +
4929 +/*
4930 + * Overrides for Emacs so that we follow Linus's tabbing style.
4931 + * Emacs will notice this stuff at the end of the file and automatically
4932 + * adjust the settings for this buffer only.  This must remain at the end
4933 + * of the file.
4934 + * ---------------------------------------------------------------------------
4935 + * Local variables:
4936 + * c-file-style: "linux"
4937 + * End:
4938 + */
4939 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_kern.c um/arch/um/drivers/mcast_kern.c
4940 --- orig/arch/um/drivers/mcast_kern.c   1969-12-31 19:00:00.000000000 -0500
4941 +++ um/arch/um/drivers/mcast_kern.c     2003-10-21 03:26:06.000000000 -0400
4942 @@ -0,0 +1,145 @@
4943 +/*
4944 + * user-mode-linux networking multicast transport
4945 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4946 + *
4947 + * based on the existing uml-networking code, which is
4948 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
4949 + * James Leu (jleu@mindspring.net).
4950 + * Copyright (C) 2001 by various other people who didn't put their name here.
4951 + *
4952 + * Licensed under the GPL.
4953 + */
4954 +
4955 +#include "linux/kernel.h"
4956 +#include "linux/init.h"
4957 +#include "linux/netdevice.h"
4958 +#include "linux/etherdevice.h"
4959 +#include "linux/in.h"
4960 +#include "linux/inet.h"
4961 +#include "net_kern.h"
4962 +#include "net_user.h"
4963 +#include "mcast.h"
4964 +
4965 +struct mcast_init {
4966 +       char *addr;
4967 +       int port;
4968 +       int ttl;
4969 +};
4970 +
4971 +void mcast_init(struct net_device *dev, void *data)
4972 +{
4973 +       struct uml_net_private *pri;
4974 +       struct mcast_data *dpri;
4975 +       struct mcast_init *init = data;
4976 +
4977 +       init_etherdev(dev, 0);
4978 +       pri = dev->priv;
4979 +       dpri = (struct mcast_data *) pri->user;
4980 +       *dpri = ((struct mcast_data)
4981 +               { .addr         = init->addr,
4982 +                 .port         = init->port,
4983 +                 .ttl          = init->ttl,
4984 +                 .mcast_addr   = NULL,
4985 +                 .dev          = dev });
4986 +       printk("mcast backend ");
4987 +       printk("multicast adddress: %s:%u, TTL:%u ",
4988 +              dpri->addr, dpri->port, dpri->ttl);
4989 +
4990 +       printk("\n");
4991 +}
4992 +
4993 +static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
4994 +{
4995 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
4996 +       if(*skb == NULL) return(-ENOMEM);
4997 +       return(net_recvfrom(fd, (*skb)->mac.raw, 
4998 +                           (*skb)->dev->mtu + ETH_HEADER_OTHER));
4999 +}
5000 +
5001 +static int mcast_write(int fd, struct sk_buff **skb,
5002 +                       struct uml_net_private *lp)
5003 +{
5004 +       return mcast_user_write(fd, (*skb)->data, (*skb)->len, 
5005 +                                (struct mcast_data *) &lp->user);
5006 +}
5007 +
5008 +static struct net_kern_info mcast_kern_info = {
5009 +       .init                   = mcast_init,
5010 +       .protocol               = eth_protocol,
5011 +       .read                   = mcast_read,
5012 +       .write                  = mcast_write,
5013 +};
5014 +
5015 +int mcast_setup(char *str, char **mac_out, void *data)
5016 +{
5017 +       struct mcast_init *init = data;
5018 +       char *port_str = NULL, *ttl_str = NULL, *remain;
5019 +       char *last;
5020 +       int n;
5021 +
5022 +       *init = ((struct mcast_init)
5023 +               { .addr         = "239.192.168.1",
5024 +                 .port         = 1102,
5025 +                 .ttl          = 1 });
5026 +
5027 +       remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
5028 +                              NULL);
5029 +       if(remain != NULL){
5030 +               printk(KERN_ERR "mcast_setup - Extra garbage on "
5031 +                      "specification : '%s'\n", remain);
5032 +               return(0);
5033 +       }
5034 +       
5035 +       if(port_str != NULL){
5036 +               n = simple_strtoul(port_str, &last, 10);
5037 +               if((*last != '\0') || (last == port_str)){
5038 +                       printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 
5039 +                              port_str);
5040 +                       return(0);
5041 +               }
5042 +               init->port = htons(n);
5043 +       }
5044 +
5045 +       if(ttl_str != NULL){
5046 +               init->ttl = simple_strtoul(ttl_str, &last, 10);
5047 +               if((*last != '\0') || (last == ttl_str)){
5048 +                       printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", 
5049 +                              ttl_str);
5050 +                       return(0);
5051 +               }
5052 +       }
5053 +
5054 +       printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
5055 +              init->port, init->ttl);
5056 +
5057 +       return(1);
5058 +}
5059 +
5060 +static struct transport mcast_transport = {
5061 +       .list           = LIST_HEAD_INIT(mcast_transport.list),
5062 +       .name           = "mcast",
5063 +       .setup          = mcast_setup,
5064 +       .user           = &mcast_user_info,
5065 +       .kern           = &mcast_kern_info,
5066 +       .private_size   = sizeof(struct mcast_data),
5067 +       .setup_size     = sizeof(struct mcast_init),
5068 +};
5069 +
5070 +static int register_mcast(void)
5071 +{
5072 +       register_transport(&mcast_transport);
5073 +       return(1);
5074 +}
5075 +
5076 +__initcall(register_mcast);
5077 +
5078 +/*
5079 + * Overrides for Emacs so that we follow Linus's tabbing style.
5080 + * Emacs will notice this stuff at the end of the file and automatically
5081 + * adjust the settings for this buffer only.  This must remain at the end
5082 + * of the file.
5083 + * ---------------------------------------------------------------------------
5084 + * Local variables:
5085 + * c-file-style: "linux"
5086 + * End:
5087 + */
5088 diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_user.c um/arch/um/drivers/mcast_user.c
5089 --- orig/arch/um/drivers/mcast_user.c   1969-12-31 19:00:00.000000000 -0500
5090 +++ um/arch/um/drivers/mcast_user.c     2003-10-21 03:26:06.000000000 -0400
5091 @@ -0,0 +1,177 @@
5092 +/*
5093 + * user-mode-linux networking multicast transport
5094 + * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
5095 + *
5096 + * based on the existing uml-networking code, which is
5097 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
5098 + * James Leu (jleu@mindspring.net).
5099 + * Copyright (C) 2001 by various other people who didn't put their name here.
5100 + *
5101 + * Licensed under the GPL.
5102 + *
5103 + */
5104 +
5105 +#include <errno.h>
5106 +#include <unistd.h>
5107 +#include <linux/inet.h>
5108 +#include <sys/socket.h>
5109 +#include <sys/un.h>
5110 +#include <sys/time.h>
5111 +#include <netinet/in.h>
5112 +#include "net_user.h"
5113 +#include "mcast.h"
5114 +#include "kern_util.h"
5115 +#include "user_util.h"
5116 +#include "user.h"
5117 +#include "os.h"
5118 +
5119 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
5120 +
5121 +static struct sockaddr_in *new_addr(char *addr, unsigned short port)
5122 +{
5123 +       struct sockaddr_in *sin;
5124 +
5125 +       sin = um_kmalloc(sizeof(struct sockaddr_in));
5126 +       if(sin == NULL){
5127 +               printk("new_addr: allocation of sockaddr_in failed\n");
5128 +               return(NULL);
5129 +       }
5130 +       sin->sin_family = AF_INET;
5131 +       sin->sin_addr.s_addr = in_aton(addr);
5132 +       sin->sin_port = port;
5133 +       return(sin);
5134 +}
5135 +
5136 +static void mcast_user_init(void *data, void *dev)
5137 +{
5138 +       struct mcast_data *pri = data;
5139 +
5140 +       pri->mcast_addr = new_addr(pri->addr, pri->port);
5141 +       pri->dev = dev;
5142 +}
5143 +
5144 +static int mcast_open(void *data)
5145 +{
5146 +       struct mcast_data *pri = data;
5147 +       struct sockaddr_in *sin = pri->mcast_addr;
5148 +       struct ip_mreq mreq;
5149 +       int fd, yes = 1;
5150 +
5151 +
5152 +       if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) {
5153 +               fd = -EINVAL;
5154 +               goto out;
5155 +       }
5156 +
5157 +       fd = socket(AF_INET, SOCK_DGRAM, 0);
5158 +       if (fd < 0){
5159 +               printk("mcast_open : data socket failed, errno = %d\n", 
5160 +                      errno);
5161 +               fd = -ENOMEM;
5162 +               goto out;
5163 +       }
5164 +
5165 +       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
5166 +               printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
5167 +                       errno);
5168 +               os_close_file(fd);
5169 +               fd = -EINVAL;
5170 +               goto out;
5171 +       }
5172 +
5173 +       /* set ttl according to config */
5174 +       if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
5175 +                      sizeof(pri->ttl)) < 0) {
5176 +               printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
5177 +                       errno);
5178 +               os_close_file(fd);
5179 +               fd = -EINVAL;
5180 +               goto out;
5181 +       }
5182 +
5183 +       /* set LOOP, so data does get fed back to local sockets */
5184 +       if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
5185 +               printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
5186 +                       errno);
5187 +               os_close_file(fd);
5188 +               fd = -EINVAL;
5189 +               goto out;
5190 +       }
5191 +
5192 +       /* bind socket to mcast address */
5193 +       if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
5194 +               printk("mcast_open : data bind failed, errno = %d\n", errno);
5195 +               os_close_file(fd);
5196 +               fd = -EINVAL;
5197 +               goto out;
5198 +       }               
5199 +       
5200 +       /* subscribe to the multicast group */
5201 +       mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
5202 +       mreq.imr_interface.s_addr = 0;
5203 +       if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, 
5204 +                      &mreq, sizeof(mreq)) < 0) {
5205 +               printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
5206 +                       errno);
5207 +               printk("There appears not to be a multicast-capable network "
5208 +                      "interface on the host.\n");
5209 +               printk("eth0 should be configured in order to use the "
5210 +                      "multicast transport.\n");
5211 +               os_close_file(fd);
5212 +               fd = -EINVAL;
5213 +       }
5214 +
5215 + out:
5216 +       return(fd);
5217 +}
5218 +
5219 +static void mcast_close(int fd, void *data)
5220 +{
5221 +       struct ip_mreq mreq;
5222 +       struct mcast_data *pri = data;
5223 +       struct sockaddr_in *sin = pri->mcast_addr;
5224 +
5225 +       mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
5226 +       mreq.imr_interface.s_addr = 0;
5227 +       if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
5228 +                      &mreq, sizeof(mreq)) < 0) {
5229 +               printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
5230 +                       errno);
5231 +       }
5232 +
5233 +       os_close_file(fd);
5234 +}
5235 +
5236 +int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
5237 +{
5238 +       struct sockaddr_in *data_addr = pri->mcast_addr;
5239 +
5240 +       return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
5241 +}
5242 +
5243 +static int mcast_set_mtu(int mtu, void *data)
5244 +{
5245 +       return(mtu);
5246 +}
5247 +
5248 +struct net_user_info mcast_user_info = {
5249 +       .init           = mcast_user_init,
5250 +       .open           = mcast_open,
5251 +       .close          = mcast_close,
5252 +       .remove         = NULL,
5253 +       .set_mtu        = mcast_set_mtu,
5254 +       .add_address    = NULL,
5255 +       .delete_address = NULL,
5256 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
5257 +};
5258 +
5259 +/*
5260 + * Overrides for Emacs so that we follow Linus's tabbing style.
5261 + * Emacs will notice this stuff at the end of the file and automatically
5262 + * adjust the settings for this buffer only.  This must remain at the end
5263 + * of the file.
5264 + * ---------------------------------------------------------------------------
5265 + * Local variables:
5266 + * c-file-style: "linux"
5267 + * End:
5268 + */
5269 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_kern.c um/arch/um/drivers/mconsole_kern.c
5270 --- orig/arch/um/drivers/mconsole_kern.c        1969-12-31 19:00:00.000000000 -0500
5271 +++ um/arch/um/drivers/mconsole_kern.c  2003-10-21 03:26:06.000000000 -0400
5272 @@ -0,0 +1,561 @@
5273 +/*
5274 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5275 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5276 + * Licensed under the GPL
5277 + */
5278 +
5279 +#include "linux/kernel.h"
5280 +#include "linux/slab.h"
5281 +#include "linux/init.h"
5282 +#include "linux/notifier.h"
5283 +#include "linux/reboot.h"
5284 +#include "linux/utsname.h"
5285 +#include "linux/ctype.h"
5286 +#include "linux/interrupt.h"
5287 +#include "linux/sysrq.h"
5288 +#include "linux/tqueue.h"
5289 +#include "linux/module.h"
5290 +#include "linux/file.h"
5291 +#include "linux/fs.h"
5292 +#include "linux/proc_fs.h"
5293 +#include "asm/irq.h"
5294 +#include "asm/uaccess.h"
5295 +#include "user_util.h"
5296 +#include "kern_util.h"
5297 +#include "kern.h"
5298 +#include "mconsole.h"
5299 +#include "mconsole_kern.h"
5300 +#include "irq_user.h"
5301 +#include "init.h"
5302 +#include "os.h"
5303 +#include "umid.h"
5304 +#include "irq_kern.h"
5305 +
5306 +static int do_unlink_socket(struct notifier_block *notifier, 
5307 +                           unsigned long what, void *data)
5308 +{
5309 +       return(mconsole_unlink_socket());
5310 +}
5311 +
5312 +
5313 +static struct notifier_block reboot_notifier = {
5314 +       .notifier_call          = do_unlink_socket,
5315 +       .priority               = 0,
5316 +};
5317 +
5318 +/* Safe without explicit locking for now.  Tasklets provide their own 
5319 + * locking, and the interrupt handler is safe because it can't interrupt
5320 + * itself and it can only happen on CPU 0.
5321 + */
5322 +
5323 +LIST_HEAD(mc_requests);
5324 +
5325 +void mc_task_proc(void *unused)
5326 +{
5327 +       struct mconsole_entry *req;
5328 +       unsigned long flags;
5329 +       int done;
5330 +
5331 +       do {
5332 +               save_flags(flags);
5333 +               req = list_entry(mc_requests.next, struct mconsole_entry, 
5334 +                                list);
5335 +               list_del(&req->list);
5336 +               done = list_empty(&mc_requests);
5337 +               restore_flags(flags);
5338 +               req->request.cmd->handler(&req->request);
5339 +               kfree(req);
5340 +       } while(!done);
5341 +}
5342 +
5343 +struct tq_struct mconsole_task = {
5344 +       .routine        = mc_task_proc,
5345 +       .data           = NULL
5346 +};
5347 +
5348 +void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
5349 +{
5350 +       int fd;
5351 +       struct mconsole_entry *new;
5352 +       struct mc_request req;
5353 +
5354 +       fd = (int) dev_id;
5355 +       while (mconsole_get_request(fd, &req)){
5356 +               if(req.cmd->context == MCONSOLE_INTR) 
5357 +                       (*req.cmd->handler)(&req);
5358 +               else {
5359 +                       new = kmalloc(sizeof(*new), GFP_ATOMIC);
5360 +                       if(new == NULL)
5361 +                               mconsole_reply(&req, "Out of memory", 1, 0);
5362 +                       else {
5363 +                               new->request = req;
5364 +                               list_add(&new->list, &mc_requests);
5365 +                       }
5366 +               }
5367 +       }
5368 +       if(!list_empty(&mc_requests)) schedule_task(&mconsole_task);
5369 +       reactivate_fd(fd, MCONSOLE_IRQ);
5370 +}
5371 +
5372 +void mconsole_version(struct mc_request *req)
5373 +{
5374 +       char version[256];
5375 +
5376 +       sprintf(version, "%s %s %s %s %s", system_utsname.sysname, 
5377 +               system_utsname.nodename, system_utsname.release, 
5378 +               system_utsname.version, system_utsname.machine);
5379 +       mconsole_reply(req, version, 0, 0);
5380 +}
5381 +
5382 +void mconsole_log(struct mc_request *req)
5383 +{
5384 +       int len;
5385 +       char *ptr = req->request.data;
5386 +       
5387 +       ptr += strlen("log");
5388 +       while(isspace(*ptr)) ptr++;
5389 +
5390 +       len = req->len - (ptr - req->request.data);
5391 +       printk("%.*s", len, ptr);
5392 +       mconsole_reply(req, "", 0, 0);
5393 +}
5394 +
5395 +void mconsole_proc(struct mc_request *req)
5396 +{
5397 +       struct nameidata nd;
5398 +       struct file_system_type *proc;
5399 +       struct super_block *super;
5400 +       struct file *file;
5401 +       int n, err;
5402 +       char *ptr = req->request.data, *buf;
5403 +       
5404 +       ptr += strlen("proc");
5405 +       while(isspace(*ptr)) ptr++;
5406 +
5407 +       proc = get_fs_type("proc");
5408 +       if(proc == NULL){
5409 +               mconsole_reply(req, "procfs not registered", 1, 0);
5410 +               goto out;
5411 +       }
5412 +
5413 +       super = get_anon_super(proc, NULL, NULL);
5414 +       if(super == NULL){
5415 +               mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
5416 +               goto out_put;
5417 +       }
5418 +
5419 +       if(super->s_root == NULL){
5420 +               super = (*proc->read_super)(super, NULL, 0);
5421 +               if(super == NULL){
5422 +                       mconsole_reply(req, "Failed to read superblock", 1, 0);
5423 +                       goto out_put;
5424 +               }
5425 +       }
5426 +       up_write(&super->s_umount);
5427 +
5428 +       nd.dentry = super->s_root;
5429 +       nd.mnt = NULL;
5430 +       nd.flags = O_RDONLY + 1;
5431 +       nd.last_type = LAST_ROOT;
5432 +
5433 +       err = link_path_walk(ptr, &nd);
5434 +       if(err){
5435 +               mconsole_reply(req, "Failed to look up file", 1, 0);
5436 +               goto out_kill;
5437 +       }
5438 +
5439 +       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
5440 +       if(IS_ERR(file)){
5441 +               mconsole_reply(req, "Failed to open file", 1, 0);
5442 +               goto out_kill;
5443 +       }
5444 +
5445 +       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
5446 +       if(buf == NULL){
5447 +               mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5448 +               goto out_fput;
5449 +       }
5450 +
5451 +       if((file->f_op != NULL) && (file->f_op->read != NULL)){
5452 +               do {
5453 +                       n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, 
5454 +                                               &file->f_pos);
5455 +                       if(n >= 0){
5456 +                               buf[n] = '\0';
5457 +                               mconsole_reply(req, buf, 0, (n > 0));
5458 +                       }
5459 +                       else {
5460 +                               mconsole_reply(req, "Read of file failed", 
5461 +                                              1, 0);
5462 +                               goto out_free;
5463 +                       }
5464 +               } while(n > 0);
5465 +       }
5466 +       else mconsole_reply(req, "", 0, 0);
5467 +
5468 + out_free:
5469 +       kfree(buf);
5470 + out_fput:
5471 +       fput(file);
5472 + out_kill:
5473 +       kill_super(super);
5474 + out_put:
5475 +       /* put_filesystem(proc); */
5476 + out: ;
5477 +}
5478 +
5479 +#define UML_MCONSOLE_HELPTEXT \
5480 +"Commands: \n\
5481 +    version - Get kernel version \n\
5482 +    help - Print this message \n\
5483 +    halt - Halt UML \n\
5484 +    reboot - Reboot UML \n\
5485 +    config <dev>=<config> - Add a new device to UML;  \n\
5486 +       same syntax as command line \n\
5487 +    config <dev> - Query the configuration of a device \n\
5488 +    remove <dev> - Remove a device from UML \n\
5489 +    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
5490 +    cad - invoke the Ctl-Alt-Del handler \n\
5491 +    stop - pause the UML; it will do nothing until it receives a 'go' \n\
5492 +    go - continue the UML after a 'stop' \n\
5493 +    log <string> - make UML enter <string> into the kernel log\n\
5494 +    proc <file> - returns the contents of the UML's /proc/<file>\n\
5495 +"
5496 +
5497 +void mconsole_help(struct mc_request *req)
5498 +{
5499 +       mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0);
5500 +}
5501 +
5502 +void mconsole_halt(struct mc_request *req)
5503 +{
5504 +       mconsole_reply(req, "", 0, 0);
5505 +       machine_halt();
5506 +}
5507 +
5508 +void mconsole_reboot(struct mc_request *req)
5509 +{
5510 +       mconsole_reply(req, "", 0, 0);
5511 +       machine_restart(NULL);
5512 +}
5513 +
5514 +extern void ctrl_alt_del(void);
5515 +
5516 +void mconsole_cad(struct mc_request *req)
5517 +{
5518 +       mconsole_reply(req, "", 0, 0);
5519 +       ctrl_alt_del();
5520 +}
5521 +
5522 +void mconsole_go(struct mc_request *req)
5523 +{
5524 +       mconsole_reply(req, "Not stopped", 1, 0);
5525 +}
5526 +
5527 +void mconsole_stop(struct mc_request *req)
5528 +{
5529 +       deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5530 +       os_set_fd_block(req->originating_fd, 1);
5531 +       mconsole_reply(req, "", 0, 0);
5532 +       while(mconsole_get_request(req->originating_fd, req)){
5533 +               if(req->cmd->handler == mconsole_go) break;
5534 +               (*req->cmd->handler)(req);
5535 +       }
5536 +       os_set_fd_block(req->originating_fd, 0);
5537 +       reactivate_fd(req->originating_fd, MCONSOLE_IRQ);
5538 +       mconsole_reply(req, "", 0, 0);
5539 +}
5540 +
5541 +/* This list is populated by __initcall routines. */
5542 +
5543 +LIST_HEAD(mconsole_devices);
5544 +
5545 +void mconsole_register_dev(struct mc_device *new)
5546 +{
5547 +       list_add(&new->list, &mconsole_devices);
5548 +}
5549 +
5550 +static struct mc_device *mconsole_find_dev(char *name)
5551 +{
5552 +       struct list_head *ele;
5553 +       struct mc_device *dev;
5554 +
5555 +       list_for_each(ele, &mconsole_devices){
5556 +               dev = list_entry(ele, struct mc_device, list);
5557 +               if(!strncmp(name, dev->name, strlen(dev->name)))
5558 +                       return(dev);
5559 +       }
5560 +       return(NULL);
5561 +}
5562 +
5563 +#define CONFIG_BUF_SIZE 64
5564 +
5565 +static void mconsole_get_config(int (*get_config)(char *, char *, int, 
5566 +                                                 char **),
5567 +                               struct mc_request *req, char *name)
5568 +{
5569 +       char default_buf[CONFIG_BUF_SIZE], *error, *buf;
5570 +       int n, size;
5571 +
5572 +       if(get_config == NULL){
5573 +               mconsole_reply(req, "No get_config routine defined", 1, 0);
5574 +               return;
5575 +       }
5576 +
5577 +       error = NULL;
5578 +       size = sizeof(default_buf)/sizeof(default_buf[0]);
5579 +       buf = default_buf;
5580 +
5581 +       while(1){
5582 +               n = (*get_config)(name, buf, size, &error);
5583 +               if(error != NULL){
5584 +                       mconsole_reply(req, error, 1, 0);
5585 +                       goto out;
5586 +               }
5587 +
5588 +               if(n <= size){
5589 +                       mconsole_reply(req, buf, 0, 0);
5590 +                       goto out;
5591 +               }
5592 +
5593 +               if(buf != default_buf)
5594 +                       kfree(buf);
5595 +
5596 +               size = n;
5597 +               buf = kmalloc(size, GFP_KERNEL);
5598 +               if(buf == NULL){
5599 +                       mconsole_reply(req, "Failed to allocate buffer", 1, 0);
5600 +                       return;
5601 +               }
5602 +       }
5603 + out:
5604 +       if(buf != default_buf)
5605 +               kfree(buf);
5606 +       
5607 +}
5608 +
5609 +void mconsole_config(struct mc_request *req)
5610 +{
5611 +       struct mc_device *dev;
5612 +       char *ptr = req->request.data, *name;
5613 +       int err;
5614 +
5615 +       ptr += strlen("config");
5616 +       while(isspace(*ptr)) ptr++;
5617 +       dev = mconsole_find_dev(ptr);
5618 +       if(dev == NULL){
5619 +               mconsole_reply(req, "Bad configuration option", 1, 0);
5620 +               return;
5621 +       }
5622 +
5623 +       name = &ptr[strlen(dev->name)];
5624 +       ptr = name;
5625 +       while((*ptr != '=') && (*ptr != '\0'))
5626 +               ptr++;
5627 +
5628 +       if(*ptr == '='){
5629 +               err = (*dev->config)(name);
5630 +               mconsole_reply(req, "", err, 0);
5631 +       }
5632 +       else mconsole_get_config(dev->get_config, req, name);
5633 +}
5634 +
5635 +void mconsole_remove(struct mc_request *req)
5636 +{
5637 +       struct mc_device *dev;  
5638 +       char *ptr = req->request.data;
5639 +       int err;
5640 +
5641 +       ptr += strlen("remove");
5642 +       while(isspace(*ptr)) ptr++;
5643 +       dev = mconsole_find_dev(ptr);
5644 +       if(dev == NULL){
5645 +               mconsole_reply(req, "Bad remove option", 1, 0);
5646 +               return;
5647 +       }
5648 +       err = (*dev->remove)(&ptr[strlen(dev->name)]);
5649 +       mconsole_reply(req, "", err, 0);
5650 +}
5651 +
5652 +#ifdef CONFIG_MAGIC_SYSRQ
5653 +void mconsole_sysrq(struct mc_request *req)
5654 +{
5655 +       char *ptr = req->request.data;
5656 +
5657 +       ptr += strlen("sysrq");
5658 +       while(isspace(*ptr)) ptr++;
5659 +
5660 +       handle_sysrq(*ptr, &current->thread.regs, NULL, NULL);
5661 +       mconsole_reply(req, "", 0, 0);
5662 +}
5663 +#else
5664 +void mconsole_sysrq(struct mc_request *req)
5665 +{
5666 +       mconsole_reply(req, "Sysrq not compiled in", 1, 0);
5667 +}
5668 +#endif
5669 +
5670 +/* Changed by mconsole_setup, which is __setup, and called before SMP is
5671 + * active.
5672 + */
5673 +static char *notify_socket = NULL; 
5674 +
5675 +int mconsole_init(void)
5676 +{
5677 +       int err, sock;
5678 +       char file[256];
5679 +
5680 +       if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
5681 +       snprintf(mconsole_socket_name, sizeof(file), "%s", file);
5682 +
5683 +       sock = os_create_unix_socket(file, sizeof(file), 1);
5684 +       if (sock < 0){
5685 +               printk("Failed to initialize management console\n");
5686 +               return(1);
5687 +       }
5688 +
5689 +       register_reboot_notifier(&reboot_notifier);
5690 +
5691 +       err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
5692 +                            SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
5693 +                            "mconsole", (void *)sock);
5694 +       if (err){
5695 +               printk("Failed to get IRQ for management console\n");
5696 +               return(1);
5697 +       }
5698 +
5699 +       if(notify_socket != NULL){
5700 +               notify_socket = uml_strdup(notify_socket);
5701 +               if(notify_socket != NULL)
5702 +                       mconsole_notify(notify_socket, MCONSOLE_SOCKET,
5703 +                                       mconsole_socket_name, 
5704 +                                       strlen(mconsole_socket_name) + 1);
5705 +               else printk(KERN_ERR "mconsole_setup failed to strdup "
5706 +                           "string\n");
5707 +       }
5708 +
5709 +       printk("mconsole (version %d) initialized on %s\n", 
5710 +              MCONSOLE_VERSION, mconsole_socket_name);
5711 +       return(0);
5712 +}
5713 +
5714 +__initcall(mconsole_init);
5715 +
5716 +static int write_proc_mconsole(struct file *file, const char *buffer,
5717 +                              unsigned long count, void *data)
5718 +{
5719 +       char *buf;
5720 +
5721 +       buf = kmalloc(count + 1, GFP_KERNEL);
5722 +       if(buf == NULL) 
5723 +               return(-ENOMEM);
5724 +
5725 +       if(copy_from_user(buf, buffer, count)){
5726 +               count = -EFAULT;
5727 +               goto out;
5728 +       }
5729 +
5730 +       buf[count] = '\0';
5731 +
5732 +       mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
5733 + out:
5734 +       kfree(buf);
5735 +       return(count);
5736 +}
5737 +
5738 +static int create_proc_mconsole(void)
5739 +{
5740 +       struct proc_dir_entry *ent;
5741 +
5742 +       if(notify_socket == NULL) return(0);
5743 +
5744 +       ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
5745 +       if(ent == NULL){
5746 +               printk("create_proc_mconsole : create_proc_entry failed\n");
5747 +               return(0);
5748 +       }
5749 +
5750 +       ent->read_proc = NULL;
5751 +       ent->write_proc = write_proc_mconsole;
5752 +       return(0);
5753 +}
5754 +
5755 +static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED;
5756 +
5757 +void lock_notify(void)
5758 +{
5759 +       spin_lock(&notify_spinlock);
5760 +}
5761 +
5762 +void unlock_notify(void)
5763 +{
5764 +       spin_unlock(&notify_spinlock);
5765 +}
5766 +
5767 +__initcall(create_proc_mconsole);
5768 +
5769 +#define NOTIFY "=notify:"
5770 +
5771 +static int mconsole_setup(char *str)
5772 +{
5773 +       if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
5774 +               str += strlen(NOTIFY);
5775 +               notify_socket = str;
5776 +       }
5777 +       else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
5778 +       return(1);
5779 +}
5780 +
5781 +__setup("mconsole", mconsole_setup);
5782 +
5783 +__uml_help(mconsole_setup,
5784 +"mconsole=notify:<socket>\n"
5785 +"    Requests that the mconsole driver send a message to the named Unix\n"
5786 +"    socket containing the name of the mconsole socket.  This also serves\n"
5787 +"    to notify outside processes when UML has booted far enough to respond\n"
5788 +"    to mconsole requests.\n\n"
5789 +);
5790 +
5791 +static int notify_panic(struct notifier_block *self, unsigned long unused1,
5792 +                       void *ptr)
5793 +{
5794 +       char *message = ptr;
5795 +
5796 +       if(notify_socket == NULL) return(0);
5797 +
5798 +       mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 
5799 +                       strlen(message) + 1);
5800 +       return(0);
5801 +}
5802 +
5803 +static struct notifier_block panic_exit_notifier = {
5804 +       .notifier_call          = notify_panic,
5805 +       .next                   = NULL,
5806 +       .priority               = 1
5807 +};
5808 +
5809 +static int add_notifier(void)
5810 +{
5811 +       notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
5812 +       return(0);
5813 +}
5814 +
5815 +__initcall(add_notifier);
5816 +
5817 +char *mconsole_notify_socket(void)
5818 +{
5819 +       return(notify_socket);
5820 +}
5821 +
5822 +EXPORT_SYMBOL(mconsole_notify_socket);
5823 +
5824 +/*
5825 + * Overrides for Emacs so that we follow Linus's tabbing style.
5826 + * Emacs will notice this stuff at the end of the file and automatically
5827 + * adjust the settings for this buffer only.  This must remain at the end
5828 + * of the file.
5829 + * ---------------------------------------------------------------------------
5830 + * Local variables:
5831 + * c-file-style: "linux"
5832 + * End:
5833 + */
5834 diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_user.c um/arch/um/drivers/mconsole_user.c
5835 --- orig/arch/um/drivers/mconsole_user.c        1969-12-31 19:00:00.000000000 -0500
5836 +++ um/arch/um/drivers/mconsole_user.c  2003-10-21 03:26:06.000000000 -0400
5837 @@ -0,0 +1,215 @@
5838 +/*
5839 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
5840 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
5841 + * Licensed under the GPL
5842 + */
5843 +
5844 +#include <stdio.h>
5845 +#include <stdlib.h>
5846 +#include <errno.h>
5847 +#include <signal.h>
5848 +#include <sys/socket.h>
5849 +#include <sys/types.h>
5850 +#include <sys/uio.h>
5851 +#include <sys/un.h>
5852 +#include <unistd.h>
5853 +#include "user.h"
5854 +#include "mconsole.h"
5855 +#include "umid.h"
5856 +
5857 +static struct mconsole_command commands[] = {
5858 +       { "version", mconsole_version, MCONSOLE_INTR },
5859 +       { "halt", mconsole_halt, MCONSOLE_PROC },
5860 +       { "reboot", mconsole_reboot, MCONSOLE_PROC },
5861 +       { "config", mconsole_config, MCONSOLE_PROC },
5862 +       { "remove", mconsole_remove, MCONSOLE_PROC },
5863 +       { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
5864 +       { "help", mconsole_help, MCONSOLE_INTR },
5865 +       { "cad", mconsole_cad, MCONSOLE_INTR },
5866 +       { "stop", mconsole_stop, MCONSOLE_PROC },
5867 +       { "go", mconsole_go, MCONSOLE_INTR },
5868 +       { "log", mconsole_log, MCONSOLE_INTR },
5869 +       { "proc", mconsole_proc, MCONSOLE_PROC },
5870 +};
5871 +
5872 +/* Initialized in mconsole_init, which is an initcall */
5873 +char mconsole_socket_name[256];
5874 +
5875 +int mconsole_reply_v0(struct mc_request *req, char *reply)
5876 +{
5877 +        struct iovec iov;
5878 +        struct msghdr msg;
5879 +
5880 +        iov.iov_base = reply;
5881 +        iov.iov_len = strlen(reply);
5882 +
5883 +        msg.msg_name = &(req->origin);
5884 +        msg.msg_namelen = req->originlen;
5885 +        msg.msg_iov = &iov;
5886 +        msg.msg_iovlen = 1;
5887 +        msg.msg_control = NULL;
5888 +        msg.msg_controllen = 0;
5889 +        msg.msg_flags = 0;
5890 +
5891 +        return sendmsg(req->originating_fd, &msg, 0);
5892 +}
5893 +
5894 +static struct mconsole_command *mconsole_parse(struct mc_request *req)
5895 +{
5896 +       struct mconsole_command *cmd;
5897 +       int i;
5898 +
5899 +       for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){
5900 +               cmd = &commands[i];
5901 +               if(!strncmp(req->request.data, cmd->command, 
5902 +                           strlen(cmd->command))){
5903 +                       return(cmd);
5904 +               }
5905 +       }
5906 +       return(NULL);
5907 +}
5908 +
5909 +#define MIN(a,b) ((a)<(b) ? (a):(b))
5910 +
5911 +#define STRINGX(x) #x
5912 +#define STRING(x) STRINGX(x)
5913 +
5914 +int mconsole_get_request(int fd, struct mc_request *req)
5915 +{
5916 +       int len;
5917 +
5918 +       req->originlen = sizeof(req->origin);
5919 +       req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
5920 +                           (struct sockaddr *) req->origin, &req->originlen);
5921 +       if (req->len < 0)
5922 +               return 0;
5923 +
5924 +       req->originating_fd = fd;
5925 +
5926 +       if(req->request.magic != MCONSOLE_MAGIC){
5927 +               /* Unversioned request */
5928 +               len = MIN(sizeof(req->request.data) - 1, 
5929 +                         strlen((char *) &req->request));
5930 +               memmove(req->request.data, &req->request, len);
5931 +               req->request.data[len] = '\0';
5932 +
5933 +               req->request.magic = MCONSOLE_MAGIC;
5934 +               req->request.version = 0;
5935 +               req->request.len = len;
5936 +
5937 +               mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
5938 +                                 "not supported by this driver");
5939 +               return(0);
5940 +       }
5941 +
5942 +       if(req->request.len >= MCONSOLE_MAX_DATA){
5943 +               mconsole_reply(req, "Request too large", 1, 0);
5944 +               return(0);
5945 +       }
5946 +       if(req->request.version != MCONSOLE_VERSION){
5947 +               mconsole_reply(req, "This driver only supports version " 
5948 +                               STRING(MCONSOLE_VERSION) " clients", 1, 0);
5949 +       }
5950 +       
5951 +       req->request.data[req->request.len] = '\0';
5952 +       req->cmd = mconsole_parse(req);
5953 +       if(req->cmd == NULL){
5954 +               mconsole_reply(req, "Unknown command", 1, 0);
5955 +               return(0);
5956 +       }
5957 +
5958 +       return(1);
5959 +}
5960 +
5961 +int mconsole_reply(struct mc_request *req, char *str, int err, int more)
5962 +{
5963 +       struct mconsole_reply reply;
5964 +       int total, len, n;
5965 +
5966 +       total = strlen(str);
5967 +       do {
5968 +               reply.err = err;
5969 +
5970 +               /* err can only be true on the first packet */
5971 +               err = 0;
5972 +
5973 +               len = MIN(total, MCONSOLE_MAX_DATA - 1);
5974 +
5975 +               if(len == total) reply.more = more;
5976 +               else reply.more = 1;
5977 +
5978 +               memcpy(reply.data, str, len);
5979 +               reply.data[len] = '\0';
5980 +               total -= len;
5981 +               str += len;
5982 +               reply.len = len + 1;
5983 +
5984 +               len = sizeof(reply) + reply.len - sizeof(reply.data);
5985 +
5986 +               n = sendto(req->originating_fd, &reply, len, 0,
5987 +                          (struct sockaddr *) req->origin, req->originlen);
5988 +
5989 +               if(n < 0) return(-errno);
5990 +       } while(total > 0);
5991 +       return(0);
5992 +}
5993 +
5994 +int mconsole_unlink_socket(void)
5995 +{
5996 +       unlink(mconsole_socket_name);
5997 +       return 0;
5998 +}
5999 +
6000 +static int notify_sock = -1;
6001 +
6002 +int mconsole_notify(char *sock_name, int type, const void *data, int len)
6003 +{
6004 +       struct sockaddr_un target;
6005 +       struct mconsole_notify packet;
6006 +       int n, err = 0;
6007 +
6008 +       lock_notify();
6009 +       if(notify_sock < 0){
6010 +               notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
6011 +               if(notify_sock < 0){
6012 +                       printk("mconsole_notify - socket failed, errno = %d\n",
6013 +                              errno);
6014 +                       err = -errno;
6015 +               }
6016 +       }
6017 +       unlock_notify();
6018 +       
6019 +       if(err)
6020 +               return(err);
6021 +
6022 +       target.sun_family = AF_UNIX;
6023 +       strcpy(target.sun_path, sock_name);
6024 +
6025 +       packet.magic = MCONSOLE_MAGIC;
6026 +       packet.version = MCONSOLE_VERSION;
6027 +       packet.type = type;
6028 +       len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
6029 +       packet.len = len;
6030 +       memcpy(packet.data, data, len);
6031 +
6032 +       err = 0;
6033 +       len = sizeof(packet) + packet.len - sizeof(packet.data);
6034 +       n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, 
6035 +                  sizeof(target));
6036 +       if(n < 0){
6037 +               printk("mconsole_notify - sendto failed, errno = %d\n", errno);
6038 +               err = -errno;
6039 +       }
6040 +       return(err);
6041 +}
6042 +
6043 +/*
6044 + * Overrides for Emacs so that we follow Linus's tabbing style.
6045 + * Emacs will notice this stuff at the end of the file and automatically
6046 + * adjust the settings for this buffer only.  This must remain at the end
6047 + * of the file.
6048 + * ---------------------------------------------------------------------------
6049 + * Local variables:
6050 + * c-file-style: "linux"
6051 + * End:
6052 + */
6053 diff -Naur -X ../exclude-files orig/arch/um/drivers/mmapper_kern.c um/arch/um/drivers/mmapper_kern.c
6054 --- orig/arch/um/drivers/mmapper_kern.c 1969-12-31 19:00:00.000000000 -0500
6055 +++ um/arch/um/drivers/mmapper_kern.c   2003-10-21 03:26:06.000000000 -0400
6056 @@ -0,0 +1,151 @@
6057 +/*
6058 + * arch/um/drivers/mmapper_kern.c
6059 + *
6060 + * BRIEF MODULE DESCRIPTION
6061 + *
6062 + * Copyright (C) 2000 RidgeRun, Inc.
6063 + * Author: RidgeRun, Inc.
6064 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
6065 + *
6066 + */
6067 +#include <linux/kdev_t.h>
6068 +#include <linux/time.h>
6069 +#include <linux/devfs_fs_kernel.h>
6070 +#include <linux/module.h>
6071 +#include <linux/mm.h> 
6072 +#include <linux/slab.h>
6073 +#include <linux/init.h> 
6074 +#include <asm/uaccess.h>
6075 +#include <asm/irq.h>
6076 +#include <asm/smplock.h>
6077 +#include <asm/pgtable.h>
6078 +#include "mem_user.h"
6079 +#include "user_util.h"
6080
6081 +/* These are set in mmapper_init, which is called at boot time */
6082 +static unsigned long mmapper_size;
6083 +static unsigned long p_buf = 0;
6084 +static char *v_buf = NULL;
6085 +
6086 +static ssize_t
6087 +mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
6088 +{
6089 +       if(*ppos > mmapper_size)
6090 +               return -EINVAL;
6091 +
6092 +       if(count + *ppos > mmapper_size)
6093 +               count = count + *ppos - mmapper_size;
6094 +
6095 +       if(count < 0)
6096 +               return -EINVAL;
6097
6098 +       copy_to_user(buf,&v_buf[*ppos],count);
6099 +       
6100 +       return count;
6101 +}
6102 +
6103 +static ssize_t
6104 +mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
6105 +{
6106 +       if(*ppos > mmapper_size)
6107 +               return -EINVAL;
6108 +
6109 +       if(count + *ppos > mmapper_size)
6110 +               count = count + *ppos - mmapper_size;
6111 +
6112 +       if(count < 0)
6113 +               return -EINVAL;
6114 +
6115 +       copy_from_user(&v_buf[*ppos],buf,count);
6116 +       
6117 +       return count;
6118 +}
6119 +
6120 +static int 
6121 +mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
6122 +        unsigned long arg)
6123 +{
6124 +       return(-ENOIOCTLCMD);
6125 +}
6126 +
6127 +static int 
6128 +mmapper_mmap(struct file *file, struct vm_area_struct * vma)
6129 +{
6130 +       int ret = -EINVAL;
6131 +       int size;
6132 +
6133 +       lock_kernel();
6134 +       if (vma->vm_pgoff != 0)
6135 +               goto out;
6136 +       
6137 +       size = vma->vm_end - vma->vm_start;
6138 +       if(size > mmapper_size) return(-EFAULT);
6139 +
6140 +       /* XXX A comment above remap_page_range says it should only be
6141 +        * called when the mm semaphore is held
6142 +        */
6143 +       if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot))
6144 +               goto out;
6145 +       ret = 0;
6146 +out:
6147 +       unlock_kernel();
6148 +       return ret;
6149 +}
6150 +
6151 +static int
6152 +mmapper_open(struct inode *inode, struct file *file)
6153 +{
6154 +       return 0;
6155 +}
6156 +
6157 +static int 
6158 +mmapper_release(struct inode *inode, struct file *file)
6159 +{
6160 +       return 0;
6161 +}
6162 +
6163 +static struct file_operations mmapper_fops = {
6164 +       .owner          = THIS_MODULE,
6165 +       .read           = mmapper_read,
6166 +       .write          = mmapper_write,
6167 +       .ioctl          = mmapper_ioctl,
6168 +       .mmap           = mmapper_mmap,
6169 +       .open           = mmapper_open,
6170 +       .release        = mmapper_release,
6171 +};
6172 +
6173 +static int __init mmapper_init(void)
6174 +{
6175 +       printk(KERN_INFO "Mapper v0.1\n");
6176 +
6177 +       v_buf = (char *) find_iomem("mmapper", &mmapper_size);
6178 +       if(mmapper_size == 0){
6179 +               printk(KERN_ERR "mmapper_init - find_iomem failed\n");
6180 +               return(0);
6181 +       }
6182 +
6183 +       p_buf = __pa(v_buf);
6184 +
6185 +       devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT, 
6186 +                       30, 0, S_IFCHR | S_IRUGO | S_IWUGO, 
6187 +                       &mmapper_fops, NULL); 
6188 +       devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper",
6189 +                        NULL, NULL);
6190 +       return(0);
6191 +}
6192 +
6193 +static void mmapper_exit(void)
6194 +{
6195 +}
6196 +
6197 +module_init(mmapper_init);
6198 +module_exit(mmapper_exit);
6199 +
6200 +MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
6201 +MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
6202 +/*
6203 + * ---------------------------------------------------------------------------
6204 + * Local variables:
6205 + * c-file-style: "linux"
6206 + * End:
6207 + */
6208 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_kern.c um/arch/um/drivers/net_kern.c
6209 --- orig/arch/um/drivers/net_kern.c     1969-12-31 19:00:00.000000000 -0500
6210 +++ um/arch/um/drivers/net_kern.c       2003-10-21 03:26:06.000000000 -0400
6211 @@ -0,0 +1,872 @@
6212 +/*
6213 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
6214 + * James Leu (jleu@mindspring.net).
6215 + * Copyright (C) 2001 by various other people who didn't put their name here.
6216 + * Licensed under the GPL.
6217 + */
6218 +
6219 +#include "linux/config.h"
6220 +#include "linux/kernel.h"
6221 +#include "linux/netdevice.h"
6222 +#include "linux/rtnetlink.h"
6223 +#include "linux/skbuff.h"
6224 +#include "linux/socket.h"
6225 +#include "linux/spinlock.h"
6226 +#include "linux/module.h"
6227 +#include "linux/init.h"
6228 +#include "linux/etherdevice.h"
6229 +#include "linux/list.h"
6230 +#include "linux/inetdevice.h"
6231 +#include "linux/ctype.h"
6232 +#include "linux/bootmem.h"
6233 +#include "user_util.h"
6234 +#include "kern_util.h"
6235 +#include "net_kern.h"
6236 +#include "net_user.h"
6237 +#include "mconsole_kern.h"
6238 +#include "init.h"
6239 +#include "irq_user.h"
6240 +#include "irq_kern.h"
6241 +
6242 +static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
6243 +LIST_HEAD(opened);
6244 +
6245 +static int uml_net_rx(struct net_device *dev)
6246 +{
6247 +       struct uml_net_private *lp = dev->priv;
6248 +       int pkt_len;
6249 +       struct sk_buff *skb;
6250 +
6251 +       /* If we can't allocate memory, try again next round. */
6252 +       skb = dev_alloc_skb(dev->mtu);
6253 +       if (skb == NULL) {
6254 +               lp->stats.rx_dropped++;
6255 +               return 0;
6256 +       }
6257 +
6258 +       skb->dev = dev;
6259 +       skb_put(skb, dev->mtu);
6260 +       skb->mac.raw = skb->data;
6261 +       pkt_len = (*lp->read)(lp->fd, &skb, lp);
6262 +
6263 +       if (pkt_len > 0) {
6264 +               skb_trim(skb, pkt_len);
6265 +               skb->protocol = (*lp->protocol)(skb);
6266 +               netif_rx(skb);
6267 +
6268 +               lp->stats.rx_bytes += skb->len;
6269 +               lp->stats.rx_packets++;
6270 +               return pkt_len;
6271 +       }
6272 +
6273 +       kfree_skb(skb);
6274 +       return pkt_len;
6275 +}
6276 +
6277 +void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6278 +{
6279 +       struct net_device *dev = dev_id;
6280 +       struct uml_net_private *lp = dev->priv;
6281 +       int err;
6282 +
6283 +       if(!netif_running(dev))
6284 +               return;
6285 +
6286 +       spin_lock(&lp->lock);
6287 +       while((err = uml_net_rx(dev)) > 0) ;
6288 +       if(err < 0) {
6289 +               printk(KERN_ERR 
6290 +                      "Device '%s' read returned %d, shutting it down\n", 
6291 +                      dev->name, err);
6292 +               dev_close(dev);
6293 +               goto out;
6294 +       }
6295 +       reactivate_fd(lp->fd, UM_ETH_IRQ);
6296 +
6297 + out:
6298 +       spin_unlock(&lp->lock);
6299 +}
6300 +
6301 +static int uml_net_open(struct net_device *dev)
6302 +{
6303 +       struct uml_net_private *lp = dev->priv;
6304 +       char addr[sizeof("255.255.255.255\0")];
6305 +       int err;
6306 +
6307 +       spin_lock(&lp->lock);
6308 +
6309 +       if(lp->fd >= 0){
6310 +               err = -ENXIO;
6311 +               goto out;
6312 +       }
6313 +
6314 +       if(!lp->have_mac){
6315 +               dev_ip_addr(dev, addr, &lp->mac[2]);
6316 +               set_ether_mac(dev, lp->mac);
6317 +       }
6318 +
6319 +       lp->fd = (*lp->open)(&lp->user);
6320 +       if(lp->fd < 0){
6321 +               err = lp->fd;
6322 +               goto out;
6323 +       }
6324 +
6325 +       err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
6326 +                            SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
6327 +       if(err != 0){
6328 +               printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
6329 +               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6330 +               lp->fd = -1;
6331 +               err = -ENETUNREACH;
6332 +       }
6333 +
6334 +       lp->tl.data = (unsigned long) &lp->user;
6335 +       netif_start_queue(dev);
6336 +
6337 +       spin_lock(&opened_lock);
6338 +       list_add(&lp->list, &opened);
6339 +       spin_unlock(&opened_lock);
6340 +       MOD_INC_USE_COUNT;
6341 + out:
6342 +       spin_unlock(&lp->lock);
6343 +       return(err);
6344 +}
6345 +
6346 +static int uml_net_close(struct net_device *dev)
6347 +{
6348 +       struct uml_net_private *lp = dev->priv;
6349 +       
6350 +       netif_stop_queue(dev);
6351 +       spin_lock(&lp->lock);
6352 +
6353 +       free_irq(dev->irq, dev);
6354 +       if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6355 +       lp->fd = -1;
6356 +       spin_lock(&opened_lock);
6357 +       list_del(&lp->list);
6358 +       spin_unlock(&opened_lock);
6359 +
6360 +       MOD_DEC_USE_COUNT;
6361 +       spin_unlock(&lp->lock);
6362 +       return 0;
6363 +}
6364 +
6365 +static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
6366 +{
6367 +       struct uml_net_private *lp = dev->priv;
6368 +       unsigned long flags;
6369 +       int len;
6370 +
6371 +       netif_stop_queue(dev);
6372 +
6373 +       spin_lock_irqsave(&lp->lock, flags);
6374 +
6375 +       len = (*lp->write)(lp->fd, &skb, lp);
6376 +
6377 +       if(len == skb->len) {
6378 +               lp->stats.tx_packets++;
6379 +               lp->stats.tx_bytes += skb->len;
6380 +               dev->trans_start = jiffies;
6381 +               netif_start_queue(dev);
6382 +
6383 +               /* this is normally done in the interrupt when tx finishes */
6384 +               netif_wake_queue(dev);
6385 +       } 
6386 +       else if(len == 0){
6387 +               netif_start_queue(dev);
6388 +               lp->stats.tx_dropped++;
6389 +       }
6390 +       else {
6391 +               netif_start_queue(dev);
6392 +               printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len);
6393 +       }
6394 +
6395 +       spin_unlock_irqrestore(&lp->lock, flags);
6396 +
6397 +       dev_kfree_skb(skb);
6398 +
6399 +       return 0;
6400 +}
6401 +
6402 +static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
6403 +{
6404 +       struct uml_net_private *lp = dev->priv;
6405 +       return &lp->stats;
6406 +}
6407 +
6408 +static void uml_net_set_multicast_list(struct net_device *dev)
6409 +{
6410 +       if (dev->flags & IFF_PROMISC) return;
6411 +       else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
6412 +       else dev->flags &= ~IFF_ALLMULTI;
6413 +}
6414 +
6415 +static void uml_net_tx_timeout(struct net_device *dev)
6416 +{
6417 +       dev->trans_start = jiffies;
6418 +       netif_wake_queue(dev);
6419 +}
6420 +
6421 +static int uml_net_set_mac(struct net_device *dev, void *addr)
6422 +{
6423 +       struct uml_net_private *lp = dev->priv;
6424 +       struct sockaddr *hwaddr = addr;
6425 +
6426 +       spin_lock(&lp->lock);
6427 +       memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
6428 +       spin_unlock(&lp->lock);
6429 +
6430 +       return(0);
6431 +}
6432 +
6433 +static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
6434 +{
6435 +       struct uml_net_private *lp = dev->priv;
6436 +       int err = 0;
6437 +
6438 +       spin_lock(&lp->lock);
6439 +
6440 +       new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
6441 +       if(new_mtu < 0){
6442 +               err = new_mtu;
6443 +               goto out;
6444 +       }
6445 +
6446 +       dev->mtu = new_mtu;
6447 +
6448 + out:
6449 +       spin_unlock(&lp->lock);
6450 +       return err;
6451 +}
6452 +
6453 +static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
6454 +{
6455 +       return(-EINVAL);
6456 +}
6457 +
6458 +void uml_net_user_timer_expire(unsigned long _conn)
6459 +{
6460 +#ifdef undef
6461 +       struct connection *conn = (struct connection *)_conn;
6462 +
6463 +       dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn);
6464 +       do_connect(conn);
6465 +#endif
6466 +}
6467 +
6468 +/*
6469 + * default do nothing hard header packet routines for struct net_device init.
6470 + * real ethernet transports will overwrite with real routines.
6471 + */
6472 +static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
6473 +                 unsigned short type, void *daddr, void *saddr, unsigned len)
6474 +{
6475 +       return(0); /* no change */
6476 +}
6477 +
6478 +static int uml_net_rebuild_header(struct sk_buff *skb)
6479 +{
6480 +       return(0); /* ignore */ 
6481 +}
6482 +
6483 +static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
6484 +{
6485 +       return(-1); /* fail */
6486 +}
6487 +
6488 +static void uml_net_header_cache_update(struct hh_cache *hh,
6489 +                 struct net_device *dev, unsigned char * haddr)
6490 +{
6491 +       /* ignore */
6492 +}
6493 +
6494 +static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
6495 +{
6496 +       return(0); /* nothing */
6497 +}
6498 +
6499 +static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
6500 +static struct list_head devices = LIST_HEAD_INIT(devices);
6501 +
6502 +static int eth_configure(int n, void *init, char *mac,
6503 +                        struct transport *transport)
6504 +{
6505 +       struct uml_net *device;
6506 +       struct net_device *dev;
6507 +       struct uml_net_private *lp;
6508 +       int save, err, size;
6509 +
6510 +       size = transport->private_size + sizeof(struct uml_net_private) + 
6511 +               sizeof(((struct uml_net_private *) 0)->user);
6512 +
6513 +       device = kmalloc(sizeof(*device), GFP_KERNEL);
6514 +       if(device == NULL){
6515 +               printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
6516 +               return(1);
6517 +       }
6518 +
6519 +       *device = ((struct uml_net) { .list     = LIST_HEAD_INIT(device->list),
6520 +                                     .dev      = NULL,
6521 +                                     .index    = n,
6522 +                                     .mac      = { [ 0 ... 5 ] = 0 },
6523 +                                     .have_mac = 0 });
6524 +
6525 +       spin_lock(&devices_lock);
6526 +       list_add(&device->list, &devices);
6527 +       spin_unlock(&devices_lock);
6528 +
6529 +       if(setup_etheraddr(mac, device->mac))
6530 +               device->have_mac = 1;
6531 +
6532 +       printk(KERN_INFO "Netdevice %d ", n);
6533 +       if(device->have_mac) printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
6534 +                                   device->mac[0], device->mac[1], 
6535 +                                   device->mac[2], device->mac[3], 
6536 +                                   device->mac[4], device->mac[5]);
6537 +       printk(": ");
6538 +       dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL);
6539 +       if(dev == NULL){
6540 +               printk(KERN_ERR "eth_configure: failed to allocate device\n");
6541 +               return(1);
6542 +       }
6543 +       memset(dev, 0, sizeof(*dev) + size);
6544 +
6545 +       snprintf(dev->name, sizeof(dev->name), "eth%d", n);
6546 +       dev->priv = (void *) &dev[1];
6547 +       device->dev = dev;
6548 +
6549 +        dev->hard_header = uml_net_hard_header;
6550 +        dev->rebuild_header = uml_net_rebuild_header;
6551 +        dev->hard_header_cache = uml_net_header_cache;
6552 +        dev->header_cache_update= uml_net_header_cache_update;
6553 +        dev->hard_header_parse = uml_net_header_parse;
6554 +
6555 +       (*transport->kern->init)(dev, init);
6556 +
6557 +       dev->mtu = transport->user->max_packet;
6558 +       dev->open = uml_net_open;
6559 +       dev->hard_start_xmit = uml_net_start_xmit;
6560 +       dev->stop = uml_net_close;
6561 +       dev->get_stats = uml_net_get_stats;
6562 +       dev->set_multicast_list = uml_net_set_multicast_list;
6563 +       dev->tx_timeout = uml_net_tx_timeout;
6564 +       dev->set_mac_address = uml_net_set_mac;
6565 +       dev->change_mtu = uml_net_change_mtu;
6566 +       dev->do_ioctl = uml_net_ioctl;
6567 +       dev->watchdog_timeo = (HZ >> 1);
6568 +       dev->irq = UM_ETH_IRQ;
6569 +
6570 +       rtnl_lock();
6571 +       err = register_netdevice(dev);
6572 +       rtnl_unlock();
6573 +       if(err)
6574 +               return(1);
6575 +       lp = dev->priv;
6576 +
6577 +       /* lp.user is the first four bytes of the transport data, which
6578 +        * has already been initialized.  This structure assignment will
6579 +        * overwrite that, so we make sure that .user gets overwritten with
6580 +        * what it already has.
6581 +        */
6582 +       save = lp->user[0];
6583 +       *lp = ((struct uml_net_private) 
6584 +               { .list                 = LIST_HEAD_INIT(lp->list),
6585 +                 .lock                 = SPIN_LOCK_UNLOCKED,
6586 +                 .dev                  = dev,
6587 +                 .fd                   = -1,
6588 +                 .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
6589 +                 .have_mac             = device->have_mac,
6590 +                 .protocol             = transport->kern->protocol,
6591 +                 .open                 = transport->user->open,
6592 +                 .close                = transport->user->close,
6593 +                 .remove               = transport->user->remove,
6594 +                 .read                 = transport->kern->read,
6595 +                 .write                = transport->kern->write,
6596 +                 .add_address          = transport->user->add_address,
6597 +                 .delete_address       = transport->user->delete_address,
6598 +                 .set_mtu              = transport->user->set_mtu,
6599 +                 .user                 = { save } });
6600 +       init_timer(&lp->tl);
6601 +       lp->tl.function = uml_net_user_timer_expire;
6602 +       memset(&lp->stats, 0, sizeof(lp->stats));
6603 +       if(lp->have_mac) memcpy(lp->mac, device->mac, sizeof(lp->mac));
6604 +
6605 +       if(transport->user->init) 
6606 +               (*transport->user->init)(&lp->user, dev);
6607 +
6608 +       if(device->have_mac)
6609 +               set_ether_mac(dev, device->mac);
6610 +       return(0);
6611 +}
6612 +
6613 +static struct uml_net *find_device(int n)
6614 +{
6615 +       struct uml_net *device;
6616 +       struct list_head *ele;
6617 +
6618 +       spin_lock(&devices_lock);
6619 +       list_for_each(ele, &devices){
6620 +               device = list_entry(ele, struct uml_net, list);
6621 +               if(device->index == n)
6622 +                       goto out;
6623 +       }
6624 +       device = NULL;
6625 + out:
6626 +       spin_unlock(&devices_lock);
6627 +       return(device);
6628 +}
6629 +
6630 +static int eth_parse(char *str, int *index_out, char **str_out)
6631 +{
6632 +       char *end;
6633 +       int n;
6634 +
6635 +       n = simple_strtoul(str, &end, 0);
6636 +       if(end == str){
6637 +               printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str);
6638 +               return(1);
6639 +       }
6640 +       if(n < 0){
6641 +               printk(KERN_ERR "eth_setup: device %d is negative\n", n);
6642 +               return(1);
6643 +       }
6644 +       str = end;
6645 +       if(*str != '='){
6646 +               printk(KERN_ERR 
6647 +                      "eth_setup: expected '=' after device number\n");
6648 +               return(1);
6649 +       }
6650 +       str++;
6651 +       if(find_device(n)){
6652 +               printk(KERN_ERR "eth_setup: Device %d already configured\n",
6653 +                      n);
6654 +               return(1);
6655 +       }
6656 +       if(index_out) *index_out = n;
6657 +       *str_out = str;
6658 +       return(0);
6659 +}
6660 +
6661 +struct eth_init {
6662 +       struct list_head list;
6663 +       char *init;
6664 +       int index;
6665 +};
6666 +
6667 +/* Filled in at boot time.  Will need locking if the transports become
6668 + * modular.
6669 + */
6670 +struct list_head transports = LIST_HEAD_INIT(transports);
6671 +
6672 +/* Filled in during early boot */
6673 +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
6674 +
6675 +static int check_transport(struct transport *transport, char *eth, int n,
6676 +                          void **init_out, char **mac_out)
6677 +{
6678 +       int len;
6679 +
6680 +       len = strlen(transport->name);
6681 +       if(strncmp(eth, transport->name, len))
6682 +               return(0);
6683 +
6684 +       eth += len;
6685 +       if(*eth == ',')
6686 +               eth++;
6687 +       else if(*eth != '\0')
6688 +               return(0);
6689 +
6690 +       *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
6691 +       if(*init_out == NULL)
6692 +               return(1);
6693 +
6694 +       if(!transport->setup(eth, mac_out, *init_out)){
6695 +               kfree(*init_out);
6696 +               *init_out = NULL;
6697 +       }
6698 +       return(1);
6699 +}
6700 +
6701 +void register_transport(struct transport *new)
6702 +{
6703 +       struct list_head *ele, *next;
6704 +       struct eth_init *eth;
6705 +       void *init;
6706 +       char *mac = NULL;
6707 +       int match;
6708 +
6709 +       list_add(&new->list, &transports);
6710 +
6711 +       list_for_each_safe(ele, next, &eth_cmd_line){
6712 +               eth = list_entry(ele, struct eth_init, list);
6713 +               match = check_transport(new, eth->init, eth->index, &init,
6714 +                                       &mac);
6715 +               if(!match)
6716 +                       continue;
6717 +               else if(init != NULL){
6718 +                       eth_configure(eth->index, init, mac, new);
6719 +                       kfree(init);
6720 +               }
6721 +               list_del(&eth->list);
6722 +       }
6723 +}
6724 +
6725 +static int eth_setup_common(char *str, int index)
6726 +{
6727 +       struct list_head *ele;
6728 +       struct transport *transport;
6729 +       void *init;
6730 +       char *mac = NULL;
6731 +
6732 +       list_for_each(ele, &transports){
6733 +               transport = list_entry(ele, struct transport, list);
6734 +               if(!check_transport(transport, str, index, &init, &mac))
6735 +                       continue;
6736 +               if(init != NULL){
6737 +                       eth_configure(index, init, mac, transport);
6738 +                       kfree(init);
6739 +               }
6740 +               return(1);
6741 +       }
6742 +       return(0);
6743 +}
6744 +
6745 +static int eth_setup(char *str)
6746 +{
6747 +       struct eth_init *new;
6748 +       int n, err;
6749 +
6750 +       err = eth_parse(str, &n, &str);
6751 +       if(err) return(1);
6752 +
6753 +       new = alloc_bootmem(sizeof(new));
6754 +       if(new == NULL){
6755 +               printk("eth_init : alloc_bootmem failed\n");
6756 +               return(1);
6757 +       }
6758 +       *new = ((struct eth_init) { .list       = LIST_HEAD_INIT(new->list),
6759 +                                   .index      = n,
6760 +                                   .init       = str });
6761 +       list_add_tail(&new->list, &eth_cmd_line);
6762 +       return(1);
6763 +}
6764 +
6765 +__setup("eth", eth_setup);
6766 +__uml_help(eth_setup,
6767 +"eth[0-9]+=<transport>,<options>\n"
6768 +"    Configure a network device.\n\n"
6769 +);
6770 +
6771 +static int eth_init(void)
6772 +{
6773 +       struct list_head *ele, *next;
6774 +       struct eth_init *eth;
6775 +
6776 +       list_for_each_safe(ele, next, &eth_cmd_line){
6777 +               eth = list_entry(ele, struct eth_init, list);
6778 +
6779 +               if(eth_setup_common(eth->init, eth->index))
6780 +                       list_del(&eth->list);
6781 +       }
6782 +       
6783 +       return(1);
6784 +}
6785 +
6786 +__initcall(eth_init);
6787 +
6788 +static int net_config(char *str)
6789 +{
6790 +       int n, err;
6791 +
6792 +       err = eth_parse(str, &n, &str);
6793 +       if(err) return(err);
6794 +
6795 +       str = uml_strdup(str);
6796 +       if(str == NULL){
6797 +               printk(KERN_ERR "net_config failed to strdup string\n");
6798 +               return(-1);
6799 +       }
6800 +       err = !eth_setup_common(str, n);
6801 +       if(err) 
6802 +               kfree(str);
6803 +       return(err);
6804 +}
6805 +
6806 +static int net_remove(char *str)
6807 +{
6808 +       struct uml_net *device;
6809 +       struct net_device *dev;
6810 +       struct uml_net_private *lp;
6811 +       char *end;
6812 +       int n;
6813 +
6814 +       n = simple_strtoul(str, &end, 0);
6815 +       if((*end != '\0') || (end == str))
6816 +               return(-1);
6817 +
6818 +       device = find_device(n);
6819 +       if(device == NULL)
6820 +               return(0);
6821 +
6822 +       dev = device->dev;
6823 +       lp = dev->priv;
6824 +       if(lp->fd > 0) return(-1);
6825 +       if(lp->remove != NULL) (*lp->remove)(&lp->user);
6826 +       unregister_netdev(dev);
6827 +
6828 +       list_del(&device->list);
6829 +       kfree(device);
6830 +       return(0);
6831 +}
6832 +
6833 +static struct mc_device net_mc = {
6834 +       .name           = "eth",
6835 +       .config         = net_config,
6836 +       .get_config     = NULL,
6837 +       .remove         = net_remove,
6838 +};
6839 +
6840 +static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
6841 +                             void *ptr)
6842 +{
6843 +       struct in_ifaddr *ifa = ptr;
6844 +       u32 addr = ifa->ifa_address;
6845 +       u32 netmask = ifa->ifa_mask;
6846 +       struct net_device *dev = ifa->ifa_dev->dev;
6847 +       struct uml_net_private *lp;
6848 +       void (*proc)(unsigned char *, unsigned char *, void *);
6849 +       unsigned char addr_buf[4], netmask_buf[4];
6850 +
6851 +       if(dev->open != uml_net_open) return(NOTIFY_DONE);
6852 +
6853 +       lp = dev->priv;
6854 +
6855 +       proc = NULL;
6856 +       switch (event){
6857 +       case NETDEV_UP:
6858 +               proc = lp->add_address;
6859 +               break;
6860 +       case NETDEV_DOWN:
6861 +               proc = lp->delete_address;
6862 +               break;
6863 +       }
6864 +       if(proc != NULL){
6865 +               addr_buf[0] = addr & 0xff;
6866 +               addr_buf[1] = (addr >> 8) & 0xff;
6867 +               addr_buf[2] = (addr >> 16) & 0xff;
6868 +               addr_buf[3] = addr >> 24;
6869 +               netmask_buf[0] = netmask & 0xff;
6870 +               netmask_buf[1] = (netmask >> 8) & 0xff;
6871 +               netmask_buf[2] = (netmask >> 16) & 0xff;
6872 +               netmask_buf[3] = netmask >> 24;
6873 +               (*proc)(addr_buf, netmask_buf, &lp->user);
6874 +       }
6875 +       return(NOTIFY_DONE);
6876 +}
6877 +
6878 +struct notifier_block uml_inetaddr_notifier = {
6879 +       .notifier_call          = uml_inetaddr_event,
6880 +};
6881 +
6882 +static int uml_net_init(void)
6883 +{
6884 +       struct list_head *ele;
6885 +       struct uml_net_private *lp;     
6886 +       struct in_device *ip;
6887 +       struct in_ifaddr *in;
6888 +
6889 +       mconsole_register_dev(&net_mc);
6890 +       register_inetaddr_notifier(&uml_inetaddr_notifier);
6891 +
6892 +       /* Devices may have been opened already, so the uml_inetaddr_notifier
6893 +        * didn't get a chance to run for them.  This fakes it so that
6894 +        * addresses which have already been set up get handled properly.
6895 +        */
6896 +       list_for_each(ele, &opened){
6897 +               lp = list_entry(ele, struct uml_net_private, list);
6898 +               ip = lp->dev->ip_ptr;
6899 +               if(ip == NULL) continue;
6900 +               in = ip->ifa_list;
6901 +               while(in != NULL){
6902 +                       uml_inetaddr_event(NULL, NETDEV_UP, in);
6903 +                       in = in->ifa_next;
6904 +               }
6905 +       }       
6906 +
6907 +       return(0);
6908 +}
6909 +
6910 +__initcall(uml_net_init);
6911 +
6912 +static void close_devices(void)
6913 +{
6914 +       struct list_head *ele;
6915 +       struct uml_net_private *lp;     
6916 +
6917 +       list_for_each(ele, &opened){
6918 +               lp = list_entry(ele, struct uml_net_private, list);
6919 +               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
6920 +               if(lp->remove != NULL) (*lp->remove)(&lp->user);
6921 +       }
6922 +}
6923 +
6924 +__uml_exitcall(close_devices);
6925 +
6926 +int setup_etheraddr(char *str, unsigned char *addr)
6927 +{
6928 +       char *end;
6929 +       int i;
6930 +
6931 +       if(str == NULL)
6932 +               return(0);
6933 +       for(i=0;i<6;i++){
6934 +               addr[i] = simple_strtoul(str, &end, 16);
6935 +               if((end == str) ||
6936 +                  ((*end != ':') && (*end != ',') && (*end != '\0'))){
6937 +                       printk(KERN_ERR 
6938 +                              "setup_etheraddr: failed to parse '%s' "
6939 +                              "as an ethernet address\n", str);
6940 +                       return(0);
6941 +               }
6942 +               str = end + 1;
6943 +       }
6944 +       if(addr[0] & 1){
6945 +               printk(KERN_ERR 
6946 +                      "Attempt to assign a broadcast ethernet address to a "
6947 +                      "device disallowed\n");
6948 +               return(0);
6949 +       }
6950 +       return(1);
6951 +}
6952 +
6953 +void dev_ip_addr(void *d, char *buf, char *bin_buf)
6954 +{
6955 +       struct net_device *dev = d;
6956 +       struct in_device *ip = dev->ip_ptr;
6957 +       struct in_ifaddr *in;
6958 +       u32 addr;
6959 +
6960 +       if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
6961 +               printk(KERN_WARNING "dev_ip_addr - device not assigned an "
6962 +                      "IP address\n");
6963 +               return;
6964 +       }
6965 +       addr = in->ifa_address;
6966 +       sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, 
6967 +               (addr >> 16) & 0xff, addr >> 24);
6968 +       if(bin_buf){
6969 +               bin_buf[0] = addr & 0xff;
6970 +               bin_buf[1] = (addr >> 8) & 0xff;
6971 +               bin_buf[2] = (addr >> 16) & 0xff;
6972 +               bin_buf[3] = addr >> 24;
6973 +       }
6974 +}
6975 +
6976 +void set_ether_mac(void *d, unsigned char *addr)
6977 +{
6978 +       struct net_device *dev = d;
6979 +
6980 +       memcpy(dev->dev_addr, addr, ETH_ALEN);  
6981 +}
6982 +
6983 +struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
6984 +{
6985 +       if((skb != NULL) && (skb_tailroom(skb) < extra)){
6986 +               struct sk_buff *skb2;
6987 +
6988 +               skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
6989 +               dev_kfree_skb(skb);
6990 +               skb = skb2;
6991 +       }
6992 +       if(skb != NULL) skb_put(skb, extra);
6993 +       return(skb);
6994 +}
6995 +
6996 +void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, 
6997 +                                       void *), 
6998 +                   void *arg)
6999 +{
7000 +       struct net_device *dev = d;
7001 +       struct in_device *ip = dev->ip_ptr;
7002 +       struct in_ifaddr *in;
7003 +       unsigned char address[4], netmask[4];
7004 +
7005 +       if(ip == NULL) return;
7006 +       in = ip->ifa_list;
7007 +       while(in != NULL){
7008 +               address[0] = in->ifa_address & 0xff;
7009 +               address[1] = (in->ifa_address >> 8) & 0xff;
7010 +               address[2] = (in->ifa_address >> 16) & 0xff;
7011 +               address[3] = in->ifa_address >> 24;
7012 +               netmask[0] = in->ifa_mask & 0xff;
7013 +               netmask[1] = (in->ifa_mask >> 8) & 0xff;
7014 +               netmask[2] = (in->ifa_mask >> 16) & 0xff;
7015 +               netmask[3] = in->ifa_mask >> 24;
7016 +               (*cb)(address, netmask, arg);
7017 +               in = in->ifa_next;
7018 +       }
7019 +}
7020 +
7021 +int dev_netmask(void *d, void *m)
7022 +{
7023 +       struct net_device *dev = d;
7024 +       struct in_device *ip = dev->ip_ptr;
7025 +       struct in_ifaddr *in;
7026 +       __u32 *mask_out = m;
7027 +
7028 +       if(ip == NULL) 
7029 +               return(1);
7030 +
7031 +       in = ip->ifa_list;
7032 +       if(in == NULL) 
7033 +               return(1);
7034 +
7035 +       *mask_out = in->ifa_mask;
7036 +       return(0);
7037 +}
7038 +
7039 +void *get_output_buffer(int *len_out)
7040 +{
7041 +       void *ret;
7042 +
7043 +       ret = (void *) __get_free_pages(GFP_KERNEL, 0);
7044 +       if(ret) *len_out = PAGE_SIZE;
7045 +       else *len_out = 0;
7046 +       return(ret);
7047 +}
7048 +
7049 +void free_output_buffer(void *buffer)
7050 +{
7051 +       free_pages((unsigned long) buffer, 0);
7052 +}
7053 +
7054 +int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, 
7055 +                    char **gate_addr)
7056 +{
7057 +       char *remain;
7058 +
7059 +       remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
7060 +       if(remain != NULL){
7061 +               printk("tap_setup_common - Extra garbage on specification : "
7062 +                      "'%s'\n", remain);
7063 +               return(1);
7064 +       }
7065 +
7066 +       return(0);
7067 +}
7068 +
7069 +unsigned short eth_protocol(struct sk_buff *skb)
7070 +{
7071 +       return(eth_type_trans(skb, skb->dev));
7072 +}
7073 +
7074 +/*
7075 + * Overrides for Emacs so that we follow Linus's tabbing style.
7076 + * Emacs will notice this stuff at the end of the file and automatically
7077 + * adjust the settings for this buffer only.  This must remain at the end
7078 + * of the file.
7079 + * ---------------------------------------------------------------------------
7080 + * Local variables:
7081 + * c-file-style: "linux"
7082 + * End:
7083 + */
7084 diff -Naur -X ../exclude-files orig/arch/um/drivers/net_user.c um/arch/um/drivers/net_user.c
7085 --- orig/arch/um/drivers/net_user.c     1969-12-31 19:00:00.000000000 -0500
7086 +++ um/arch/um/drivers/net_user.c       2003-10-21 03:26:06.000000000 -0400
7087 @@ -0,0 +1,252 @@
7088 +/* 
7089 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7090 + * Licensed under the GPL
7091 + */
7092 +
7093 +#include <stddef.h>
7094 +#include <stdarg.h>
7095 +#include <unistd.h>
7096 +#include <stdio.h>
7097 +#include <errno.h>
7098 +#include <stdlib.h>
7099 +#include <string.h>
7100 +#include <sys/socket.h>
7101 +#include <sys/wait.h>
7102 +#include "user.h"
7103 +#include "user_util.h"
7104 +#include "kern_util.h"
7105 +#include "net_user.h"
7106 +#include "helper.h"
7107 +#include "os.h"
7108 +
7109 +int tap_open_common(void *dev, char *gate_addr)
7110 +{
7111 +       int tap_addr[4];
7112 +
7113 +       if(gate_addr == NULL) return(0);
7114 +       if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
7115 +                 &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
7116 +               printk("Invalid tap IP address - '%s'\n", gate_addr);
7117 +               return(-EINVAL);
7118 +       }
7119 +       return(0);
7120 +}
7121 +
7122 +void tap_check_ips(char *gate_addr, char *eth_addr)
7123 +{
7124 +       int tap_addr[4];
7125 +
7126 +       if((gate_addr != NULL) && 
7127 +          (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
7128 +                  &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
7129 +          (eth_addr[0] == tap_addr[0]) && 
7130 +          (eth_addr[1] == tap_addr[1]) && 
7131 +          (eth_addr[2] == tap_addr[2]) && 
7132 +          (eth_addr[3] == tap_addr[3])){
7133 +               printk("The tap IP address and the UML eth IP address"
7134 +                      " must be different\n");
7135 +       }
7136 +}
7137 +
7138 +void read_output(int fd, char *output, int len)
7139 +{
7140 +       int remain, n, actual;
7141 +       char c;
7142 +
7143 +       if(output == NULL){
7144 +               output = &c;
7145 +               len = sizeof(c);
7146 +       }
7147 +               
7148 +       *output = '\0';
7149 +       n = os_read_file(fd, &remain, sizeof(remain));
7150 +       if(n != sizeof(remain)){
7151 +               printk("read_output - read of length failed, err = %d\n", -n);
7152 +               return;
7153 +       }
7154 +
7155 +       while(remain != 0){
7156 +               n = (remain < len) ? remain : len;
7157 +               actual = os_read_file(fd, output, n);
7158 +               if(actual != n){
7159 +                       printk("read_output - read of data failed, "
7160 +                              "err = %d\n", -actual);
7161 +                       return;
7162 +               }
7163 +               remain -= actual;
7164 +       }
7165 +       return;
7166 +}
7167 +
7168 +int net_read(int fd, void *buf, int len)
7169 +{
7170 +       int n;
7171 +
7172 +       n = os_read_file(fd,  buf,  len);
7173 +
7174 +       if(n == -EAGAIN) 
7175 +               return(0);
7176 +       else if(n == 0) 
7177 +               return(-ENOTCONN);
7178 +       return(n);
7179 +}
7180 +
7181 +int net_recvfrom(int fd, void *buf, int len)
7182 +{
7183 +       int n;
7184 +
7185 +       while(((n = recvfrom(fd,  buf,  len, 0, NULL, NULL)) < 0) && 
7186 +             (errno == EINTR)) ;
7187 +
7188 +       if(n < 0){
7189 +               if(errno == EAGAIN) return(0);
7190 +               return(-errno);
7191 +       }
7192 +       else if(n == 0) return(-ENOTCONN);
7193 +       return(n);
7194 +}
7195 +
7196 +int net_write(int fd, void *buf, int len)
7197 +{
7198 +       int n;
7199 +
7200 +       n = os_write_file(fd, buf, len);
7201 +
7202 +       if(n == -EAGAIN) 
7203 +               return(0);
7204 +       else if(n == 0) 
7205 +               return(-ENOTCONN);
7206 +       return(n);
7207 +}
7208 +
7209 +int net_send(int fd, void *buf, int len)
7210 +{
7211 +       int n;
7212 +
7213 +       while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ;
7214 +       if(n < 0){
7215 +               if(errno == EAGAIN) return(0);
7216 +               return(-errno);
7217 +       }
7218 +       else if(n == 0) return(-ENOTCONN);
7219 +       return(n);      
7220 +}
7221 +
7222 +int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
7223 +{
7224 +       int n;
7225 +
7226 +       while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
7227 +                          sock_len)) < 0) && (errno == EINTR)) ;
7228 +       if(n < 0){
7229 +               if(errno == EAGAIN) return(0);
7230 +               return(-errno);
7231 +       }
7232 +       else if(n == 0) return(-ENOTCONN);
7233 +       return(n);      
7234 +}
7235 +
7236 +struct change_pre_exec_data {
7237 +       int close_me;
7238 +       int stdout;
7239 +};
7240 +
7241 +static void change_pre_exec(void *arg)
7242 +{
7243 +       struct change_pre_exec_data *data = arg;
7244 +
7245 +       os_close_file(data->close_me);
7246 +       dup2(data->stdout, 1);
7247 +}
7248 +
7249 +static int change_tramp(char **argv, char *output, int output_len)
7250 +{
7251 +       int pid, fds[2], err;
7252 +       struct change_pre_exec_data pe_data;
7253 +
7254 +       err = os_pipe(fds, 1, 0);
7255 +       if(err < 0){
7256 +               printk("change_tramp - pipe failed, err = %d\n", -err);
7257 +               return(err);
7258 +       }
7259 +       pe_data.close_me = fds[0];
7260 +       pe_data.stdout = fds[1];
7261 +       pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
7262 +
7263 +       os_close_file(fds[1]);
7264 +       read_output(fds[0], output, output_len);
7265 +       waitpid(pid, NULL, 0);  
7266 +       return(pid);
7267 +}
7268 +
7269 +static void change(char *dev, char *what, unsigned char *addr,
7270 +                  unsigned char *netmask)
7271 +{
7272 +       char addr_buf[sizeof("255.255.255.255\0")];
7273 +       char netmask_buf[sizeof("255.255.255.255\0")];
7274 +       char version[sizeof("nnnnn\0")];
7275 +       char *argv[] = { "uml_net", version, what, dev, addr_buf, 
7276 +                        netmask_buf, NULL };
7277 +       char *output;
7278 +       int output_len, pid;
7279 +
7280 +       sprintf(version, "%d", UML_NET_VERSION);
7281 +       sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
7282 +       sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], 
7283 +               netmask[2], netmask[3]);
7284 +
7285 +       output_len = page_size();
7286 +       output = um_kmalloc(output_len);
7287 +       if(output == NULL)
7288 +               printk("change : failed to allocate output buffer\n");
7289 +
7290 +       pid = change_tramp(argv, output, output_len);
7291 +       if(pid < 0) return;
7292 +
7293 +       if(output != NULL){
7294 +               printk("%s", output);
7295 +               kfree(output);
7296 +       }
7297 +}
7298 +
7299 +void open_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7300 +{
7301 +       change(arg, "add", addr, netmask);
7302 +}
7303 +
7304 +void close_addr(unsigned char *addr, unsigned char *netmask, void *arg)
7305 +{
7306 +       change(arg, "del", addr, netmask);
7307 +}
7308 +
7309 +char *split_if_spec(char *str, ...)
7310 +{
7311 +       char **arg, *end;
7312 +       va_list ap;
7313 +
7314 +       va_start(ap, str);
7315 +       while((arg = va_arg(ap, char **)) != NULL){
7316 +               if(*str == '\0')
7317 +                       return(NULL);
7318 +               end = strchr(str, ',');
7319 +               if(end != str)
7320 +                       *arg = str;
7321 +               if(end == NULL)
7322 +                       return(NULL);
7323 +               *end++ = '\0';
7324 +               str = end;
7325 +       }
7326 +       va_end(ap);
7327 +       return(str);
7328 +}
7329 +
7330 +/*
7331 + * Overrides for Emacs so that we follow Linus's tabbing style.
7332 + * Emacs will notice this stuff at the end of the file and automatically
7333 + * adjust the settings for this buffer only.  This must remain at the end
7334 + * of the file.
7335 + * ---------------------------------------------------------------------------
7336 + * Local variables:
7337 + * c-file-style: "linux"
7338 + * End:
7339 + */
7340 diff -Naur -X ../exclude-files orig/arch/um/drivers/null.c um/arch/um/drivers/null.c
7341 --- orig/arch/um/drivers/null.c 1969-12-31 19:00:00.000000000 -0500
7342 +++ um/arch/um/drivers/null.c   2003-10-21 03:26:06.000000000 -0400
7343 @@ -0,0 +1,55 @@
7344 +/* 
7345 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7346 + * Licensed under the GPL
7347 + */
7348 +
7349 +#include <stdlib.h>
7350 +#include <errno.h>
7351 +#include "chan_user.h"
7352 +#include "os.h"
7353 +
7354 +static int null_chan;
7355 +
7356 +void *null_init(char *str, int device, struct chan_opts *opts)
7357 +{
7358 +       return(&null_chan);
7359 +}
7360 +
7361 +int null_open(int input, int output, int primary, void *d, char **dev_out)
7362 +{
7363 +       *dev_out = NULL;
7364 +       return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
7365 +}
7366 +
7367 +int null_read(int fd, char *c_out, void *unused)
7368 +{
7369 +       return(-ENODEV);
7370 +}
7371 +
7372 +void null_free(void *data)
7373 +{
7374 +}
7375 +
7376 +struct chan_ops null_ops = {
7377 +       .type           = "null",
7378 +       .init           = null_init,
7379 +       .open           = null_open,
7380 +       .close          = generic_close,
7381 +       .read           = null_read,
7382 +       .write          = generic_write,
7383 +       .console_write  = generic_console_write,
7384 +       .window_size    = generic_window_size,
7385 +       .free           = null_free,
7386 +       .winch          = 0,
7387 +};
7388 +
7389 +/*
7390 + * Overrides for Emacs so that we follow Linus's tabbing style.
7391 + * Emacs will notice this stuff at the end of the file and automatically
7392 + * adjust the settings for this buffer only.  This must remain at the end
7393 + * of the file.
7394 + * ---------------------------------------------------------------------------
7395 + * Local variables:
7396 + * c-file-style: "linux"
7397 + * End:
7398 + */
7399 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_kern.c um/arch/um/drivers/pcap_kern.c
7400 --- orig/arch/um/drivers/pcap_kern.c    1969-12-31 19:00:00.000000000 -0500
7401 +++ um/arch/um/drivers/pcap_kern.c      2003-10-21 03:26:06.000000000 -0400
7402 @@ -0,0 +1,127 @@
7403 +/*
7404 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7405 + * Licensed under the GPL.
7406 + */
7407 +
7408 +#include "linux/init.h"
7409 +#include "linux/netdevice.h"
7410 +#include "linux/etherdevice.h"
7411 +#include "net_kern.h"
7412 +#include "net_user.h"
7413 +#include "pcap_user.h"
7414 +
7415 +struct pcap_init {
7416 +       char *host_if;
7417 +       int promisc;
7418 +       int optimize;
7419 +       char *filter;
7420 +};
7421 +
7422 +void pcap_init(struct net_device *dev, void *data)
7423 +{
7424 +       struct uml_net_private *pri;
7425 +       struct pcap_data *ppri;
7426 +       struct pcap_init *init = data;
7427 +
7428 +       init_etherdev(dev, 0);
7429 +       pri = dev->priv;
7430 +       ppri = (struct pcap_data *) pri->user;
7431 +       *ppri = ((struct pcap_data)
7432 +               { .host_if      = init->host_if,
7433 +                 .promisc      = init->promisc,
7434 +                 .optimize     = init->optimize,
7435 +                 .filter       = init->filter,
7436 +                 .compiled     = NULL,
7437 +                 .pcap         = NULL });
7438 +}
7439 +
7440 +static int pcap_read(int fd, struct sk_buff **skb, 
7441 +                      struct uml_net_private *lp)
7442 +{
7443 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
7444 +       if(*skb == NULL) return(-ENOMEM);
7445 +       return(pcap_user_read(fd, (*skb)->mac.raw, 
7446 +                             (*skb)->dev->mtu + ETH_HEADER_OTHER,
7447 +                             (struct pcap_data *) &lp->user));
7448 +}
7449 +
7450 +static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
7451 +{
7452 +       return(-EPERM);
7453 +}
7454 +
7455 +static struct net_kern_info pcap_kern_info = {
7456 +       .init                   = pcap_init,
7457 +       .protocol               = eth_protocol,
7458 +       .read                   = pcap_read,
7459 +       .write                  = pcap_write,
7460 +};
7461 +
7462 +int pcap_setup(char *str, char **mac_out, void *data)
7463 +{
7464 +       struct pcap_init *init = data;
7465 +       char *remain, *host_if = NULL, *options[2] = { NULL, NULL };
7466 +       int i;
7467 +
7468 +       *init = ((struct pcap_init)
7469 +               { .host_if      = "eth0",
7470 +                 .promisc      = 1,
7471 +                 .optimize     = 0,
7472 +                 .filter       = NULL });
7473 +
7474 +       remain = split_if_spec(str, &host_if, &init->filter, 
7475 +                              &options[0], &options[1], NULL);
7476 +       if(remain != NULL){
7477 +               printk(KERN_ERR "pcap_setup - Extra garbage on "
7478 +                      "specification : '%s'\n", remain);
7479 +               return(0);
7480 +       }
7481 +
7482 +       if(host_if != NULL)
7483 +               init->host_if = host_if;
7484 +
7485 +       for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){
7486 +               if(options[i] == NULL)
7487 +                       continue;
7488 +               if(!strcmp(options[i], "promisc"))
7489 +                       init->promisc = 1;
7490 +               else if(!strcmp(options[i], "nopromisc"))
7491 +                       init->promisc = 0;
7492 +               else if(!strcmp(options[i], "optimize"))
7493 +                       init->optimize = 1;
7494 +               else if(!strcmp(options[i], "nooptimize"))
7495 +                       init->optimize = 0;
7496 +               else printk("pcap_setup : bad option - '%s'\n", options[i]);
7497 +       }
7498 +
7499 +       return(1);
7500 +}
7501 +
7502 +static struct transport pcap_transport = {
7503 +       .list           = LIST_HEAD_INIT(pcap_transport.list),
7504 +       .name           = "pcap",
7505 +       .setup          = pcap_setup,
7506 +       .user           = &pcap_user_info,
7507 +       .kern           = &pcap_kern_info,
7508 +       .private_size   = sizeof(struct pcap_data),
7509 +       .setup_size     = sizeof(struct pcap_init),
7510 +};
7511 +
7512 +static int register_pcap(void)
7513 +{
7514 +       register_transport(&pcap_transport);
7515 +       return(1);
7516 +}
7517 +
7518 +__initcall(register_pcap);
7519 +
7520 +/*
7521 + * Overrides for Emacs so that we follow Linus's tabbing style.
7522 + * Emacs will notice this stuff at the end of the file and automatically
7523 + * adjust the settings for this buffer only.  This must remain at the end
7524 + * of the file.
7525 + * ---------------------------------------------------------------------------
7526 + * Local variables:
7527 + * c-file-style: "linux"
7528 + * End:
7529 + */
7530 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.c um/arch/um/drivers/pcap_user.c
7531 --- orig/arch/um/drivers/pcap_user.c    1969-12-31 19:00:00.000000000 -0500
7532 +++ um/arch/um/drivers/pcap_user.c      2003-10-21 03:26:06.000000000 -0400
7533 @@ -0,0 +1,143 @@
7534 +/*
7535 + * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
7536 + * Licensed under the GPL.
7537 + */
7538 +
7539 +#include <unistd.h>
7540 +#include <stdlib.h>
7541 +#include <string.h>
7542 +#include <errno.h>
7543 +#include <pcap.h>
7544 +#include <asm/types.h>
7545 +#include "net_user.h"
7546 +#include "pcap_user.h"
7547 +#include "user.h"
7548 +
7549 +#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
7550 +
7551 +#define PCAP_FD(p) (*(int *)(p))
7552 +
7553 +static void pcap_user_init(void *data, void *dev)
7554 +{
7555 +       struct pcap_data *pri = data;
7556 +       pcap_t *p;
7557 +       char errors[PCAP_ERRBUF_SIZE];
7558 +
7559 +       p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
7560 +       if(p == NULL){
7561 +               printk("pcap_user_init : pcap_open_live failed - '%s'\n", 
7562 +                      errors);
7563 +               return;
7564 +       }
7565 +
7566 +       pri->dev = dev;
7567 +       pri->pcap = p;
7568 +}
7569 +
7570 +static int pcap_open(void *data)
7571 +{
7572 +       struct pcap_data *pri = data;
7573 +       __u32 netmask;
7574 +       int err;
7575 +
7576 +       if(pri->pcap == NULL)
7577 +               return(-ENODEV);
7578 +
7579 +       if(pri->filter != NULL){
7580 +               err = dev_netmask(pri->dev, &netmask);
7581 +               if(err < 0){
7582 +                       printk("pcap_open : dev_netmask failed\n");
7583 +                       return(-EIO);
7584 +               }
7585 +
7586 +               pri->compiled = um_kmalloc(sizeof(struct bpf_program));
7587 +               if(pri->compiled == NULL){
7588 +                       printk("pcap_open : kmalloc failed\n");
7589 +                       return(-ENOMEM);
7590 +               }
7591 +               
7592 +               err = pcap_compile(pri->pcap, 
7593 +                                  (struct bpf_program *) pri->compiled, 
7594 +                                  pri->filter, pri->optimize, netmask);
7595 +               if(err < 0){
7596 +                       printk("pcap_open : pcap_compile failed - '%s'\n", 
7597 +                              pcap_geterr(pri->pcap));
7598 +                       return(-EIO);
7599 +               }
7600 +
7601 +               err = pcap_setfilter(pri->pcap, pri->compiled);
7602 +               if(err < 0){
7603 +                       printk("pcap_open : pcap_setfilter failed - '%s'\n", 
7604 +                              pcap_geterr(pri->pcap));
7605 +                       return(-EIO);
7606 +               }
7607 +       }
7608 +       
7609 +       return(PCAP_FD(pri->pcap));
7610 +}
7611 +
7612 +static void pcap_remove(void *data)
7613 +{
7614 +       struct pcap_data *pri = data;
7615 +
7616 +       if(pri->compiled != NULL)
7617 +               pcap_freecode(pri->compiled);
7618 +
7619 +       pcap_close(pri->pcap);
7620 +}
7621 +
7622 +struct pcap_handler_data {
7623 +       char *buffer;
7624 +       int len;
7625 +};
7626 +
7627 +static void handler(u_char *data, const struct pcap_pkthdr *header, 
7628 +                   const u_char *packet)
7629 +{
7630 +       int len;
7631 +
7632 +       struct pcap_handler_data *hdata = (struct pcap_handler_data *) data;
7633 +
7634 +       len = hdata->len < header->caplen ? hdata->len : header->caplen;
7635 +       memcpy(hdata->buffer, packet, len);
7636 +       hdata->len = len;
7637 +}
7638 +
7639 +int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
7640 +{
7641 +       struct pcap_handler_data hdata = ((struct pcap_handler_data)
7642 +                                         { .buffer     = buffer,
7643 +                                           .len        = len });
7644 +       int n;
7645 +
7646 +       n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
7647 +       if(n < 0){
7648 +               printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
7649 +               return(-EIO);
7650 +       }
7651 +       else if(n == 0) 
7652 +               return(0);
7653 +       return(hdata.len);
7654 +}
7655 +
7656 +struct net_user_info pcap_user_info = {
7657 +       .init           = pcap_user_init,
7658 +       .open           = pcap_open,
7659 +       .close          = NULL,
7660 +       .remove         = pcap_remove,
7661 +       .set_mtu        = NULL,
7662 +       .add_address    = NULL,
7663 +       .delete_address = NULL,
7664 +       .max_packet     = MAX_PACKET - ETH_HEADER_OTHER
7665 +};
7666 +
7667 +/*
7668 + * Overrides for Emacs so that we follow Linus's tabbing style.
7669 + * Emacs will notice this stuff at the end of the file and automatically
7670 + * adjust the settings for this buffer only.  This must remain at the end
7671 + * of the file.
7672 + * ---------------------------------------------------------------------------
7673 + * Local variables:
7674 + * c-file-style: "linux"
7675 + * End:
7676 + */
7677 diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.h um/arch/um/drivers/pcap_user.h
7678 --- orig/arch/um/drivers/pcap_user.h    1969-12-31 19:00:00.000000000 -0500
7679 +++ um/arch/um/drivers/pcap_user.h      2003-10-21 03:26:06.000000000 -0400
7680 @@ -0,0 +1,31 @@
7681 +/* 
7682 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7683 + * Licensed under the GPL
7684 + */
7685 +
7686 +#include "net_user.h"
7687 +
7688 +struct pcap_data {
7689 +       char *host_if;
7690 +       int promisc;
7691 +       int optimize;
7692 +       char *filter;
7693 +       void *compiled;
7694 +       void *pcap;
7695 +       void *dev;
7696 +};
7697 +
7698 +extern struct net_user_info pcap_user_info;
7699 +
7700 +extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
7701 +
7702 +/*
7703 + * Overrides for Emacs so that we follow Linus's tabbing style.
7704 + * Emacs will notice this stuff at the end of the file and automatically
7705 + * adjust the settings for this buffer only.  This must remain at the end
7706 + * of the file.
7707 + * ---------------------------------------------------------------------------
7708 + * Local variables:
7709 + * c-file-style: "linux"
7710 + * End:
7711 + */
7712 diff -Naur -X ../exclude-files orig/arch/um/drivers/port.h um/arch/um/drivers/port.h
7713 --- orig/arch/um/drivers/port.h 1969-12-31 19:00:00.000000000 -0500
7714 +++ um/arch/um/drivers/port.h   2003-10-21 03:26:06.000000000 -0400
7715 @@ -0,0 +1,30 @@
7716 +/* 
7717 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
7718 + * Licensed under the GPL
7719 + */
7720 +
7721 +#ifndef __PORT_H__
7722 +#define __PORT_H__
7723 +
7724 +extern void *port_data(int port);
7725 +extern int port_wait(void *data);
7726 +extern void port_kern_close(void *d);
7727 +extern int port_connection(int fd, int *socket_out, int *pid_out);
7728 +extern int port_listen_fd(int port);
7729 +extern void port_read(int fd, void *data);
7730 +extern void port_kern_free(void *d);
7731 +extern int port_rcv_fd(int fd);
7732 +extern void port_remove_dev(void *d);
7733 +
7734 +#endif
7735 +
7736 +/*
7737 + * Overrides for Emacs so that we follow Linus's tabbing style.
7738 + * Emacs will notice this stuff at the end of the file and automatically
7739 + * adjust the settings for this buffer only.  This must remain at the end
7740 + * of the file.
7741 + * ---------------------------------------------------------------------------
7742 + * Local variables:
7743 + * c-file-style: "linux"
7744 + * End:
7745 + */
7746 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_kern.c um/arch/um/drivers/port_kern.c
7747 --- orig/arch/um/drivers/port_kern.c    1969-12-31 19:00:00.000000000 -0500
7748 +++ um/arch/um/drivers/port_kern.c      2003-10-21 03:26:06.000000000 -0400
7749 @@ -0,0 +1,303 @@
7750 +/* 
7751 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7752 + * Licensed under the GPL
7753 + */
7754 +
7755 +#include "linux/list.h"
7756 +#include "linux/sched.h"
7757 +#include "linux/slab.h"
7758 +#include "linux/irq.h"
7759 +#include "linux/spinlock.h"
7760 +#include "linux/errno.h"
7761 +#include "asm/semaphore.h"
7762 +#include "asm/errno.h"
7763 +#include "kern_util.h"
7764 +#include "kern.h"
7765 +#include "irq_user.h"
7766 +#include "irq_kern.h"
7767 +#include "port.h"
7768 +#include "init.h"
7769 +#include "os.h"
7770 +
7771 +struct port_list {
7772 +       struct list_head list;
7773 +       int has_connection;
7774 +       struct semaphore sem;
7775 +       int port;
7776 +       int fd;
7777 +       spinlock_t lock;
7778 +       struct list_head pending;
7779 +       struct list_head connections;
7780 +};
7781 +
7782 +struct port_dev {
7783 +       struct port_list *port;
7784 +       int helper_pid;
7785 +       int telnetd_pid;
7786 +};
7787 +
7788 +struct connection {
7789 +       struct list_head list;
7790 +       int fd;
7791 +       int helper_pid;
7792 +       int socket[2];
7793 +       int telnetd_pid;
7794 +       struct port_list *port;
7795 +};
7796 +
7797 +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
7798 +{
7799 +       struct connection *conn = data;
7800 +       int fd;
7801 +
7802 +       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
7803 +       if(fd < 0){
7804 +               if(fd == -EAGAIN)
7805 +                       return;
7806 +
7807 +               printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
7808 +                      -fd);
7809 +               os_close_file(conn->fd);
7810 +       }
7811 +
7812 +       list_del(&conn->list);
7813 +
7814 +       conn->fd = fd;
7815 +       list_add(&conn->list, &conn->port->connections);
7816 +
7817 +       up(&conn->port->sem);
7818 +}
7819 +
7820 +static int port_accept(struct port_list *port)
7821 +{
7822 +       struct connection *conn;
7823 +       int fd, socket[2], pid, ret = 0;
7824 +
7825 +       fd = port_connection(port->fd, socket, &pid);
7826 +       if(fd < 0){
7827 +               if(fd != -EAGAIN)
7828 +                       printk(KERN_ERR "port_accept : port_connection "
7829 +                              "returned %d\n", -fd);
7830 +               goto out;
7831 +       }
7832 +
7833 +       conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
7834 +       if(conn == NULL){
7835 +               printk(KERN_ERR "port_accept : failed to allocate "
7836 +                      "connection\n");
7837 +               goto out_close;
7838 +       }
7839 +       *conn = ((struct connection) 
7840 +               { .list         = LIST_HEAD_INIT(conn->list),
7841 +                 .fd           = fd,
7842 +                 .socket       = { socket[0], socket[1] },
7843 +                 .telnetd_pid  = pid,
7844 +                 .port         = port });
7845 +
7846 +       if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 
7847 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
7848 +                         "telnetd", conn)){
7849 +               printk(KERN_ERR "port_accept : failed to get IRQ for "
7850 +                      "telnetd\n");
7851 +               goto out_free;
7852 +       }
7853 +
7854 +       list_add(&conn->list, &port->pending);
7855 +       return(1);
7856 +
7857 + out_free:
7858 +       kfree(conn);
7859 + out_close:
7860 +       os_close_file(fd);
7861 +       if(pid != -1) 
7862 +               os_kill_process(pid, 1);
7863 + out:
7864 +       return(ret);
7865 +} 
7866 +
7867 +DECLARE_MUTEX(ports_sem);
7868 +struct list_head ports = LIST_HEAD_INIT(ports);
7869 +
7870 +void port_task_proc(void *unused)
7871 +{
7872 +       struct port_list *port;
7873 +       struct list_head *ele;
7874 +       unsigned long flags;
7875 +
7876 +       save_flags(flags);
7877 +       list_for_each(ele, &ports){
7878 +               port = list_entry(ele, struct port_list, list);
7879 +               if(!port->has_connection)
7880 +                       continue;
7881 +               reactivate_fd(port->fd, ACCEPT_IRQ);
7882 +               while(port_accept(port)) ;
7883 +               port->has_connection = 0;
7884 +       }
7885 +       restore_flags(flags);
7886 +}
7887 +
7888 +struct tq_struct port_task = {
7889 +       .routine        = port_task_proc,
7890 +       .data           = NULL
7891 +};
7892 +
7893 +static void port_interrupt(int irq, void *data, struct pt_regs *regs)
7894 +{
7895 +       struct port_list *port = data;
7896 +
7897 +       port->has_connection = 1;
7898 +       schedule_task(&port_task);
7899 +} 
7900 +
7901 +void *port_data(int port_num)
7902 +{
7903 +       struct list_head *ele;
7904 +       struct port_list *port;
7905 +       struct port_dev *dev = NULL;
7906 +       int fd;
7907 +
7908 +       down(&ports_sem);
7909 +       list_for_each(ele, &ports){
7910 +               port = list_entry(ele, struct port_list, list);
7911 +               if(port->port == port_num) goto found;
7912 +       }
7913 +       port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
7914 +       if(port == NULL){
7915 +               printk(KERN_ERR "Allocation of port list failed\n");
7916 +               goto out;
7917 +       }
7918 +
7919 +       fd = port_listen_fd(port_num);
7920 +       if(fd < 0){
7921 +               printk(KERN_ERR "binding to port %d failed, errno = %d\n",
7922 +                      port_num, -fd);
7923 +               goto out_free;
7924 +       }
7925 +       if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, 
7926 +                         SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port",
7927 +                         port)){
7928 +               printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
7929 +               goto out_close;
7930 +       }
7931 +
7932 +       *port = ((struct port_list) 
7933 +               { .list                 = LIST_HEAD_INIT(port->list),
7934 +                 .has_connection       = 0,
7935 +                 .sem                  = __SEMAPHORE_INITIALIZER(port->sem, 
7936 +                                                                 0),
7937 +                 .lock                 = SPIN_LOCK_UNLOCKED,
7938 +                 .port                 = port_num,
7939 +                 .fd                   = fd,
7940 +                 .pending              = LIST_HEAD_INIT(port->pending),
7941 +                 .connections          = LIST_HEAD_INIT(port->connections) });
7942 +       list_add(&port->list, &ports);
7943 +
7944 + found:
7945 +       dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
7946 +       if(dev == NULL){
7947 +               printk(KERN_ERR "Allocation of port device entry failed\n");
7948 +               goto out;
7949 +       }
7950 +
7951 +       *dev = ((struct port_dev) { .port               = port,
7952 +                                   .helper_pid         = -1,
7953 +                                   .telnetd_pid        = -1 });
7954 +       goto out;
7955 +
7956 + out_free:
7957 +       kfree(port);
7958 + out_close:
7959 +       os_close_file(fd);
7960 + out:
7961 +       up(&ports_sem);
7962 +       return(dev);
7963 +}
7964 +
7965 +int port_wait(void *data)
7966 +{
7967 +       struct port_dev *dev = data;
7968 +       struct connection *conn;
7969 +       struct port_list *port = dev->port;
7970 +       int fd;
7971 +
7972 +       while(1){
7973 +               if(down_interruptible(&port->sem)) 
7974 +                       return(-ERESTARTSYS);
7975 +
7976 +               spin_lock(&port->lock);
7977 +
7978 +               conn = list_entry(port->connections.next, struct connection, 
7979 +                                 list);
7980 +               list_del(&conn->list);
7981 +               spin_unlock(&port->lock);
7982 +
7983 +               os_shutdown_socket(conn->socket[0], 1, 1);
7984 +               os_close_file(conn->socket[0]);
7985 +               os_shutdown_socket(conn->socket[1], 1, 1);
7986 +               os_close_file(conn->socket[1]); 
7987 +
7988 +               /* This is done here because freeing an IRQ can't be done
7989 +                * within the IRQ handler.  So, pipe_interrupt always ups
7990 +                * the semaphore regardless of whether it got a successful
7991 +                * connection.  Then we loop here throwing out failed 
7992 +                * connections until a good one is found.
7993 +                */
7994 +               free_irq(TELNETD_IRQ, conn);
7995 +
7996 +               if(conn->fd >= 0) break;
7997 +               os_close_file(conn->fd);
7998 +               kfree(conn);
7999 +       }
8000 +
8001 +       fd = conn->fd;
8002 +       dev->helper_pid = conn->helper_pid;
8003 +       dev->telnetd_pid = conn->telnetd_pid;
8004 +       kfree(conn);
8005 +
8006 +       return(fd);
8007 +}
8008 +
8009 +void port_remove_dev(void *d)
8010 +{
8011 +       struct port_dev *dev = d;
8012 +
8013 +       if(dev->helper_pid != -1)
8014 +               os_kill_process(dev->helper_pid, 0);
8015 +       if(dev->telnetd_pid != -1)
8016 +               os_kill_process(dev->telnetd_pid, 1);
8017 +       dev->helper_pid = -1;
8018 +       dev->telnetd_pid = -1;
8019 +}
8020 +
8021 +void port_kern_free(void *d)
8022 +{
8023 +       struct port_dev *dev = d;
8024 +
8025 +       port_remove_dev(dev);
8026 +       kfree(dev);
8027 +}
8028 +
8029 +static void free_port(void)
8030 +{
8031 +       struct list_head *ele;
8032 +       struct port_list *port;
8033 +
8034 +       list_for_each(ele, &ports){
8035 +               port = list_entry(ele, struct port_list, list);
8036 +               free_irq_by_fd(port->fd);
8037 +               os_close_file(port->fd);
8038 +       }
8039 +}
8040 +
8041 +__uml_exitcall(free_port);
8042 +
8043 +/*
8044 + * Overrides for Emacs so that we follow Linus's tabbing style.
8045 + * Emacs will notice this stuff at the end of the file and automatically
8046 + * adjust the settings for this buffer only.  This must remain at the end
8047 + * of the file.
8048 + * ---------------------------------------------------------------------------
8049 + * Local variables:
8050 + * c-file-style: "linux"
8051 + * End:
8052 + */
8053 diff -Naur -X ../exclude-files orig/arch/um/drivers/port_user.c um/arch/um/drivers/port_user.c
8054 --- orig/arch/um/drivers/port_user.c    1969-12-31 19:00:00.000000000 -0500
8055 +++ um/arch/um/drivers/port_user.c      2003-10-21 03:26:06.000000000 -0400
8056 @@ -0,0 +1,213 @@
8057 +/* 
8058 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
8059 + * Licensed under the GPL
8060 + */
8061 +
8062 +#include <stdio.h>
8063 +#include <stddef.h>
8064 +#include <stdlib.h>
8065 +#include <string.h>
8066 +#include <errno.h>
8067 +#include <unistd.h>
8068 +#include <termios.h>
8069 +#include <sys/socket.h>
8070 +#include <sys/un.h>
8071 +#include <netinet/in.h>
8072 +#include "user_util.h"
8073 +#include "kern_util.h"
8074 +#include "user.h"
8075 +#include "chan_user.h"
8076 +#include "port.h"
8077 +#include "helper.h"
8078 +#include "os.h"
8079 +
8080 +struct port_chan {
8081 +       int raw;
8082 +       struct termios tt;
8083 +       void *kernel_data;
8084 +       char dev[sizeof("32768\0")];
8085 +};
8086 +
8087 +void *port_init(char *str, int device, struct chan_opts *opts)
8088 +{
8089 +       struct port_chan *data;
8090 +       void *kern_data;
8091 +       char *end;
8092 +       int port;
8093 +
8094 +       if(*str != ':'){
8095 +               printk("port_init : channel type 'port' must specify a "
8096 +                      "port number\n");
8097 +               return(NULL);
8098 +       }
8099 +       str++;
8100 +       port = strtoul(str, &end, 0);
8101 +       if((*end != '\0') || (end == str)){
8102 +               printk("port_init : couldn't parse port '%s'\n", str);
8103 +               return(NULL);
8104 +       }
8105 +
8106 +       kern_data = port_data(port);
8107 +       if(kern_data == NULL) 
8108 +               return(NULL);
8109 +
8110 +       data = um_kmalloc(sizeof(*data));
8111 +       if(data == NULL) 
8112 +               goto err;
8113 +
8114 +       *data = ((struct port_chan) { .raw              = opts->raw,
8115 +                                     .kernel_data      = kern_data });
8116 +       sprintf(data->dev, "%d", port);
8117 +
8118 +       return(data);
8119 + err:
8120 +       port_kern_free(kern_data);
8121 +       return(NULL);
8122 +}
8123 +
8124 +void port_free(void *d)
8125 +{
8126 +       struct port_chan *data = d;
8127 +
8128 +       port_kern_free(data->kernel_data);
8129 +       kfree(data);
8130 +}
8131 +
8132 +int port_open(int input, int output, int primary, void *d, char **dev_out)
8133 +{
8134 +       struct port_chan *data = d;
8135 +       int fd;
8136 +
8137 +       fd = port_wait(data->kernel_data);
8138 +       if((fd >= 0) && data->raw){
8139 +               tcgetattr(fd, &data->tt);
8140 +               raw(fd, 0);
8141 +       }
8142 +       *dev_out = data->dev;
8143 +       return(fd);
8144 +}
8145 +
8146 +void port_close(int fd, void *d)
8147 +{
8148 +       struct port_chan *data = d;
8149 +
8150 +       port_remove_dev(data->kernel_data);
8151 +       os_close_file(fd);
8152 +}
8153 +
8154 +int port_console_write(int fd, const char *buf, int n, void *d)
8155 +{
8156 +       struct port_chan *data = d;
8157 +
8158 +       return(generic_console_write(fd, buf, n, &data->tt));
8159 +}
8160 +
8161 +struct chan_ops port_ops = {
8162 +       .type           = "port",
8163 +       .init           = port_init,
8164 +       .open           = port_open,
8165 +       .close          = port_close,
8166 +       .read           = generic_read,
8167 +       .write          = generic_write,
8168 +       .console_write  = port_console_write,
8169 +       .window_size    = generic_window_size,
8170 +       .free           = port_free,
8171 +       .winch          = 1,
8172 +};
8173 +
8174 +int port_listen_fd(int port)
8175 +{
8176 +       struct sockaddr_in addr;
8177 +       int fd, err;
8178 +
8179 +       fd = socket(PF_INET, SOCK_STREAM, 0);
8180 +       if(fd == -1) 
8181 +               return(-errno);
8182 +
8183 +       addr.sin_family = AF_INET;
8184 +       addr.sin_port = htons(port);
8185 +       addr.sin_addr.s_addr = htonl(INADDR_ANY);
8186 +       if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
8187 +               err = -errno;
8188 +               goto out;
8189 +       }
8190 +  
8191 +       if(listen(fd, 1) < 0){
8192 +               err = -errno;
8193 +               goto out;
8194 +       }
8195 +
8196 +       err = os_set_fd_block(fd, 0);
8197 +       if(err < 0)
8198 +               goto out;
8199 +
8200 +       return(fd);
8201 + out:
8202 +       os_close_file(fd);
8203 +       return(err);
8204 +}
8205 +
8206 +struct port_pre_exec_data {
8207 +       int sock_fd;
8208 +       int pipe_fd;
8209 +};
8210 +
8211 +void port_pre_exec(void *arg)
8212 +{
8213 +       struct port_pre_exec_data *data = arg;
8214 +
8215 +       dup2(data->sock_fd, 0);
8216 +       dup2(data->sock_fd, 1);
8217 +       dup2(data->sock_fd, 2);
8218 +       os_close_file(data->sock_fd);
8219 +       dup2(data->pipe_fd, 3);
8220 +       os_shutdown_socket(3, 1, 0);
8221 +       os_close_file(data->pipe_fd);
8222 +}
8223 +
8224 +int port_connection(int fd, int *socket, int *pid_out)
8225 +{
8226 +       int new, err;
8227 +       char *argv[] = { "/usr/sbin/in.telnetd", "-L", 
8228 +                        "/usr/lib/uml/port-helper", NULL };
8229 +       struct port_pre_exec_data data;
8230 +
8231 +       new = os_accept_connection(fd);
8232 +       if(new < 0)
8233 +               return(new);
8234 +
8235 +       err = os_pipe(socket, 0, 0);
8236 +       if(err < 0) 
8237 +               goto out_close;
8238 +
8239 +       data = ((struct port_pre_exec_data)
8240 +               { .sock_fd              = new,
8241 +                 .pipe_fd              = socket[1] });
8242 +
8243 +       err = run_helper(port_pre_exec, &data, argv, NULL);
8244 +       if(err < 0) 
8245 +               goto out_shutdown;
8246 +
8247 +       *pid_out = err;
8248 +       return(new);
8249 +
8250 + out_shutdown:
8251 +       os_shutdown_socket(socket[0], 1, 1);
8252 +       os_close_file(socket[0]);
8253 +       os_shutdown_socket(socket[1], 1, 1);    
8254 +       os_close_file(socket[1]);
8255 + out_close:
8256 +       os_close_file(new);
8257 +       return(err);
8258 +}
8259 +
8260 +/*
8261 + * Overrides for Emacs so that we follow Linus's tabbing style.
8262 + * Emacs will notice this stuff at the end of the file and automatically
8263 + * adjust the settings for this buffer only.  This must remain at the end
8264 + * of the file.
8265 + * ---------------------------------------------------------------------------
8266 + * Local variables:
8267 + * c-file-style: "linux"
8268 + * End:
8269 + */
8270 diff -Naur -X ../exclude-files orig/arch/um/drivers/pty.c um/arch/um/drivers/pty.c
8271 --- orig/arch/um/drivers/pty.c  1969-12-31 19:00:00.000000000 -0500
8272 +++ um/arch/um/drivers/pty.c    2003-10-21 03:26:06.000000000 -0400
8273 @@ -0,0 +1,148 @@
8274 +/* 
8275 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
8276 + * Licensed under the GPL
8277 + */
8278 +
8279 +#include <stdio.h>
8280 +#include <unistd.h>
8281 +#include <string.h>
8282 +#include <errno.h>
8283 +#include <termios.h>
8284 +#include "chan_user.h"
8285 +#include "user.h"
8286 +#include "user_util.h"
8287 +#include "kern_util.h"
8288 +#include "os.h"
8289 +
8290 +struct pty_chan {
8291 +       void (*announce)(char *dev_name, int dev);
8292 +       int dev;
8293 +       int raw;
8294 +       struct termios tt;
8295 +       char dev_name[sizeof("/dev/pts/0123456\0")];
8296 +};
8297 +
8298 +void *pty_chan_init(char *str, int device, struct chan_opts *opts)
8299 +{
8300 +       struct pty_chan *data;
8301 +
8302 +       data = um_kmalloc(sizeof(*data));
8303 +       if(data == NULL) return(NULL);
8304 +       *data = ((struct pty_chan) { .announce          = opts->announce, 
8305 +                                    .dev               = device,
8306 +                                    .raw               = opts->raw });
8307 +       return(data);
8308 +}
8309 +
8310 +int pts_open(int input, int output, int primary, void *d, char **dev_out)
8311 +{
8312 +       struct pty_chan *data = d;
8313 +       char *dev;
8314 +       int fd;
8315 +
8316 +       fd = get_pty();
8317 +       if(fd < 0){
8318 +               printk("open_pts : Failed to open pts\n");
8319 +               return(-errno);
8320 +       }
8321 +       if(data->raw){
8322 +               tcgetattr(fd, &data->tt);
8323 +               raw(fd, 0);
8324 +       }
8325 +
8326 +       dev = ptsname(fd);
8327 +       sprintf(data->dev_name, "%s", dev);
8328 +       *dev_out = data->dev_name;
8329 +       if(data->announce) (*data->announce)(dev, data->dev);
8330 +       return(fd);
8331 +}
8332 +
8333 +int getmaster(char *line)
8334 +{
8335 +       char *pty, *bank, *cp;
8336 +       int master, err;
8337 +
8338 +       pty = &line[strlen("/dev/ptyp")];
8339 +       for (bank = "pqrs"; *bank; bank++) {
8340 +               line[strlen("/dev/pty")] = *bank;
8341 +               *pty = '0';
8342 +               if (os_stat_file(line, NULL) < 0)
8343 +                       break;
8344 +               for (cp = "0123456789abcdef"; *cp; cp++) {
8345 +                       *pty = *cp;
8346 +                       master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
8347 +                       if (master >= 0) {
8348 +                               char *tp = &line[strlen("/dev/")];
8349 +
8350 +                               /* verify slave side is usable */
8351 +                               *tp = 't';
8352 +                               err = os_access(line, OS_ACC_RW_OK);
8353 +                               *tp = 'p';
8354 +                               if(err == 0) return(master);
8355 +                               (void) os_close_file(master);
8356 +                       }
8357 +               }
8358 +       }
8359 +       return(-1);
8360 +}
8361 +
8362 +int pty_open(int input, int output, int primary, void *d, char **dev_out)
8363 +{
8364 +       struct pty_chan *data = d;
8365 +       int fd;
8366 +       char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
8367 +
8368 +       fd = getmaster(dev);
8369 +       if(fd < 0) return(-errno);
8370 +       
8371 +       if(data->raw) raw(fd, 0);
8372 +       if(data->announce) (*data->announce)(dev, data->dev);
8373 +
8374 +       sprintf(data->dev_name, "%s", dev);
8375 +       *dev_out = data->dev_name;
8376 +       return(fd);
8377 +}
8378 +
8379 +int pty_console_write(int fd, const char *buf, int n, void *d)
8380 +{
8381 +       struct pty_chan *data = d;
8382 +
8383 +       return(generic_console_write(fd, buf, n, &data->tt));
8384 +}
8385 +
8386 +struct chan_ops pty_ops = {
8387 +       .type           = "pty",
8388 +       .init           = pty_chan_init,
8389 +       .open           = pty_open,
8390 +       .close          = generic_close,
8391 +       .read           = generic_read,
8392 +       .write          = generic_write,
8393 +       .console_write  = pty_console_write,
8394 +       .window_size    = generic_window_size,
8395 +       .free           = generic_free,
8396 +       .winch          = 0,
8397 +};
8398 +
8399 +struct chan_ops pts_ops = {
8400 +       .type           = "pts",
8401 +       .init           = pty_chan_init,
8402 +       .open           = pts_open,
8403 +       .close          = generic_close,
8404 +       .read           = generic_read,
8405 +       .write          = generic_write,
8406 +       .console_write  = pty_console_write,
8407 +       .window_size    = generic_window_size,
8408 +       .free           = generic_free,
8409 +       .winch          = 0,
8410 +};
8411 +
8412 +/*
8413 + * Overrides for Emacs so that we follow Linus's tabbing style.
8414 + * Emacs will notice this stuff at the end of the file and automatically
8415 + * adjust the settings for this buffer only.  This must remain at the end
8416 + * of the file.
8417 + * ---------------------------------------------------------------------------
8418 + * Local variables:
8419 + * c-file-style: "linux"
8420 + * End:
8421 + */
8422 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip.h um/arch/um/drivers/slip.h
8423 --- orig/arch/um/drivers/slip.h 1969-12-31 19:00:00.000000000 -0500
8424 +++ um/arch/um/drivers/slip.h   2003-10-21 03:26:06.000000000 -0400
8425 @@ -0,0 +1,39 @@
8426 +#ifndef __UM_SLIP_H
8427 +#define __UM_SLIP_H
8428 +
8429 +#define BUF_SIZE 1500
8430 + /* two bytes each for a (pathological) max packet of escaped chars +  * 
8431 +  * terminating END char + initial END char                            */
8432 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8433 +
8434 +struct slip_data {
8435 +       void *dev;
8436 +       char name[sizeof("slnnnnn\0")];
8437 +       char *addr;
8438 +       char *gate_addr;
8439 +       int slave;
8440 +       char ibuf[ENC_BUF_SIZE];
8441 +       char obuf[ENC_BUF_SIZE];
8442 +       int more; /* more data: do not read fd until ibuf has been drained */
8443 +       int pos;
8444 +       int esc;
8445 +};
8446 +
8447 +extern struct net_user_info slip_user_info;
8448 +
8449 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8450 +extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
8451 +extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
8452 +
8453 +#endif
8454 +
8455 +/*
8456 + * Overrides for Emacs so that we follow Linus's tabbing style.
8457 + * Emacs will notice this stuff at the end of the file and automatically
8458 + * adjust the settings for this buffer only.  This must remain at the end
8459 + * of the file.
8460 + * ---------------------------------------------------------------------------
8461 + * Local variables:
8462 + * c-file-style: "linux"
8463 + * End:
8464 + */
8465 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_kern.c um/arch/um/drivers/slip_kern.c
8466 --- orig/arch/um/drivers/slip_kern.c    1969-12-31 19:00:00.000000000 -0500
8467 +++ um/arch/um/drivers/slip_kern.c      2003-10-21 03:26:06.000000000 -0400
8468 @@ -0,0 +1,109 @@
8469 +#include "linux/config.h"
8470 +#include "linux/kernel.h"
8471 +#include "linux/stddef.h"
8472 +#include "linux/init.h"
8473 +#include "linux/netdevice.h"
8474 +#include "linux/if_arp.h"
8475 +#include "net_kern.h"
8476 +#include "net_user.h"
8477 +#include "kern.h"
8478 +#include "slip.h"
8479 +
8480 +struct slip_init {
8481 +       char *gate_addr;
8482 +};
8483 +
8484 +void slip_init(struct net_device *dev, void *data)
8485 +{
8486 +       struct uml_net_private *private;
8487 +       struct slip_data *spri;
8488 +       struct slip_init *init = data;
8489 +
8490 +       private = dev->priv;
8491 +       spri = (struct slip_data *) private->user;
8492 +       *spri = ((struct slip_data)
8493 +               { .name         = { '\0' },
8494 +                 .addr         = NULL,
8495 +                 .gate_addr    = init->gate_addr,
8496 +                 .slave        = -1,
8497 +                 .ibuf         = { '\0' },
8498 +                 .obuf         = { '\0' },
8499 +                 .pos          = 0,
8500 +                 .esc          = 0,
8501 +                 .dev          = dev });
8502 +
8503 +       dev->init = NULL;
8504 +       dev->hard_header_len = 0;
8505 +       dev->addr_len = 4;
8506 +       dev->type = ARPHRD_ETHER;
8507 +       dev->tx_queue_len = 256;
8508 +       dev->flags = IFF_NOARP;
8509 +       printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
8510 +}
8511 +
8512 +static unsigned short slip_protocol(struct sk_buff *skbuff)
8513 +{
8514 +       return(htons(ETH_P_IP));
8515 +}
8516 +
8517 +static int slip_read(int fd, struct sk_buff **skb, 
8518 +                      struct uml_net_private *lp)
8519 +{
8520 +       return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 
8521 +                             (struct slip_data *) &lp->user));
8522 +}
8523 +
8524 +static int slip_write(int fd, struct sk_buff **skb,
8525 +                     struct uml_net_private *lp)
8526 +{
8527 +       return(slip_user_write(fd, (*skb)->data, (*skb)->len, 
8528 +                              (struct slip_data *) &lp->user));
8529 +}
8530 +
8531 +struct net_kern_info slip_kern_info = {
8532 +       .init                   = slip_init,
8533 +       .protocol               = slip_protocol,
8534 +       .read                   = slip_read,
8535 +       .write                  = slip_write,
8536 +};
8537 +
8538 +static int slip_setup(char *str, char **mac_out, void *data)
8539 +{
8540 +       struct slip_init *init = data;
8541 +
8542 +       *init = ((struct slip_init)
8543 +               { .gate_addr            = NULL });
8544 +
8545 +       if(str[0] != '\0') 
8546 +               init->gate_addr = str;
8547 +       return(1);
8548 +}
8549 +
8550 +static struct transport slip_transport = {
8551 +       .list           = LIST_HEAD_INIT(slip_transport.list),
8552 +       .name           = "slip",
8553 +       .setup          = slip_setup,
8554 +       .user           = &slip_user_info,
8555 +       .kern           = &slip_kern_info,
8556 +       .private_size   = sizeof(struct slip_data),
8557 +       .setup_size     = sizeof(struct slip_init),
8558 +};
8559 +
8560 +static int register_slip(void)
8561 +{
8562 +       register_transport(&slip_transport);
8563 +       return(1);
8564 +}
8565 +
8566 +__initcall(register_slip);
8567 +
8568 +/*
8569 + * Overrides for Emacs so that we follow Linus's tabbing style.
8570 + * Emacs will notice this stuff at the end of the file and automatically
8571 + * adjust the settings for this buffer only.  This must remain at the end
8572 + * of the file.
8573 + * ---------------------------------------------------------------------------
8574 + * Local variables:
8575 + * c-file-style: "linux"
8576 + * End:
8577 + */
8578 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_proto.h um/arch/um/drivers/slip_proto.h
8579 --- orig/arch/um/drivers/slip_proto.h   1969-12-31 19:00:00.000000000 -0500
8580 +++ um/arch/um/drivers/slip_proto.h     2003-10-21 03:26:06.000000000 -0400
8581 @@ -0,0 +1,93 @@
8582 +/* 
8583 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8584 + * Licensed under the GPL
8585 + */
8586 +
8587 +#ifndef __UM_SLIP_PROTO_H__
8588 +#define __UM_SLIP_PROTO_H__
8589 +
8590 +/* SLIP protocol characters. */
8591 +#define SLIP_END             0300      /* indicates end of frame       */
8592 +#define SLIP_ESC             0333      /* indicates byte stuffing      */
8593 +#define SLIP_ESC_END         0334      /* ESC ESC_END means END 'data' */
8594 +#define SLIP_ESC_ESC         0335      /* ESC ESC_ESC means ESC 'data' */
8595 +
8596 +static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc)
8597 +{
8598 +       int ret;
8599 +
8600 +       switch(c){
8601 +       case SLIP_END:
8602 +               *esc = 0;
8603 +               ret=*pos;
8604 +               *pos=0;
8605 +               return(ret);
8606 +       case SLIP_ESC:
8607 +               *esc = 1;
8608 +               return(0);
8609 +       case SLIP_ESC_ESC:
8610 +               if(*esc){
8611 +                       *esc = 0;
8612 +                       c = SLIP_ESC;
8613 +               }
8614 +               break;
8615 +       case SLIP_ESC_END:
8616 +               if(*esc){
8617 +                       *esc = 0;
8618 +                       c = SLIP_END;
8619 +               }
8620 +               break;
8621 +       }
8622 +       buf[(*pos)++] = c;
8623 +       return(0);
8624 +}
8625 +
8626 +static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
8627 +{
8628 +       unsigned char *ptr = d;
8629 +       unsigned char c;
8630 +
8631 +       /*
8632 +        * Send an initial END character to flush out any
8633 +        * data that may have accumulated in the receiver
8634 +        * due to line noise.
8635 +        */
8636 +
8637 +       *ptr++ = SLIP_END;
8638 +
8639 +       /*
8640 +        * For each byte in the packet, send the appropriate
8641 +        * character sequence, according to the SLIP protocol.
8642 +        */
8643 +
8644 +       while (len-- > 0) {
8645 +               switch(c = *s++) {
8646 +               case SLIP_END:
8647 +                       *ptr++ = SLIP_ESC;
8648 +                       *ptr++ = SLIP_ESC_END;
8649 +                       break;
8650 +               case SLIP_ESC:
8651 +                       *ptr++ = SLIP_ESC;
8652 +                       *ptr++ = SLIP_ESC_ESC;
8653 +                       break;
8654 +               default:
8655 +                       *ptr++ = c;
8656 +                       break;
8657 +               }
8658 +       }
8659 +       *ptr++ = SLIP_END;
8660 +       return (ptr - d);
8661 +}
8662 +
8663 +#endif
8664 +
8665 +/*
8666 + * Overrides for Emacs so that we follow Linus's tabbing style.
8667 + * Emacs will notice this stuff at the end of the file and automatically
8668 + * adjust the settings for this buffer only.  This must remain at the end
8669 + * of the file.
8670 + * ---------------------------------------------------------------------------
8671 + * Local variables:
8672 + * c-file-style: "linux"
8673 + * End:
8674 + */
8675 diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_user.c um/arch/um/drivers/slip_user.c
8676 --- orig/arch/um/drivers/slip_user.c    1969-12-31 19:00:00.000000000 -0500
8677 +++ um/arch/um/drivers/slip_user.c      2003-10-21 03:26:06.000000000 -0400
8678 @@ -0,0 +1,274 @@
8679 +#include <stdio.h>
8680 +#include <stdlib.h>
8681 +#include <unistd.h>
8682 +#include <stddef.h>
8683 +#include <sched.h>
8684 +#include <string.h>
8685 +#include <sys/errno.h>
8686 +#include <sys/termios.h>
8687 +#include <sys/wait.h>
8688 +#include <sys/signal.h>
8689 +#include "user_util.h"
8690 +#include "kern_util.h"
8691 +#include "user.h"
8692 +#include "net_user.h"
8693 +#include "slip.h"
8694 +#include "slip_proto.h"
8695 +#include "helper.h"
8696 +#include "os.h"
8697 +
8698 +void slip_user_init(void *data, void *dev)
8699 +{
8700 +       struct slip_data *pri = data;
8701 +
8702 +       pri->dev = dev;
8703 +}
8704 +
8705 +static int set_up_tty(int fd)
8706 +{
8707 +       int i;
8708 +       struct termios tios;
8709 +
8710 +       if (tcgetattr(fd, &tios) < 0) {
8711 +               printk("could not get initial terminal attributes\n");
8712 +               return(-1);
8713 +       }
8714 +
8715 +       tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
8716 +       tios.c_iflag = IGNBRK | IGNPAR;
8717 +       tios.c_oflag = 0;
8718 +       tios.c_lflag = 0;
8719 +       for (i = 0; i < NCCS; i++)
8720 +               tios.c_cc[i] = 0;
8721 +       tios.c_cc[VMIN] = 1;
8722 +       tios.c_cc[VTIME] = 0;
8723 +
8724 +       cfsetospeed(&tios, B38400);
8725 +       cfsetispeed(&tios, B38400);
8726 +
8727 +       if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
8728 +               printk("failed to set terminal attributes\n");
8729 +               return(-1);
8730 +       }
8731 +       return(0);
8732 +}
8733 +
8734 +struct slip_pre_exec_data {
8735 +       int stdin;
8736 +       int stdout;
8737 +       int close_me;
8738 +};
8739 +
8740 +static void slip_pre_exec(void *arg)
8741 +{
8742 +       struct slip_pre_exec_data *data = arg;
8743 +
8744 +       if(data->stdin >= 0) dup2(data->stdin, 0);
8745 +       dup2(data->stdout, 1);
8746 +       if(data->close_me >= 0) os_close_file(data->close_me);
8747 +}
8748 +
8749 +static int slip_tramp(char **argv, int fd)
8750 +{
8751 +       struct slip_pre_exec_data pe_data;
8752 +       char *output;
8753 +       int status, pid, fds[2], err, output_len;
8754 +
8755 +       err = os_pipe(fds, 1, 0);
8756 +       if(err < 0){
8757 +               printk("slip_tramp : pipe failed, err = %d\n", -err);
8758 +               return(err);
8759 +       }
8760 +
8761 +       err = 0;
8762 +       pe_data.stdin = fd;
8763 +       pe_data.stdout = fds[1];
8764 +       pe_data.close_me = fds[0];
8765 +       pid = run_helper(slip_pre_exec, &pe_data, argv, NULL);
8766 +
8767 +       if(pid < 0) err = pid;
8768 +       else {
8769 +               output_len = page_size();
8770 +               output = um_kmalloc(output_len);
8771 +               if(output == NULL)
8772 +                       printk("slip_tramp : failed to allocate output "
8773 +                              "buffer\n");
8774 +
8775 +               os_close_file(fds[1]);
8776 +               read_output(fds[0], output, output_len);
8777 +               if(output != NULL){
8778 +                       printk("%s", output);
8779 +                       kfree(output);
8780 +               }
8781 +               if(waitpid(pid, &status, 0) < 0) err = errno;
8782 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
8783 +                       printk("'%s' didn't exit with status 0\n", argv[0]);
8784 +                       err = -EINVAL;
8785 +               }
8786 +       }
8787 +       return(err);
8788 +}
8789 +
8790 +static int slip_open(void *data)
8791 +{
8792 +       struct slip_data *pri = data;
8793 +       char version_buf[sizeof("nnnnn\0")];
8794 +       char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
8795 +       char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, 
8796 +                        NULL };
8797 +       int sfd, mfd, err;
8798 +
8799 +       mfd = get_pty();
8800 +       if(mfd < 0){
8801 +               printk("umn : Failed to open pty, err = %d\n", -mfd);
8802 +               return(mfd);
8803 +       }
8804 +       sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
8805 +       if(sfd < 0){
8806 +               printk("Couldn't open tty for slip line, err = %d\n", -sfd);
8807 +               return(sfd);
8808 +       }
8809 +       if(set_up_tty(sfd)) return(-1);
8810 +       pri->slave = sfd;
8811 +       pri->pos = 0;
8812 +       pri->esc = 0;
8813 +       if(pri->gate_addr != NULL){
8814 +               sprintf(version_buf, "%d", UML_NET_VERSION);
8815 +               strcpy(gate_buf, pri->gate_addr);
8816 +
8817 +               err = slip_tramp(argv, sfd);
8818 +
8819 +               if(err < 0){
8820 +                       printk("slip_tramp failed - err = %d\n", -err);
8821 +                       return(err);
8822 +               }
8823 +               err = os_get_ifname(pri->slave, pri->name);
8824 +               if(err < 0){
8825 +                       printk("get_ifname failed, err = %d\n", -err);
8826 +                       return(err);
8827 +               }
8828 +               iter_addresses(pri->dev, open_addr, pri->name);
8829 +       }
8830 +       else {
8831 +               err = os_set_slip(sfd);
8832 +               if(err < 0){
8833 +                       printk("Failed to set slip discipline encapsulation - "
8834 +                              "err = %d\n", -err);
8835 +                       return(err);
8836 +               }
8837 +       }
8838 +       return(mfd);
8839 +}
8840 +
8841 +static void slip_close(int fd, void *data)
8842 +{
8843 +       struct slip_data *pri = data;
8844 +       char version_buf[sizeof("nnnnn\0")];
8845 +       char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, 
8846 +                        NULL };
8847 +       int err;
8848 +
8849 +       if(pri->gate_addr != NULL)
8850 +               iter_addresses(pri->dev, close_addr, pri->name);
8851 +
8852 +       sprintf(version_buf, "%d", UML_NET_VERSION);
8853 +
8854 +       err = slip_tramp(argv, -1);
8855 +
8856 +       if(err != 0)
8857 +               printk("slip_tramp failed - errno = %d\n", -err);
8858 +       os_close_file(fd);
8859 +       os_close_file(pri->slave);
8860 +       pri->slave = -1;
8861 +}
8862 +
8863 +int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
8864 +{
8865 +       int i, n, size, start;
8866 +
8867 +       if(pri->more>0) {
8868 +               i = 0;
8869 +               while(i < pri->more) {
8870 +                       size = slip_unesc(pri->ibuf[i++],
8871 +                                       pri->ibuf, &pri->pos, &pri->esc);
8872 +                       if(size){
8873 +                               memcpy(buf, pri->ibuf, size);
8874 +                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
8875 +                               pri->more=pri->more-i; 
8876 +                               return(size);
8877 +                       }
8878 +               }
8879 +               pri->more=0;
8880 +       }
8881 +
8882 +       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
8883 +       if(n <= 0) return(n);
8884 +
8885 +       start = pri->pos;
8886 +       for(i = 0; i < n; i++){
8887 +               size = slip_unesc(pri->ibuf[start + i],
8888 +                               pri->ibuf, &pri->pos, &pri->esc);
8889 +               if(size){
8890 +                       memcpy(buf, pri->ibuf, size);
8891 +                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
8892 +                       pri->more=n-(i+1); 
8893 +                       return(size);
8894 +               }
8895 +       }
8896 +       return(0);
8897 +}
8898 +
8899 +int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
8900 +{
8901 +       int actual, n;
8902 +
8903 +       actual = slip_esc(buf, pri->obuf, len);
8904 +       n = net_write(fd, pri->obuf, actual);
8905 +       if(n < 0) return(n);
8906 +       else return(len);
8907 +}
8908 +
8909 +static int slip_set_mtu(int mtu, void *data)
8910 +{
8911 +       return(mtu);
8912 +}
8913 +
8914 +static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
8915 +                         void *data)
8916 +{
8917 +       struct slip_data *pri = data;
8918 +
8919 +       if(pri->slave < 0) return;
8920 +       open_addr(addr, netmask, pri->name);
8921 +}
8922 +
8923 +static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
8924 +                           void *data)
8925 +{
8926 +       struct slip_data *pri = data;
8927 +
8928 +       if(pri->slave < 0) return;
8929 +       close_addr(addr, netmask, pri->name);
8930 +}
8931 +
8932 +struct net_user_info slip_user_info = {
8933 +       .init           = slip_user_init,
8934 +       .open           = slip_open,
8935 +       .close          = slip_close,
8936 +       .remove         = NULL,
8937 +       .set_mtu        = slip_set_mtu,
8938 +       .add_address    = slip_add_addr,
8939 +       .delete_address = slip_del_addr,
8940 +       .max_packet     = BUF_SIZE
8941 +};
8942 +
8943 +/*
8944 + * Overrides for Emacs so that we follow Linus's tabbing style.
8945 + * Emacs will notice this stuff at the end of the file and automatically
8946 + * adjust the settings for this buffer only.  This must remain at the end
8947 + * of the file.
8948 + * ---------------------------------------------------------------------------
8949 + * Local variables:
8950 + * c-file-style: "linux"
8951 + * End:
8952 + */
8953 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp.h um/arch/um/drivers/slirp.h
8954 --- orig/arch/um/drivers/slirp.h        1969-12-31 19:00:00.000000000 -0500
8955 +++ um/arch/um/drivers/slirp.h  2003-10-21 03:26:06.000000000 -0400
8956 @@ -0,0 +1,51 @@
8957 +#ifndef __UM_SLIRP_H
8958 +#define __UM_SLIRP_H
8959 +
8960 +#define BUF_SIZE 1500
8961 + /* two bytes each for a (pathological) max packet of escaped chars +  * 
8962 +  * terminating END char + initial END char                            */
8963 +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8964 +
8965 +#define SLIRP_MAX_ARGS 100
8966 +/*
8967 + * XXX this next definition is here because I don't understand why this
8968 + * initializer doesn't work in slirp_kern.c:
8969 + *
8970 + *   argv :  { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] },
8971 + *
8972 + * or why I can't typecast like this:
8973 + *
8974 + *   argv :  (char* [SLIRP_MAX_ARGS])(init->argv), 
8975 + */
8976 +struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; };
8977 +
8978 +struct slirp_data {
8979 +       void *dev;
8980 +       struct arg_list_dummy_wrapper argw;
8981 +       int pid;
8982 +       int slave;
8983 +       char ibuf[ENC_BUF_SIZE];
8984 +       char obuf[ENC_BUF_SIZE];
8985 +       int more; /* more data: do not read fd until ibuf has been drained */
8986 +       int pos;
8987 +       int esc;
8988 +};
8989 +
8990 +extern struct net_user_info slirp_user_info;
8991 +
8992 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
8993 +extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
8994 +extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri);
8995 +
8996 +#endif
8997 +
8998 +/*
8999 + * Overrides for Emacs so that we follow Linus's tabbing style.
9000 + * Emacs will notice this stuff at the end of the file and automatically
9001 + * adjust the settings for this buffer only.  This must remain at the end
9002 + * of the file.
9003 + * ---------------------------------------------------------------------------
9004 + * Local variables:
9005 + * c-file-style: "linux"
9006 + * End:
9007 + */
9008 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_kern.c um/arch/um/drivers/slirp_kern.c
9009 --- orig/arch/um/drivers/slirp_kern.c   1969-12-31 19:00:00.000000000 -0500
9010 +++ um/arch/um/drivers/slirp_kern.c     2003-10-21 03:26:06.000000000 -0400
9011 @@ -0,0 +1,132 @@
9012 +#include "linux/kernel.h"
9013 +#include "linux/stddef.h"
9014 +#include "linux/init.h"
9015 +#include "linux/netdevice.h"
9016 +#include "linux/if_arp.h"
9017 +#include "net_kern.h"
9018 +#include "net_user.h"
9019 +#include "kern.h"
9020 +#include "slirp.h"
9021 +
9022 +struct slirp_init {
9023 +       struct arg_list_dummy_wrapper argw;  /* XXX should be simpler... */
9024 +};
9025 +
9026 +void slirp_init(struct net_device *dev, void *data)
9027 +{
9028 +       struct uml_net_private *private;
9029 +       struct slirp_data *spri;
9030 +       struct slirp_init *init = data;
9031 +       int i;
9032 +
9033 +       private = dev->priv;
9034 +       spri = (struct slirp_data *) private->user;
9035 +       *spri = ((struct slirp_data)
9036 +               { .argw         = init->argw,
9037 +                 .pid          = -1,
9038 +                 .slave        = -1,
9039 +                 .ibuf         = { '\0' },
9040 +                 .obuf         = { '\0' },
9041 +                 .pos          = 0,
9042 +                 .esc          = 0,
9043 +                 .dev          = dev });
9044 +
9045 +       dev->init = NULL;
9046 +       dev->hard_header_len = 0;
9047 +       dev->addr_len = 4;
9048 +       dev->type = ARPHRD_ETHER;
9049 +       dev->tx_queue_len = 256;
9050 +       dev->flags = IFF_NOARP;
9051 +       printk("SLIRP backend - command line:");
9052 +       for(i=0;spri->argw.argv[i]!=NULL;i++) {
9053 +               printk(" '%s'",spri->argw.argv[i]);
9054 +       }
9055 +       printk("\n");
9056 +}
9057 +
9058 +static unsigned short slirp_protocol(struct sk_buff *skbuff)
9059 +{
9060 +       return(htons(ETH_P_IP));
9061 +}
9062 +
9063 +static int slirp_read(int fd, struct sk_buff **skb, 
9064 +                      struct uml_net_private *lp)
9065 +{
9066 +       return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, 
9067 +                             (struct slirp_data *) &lp->user));
9068 +}
9069 +
9070 +static int slirp_write(int fd, struct sk_buff **skb,
9071 +                     struct uml_net_private *lp)
9072 +{
9073 +       return(slirp_user_write(fd, (*skb)->data, (*skb)->len, 
9074 +                              (struct slirp_data *) &lp->user));
9075 +}
9076 +
9077 +struct net_kern_info slirp_kern_info = {
9078 +       .init                   = slirp_init,
9079 +       .protocol               = slirp_protocol,
9080 +       .read                   = slirp_read,
9081 +       .write                  = slirp_write,
9082 +};
9083 +
9084 +static int slirp_setup(char *str, char **mac_out, void *data)
9085 +{
9086 +       struct slirp_init *init = data;
9087 +       int i=0;
9088 +
9089 +       *init = ((struct slirp_init)
9090 +               { argw :                { { "slirp", NULL  } } });
9091 +
9092 +       str = split_if_spec(str, mac_out, NULL);
9093 +
9094 +       if(str == NULL) { /* no command line given after MAC addr */
9095 +               return(1);
9096 +       }
9097 +
9098 +       do {
9099 +               if(i>=SLIRP_MAX_ARGS-1) {
9100 +                       printk("slirp_setup: truncating slirp arguments\n");
9101 +                       break;
9102 +               }
9103 +               init->argw.argv[i++] = str;
9104 +               while(*str && *str!=',') {
9105 +                       if(*str=='_') *str=' ';
9106 +                       str++;
9107 +               }
9108 +               if(*str!=',')
9109 +                       break;
9110 +               *str++='\0';
9111 +       } while(1);
9112 +       init->argw.argv[i]=NULL;
9113 +       return(1);
9114 +}
9115 +
9116 +static struct transport slirp_transport = {
9117 +       .list           = LIST_HEAD_INIT(slirp_transport.list),
9118 +       .name           = "slirp",
9119 +       .setup          = slirp_setup,
9120 +       .user           = &slirp_user_info,
9121 +       .kern           = &slirp_kern_info,
9122 +       .private_size   = sizeof(struct slirp_data),
9123 +       .setup_size     = sizeof(struct slirp_init),
9124 +};
9125 +
9126 +static int register_slirp(void)
9127 +{
9128 +       register_transport(&slirp_transport);
9129 +       return(1);
9130 +}
9131 +
9132 +__initcall(register_slirp);
9133 +
9134 +/*
9135 + * Overrides for Emacs so that we follow Linus's tabbing style.
9136 + * Emacs will notice this stuff at the end of the file and automatically
9137 + * adjust the settings for this buffer only.  This must remain at the end
9138 + * of the file.
9139 + * ---------------------------------------------------------------------------
9140 + * Local variables:
9141 + * c-file-style: "linux"
9142 + * End:
9143 + */
9144 diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_user.c um/arch/um/drivers/slirp_user.c
9145 --- orig/arch/um/drivers/slirp_user.c   1969-12-31 19:00:00.000000000 -0500
9146 +++ um/arch/um/drivers/slirp_user.c     2003-10-21 03:26:06.000000000 -0400
9147 @@ -0,0 +1,201 @@
9148 +#include <stdio.h>
9149 +#include <stdlib.h>
9150 +#include <unistd.h>
9151 +#include <stddef.h>
9152 +#include <sched.h>
9153 +#include <string.h>
9154 +#include <sys/errno.h>
9155 +#include <sys/wait.h>
9156 +#include <sys/signal.h>
9157 +#include "user_util.h"
9158 +#include "kern_util.h"
9159 +#include "user.h"
9160 +#include "net_user.h"
9161 +#include "slirp.h"
9162 +#include "slip_proto.h"
9163 +#include "helper.h"
9164 +#include "os.h"
9165 +
9166 +void slirp_user_init(void *data, void *dev)
9167 +{
9168 +       struct slirp_data *pri = data;
9169 +
9170 +       pri->dev = dev;
9171 +}
9172 +
9173 +struct slirp_pre_exec_data {
9174 +       int stdin;
9175 +       int stdout;
9176 +};
9177 +
9178 +static void slirp_pre_exec(void *arg)
9179 +{
9180 +       struct slirp_pre_exec_data *data = arg;
9181 +
9182 +       if(data->stdin != -1) dup2(data->stdin, 0);
9183 +       if(data->stdout != -1) dup2(data->stdout, 1);
9184 +}
9185 +
9186 +static int slirp_tramp(char **argv, int fd)
9187 +{
9188 +       struct slirp_pre_exec_data pe_data;
9189 +       int pid;
9190 +
9191 +       pe_data.stdin = fd;
9192 +       pe_data.stdout = fd;
9193 +       pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL);
9194 +
9195 +       return(pid);
9196 +}
9197 +
9198 +/* XXX This is just a trivial wrapper around os_pipe */ 
9199 +static int slirp_datachan(int *mfd, int *sfd)
9200 +{
9201 +       int fds[2], err;
9202 +
9203 +       err = os_pipe(fds, 1, 1);
9204 +       if(err < 0){
9205 +               printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
9206 +               return(err);
9207 +       }
9208 +
9209 +       *mfd = fds[0];
9210 +       *sfd = fds[1];
9211 +       return(0);
9212 +}
9213 +
9214 +static int slirp_open(void *data)
9215 +{
9216 +       struct slirp_data *pri = data;
9217 +       int sfd, mfd, pid, err;
9218 +
9219 +       err = slirp_datachan(&mfd, &sfd);
9220 +       if(err)
9221 +               return(err);
9222 +
9223 +       pid = slirp_tramp(pri->argw.argv, sfd);
9224 +
9225 +       if(pid < 0){
9226 +               printk("slirp_tramp failed - errno = %d\n", -pid);
9227 +               os_close_file(sfd);     
9228 +               os_close_file(mfd);     
9229 +               return(pid);
9230 +       }
9231 +
9232 +       pri->slave = sfd;
9233 +       pri->pos = 0;
9234 +       pri->esc = 0;
9235 +
9236 +       pri->pid = pid;
9237 +
9238 +       return(mfd);
9239 +}
9240 +
9241 +static void slirp_close(int fd, void *data)
9242 +{
9243 +       struct slirp_data *pri = data;
9244 +       int status,err;
9245 +
9246 +       os_close_file(fd);
9247 +       os_close_file(pri->slave);
9248 +
9249 +       pri->slave = -1;
9250 +
9251 +       if(pri->pid<1) {
9252 +               printk("slirp_close: no child process to shut down\n");
9253 +               return;
9254 +       }
9255 +
9256 +#if 0
9257 +       if(kill(pri->pid, SIGHUP)<0) {
9258 +               printk("slirp_close: sending hangup to %d failed (%d)\n",
9259 +                       pri->pid, errno);
9260 +       }
9261 +#endif
9262 +
9263 +       err = waitpid(pri->pid, &status, WNOHANG);
9264 +       if(err<0) {
9265 +               printk("slirp_close: waitpid returned %d\n", errno);
9266 +               return;
9267 +       }
9268 +
9269 +       if(err==0) {
9270 +               printk("slirp_close: process %d has not exited\n");
9271 +               return;
9272 +       }
9273 +
9274 +       pri->pid = -1;
9275 +}
9276 +
9277 +int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
9278 +{
9279 +       int i, n, size, start;
9280 +
9281 +       if(pri->more>0) {
9282 +               i = 0;
9283 +               while(i < pri->more) {
9284 +                       size = slip_unesc(pri->ibuf[i++],
9285 +                                       pri->ibuf,&pri->pos,&pri->esc);
9286 +                       if(size){
9287 +                               memcpy(buf, pri->ibuf, size);
9288 +                               memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
9289 +                               pri->more=pri->more-i; 
9290 +                               return(size);
9291 +                       }
9292 +               }
9293 +               pri->more=0;
9294 +       }
9295 +
9296 +       n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
9297 +       if(n <= 0) return(n);
9298 +
9299 +       start = pri->pos;
9300 +       for(i = 0; i < n; i++){
9301 +               size = slip_unesc(pri->ibuf[start + i],
9302 +                               pri->ibuf,&pri->pos,&pri->esc);
9303 +               if(size){
9304 +                       memcpy(buf, pri->ibuf, size);
9305 +                       memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
9306 +                       pri->more=n-(i+1); 
9307 +                       return(size);
9308 +               }
9309 +       }
9310 +       return(0);
9311 +}
9312 +
9313 +int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
9314 +{
9315 +       int actual, n;
9316 +
9317 +       actual = slip_esc(buf, pri->obuf, len);
9318 +       n = net_write(fd, pri->obuf, actual);
9319 +       if(n < 0) return(n);
9320 +       else return(len);
9321 +}
9322 +
9323 +static int slirp_set_mtu(int mtu, void *data)
9324 +{
9325 +       return(mtu);
9326 +}
9327 +
9328 +struct net_user_info slirp_user_info = {
9329 +       .init           = slirp_user_init,
9330 +       .open           = slirp_open,
9331 +       .close          = slirp_close,
9332 +       .remove         = NULL,
9333 +       .set_mtu        = slirp_set_mtu,
9334 +       .add_address    = NULL,
9335 +       .delete_address = NULL,
9336 +       .max_packet     = BUF_SIZE
9337 +};
9338 +
9339 +/*
9340 + * Overrides for Emacs so that we follow Linus's tabbing style.
9341 + * Emacs will notice this stuff at the end of the file and automatically
9342 + * adjust the settings for this buffer only.  This must remain at the end
9343 + * of the file.
9344 + * ---------------------------------------------------------------------------
9345 + * Local variables:
9346 + * c-file-style: "linux"
9347 + * End:
9348 + */
9349 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.c um/arch/um/drivers/ssl.c
9350 --- orig/arch/um/drivers/ssl.c  1969-12-31 19:00:00.000000000 -0500
9351 +++ um/arch/um/drivers/ssl.c    2003-11-08 02:57:02.000000000 -0500
9352 @@ -0,0 +1,306 @@
9353 +/* 
9354 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
9355 + * Licensed under the GPL
9356 + */
9357 +
9358 +#include "linux/config.h"
9359 +#include "linux/fs.h"
9360 +#include "linux/tty.h"
9361 +#include "linux/tty_driver.h"
9362 +#include "linux/major.h"
9363 +#include "linux/mm.h"
9364 +#include "linux/init.h"
9365 +#include "linux/console.h"
9366 +#include "asm/termbits.h"
9367 +#include "asm/irq.h"
9368 +#include "line.h"
9369 +#include "ssl.h"
9370 +#include "chan_kern.h"
9371 +#include "user_util.h"
9372 +#include "kern_util.h"
9373 +#include "kern.h"
9374 +#include "init.h"
9375 +#include "irq_user.h"
9376 +#include "mconsole_kern.h"
9377 +#include "2_5compat.h"
9378 +
9379 +static int ssl_version = 1;
9380 +
9381 +/* Referenced only by tty_driver below - presumably it's locked correctly
9382 + * by the tty driver.
9383 + */
9384 +static int ssl_refcount = 0;
9385 +
9386 +static struct tty_driver ssl_driver;
9387 +
9388 +#define NR_PORTS 64
9389 +
9390 +void ssl_announce(char *dev_name, int dev)
9391 +{
9392 +       printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev,
9393 +              dev_name);
9394 +}
9395 +
9396 +static struct chan_opts opts = {
9397 +       .announce       = ssl_announce,
9398 +       .xterm_title    = "Serial Line #%d",
9399 +       .raw            = 1,
9400 +       .tramp_stack    = 0,
9401 +       .in_kernel      = 1,
9402 +};
9403 +
9404 +static int ssl_config(char *str);
9405 +static int ssl_get_config(char *dev, char *str, int size, char **error_out);
9406 +static int ssl_remove(char *str);
9407 +
9408 +static struct line_driver driver = {
9409 +       .name                   = "UML serial line",
9410 +       .devfs_name             = "tts/%d",
9411 +       .major                  = TTY_MAJOR,
9412 +       .minor_start            = 64,
9413 +       .type                   = TTY_DRIVER_TYPE_SERIAL,
9414 +       .subtype                = 0,
9415 +       .read_irq               = SSL_IRQ,
9416 +       .read_irq_name          = "ssl",
9417 +       .write_irq              = SSL_WRITE_IRQ,
9418 +       .write_irq_name         = "ssl-write",
9419 +       .symlink_from           = "serial",
9420 +       .symlink_to             = "tts",
9421 +       .mc  = {
9422 +               .name           = "ssl",
9423 +               .config         = ssl_config,
9424 +               .get_config     = ssl_get_config,
9425 +               .remove         = ssl_remove,
9426 +       },
9427 +};
9428 +
9429 +/* The array is initialized by line_init, which is an initcall.  The 
9430 + * individual elements are protected by individual semaphores.
9431 + */
9432 +static struct line serial_lines[NR_PORTS] =
9433 +       { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
9434 +
9435 +static struct lines lines = LINES_INIT(NR_PORTS);
9436 +
9437 +static int ssl_config(char *str)
9438 +{
9439 +       return(line_config(serial_lines, 
9440 +                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9441 +}
9442 +
9443 +static int ssl_get_config(char *dev, char *str, int size, char **error_out)
9444 +{
9445 +       return(line_get_config(dev, serial_lines, 
9446 +                              sizeof(serial_lines)/sizeof(serial_lines[0]), 
9447 +                              str, size, error_out));
9448 +}
9449 +
9450 +static int ssl_remove(char *str)
9451 +{
9452 +       return(line_remove(serial_lines, 
9453 +                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
9454 +}
9455 +
9456 +int ssl_open(struct tty_struct *tty, struct file *filp)
9457 +{
9458 +       return(line_open(serial_lines, tty, &opts));
9459 +}
9460 +
9461 +static void ssl_close(struct tty_struct *tty, struct file * filp)
9462 +{
9463 +       line_close(serial_lines, tty);
9464 +}
9465 +
9466 +static int ssl_write(struct tty_struct * tty, int from_user,
9467 +                    const unsigned char *buf, int count)
9468 +{
9469 +       return(line_write(serial_lines, tty, from_user, buf, count));
9470 +}
9471 +
9472 +static void ssl_put_char(struct tty_struct *tty, unsigned char ch)
9473 +{
9474 +       line_write(serial_lines, tty, 0, &ch, sizeof(ch));
9475 +}
9476 +
9477 +static void ssl_flush_chars(struct tty_struct *tty)
9478 +{
9479 +       return;
9480 +}
9481 +
9482 +static int ssl_chars_in_buffer(struct tty_struct *tty)
9483 +{
9484 +       return(0);
9485 +}
9486 +
9487 +static void ssl_flush_buffer(struct tty_struct *tty)
9488 +{
9489 +       return;
9490 +}
9491 +
9492 +static int ssl_ioctl(struct tty_struct *tty, struct file * file,
9493 +                    unsigned int cmd, unsigned long arg)
9494 +{
9495 +       int ret;
9496 +
9497 +       ret = 0;
9498 +       switch(cmd){
9499 +       case TCGETS:
9500 +       case TCSETS:
9501 +       case TCFLSH:
9502 +       case TCSETSF:
9503 +       case TCSETSW:
9504 +       case TCGETA:
9505 +       case TIOCMGET:
9506 +       case TCSBRK:
9507 +       case TCSBRKP:
9508 +       case TIOCMSET:
9509 +               ret = -ENOIOCTLCMD;
9510 +               break;
9511 +       default:
9512 +               printk(KERN_ERR 
9513 +                      "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd);
9514 +               ret = -ENOIOCTLCMD;
9515 +               break;
9516 +       }
9517 +       return(ret);
9518 +}
9519 +
9520 +static void ssl_throttle(struct tty_struct * tty)
9521 +{
9522 +       printk(KERN_ERR "Someone should implement ssl_throttle\n");
9523 +}
9524 +
9525 +static void ssl_unthrottle(struct tty_struct * tty)
9526 +{
9527 +       printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
9528 +}
9529 +
9530 +static void ssl_set_termios(struct tty_struct *tty, 
9531 +                           struct termios *old_termios)
9532 +{
9533 +}
9534 +
9535 +static void ssl_stop(struct tty_struct *tty)
9536 +{
9537 +       printk(KERN_ERR "Someone should implement ssl_stop\n");
9538 +}
9539 +
9540 +static void ssl_start(struct tty_struct *tty)
9541 +{
9542 +       printk(KERN_ERR "Someone should implement ssl_start\n");
9543 +}
9544 +
9545 +void ssl_hangup(struct tty_struct *tty)
9546 +{
9547 +}
9548 +
9549 +static struct tty_driver ssl_driver = {
9550 +       .refcount               = &ssl_refcount,
9551 +       .open                   = ssl_open,
9552 +       .close                  = ssl_close,
9553 +       .write                  = ssl_write,
9554 +       .put_char               = ssl_put_char,
9555 +       .flush_chars            = ssl_flush_chars,
9556 +       .chars_in_buffer        = ssl_chars_in_buffer,
9557 +       .flush_buffer           = ssl_flush_buffer,
9558 +       .ioctl                  = ssl_ioctl,
9559 +       .throttle               = ssl_throttle,
9560 +       .unthrottle             = ssl_unthrottle,
9561 +       .set_termios            = ssl_set_termios,
9562 +       .stop                   = ssl_stop,
9563 +       .start                  = ssl_start,
9564 +       .hangup                 = ssl_hangup
9565 +};
9566 +
9567 +/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
9568 + * by being an initcall and exitcall, respectively.
9569 + */
9570 +static int ssl_init_done = 0;
9571 +
9572 +static void ssl_console_write(struct console *c, const char *string, 
9573 +                             unsigned len)
9574 +{
9575 +       struct line *line = &serial_lines[c->index];
9576 +       if(ssl_init_done)
9577 +               down(&line->sem);
9578 +       console_write_chan(&line->chan_list, string, len);
9579 +       if(ssl_init_done)
9580 +               up(&line->sem);
9581 +}
9582 +
9583 +static kdev_t ssl_console_device(struct console *c)
9584 +{
9585 +#if 0 /* This is the 2.5 implementation */
9586 +static struct tty_driver *ssl_console_device(struct console *c, int *index)
9587 +       *index = c->index;
9588 +       return ssl_driver;
9589 +#endif
9590 +
9591 +       return mk_kdev(TTY_MAJOR, c->index);
9592 +}
9593 +
9594 +static int ssl_console_setup(struct console *co, char *options)
9595 +{
9596 +       return(0);
9597 +}
9598 +
9599 +static struct console ssl_cons = {
9600 +       name:           "ttyS",
9601 +       write:          ssl_console_write,
9602 +       device:         ssl_console_device,
9603 +       setup:          ssl_console_setup,
9604 +       flags:          CON_PRINTBUFFER,
9605 +       index:          -1,
9606 +};
9607 +
9608 +int ssl_init(void)
9609 +{
9610 +       char *new_title;
9611 +
9612 +       printk(KERN_INFO "Initializing software serial port version %d\n", 
9613 +              ssl_version);
9614 +
9615 +       line_register_devfs(&lines, &driver, &ssl_driver, serial_lines, 
9616 +                           sizeof(serial_lines)/sizeof(serial_lines[0]));
9617 +
9618 +       lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
9619 +
9620 +       new_title = add_xterm_umid(opts.xterm_title);
9621 +       if(new_title != NULL) opts.xterm_title = new_title;
9622 +
9623 +       register_console(&ssl_cons);
9624 +       ssl_init_done = 1;
9625 +       return(0);
9626 +}
9627 +
9628 +__initcall(ssl_init);
9629 +
9630 +static int ssl_chan_setup(char *str)
9631 +{
9632 +       return(line_setup(serial_lines, 
9633 +                         sizeof(serial_lines)/sizeof(serial_lines[0]), 
9634 +                         str, 1));
9635 +}
9636 +
9637 +__setup("ssl", ssl_chan_setup);
9638 +__channel_help(ssl_chan_setup, "ssl");
9639 +
9640 +static void ssl_exit(void)
9641 +{
9642 +       if(!ssl_init_done) return;
9643 +       close_lines(serial_lines, 
9644 +                   sizeof(serial_lines)/sizeof(serial_lines[0]));
9645 +}
9646 +
9647 +__uml_exitcall(ssl_exit);
9648 +
9649 +/*
9650 + * Overrides for Emacs so that we follow Linus's tabbing style.
9651 + * Emacs will notice this stuff at the end of the file and automatically
9652 + * adjust the settings for this buffer only.  This must remain at the end
9653 + * of the file.
9654 + * ---------------------------------------------------------------------------
9655 + * Local variables:
9656 + * c-file-style: "linux"
9657 + * End:
9658 + */
9659 diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.h um/arch/um/drivers/ssl.h
9660 --- orig/arch/um/drivers/ssl.h  1969-12-31 19:00:00.000000000 -0500
9661 +++ um/arch/um/drivers/ssl.h    2003-10-21 03:26:06.000000000 -0400
9662 @@ -0,0 +1,23 @@
9663 +/* 
9664 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9665 + * Licensed under the GPL
9666 + */
9667 +
9668 +#ifndef __SSL_H__
9669 +#define __SSL_H__
9670 +
9671 +extern int ssl_read(int fd, int line);
9672 +extern void ssl_receive_char(int line, char ch);
9673 +
9674 +#endif
9675 +
9676 +/*
9677 + * Overrides for Emacs so that we follow Linus's tabbing style.
9678 + * Emacs will notice this stuff at the end of the file and automatically
9679 + * adjust the settings for this buffer only.  This must remain at the end
9680 + * of the file.
9681 + * ---------------------------------------------------------------------------
9682 + * Local variables:
9683 + * c-file-style: "linux"
9684 + * End:
9685 + */
9686 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.c um/arch/um/drivers/stdio_console.c
9687 --- orig/arch/um/drivers/stdio_console.c        1969-12-31 19:00:00.000000000 -0500
9688 +++ um/arch/um/drivers/stdio_console.c  2003-11-07 03:03:03.000000000 -0500
9689 @@ -0,0 +1,258 @@
9690 +/* 
9691 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
9692 + * Licensed under the GPL
9693 + */
9694 +
9695 +#include "linux/config.h"
9696 +#include "linux/posix_types.h"
9697 +#include "linux/tty.h"
9698 +#include "linux/tty_flip.h"
9699 +#include "linux/types.h"
9700 +#include "linux/major.h"
9701 +#include "linux/kdev_t.h"
9702 +#include "linux/console.h"
9703 +#include "linux/string.h"
9704 +#include "linux/sched.h"
9705 +#include "linux/list.h"
9706 +#include "linux/init.h"
9707 +#include "linux/interrupt.h"
9708 +#include "linux/slab.h"
9709 +#include "asm/current.h"
9710 +#include "asm/softirq.h"
9711 +#include "asm/hardirq.h"
9712 +#include "asm/irq.h"
9713 +#include "stdio_console.h"
9714 +#include "line.h"
9715 +#include "chan_kern.h"
9716 +#include "user_util.h"
9717 +#include "kern_util.h"
9718 +#include "irq_user.h"
9719 +#include "mconsole_kern.h"
9720 +#include "init.h"
9721 +#include "2_5compat.h"
9722 +
9723 +#define MAX_TTYS (8)
9724 +
9725 +/* Referenced only by tty_driver below - presumably it's locked correctly
9726 + * by the tty driver.
9727 + */
9728 +
9729 +static struct tty_driver console_driver;
9730 +
9731 +static int console_refcount = 0;
9732 +
9733 +static struct chan_ops init_console_ops = {
9734 +       .type           = "you shouldn't see this",
9735 +       .init           = NULL,
9736 +       .open           = NULL,
9737 +       .close          = NULL,
9738 +       .read           = NULL,
9739 +       .write          = NULL,
9740 +       .console_write  = generic_write,
9741 +       .window_size    = NULL,
9742 +       .free           = NULL,
9743 +       .winch          = 0,
9744 +};
9745 +
9746 +static struct chan init_console_chan = {
9747 +       .list           = { },
9748 +       .primary        = 1,
9749 +       .input          = 0,
9750 +       .output         = 1,
9751 +       .opened         = 1,
9752 +       .fd             = 1,
9753 +       .pri            = INIT_STATIC,
9754 +       .ops            = &init_console_ops,
9755 +       .data           = NULL
9756 +};
9757 +
9758 +void stdio_announce(char *dev_name, int dev)
9759 +{
9760 +       printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
9761 +              dev_name);
9762 +}
9763 +
9764 +static struct chan_opts opts = {
9765 +       .announce       = stdio_announce,
9766 +       .xterm_title    = "Virtual Console #%d",
9767 +       .raw            = 1,
9768 +       .tramp_stack    = 0,
9769 +       .in_kernel      = 1,
9770 +};
9771 +
9772 +static int con_config(char *str);
9773 +static int con_get_config(char *dev, char *str, int size, char **error_out);
9774 +static int con_remove(char *str);
9775 +
9776 +static struct line_driver driver = {
9777 +       .name                   = "UML console",
9778 +       .devfs_name             = "vc/%d",
9779 +       .major                  = TTY_MAJOR,
9780 +       .minor_start            = 0,
9781 +       .type                   = TTY_DRIVER_TYPE_CONSOLE,
9782 +       .subtype                = SYSTEM_TYPE_CONSOLE,
9783 +       .read_irq               = CONSOLE_IRQ,
9784 +       .read_irq_name          = "console",
9785 +       .write_irq              = CONSOLE_WRITE_IRQ,
9786 +       .write_irq_name         = "console-write",
9787 +       .symlink_from           = "ttys",
9788 +       .symlink_to             = "vc",
9789 +       .mc  = {
9790 +               .name           = "con",
9791 +               .config         = con_config,
9792 +               .get_config     = con_get_config,
9793 +               .remove         = con_remove,
9794 +       },
9795 +};
9796 +
9797 +static struct lines console_lines = LINES_INIT(MAX_TTYS);
9798 +
9799 +/* The array is initialized by line_init, which is an initcall.  The 
9800 + * individual elements are protected by individual semaphores.
9801 + */
9802 +struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
9803 +                             [ 1 ... MAX_TTYS - 1 ] = 
9804 +                             LINE_INIT(CONFIG_CON_CHAN, &driver) };
9805 +
9806 +static int con_config(char *str)
9807 +{
9808 +       return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
9809 +}
9810 +
9811 +static int con_get_config(char *dev, char *str, int size, char **error_out)
9812 +{
9813 +       return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str, 
9814 +                              size, error_out));
9815 +}
9816 +
9817 +static int con_remove(char *str)
9818 +{
9819 +       return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
9820 +}
9821 +
9822 +static int open_console(struct tty_struct *tty)
9823 +{
9824 +       return(line_open(vts, tty, &opts));
9825 +}
9826 +
9827 +static int con_open(struct tty_struct *tty, struct file *filp)
9828 +{
9829 +       return(open_console(tty));
9830 +}
9831 +
9832 +static void con_close(struct tty_struct *tty, struct file *filp)
9833 +{
9834 +       line_close(vts, tty);
9835 +}
9836 +
9837 +static int con_write(struct tty_struct *tty, int from_user, 
9838 +                    const unsigned char *buf, int count)
9839 +{
9840 +        return(line_write(vts, tty, from_user, buf, count));
9841 +}
9842 +
9843 +static void set_termios(struct tty_struct *tty, struct termios * old)
9844 +{
9845 +}
9846 +
9847 +static int chars_in_buffer(struct tty_struct *tty)
9848 +{
9849 +       return(0);
9850 +}
9851 +
9852 +static int con_init_done = 0;
9853 +
9854 +int stdio_init(void)
9855 +{
9856 +       char *new_title;
9857 +
9858 +       printk(KERN_INFO "Initializing stdio console driver\n");
9859 +
9860 +       line_register_devfs(&console_lines, &driver, &console_driver, vts, 
9861 +                           sizeof(vts)/sizeof(vts[0]));
9862 +
9863 +       lines_init(vts, sizeof(vts)/sizeof(vts[0]));
9864 +
9865 +       new_title = add_xterm_umid(opts.xterm_title);
9866 +       if(new_title != NULL) opts.xterm_title = new_title;
9867 +
9868 +       open_console(NULL);
9869 +       con_init_done = 1;
9870 +       return(0);
9871 +}
9872 +
9873 +__initcall(stdio_init);
9874 +
9875 +static void console_write(struct console *console, const char *string, 
9876 +                         unsigned len)
9877 +{
9878 +       struct line *line = &vts[console->index];
9879 +
9880 +       if(con_init_done)
9881 +               down(&line->sem);
9882 +       console_write_chan(&line->chan_list, string, len);
9883 +       if(con_init_done)
9884 +               up(&line->sem);
9885 +}
9886 +
9887 +static struct tty_driver console_driver = {
9888 +       .refcount               = &console_refcount,
9889 +       .open                   = con_open,
9890 +       .close                  = con_close,
9891 +       .write                  = con_write,
9892 +       .chars_in_buffer        = chars_in_buffer,
9893 +       .set_termios            = set_termios
9894 +};
9895 +
9896 +static kdev_t console_device(struct console *c)
9897 +{
9898 +       return mk_kdev(TTY_MAJOR, c->index);
9899 +}
9900 +
9901 +static int console_setup(struct console *co, char *options)
9902 +{
9903 +       return(0);
9904 +}
9905 +
9906 +static struct console stdiocons = {
9907 +       name:           "tty",
9908 +       write:          console_write,
9909 +       device:         console_device,
9910 +       setup:          console_setup,
9911 +       flags:          CON_PRINTBUFFER,
9912 +       index:          -1,
9913 +};
9914 +
9915 +void stdio_console_init(void)
9916 +{
9917 +       INIT_LIST_HEAD(&vts[0].chan_list);
9918 +       list_add(&init_console_chan.list, &vts[0].chan_list);
9919 +       register_console(&stdiocons);
9920 +}
9921 +
9922 +static int console_chan_setup(char *str)
9923 +{
9924 +       return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
9925 +}
9926 +
9927 +__setup("con", console_chan_setup);
9928 +__channel_help(console_chan_setup, "con");
9929 +
9930 +static void console_exit(void)
9931 +{
9932 +       if(!con_init_done) return;
9933 +       close_lines(vts, sizeof(vts)/sizeof(vts[0]));
9934 +}
9935 +
9936 +__uml_exitcall(console_exit);
9937 +
9938 +/*
9939 + * Overrides for Emacs so that we follow Linus's tabbing style.
9940 + * Emacs will notice this stuff at the end of the file and automatically
9941 + * adjust the settings for this buffer only.  This must remain at the end
9942 + * of the file.
9943 + * ---------------------------------------------------------------------------
9944 + * Local variables:
9945 + * c-file-style: "linux"
9946 + * End:
9947 + */
9948 diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.h um/arch/um/drivers/stdio_console.h
9949 --- orig/arch/um/drivers/stdio_console.h        1969-12-31 19:00:00.000000000 -0500
9950 +++ um/arch/um/drivers/stdio_console.h  2003-10-21 03:26:06.000000000 -0400
9951 @@ -0,0 +1,21 @@
9952 +/* 
9953 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
9954 + * Licensed under the GPL
9955 + */
9956 +
9957 +#ifndef __STDIO_CONSOLE_H
9958 +#define __STDIO_CONSOLE_H
9959 +
9960 +extern void save_console_flags(void);
9961 +#endif
9962 +
9963 +/*
9964 + * Overrides for Emacs so that we follow Linus's tabbing style.
9965 + * Emacs will notice this stuff at the end of the file and automatically
9966 + * adjust the settings for this buffer only.  This must remain at the end
9967 + * of the file.
9968 + * ---------------------------------------------------------------------------
9969 + * Local variables:
9970 + * c-file-style: "linux"
9971 + * End:
9972 + */
9973 diff -Naur -X ../exclude-files orig/arch/um/drivers/tty.c um/arch/um/drivers/tty.c
9974 --- orig/arch/um/drivers/tty.c  1969-12-31 19:00:00.000000000 -0500
9975 +++ um/arch/um/drivers/tty.c    2003-10-21 03:26:06.000000000 -0400
9976 @@ -0,0 +1,86 @@
9977 +/* 
9978 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
9979 + * Licensed under the GPL
9980 + */
9981 +
9982 +#include <stdio.h>
9983 +#include <termios.h>
9984 +#include <errno.h>
9985 +#include <unistd.h>
9986 +#include "chan_user.h"
9987 +#include "user_util.h"
9988 +#include "user.h"
9989 +#include "os.h"
9990 +
9991 +struct tty_chan {
9992 +       char *dev;
9993 +       int raw;
9994 +       struct termios tt;
9995 +};
9996 +
9997 +void *tty_chan_init(char *str, int device, struct chan_opts *opts)
9998 +{
9999 +       struct tty_chan *data;
10000 +
10001 +       if(*str != ':'){
10002 +               printk("tty_init : channel type 'tty' must specify "
10003 +                      "a device\n");
10004 +               return(NULL);
10005 +       }
10006 +       str++;
10007 +
10008 +       data = um_kmalloc(sizeof(*data)); 
10009 +       if(data == NULL) 
10010 +               return(NULL);
10011 +       *data = ((struct tty_chan) { .dev       = str,
10012 +                                    .raw       = opts->raw });
10013 +                                    
10014 +       return(data);
10015 +}
10016 +
10017 +int tty_open(int input, int output, int primary, void *d, char **dev_out)
10018 +{
10019 +       struct tty_chan *data = d;
10020 +       int fd;
10021 +
10022 +       fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
10023 +       if(fd < 0) return(fd);
10024 +       if(data->raw){
10025 +               tcgetattr(fd, &data->tt);
10026 +               raw(fd, 0);
10027 +       }
10028 +
10029 +       *dev_out = data->dev;
10030 +       return(fd);
10031 +}
10032 +
10033 +int tty_console_write(int fd, const char *buf, int n, void *d)
10034 +{
10035 +       struct tty_chan *data = d;
10036 +
10037 +       return(generic_console_write(fd, buf, n, &data->tt));
10038 +}
10039 +
10040 +struct chan_ops tty_ops = {
10041 +       .type           = "tty",
10042 +       .init           = tty_chan_init,
10043 +       .open           = tty_open,
10044 +       .close          = generic_close,
10045 +       .read           = generic_read,
10046 +       .write          = generic_write,
10047 +       .console_write  = tty_console_write,
10048 +       .window_size    = generic_window_size,
10049 +       .free           = generic_free,
10050 +       .winch          = 0,
10051 +};
10052 +
10053 +/*
10054 + * Overrides for Emacs so that we follow Linus's tabbing style.
10055 + * Emacs will notice this stuff at the end of the file and automatically
10056 + * adjust the settings for this buffer only.  This must remain at the end
10057 + * of the file.
10058 + * ---------------------------------------------------------------------------
10059 + * Local variables:
10060 + * c-file-style: "linux"
10061 + * End:
10062 + */
10063 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_kern.c um/arch/um/drivers/ubd_kern.c
10064 --- orig/arch/um/drivers/ubd_kern.c     1969-12-31 19:00:00.000000000 -0500
10065 +++ um/arch/um/drivers/ubd_kern.c       2003-12-17 10:48:17.000000000 -0500
10066 @@ -0,0 +1,1390 @@
10067 +/* 
10068 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10069 + * Licensed under the GPL
10070 + */
10071 +
10072 +/* 2001-09-28...2002-04-17
10073 + * Partition stuff by James_McMechan@hotmail.com
10074 + * old style ubd by setting UBD_SHIFT to 0
10075 + */
10076 +
10077 +#define MAJOR_NR UBD_MAJOR
10078 +#define UBD_SHIFT 4
10079 +
10080 +#include "linux/config.h"
10081 +#include "linux/blk.h"
10082 +#include "linux/blkdev.h"
10083 +#include "linux/hdreg.h"
10084 +#include "linux/init.h"
10085 +#include "linux/devfs_fs_kernel.h"
10086 +#include "linux/cdrom.h"
10087 +#include "linux/proc_fs.h"
10088 +#include "linux/ctype.h"
10089 +#include "linux/capability.h"
10090 +#include "linux/mm.h"
10091 +#include "linux/vmalloc.h"
10092 +#include "linux/blkpg.h"
10093 +#include "linux/genhd.h"
10094 +#include "linux/spinlock.h"
10095 +#include "asm/segment.h"
10096 +#include "asm/uaccess.h"
10097 +#include "asm/irq.h"
10098 +#include "asm/types.h"
10099 +#include "user_util.h"
10100 +#include "mem_user.h"
10101 +#include "kern_util.h"
10102 +#include "kern.h"
10103 +#include "mconsole_kern.h"
10104 +#include "init.h"
10105 +#include "irq_user.h"
10106 +#include "irq_kern.h"
10107 +#include "ubd_user.h"
10108 +#include "2_5compat.h"
10109 +#include "os.h"
10110 +#include "mem.h"
10111 +#include "mem_kern.h"
10112 +
10113 +static int ubd_open(struct inode * inode, struct file * filp);
10114 +static int ubd_release(struct inode * inode, struct file * file);
10115 +static int ubd_ioctl(struct inode * inode, struct file * file,
10116 +                    unsigned int cmd, unsigned long arg);
10117 +static int ubd_revalidate(kdev_t rdev);
10118 +static int ubd_revalidate1(kdev_t rdev);
10119 +
10120 +#define MAX_DEV (8)
10121 +#define MAX_MINOR (MAX_DEV << UBD_SHIFT)
10122 +
10123 +/* Changed in early boot */
10124 +static int ubd_do_mmap = 0;
10125 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
10126 +
10127 +/* Not modified by this driver */
10128 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
10129 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
10130 +
10131 +/* Protected by ubd_lock */
10132 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
10133 +
10134 +static struct block_device_operations ubd_blops = {
10135 +        .open          = ubd_open,
10136 +        .release       = ubd_release,
10137 +        .ioctl         = ubd_ioctl,
10138 +        .revalidate    = ubd_revalidate,
10139 +};
10140 +
10141 +/* Protected by ubd_lock, except in prepare_request and ubd_ioctl because 
10142 + * the block layer should ensure that the device is idle before closing it.
10143 + */
10144 +static struct hd_struct        ubd_part[MAX_MINOR] =
10145 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
10146 +
10147 +/* Protected by io_request_lock */
10148 +static request_queue_t *ubd_queue;
10149 +
10150 +/* Protected by ubd_lock */
10151 +static int fake_major = MAJOR_NR;
10152 +
10153 +static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
10154 +
10155 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
10156 +{ \
10157 +       .major          = maj, \
10158 +       .major_name     = name, \
10159 +       .minor_shift    = shift, \
10160 +       .max_p          = 1 << shift, \
10161 +       .part           = parts, \
10162 +       .sizes          = bsizes, \
10163 +       .nr_real        = max, \
10164 +       .real_devices   = NULL, \
10165 +       .next           = NULL, \
10166 +       .fops           = blops, \
10167 +       .de_arr         = NULL, \
10168 +       .flags          = 0 \
10169 +}
10170 +
10171 +static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part,
10172 +                                                UBD_SHIFT, sizes, MAX_DEV, 
10173 +                                                &ubd_blops);
10174 +static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part, 
10175 +                                                 UBD_SHIFT, sizes, MAX_DEV, 
10176 +                                                 &ubd_blops);
10177 +
10178 +#ifdef CONFIG_BLK_DEV_UBD_SYNC
10179 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
10180 +                                        .cl = 1 })
10181 +#else
10182 +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \
10183 +                                        .cl = 1 })
10184 +#endif
10185 +
10186 +/* Not protected - changed only in ubd_setup_common and then only to
10187 + * to enable O_SYNC.
10188 + */
10189 +static struct openflags global_openflags = OPEN_FLAGS;
10190 +
10191 +struct cow {
10192 +       char *file;
10193 +       int fd;
10194 +       unsigned long *bitmap;
10195 +       unsigned long bitmap_len;
10196 +       int bitmap_offset;
10197 +        int data_offset;
10198 +};
10199 +
10200 +struct ubd {
10201 +       char *file;
10202 +       int count;
10203 +       int fd;
10204 +       __u64 size;
10205 +       struct openflags boot_openflags;
10206 +       struct openflags openflags;
10207 +       devfs_handle_t devfs;
10208 +       int no_cow;
10209 +       struct cow cow;
10210 +
10211 +       int map_writes;
10212 +       int map_reads;
10213 +       int nomap_writes;
10214 +       int nomap_reads;
10215 +       int write_maps;
10216 +};
10217 +
10218 +#define DEFAULT_COW { \
10219 +       .file                   = NULL, \
10220 +        .fd                    = -1, \
10221 +        .bitmap                        = NULL, \
10222 +       .bitmap_offset          = 0, \
10223 +        .data_offset           = 0, \
10224 +}
10225 +
10226 +#define DEFAULT_UBD { \
10227 +       .file                   = NULL, \
10228 +       .count                  = 0, \
10229 +       .fd                     = -1, \
10230 +       .size                   = -1, \
10231 +       .boot_openflags         = OPEN_FLAGS, \
10232 +       .openflags              = OPEN_FLAGS, \
10233 +       .devfs                  = NULL, \
10234 +       .no_cow                 = 0, \
10235 +        .cow                   = DEFAULT_COW, \
10236 +       .map_writes             = 0, \
10237 +       .map_reads              = 0, \
10238 +       .nomap_writes           = 0, \
10239 +       .nomap_reads            = 0, \
10240 +       .write_maps             = 0, \
10241 +}
10242 +
10243 +struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
10244 +
10245 +static int ubd0_init(void)
10246 +{
10247 +       struct ubd *dev = &ubd_dev[0];
10248 +
10249 +       if(dev->file == NULL)
10250 +               dev->file = "root_fs";
10251 +       return(0);
10252 +}
10253 +
10254 +__initcall(ubd0_init);
10255 +
10256 +/* Only changed by fake_ide_setup which is a setup */
10257 +static int fake_ide = 0;
10258 +static struct proc_dir_entry *proc_ide_root = NULL;
10259 +static struct proc_dir_entry *proc_ide = NULL;
10260 +
10261 +static void make_proc_ide(void)
10262 +{
10263 +       proc_ide_root = proc_mkdir("ide", 0);
10264 +       proc_ide = proc_mkdir("ide0", proc_ide_root);
10265 +}
10266 +
10267 +static int proc_ide_read_media(char *page, char **start, off_t off, int count,
10268 +                              int *eof, void *data)
10269 +{
10270 +       int len;
10271 +
10272 +       strcpy(page, "disk\n");
10273 +       len = strlen("disk\n");
10274 +       len -= off;
10275 +       if (len < count){
10276 +               *eof = 1;
10277 +               if (len <= 0) return 0;
10278 +       }
10279 +       else len = count;
10280 +       *start = page + off;
10281 +       return len;
10282 +}
10283 +
10284 +static void make_ide_entries(char *dev_name)
10285 +{
10286 +       struct proc_dir_entry *dir, *ent;
10287 +       char name[64];
10288 +
10289 +       if(!fake_ide) return;
10290 +
10291 +       /* Without locking this could race if a UML was booted with no 
10292 +        * disks and then two mconsole requests which add disks came in 
10293 +        * at the same time.
10294 +        */
10295 +       spin_lock(&ubd_lock);
10296 +       if(proc_ide_root == NULL) make_proc_ide();
10297 +       spin_unlock(&ubd_lock);
10298 +
10299 +       dir = proc_mkdir(dev_name, proc_ide);
10300 +       if(!dir) return;
10301 +
10302 +       ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir);
10303 +       if(!ent) return;
10304 +       ent->nlink = 1;
10305 +       ent->data = NULL;
10306 +       ent->read_proc = proc_ide_read_media;
10307 +       ent->write_proc = NULL;
10308 +       sprintf(name,"ide0/%s", dev_name);
10309 +       proc_symlink(dev_name, proc_ide_root, name);
10310 +}
10311 +
10312 +static int fake_ide_setup(char *str)
10313 +{
10314 +       fake_ide = 1;
10315 +       return(1);
10316 +}
10317 +
10318 +__setup("fake_ide", fake_ide_setup);
10319 +
10320 +__uml_help(fake_ide_setup,
10321 +"fake_ide\n"
10322 +"    Create ide0 entries that map onto ubd devices.\n\n"
10323 +);
10324 +
10325 +static int parse_unit(char **ptr)
10326 +{
10327 +       char *str = *ptr, *end;
10328 +       int n = -1;
10329 +
10330 +       if(isdigit(*str)) {
10331 +               n = simple_strtoul(str, &end, 0);
10332 +               if(end == str)
10333 +                       return(-1);
10334 +               *ptr = end;
10335 +       }
10336 +       else if (('a' <= *str) && (*str <= 'h')) {
10337 +               n = *str - 'a';
10338 +               str++;
10339 +               *ptr = str;
10340 +       }
10341 +       return(n);
10342 +}
10343 +
10344 +static int ubd_setup_common(char *str, int *index_out)
10345 +{
10346 +       struct openflags flags = global_openflags;
10347 +       struct ubd *dev;
10348 +       char *backing_file;
10349 +       int n, err;
10350 +
10351 +       if(index_out) *index_out = -1;
10352 +       n = *str;
10353 +       if(n == '='){
10354 +               char *end;
10355 +               int major;
10356 +
10357 +               str++;
10358 +               if(!strcmp(str, "mmap")){
10359 +                       CHOOSE_MODE(printk("mmap not supported by the ubd "
10360 +                                          "driver in tt mode\n"),
10361 +                                   ubd_do_mmap = 1);
10362 +                       return(0);
10363 +               }
10364 +
10365 +               if(!strcmp(str, "sync")){
10366 +                       global_openflags.s = 1;
10367 +                       return(0);
10368 +               }
10369 +               major = simple_strtoul(str, &end, 0);
10370 +               if((*end != '\0') || (end == str)){
10371 +                       printk(KERN_ERR 
10372 +                              "ubd_setup : didn't parse major number\n");
10373 +                       return(1);
10374 +               }
10375 +
10376 +               err = 1;
10377 +               spin_lock(&ubd_lock);
10378 +               if(fake_major != MAJOR_NR){
10379 +                       printk(KERN_ERR "Can't assign a fake major twice\n");
10380 +                       goto out1;
10381 +               }
10382 +
10383 +               fake_gendisk.major = major;
10384 +               fake_major = major;
10385 +       
10386 +               printk(KERN_INFO "Setting extra ubd major number to %d\n",
10387 +                      major);
10388 +               err = 0;
10389 +       out1:
10390 +               spin_unlock(&ubd_lock);
10391 +               return(err);
10392 +       }
10393 +
10394 +       n = parse_unit(&str);
10395 +       if(n < 0){
10396 +               printk(KERN_ERR "ubd_setup : couldn't parse unit number "
10397 +                      "'%s'\n", str);
10398 +               return(1);
10399 +       }
10400 +
10401 +       if(n >= MAX_DEV){
10402 +               printk(KERN_ERR "ubd_setup : index %d out of range "
10403 +                      "(%d devices)\n", n, MAX_DEV);   
10404 +               return(1);
10405 +       }
10406 +
10407 +       err = 1;
10408 +       spin_lock(&ubd_lock);
10409 +
10410 +       dev = &ubd_dev[n];
10411 +       if(dev->file != NULL){
10412 +               printk(KERN_ERR "ubd_setup : device already configured\n");
10413 +               goto out2;
10414 +       }
10415 +
10416 +       if(index_out) *index_out = n;
10417 +
10418 +       if(*str == 'r'){
10419 +               flags.w = 0;
10420 +               str++;
10421 +       }
10422 +       if(*str == 's'){
10423 +               flags.s = 1;
10424 +               str++;
10425 +       }
10426 +       if(*str == 'd'){
10427 +               dev->no_cow = 1;
10428 +               str++;
10429 +       }
10430 +
10431 +       if(*str++ != '='){
10432 +               printk(KERN_ERR "ubd_setup : Expected '='\n");
10433 +               goto out2;
10434 +       }
10435 +
10436 +       err = 0;
10437 +       backing_file = strchr(str, ',');
10438 +       if(backing_file){
10439 +               if(dev->no_cow)
10440 +                       printk(KERN_ERR "Can't specify both 'd' and a "
10441 +                              "cow file\n");
10442 +               else {
10443 +                       *backing_file = '\0';
10444 +                       backing_file++;
10445 +               }
10446 +       }
10447 +       dev->file = str;
10448 +       dev->cow.file = backing_file;
10449 +       dev->boot_openflags = flags;
10450 + out2:
10451 +       spin_unlock(&ubd_lock);
10452 +       return(err);
10453 +}
10454 +
10455 +static int ubd_setup(char *str)
10456 +{
10457 +       ubd_setup_common(str, NULL);
10458 +       return(1);
10459 +}
10460 +
10461 +__setup("ubd", ubd_setup);
10462 +__uml_help(ubd_setup,
10463 +"ubd<n>=<filename>\n"
10464 +"    This is used to associate a device with a file in the underlying\n"
10465 +"    filesystem. Usually, there is a filesystem in the file, but \n"
10466 +"    that's not required. Swap devices containing swap files can be\n"
10467 +"    specified like this. Also, a file which doesn't contain a\n"
10468 +"    filesystem can have its contents read in the virtual \n"
10469 +"    machine by running dd on the device. n must be in the range\n"
10470 +"    0 to 7. Appending an 'r' to the number will cause that device\n"
10471 +"    to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
10472 +"    an 's' (has to be _after_ 'r', if there is one) will cause data\n"
10473 +"    to be written to disk on the host immediately.\n\n"
10474 +);
10475 +
10476 +static int fakehd(char *str)
10477 +{
10478 +       printk(KERN_INFO 
10479 +              "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n");
10480 +       ubd_gendisk.major_name = "hd";
10481 +       return(1);
10482 +}
10483 +
10484 +__setup("fakehd", fakehd);
10485 +__uml_help(fakehd,
10486 +"fakehd\n"
10487 +"    Change the ubd device name to \"hd\".\n\n"
10488 +);
10489 +
10490 +static void do_ubd_request(request_queue_t * q);
10491 +
10492 +/* Only changed by ubd_init, which is an initcall. */
10493 +int thread_fd = -1;
10494 +
10495 +/* Changed by ubd_handler, which is serialized because interrupts only
10496 + * happen on CPU 0.
10497 + */
10498 +int intr_count = 0;
10499 +
10500 +static void ubd_finish(int error)
10501 +{
10502 +       int nsect;
10503 +
10504 +       if(error){
10505 +               end_request(0);
10506 +               return;
10507 +       }
10508 +       nsect = CURRENT->current_nr_sectors;
10509 +       CURRENT->sector += nsect;
10510 +       CURRENT->buffer += nsect << 9;
10511 +       CURRENT->errors = 0;
10512 +       CURRENT->nr_sectors -= nsect;
10513 +       CURRENT->current_nr_sectors = 0;
10514 +       end_request(1);
10515 +}
10516 +
10517 +static void ubd_handler(void)
10518 +{
10519 +       struct io_thread_req req;
10520 +       int n, err;
10521 +
10522 +       DEVICE_INTR = NULL;
10523 +       intr_count++;
10524 +       n = read_ubd_fs(thread_fd, &req, sizeof(req));
10525 +       if(n != sizeof(req)){
10526 +               printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
10527 +                      "err = %d\n", os_getpid(), -n);
10528 +               spin_lock(&io_request_lock);
10529 +               end_request(0);
10530 +               spin_unlock(&io_request_lock);
10531 +               return;
10532 +       }
10533 +        
10534 +        if((req.op != UBD_MMAP) && 
10535 +          ((req.offset != ((__u64) (CURRENT->sector)) << 9) ||
10536 +           (req.length != (CURRENT->current_nr_sectors) << 9)))
10537 +               panic("I/O op mismatch");
10538 +
10539 +       if(req.map_fd != -1){
10540 +               err = physmem_subst_mapping(req.buffer, req.map_fd, 
10541 +                                           req.map_offset, 1);
10542 +               if(err)
10543 +                       printk("ubd_handler - physmem_subst_mapping failed, "
10544 +                              "err = %d\n", -err);
10545 +       }
10546 +       
10547 +       spin_lock(&io_request_lock);
10548 +       ubd_finish(req.error);
10549 +       reactivate_fd(thread_fd, UBD_IRQ);      
10550 +       do_ubd_request(ubd_queue);
10551 +       spin_unlock(&io_request_lock);
10552 +}
10553 +
10554 +static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
10555 +{
10556 +       ubd_handler();
10557 +}
10558 +
10559 +/* Only changed by ubd_init, which is an initcall. */
10560 +static int io_pid = -1;
10561 +
10562 +void kill_io_thread(void)
10563 +{
10564 +       if(io_pid != -1)
10565 +               os_kill_process(io_pid, 1);
10566 +}
10567 +
10568 +__uml_exitcall(kill_io_thread);
10569 +
10570 +/* Initialized in an initcall, and unchanged thereafter */
10571 +devfs_handle_t ubd_dir_handle;
10572 +
10573 +static int ubd_add(int n)
10574 +{
10575 +       struct ubd *dev = &ubd_dev[n];
10576 +       char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")];
10577 +       int err = -EISDIR;
10578 +
10579 +       if(dev->file == NULL)
10580 +               goto out;
10581 +
10582 +       err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT));
10583 +       if(err)
10584 +               goto out;
10585 +
10586 +       if(dev->cow.file == NULL)
10587 +               blk_sizes[n] = UBD_MMAP_BLOCK_SIZE;
10588 +
10589 +       sprintf(name, "%d", n);
10590 +       dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE,
10591 +                                   MAJOR_NR, n << UBD_SHIFT, S_IFBLK | 
10592 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
10593 +                                   &ubd_blops, NULL);
10594 +
10595 +#if 0 /* 2.5 ... */
10596 +       sprintf(disk->disk_name, "ubd%c", 'a' + unit);
10597 +#endif
10598 +
10599 +       sprintf(dev_name, "%s%c", ubd_gendisk.major_name, 
10600 +                    n + 'a');
10601 +
10602 +       make_ide_entries(dev_name);
10603 +       return(0);
10604 +
10605 + out:
10606 +       return(err);
10607 +}
10608 +
10609 +static int ubd_config(char *str)
10610 +{
10611 +       int n, err;
10612 +
10613 +       str = uml_strdup(str);
10614 +       if(str == NULL){
10615 +               printk(KERN_ERR "ubd_config failed to strdup string\n");
10616 +               return(1);
10617 +       }
10618 +       err = ubd_setup_common(str, &n);
10619 +       if(err){
10620 +               kfree(str);
10621 +               return(-1);
10622 +       }
10623 +       if(n == -1) return(0);
10624 +
10625 +       spin_lock(&ubd_lock);
10626 +       err = ubd_add(n);
10627 +       if(err)
10628 +               ubd_dev[n].file = NULL;
10629 +       spin_unlock(&ubd_lock);
10630 +
10631 +       return(err);
10632 +}
10633 +
10634 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
10635 +{
10636 +       struct ubd *dev;
10637 +       char *end;
10638 +       int n, len = 0;
10639 +
10640 +       n = simple_strtoul(name, &end, 0);
10641 +       if((*end != '\0') || (end == name)){
10642 +               *error_out = "ubd_get_config : didn't parse device number";
10643 +               return(-1);
10644 +       }
10645 +
10646 +       if((n >= MAX_DEV) || (n < 0)){
10647 +               *error_out = "ubd_get_config : device number out of range";
10648 +               return(-1);
10649 +       }
10650 +
10651 +       dev = &ubd_dev[n];
10652 +       spin_lock(&ubd_lock);
10653 +
10654 +       if(dev->file == NULL){
10655 +               CONFIG_CHUNK(str, size, len, "", 1);
10656 +               goto out;
10657 +       }
10658 +
10659 +       CONFIG_CHUNK(str, size, len, dev->file, 0);
10660 +
10661 +       if(dev->cow.file != NULL){
10662 +               CONFIG_CHUNK(str, size, len, ",", 0);
10663 +               CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
10664 +       }
10665 +       else CONFIG_CHUNK(str, size, len, "", 1);
10666 +
10667 + out:
10668 +       spin_unlock(&ubd_lock);
10669 +       return(len);
10670 +}
10671 +
10672 +static int ubd_remove(char *str)
10673 +{
10674 +       struct ubd *dev;
10675 +       int n, err = -ENODEV;
10676 +
10677 +       if(isdigit(*str)){
10678 +               char *end;
10679 +               n = simple_strtoul(str, &end, 0);
10680 +               if ((*end != '\0') || (end == str)) 
10681 +                       return(err);
10682 +       }
10683 +       else if (('a' <= *str) && (*str <= 'h'))
10684 +               n = *str - 'a';
10685 +       else
10686 +               return(err);    /* it should be a number 0-7/a-h */
10687 +
10688 +       if((n < 0) || (n >= MAX_DEV))
10689 +               return(err);
10690 +
10691 +       dev = &ubd_dev[n];
10692 +
10693 +       spin_lock(&ubd_lock);
10694 +       err = 0;
10695 +       if(dev->file == NULL)
10696 +               goto out;
10697 +       err = -1;
10698 +       if(dev->count > 0)
10699 +               goto out;
10700 +       if(dev->devfs != NULL) 
10701 +               devfs_unregister(dev->devfs);
10702 +
10703 +       *dev = ((struct ubd) DEFAULT_UBD);
10704 +       err = 0;
10705 + out:
10706 +       spin_unlock(&ubd_lock);
10707 +       return(err);
10708 +}
10709 +
10710 +static struct mc_device ubd_mc = {
10711 +       .name           = "ubd",
10712 +       .config         = ubd_config,
10713 +       .get_config     = ubd_get_config,
10714 +       .remove         = ubd_remove,
10715 +};
10716 +
10717 +static int ubd_mc_init(void)
10718 +{
10719 +       mconsole_register_dev(&ubd_mc);
10720 +       return(0);
10721 +}
10722 +
10723 +__initcall(ubd_mc_init);
10724 +
10725 +static request_queue_t *ubd_get_queue(kdev_t device)
10726 +{
10727 +       return(ubd_queue);
10728 +}
10729 +
10730 +int ubd_init(void)
10731 +{
10732 +       unsigned long stack;
10733 +        int i, err;
10734 +
10735 +       ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL);
10736 +       if (devfs_register_blkdev(MAJOR_NR, "ubd", &ubd_blops)) {
10737 +               printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR);
10738 +               return -1;
10739 +       }
10740 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
10741 +       blksize_size[MAJOR_NR] = blk_sizes;
10742 +       blk_size[MAJOR_NR] = sizes;
10743 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
10744 +
10745 +       ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
10746 +       blk_init_queue(ubd_queue, DEVICE_REQUEST);
10747 +       INIT_ELV(ubd_queue, &ubd_queue->elevator);
10748 +
10749 +        add_gendisk(&ubd_gendisk);
10750 +       if (fake_major != MAJOR_NR){
10751 +               /* major number 0 is used to auto select */
10752 +               err = devfs_register_blkdev(fake_major, "fake", &ubd_blops);
10753 +               if(fake_major == 0){
10754 +               /* auto device number case */
10755 +                       fake_major = err;
10756 +                       if(err == 0)
10757 +                               return(-ENODEV);
10758 +               } 
10759 +               else if (err){
10760 +                       /* not auto so normal error */
10761 +                       printk(KERN_ERR "ubd: error %d getting major %d\n", 
10762 +                              -err, fake_major);
10763 +                       return(-ENODEV);
10764 +               }
10765 +
10766 +               blk_dev[fake_major].queue = ubd_get_queue;
10767 +               read_ahead[fake_major] = 8;     /* 8 sector (4kB) read-ahead */
10768 +               blksize_size[fake_major] = blk_sizes;
10769 +               blk_size[fake_major] = sizes;
10770 +               INIT_HARDSECT(hardsect_size, fake_major, hardsect_sizes);
10771 +                add_gendisk(&fake_gendisk);
10772 +       }
10773 +
10774 +       for(i=0;i<MAX_DEV;i++) 
10775 +               ubd_add(i);
10776 +
10777 +       if(global_openflags.s){
10778 +               printk(KERN_INFO "ubd : Synchronous mode\n");
10779 +               return(0);
10780 +       }
10781 +       stack = alloc_stack(0, 0);
10782 +       io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 
10783 +                                &thread_fd);
10784 +       if(io_pid < 0){
10785 +               io_pid = -1;
10786 +               printk(KERN_ERR 
10787 +                      "ubd : Failed to start I/O thread (errno = %d) - "
10788 +                      "falling back to synchronous I/O\n", -io_pid);
10789 +               return(0);
10790 +       }
10791 +       err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 
10792 +                            SA_INTERRUPT, "ubd", ubd_dev);
10793 +       if(err != 0) 
10794 +               printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
10795 +       return(err);
10796 +}
10797 +
10798 +__initcall(ubd_init);
10799 +
10800 +static void ubd_close(struct ubd *dev)
10801 +{
10802 +       os_close_file(dev->fd);
10803 +       if(dev->cow.file != NULL) {
10804 +               os_close_file(dev->cow.fd);
10805 +               vfree(dev->cow.bitmap);
10806 +               dev->cow.bitmap = NULL;
10807 +       }
10808 +}
10809 +
10810 +static int ubd_open_dev(struct ubd *dev)
10811 +{
10812 +       struct openflags flags;
10813 +       char **back_ptr;
10814 +       int err, create_cow, *create_ptr;
10815 +
10816 +       dev->openflags = dev->boot_openflags;
10817 +       create_cow = 0;
10818 +       create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
10819 +       back_ptr = dev->no_cow ? NULL : &dev->cow.file;
10820 +       dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
10821 +                               &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
10822 +                               &dev->cow.data_offset, create_ptr);
10823 +
10824 +       if((dev->fd == -ENOENT) && create_cow){
10825 +               dev->fd = create_cow_file(dev->file, dev->cow.file, 
10826 +                                         dev->openflags, 1 << 9, PAGE_SIZE,
10827 +                                         &dev->cow.bitmap_offset, 
10828 +                                         &dev->cow.bitmap_len,
10829 +                                         &dev->cow.data_offset);
10830 +               if(dev->fd >= 0){
10831 +                       printk(KERN_INFO "Creating \"%s\" as COW file for "
10832 +                              "\"%s\"\n", dev->file, dev->cow.file);
10833 +               }
10834 +       }
10835 +
10836 +       if(dev->fd < 0) return(dev->fd);
10837 +
10838 +       if(dev->cow.file != NULL){
10839 +               err = -ENOMEM;
10840 +               dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
10841 +               if(dev->cow.bitmap == NULL){
10842 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
10843 +                       goto error;
10844 +               }
10845 +               flush_tlb_kernel_vm();
10846 +
10847 +               err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
10848 +                                     dev->cow.bitmap_offset, 
10849 +                                     dev->cow.bitmap_len);
10850 +               if(err < 0) goto error;
10851 +
10852 +               flags = dev->openflags;
10853 +               flags.w = 0;
10854 +               err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, 
10855 +                                   NULL, NULL);
10856 +               if(err < 0) goto error;
10857 +               dev->cow.fd = err;
10858 +       }
10859 +       return(0);
10860 + error:
10861 +       os_close_file(dev->fd);
10862 +       return(err);
10863 +}
10864 +
10865 +static int ubd_file_size(struct ubd *dev, __u64 *size_out)
10866 +{
10867 +       char *file;
10868 +
10869 +       file = dev->cow.file ? dev->cow.file : dev->file;
10870 +       return(os_file_size(file, size_out));
10871 +}
10872 +
10873 +static int ubd_open(struct inode *inode, struct file *filp)
10874 +{
10875 +       struct ubd *dev;
10876 +       int n, offset, err = 0;
10877 +
10878 +       n = DEVICE_NR(inode->i_rdev);
10879 +       dev = &ubd_dev[n];
10880 +       if(n >= MAX_DEV)
10881 +               return -ENODEV;
10882 +
10883 +       spin_lock(&ubd_lock);
10884 +       offset = n << UBD_SHIFT;
10885 +
10886 +       if(dev->count == 0){
10887 +               err = ubd_open_dev(dev);
10888 +               if(err){
10889 +                       printk(KERN_ERR "ubd%d: Can't open \"%s\": "
10890 +                              "errno = %d\n", n, dev->file, -err);
10891 +                       goto out;
10892 +               }
10893 +               err = ubd_file_size(dev, &dev->size);
10894 +               if(err < 0)
10895 +                       goto out;
10896 +               sizes[offset] = dev->size / BLOCK_SIZE;
10897 +               ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset];
10898 +       }
10899 +       dev->count++;
10900 +       if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
10901 +               if(--dev->count == 0) ubd_close(dev);
10902 +               err = -EROFS;
10903 +       }
10904 + out:
10905 +       spin_unlock(&ubd_lock);
10906 +       return(err);
10907 +}
10908 +
10909 +static int ubd_release(struct inode * inode, struct file * file)
10910 +{
10911 +        int n, offset;
10912 +
10913 +       n =  DEVICE_NR(inode->i_rdev);
10914 +       offset = n << UBD_SHIFT;
10915 +       if(n >= MAX_DEV)
10916 +               return -ENODEV;
10917 +
10918 +       spin_lock(&ubd_lock);
10919 +       if(--ubd_dev[n].count == 0)
10920 +               ubd_close(&ubd_dev[n]);
10921 +       spin_unlock(&ubd_lock);
10922 +
10923 +       return(0);
10924 +}
10925 +
10926 +static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, 
10927 +                         __u64 *cow_offset, unsigned long *bitmap, 
10928 +                         __u64 bitmap_offset, unsigned long *bitmap_words,
10929 +                         __u64 bitmap_len)
10930 +{
10931 +       __u64 sector = io_offset >> 9;
10932 +       int i, update_bitmap = 0;
10933 +
10934 +       for(i = 0; i < length >> 9; i++){
10935 +               if(cow_mask != NULL)
10936 +                       ubd_set_bit(i, (unsigned char *) cow_mask);
10937 +               if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
10938 +                       continue;
10939 +
10940 +               update_bitmap = 1;
10941 +               ubd_set_bit(sector + i, (unsigned char *) bitmap);
10942 +       }
10943 +
10944 +       if(!update_bitmap)
10945 +               return;
10946 +
10947 +       *cow_offset = sector / (sizeof(unsigned long) * 8);
10948 +
10949 +       /* This takes care of the case where we're exactly at the end of the
10950 +        * device, and *cow_offset + 1 is off the end.  So, just back it up
10951 +        * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
10952 +        * for the original diagnosis.
10953 +        */
10954 +       if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / 
10955 +                          sizeof(unsigned long) - 1))
10956 +               (*cow_offset)--;
10957 +
10958 +       bitmap_words[0] = bitmap[*cow_offset];
10959 +       bitmap_words[1] = bitmap[*cow_offset + 1];
10960 +
10961 +       *cow_offset *= sizeof(unsigned long);
10962 +       *cow_offset += bitmap_offset;
10963 +}
10964 +
10965 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, 
10966 +                      __u64 bitmap_offset, __u64 bitmap_len)
10967 +{
10968 +       __u64 sector = req->offset >> 9;
10969 +        int i;
10970 +
10971 +       if(req->length > (sizeof(req->sector_mask) * 8) << 9)
10972 +               panic("Operation too long");
10973 +
10974 +       if(req->op == UBD_READ) {
10975 +               for(i = 0; i < req->length >> 9; i++){
10976 +                       if(ubd_test_bit(sector + i, (unsigned char *) bitmap)){
10977 +                               ubd_set_bit(i, (unsigned char *) 
10978 +                                           &req->sector_mask);
10979 +                       }
10980 +                }
10981 +        } 
10982 +        else cowify_bitmap(req->offset, req->length, &req->sector_mask,
10983 +                          &req->cow_offset, bitmap, bitmap_offset, 
10984 +                          req->bitmap_words, bitmap_len);
10985 +}
10986 +
10987 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
10988 +{
10989 +       __u64 sector;
10990 +       unsigned char *bitmap;
10991 +       int bit, i;
10992 +
10993 +       /* mmap must have been requested on the command line */
10994 +       if(!ubd_do_mmap)
10995 +               return(-1);
10996 +
10997 +       /* The buffer must be page aligned */
10998 +       if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
10999 +               return(-1);
11000 +
11001 +       /* The request must be a page long */
11002 +       if((req->current_nr_sectors << 9) != PAGE_SIZE)
11003 +               return(-1);
11004 +
11005 +       if(dev->cow.file == NULL)
11006 +               return(dev->fd);
11007 +
11008 +       sector = offset >> 9;
11009 +       bitmap = (unsigned char *) dev->cow.bitmap;
11010 +       bit = ubd_test_bit(sector, bitmap);
11011 +
11012 +       for(i = 1; i < req->current_nr_sectors; i++){
11013 +               if(ubd_test_bit(sector + i, bitmap) != bit)
11014 +                       return(-1);
11015 +       }
11016 +
11017 +       if(bit || (req->cmd == WRITE))
11018 +               offset += dev->cow.data_offset;
11019 +
11020 +       /* The data on disk must be page aligned */
11021 +       if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
11022 +               return(-1);
11023 +
11024 +       return(bit ? dev->fd : dev->cow.fd);
11025 +}
11026 +
11027 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, 
11028 +                               struct request *req, 
11029 +                               struct io_thread_req *io_req)
11030 +{
11031 +       int err;
11032 +
11033 +       if(req->cmd == WRITE){
11034 +               /* Writes are almost no-ops since the new data is already in the
11035 +                * host page cache
11036 +                */
11037 +               dev->map_writes++;
11038 +               if(dev->cow.file != NULL)
11039 +                       cowify_bitmap(io_req->offset, io_req->length, 
11040 +                                     &io_req->sector_mask, &io_req->cow_offset,
11041 +                                     dev->cow.bitmap, dev->cow.bitmap_offset,
11042 +                                     io_req->bitmap_words, 
11043 +                                     dev->cow.bitmap_len);
11044 +       }
11045 +       else {
11046 +               int w;
11047 +
11048 +               if((dev->cow.file != NULL) && (fd == dev->cow.fd))
11049 +                       w = 0;
11050 +               else w = dev->openflags.w;
11051 +
11052 +               if((dev->cow.file != NULL) && (fd == dev->fd))
11053 +                       offset += dev->cow.data_offset;
11054 +
11055 +               err = physmem_subst_mapping(req->buffer, fd, offset, w);
11056 +               if(err){
11057 +                       printk("physmem_subst_mapping failed, err = %d\n", 
11058 +                              -err);
11059 +                       return(1);
11060 +               }
11061 +               dev->map_reads++;
11062 +       }
11063 +       io_req->op = UBD_MMAP;
11064 +       io_req->buffer = req->buffer;
11065 +       return(0);
11066 +}
11067 +
11068 +static int prepare_request(struct request *req, struct io_thread_req *io_req)
11069 +{
11070 +       struct ubd *dev;
11071 +       __u64 offset;
11072 +       int minor, n, len, fd;
11073 +
11074 +       if(req->rq_status == RQ_INACTIVE) return(1);
11075 +
11076 +       minor = MINOR(req->rq_dev);
11077 +       n = minor >> UBD_SHIFT;
11078 +       dev = &ubd_dev[n];
11079 +
11080 +       if(IS_WRITE(req) && !dev->openflags.w){
11081 +               printk("Write attempted on readonly ubd device %d\n", n);
11082 +               end_request(0);
11083 +               return(1);
11084 +       }
11085 +
11086 +        req->sector += ubd_part[minor].start_sect;
11087 +       offset = ((__u64) req->sector) << 9;
11088 +       len = req->current_nr_sectors << 9;
11089 +
11090 +       io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
11091 +       io_req->fds[1] = dev->fd;
11092 +       io_req->map_fd = -1;
11093 +       io_req->cow_offset = -1;
11094 +       io_req->offset = offset;
11095 +       io_req->length = len;
11096 +       io_req->error = 0;
11097 +       io_req->sector_mask = 0;
11098 +
11099 +       fd = mmap_fd(req, dev, io_req->offset);
11100 +       if(fd > 0){
11101 +               /* If mmapping is otherwise OK, but the first access to the 
11102 +                * page is a write, then it's not mapped in yet.  So we have 
11103 +                * to write the data to disk first, then we can map the disk
11104 +                * page in and continue normally from there.
11105 +                */
11106 +               if((req->cmd == WRITE) && !is_remapped(req->buffer)){
11107 +                       io_req->map_fd = dev->fd;
11108 +                       io_req->map_offset = io_req->offset + 
11109 +                               dev->cow.data_offset;
11110 +                       dev->write_maps++;
11111 +               }
11112 +               else return(prepare_mmap_request(dev, fd, io_req->offset, req, 
11113 +                                                io_req));
11114 +       }
11115 +
11116 +       if(req->cmd == READ)
11117 +               dev->nomap_reads++;
11118 +       else dev->nomap_writes++;
11119 +
11120 +       io_req->op = (req->cmd == READ) ? UBD_READ : UBD_WRITE;
11121 +       io_req->offsets[0] = 0;
11122 +       io_req->offsets[1] = dev->cow.data_offset;
11123 +       io_req->buffer = req->buffer;
11124 +       io_req->sectorsize = 1 << 9;
11125 +
11126 +        if(dev->cow.file != NULL) 
11127 +               cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
11128 +                          dev->cow.bitmap_len);
11129 +       return(0);
11130 +}
11131 +
11132 +static void do_ubd_request(request_queue_t *q)
11133 +{
11134 +       struct io_thread_req io_req;
11135 +       struct request *req;
11136 +       int err, n;
11137 +
11138 +       if(thread_fd == -1){
11139 +               while(!list_empty(&q->queue_head)){
11140 +                       req = blkdev_entry_next_request(&q->queue_head);
11141 +                       err = prepare_request(req, &io_req);
11142 +                       if(!err){
11143 +                               do_io(&io_req);
11144 +                               ubd_finish(io_req.error);
11145 +                       }
11146 +               }
11147 +       }
11148 +       else {
11149 +               if(DEVICE_INTR || list_empty(&q->queue_head)) return;
11150 +               req = blkdev_entry_next_request(&q->queue_head);
11151 +               err = prepare_request(req, &io_req);
11152 +               if(!err){
11153 +                       SET_INTR(ubd_handler);
11154 +                       n = write_ubd_fs(thread_fd, (char *) &io_req, 
11155 +                                        sizeof(io_req));
11156 +                       if(n != sizeof(io_req))
11157 +                               printk("write to io thread failed, "
11158 +                                      "errno = %d\n", -n);
11159 +               }
11160 +       }
11161 +}
11162 +
11163 +static int ubd_ioctl(struct inode * inode, struct file * file,
11164 +                    unsigned int cmd, unsigned long arg)
11165 +{
11166 +       struct hd_geometry *loc = (struct hd_geometry *) arg;
11167 +       struct ubd *dev;
11168 +       int n, minor, err;
11169 +       struct hd_driveid ubd_id = {
11170 +               .cyls           = 0,
11171 +               .heads          = 128,
11172 +               .sectors        = 32,
11173 +       };
11174 +       
11175 +        if(!inode) return(-EINVAL);
11176 +       minor = MINOR(inode->i_rdev);
11177 +       n = minor >> UBD_SHIFT;
11178 +       if(n >= MAX_DEV)
11179 +               return(-EINVAL);
11180 +       dev = &ubd_dev[n];
11181 +       switch (cmd) {
11182 +               struct hd_geometry g;
11183 +               struct cdrom_volctrl volume;
11184 +       case HDIO_GETGEO:
11185 +               if(!loc) return(-EINVAL);
11186 +               g.heads = 128;
11187 +               g.sectors = 32;
11188 +               g.cylinders = dev->size / (128 * 32 * hardsect_sizes[minor]);
11189 +               g.start = ubd_part[minor].start_sect;
11190 +               return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
11191 +       case BLKGETSIZE:   /* Return device size */
11192 +               if(!arg) return(-EINVAL);
11193 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11194 +               if(err)
11195 +                       return(err);
11196 +               put_user(ubd_part[minor].nr_sects, (long *) arg);
11197 +               return(0);
11198 +       case BLKRRPART: /* Re-read partition tables */
11199 +               return(ubd_revalidate(inode->i_rdev));
11200 +
11201 +       case HDIO_SET_UNMASKINTR:
11202 +               if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
11203 +               if((arg > 1) || (minor & 0x3F)) return(-EINVAL);
11204 +               return(0);
11205 +
11206 +       case HDIO_GET_UNMASKINTR:
11207 +               if(!arg)  return(-EINVAL);
11208 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11209 +               if(err)
11210 +                       return(err);
11211 +               return(0);
11212 +
11213 +       case HDIO_GET_MULTCOUNT:
11214 +               if(!arg)  return(-EINVAL);
11215 +               err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
11216 +               if(err)
11217 +                       return(err);
11218 +               return(0);
11219 +
11220 +       case HDIO_SET_MULTCOUNT:
11221 +               if(!capable(CAP_SYS_ADMIN)) return(-EACCES);
11222 +               if(MINOR(inode->i_rdev) & 0x3F) return(-EINVAL);
11223 +               return(0);
11224 +
11225 +       case HDIO_GET_IDENTITY:
11226 +               ubd_id.cyls = dev->size / (128 * 32 * hardsect_sizes[minor]);
11227 +               if(copy_to_user((char *) arg, (char *) &ubd_id, 
11228 +                                sizeof(ubd_id)))
11229 +                       return(-EFAULT);
11230 +               return(0);
11231 +               
11232 +       case CDROMVOLREAD:
11233 +               if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
11234 +                       return(-EFAULT);
11235 +               volume.channel0 = 255;
11236 +               volume.channel1 = 255;
11237 +               volume.channel2 = 255;
11238 +               volume.channel3 = 255;
11239 +               if(copy_to_user((char *) arg, &volume, sizeof(volume)))
11240 +                       return(-EFAULT);
11241 +               return(0);
11242 +
11243 +       default:
11244 +               return blk_ioctl(inode->i_rdev, cmd, arg);
11245 +       }
11246 +}
11247 +
11248 +static int ubd_revalidate1(kdev_t rdev)
11249 +{
11250 +       int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT;
11251 +       struct ubd *dev;
11252 +       struct hd_struct *part;
11253 +
11254 +       n = DEVICE_NR(rdev);
11255 +       offset = n << UBD_SHIFT;
11256 +       dev = &ubd_dev[n];
11257 +
11258 +       part = &ubd_part[offset];
11259 +
11260 +       /* clear all old partition counts */
11261 +       for(i = 1; i < pcount; i++) {
11262 +               part[i].start_sect = 0;
11263 +               part[i].nr_sects = 0;
11264 +       }
11265 +
11266 +       /* If it already has been opened we can check the partitions 
11267 +        * directly 
11268 +        */
11269 +       if(dev->count){
11270 +               part->start_sect = 0;
11271 +               register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, 
11272 +                             &ubd_blops, part->nr_sects);
11273 +       } 
11274 +       else if(dev->file){
11275 +               err = ubd_open_dev(dev);
11276 +               if(err){
11277 +                       printk(KERN_ERR "unable to open %s for validation\n",
11278 +                              dev->file);
11279 +                       goto out;
11280 +               }
11281 +
11282 +               /* have to recompute sizes since we opened it */
11283 +               err = ubd_file_size(dev, &dev->size);
11284 +               if(err < 0) {
11285 +                       ubd_close(dev);
11286 +                       goto out;
11287 +               }
11288 +               part->start_sect = 0;
11289 +               part->nr_sects = dev->size / hardsect_sizes[offset];
11290 +               register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, 
11291 +                             &ubd_blops, part->nr_sects);
11292 +
11293 +               /* we are done so close it */
11294 +               ubd_close(dev);
11295 +       } 
11296 +       else err = -ENODEV;
11297 + out:
11298 +       return(err);
11299 +}
11300 +
11301 +static int ubd_revalidate(kdev_t rdev)
11302 +{
11303 +       int err;
11304 +
11305 +       spin_lock(&ubd_lock);
11306 +       err = ubd_revalidate1(rdev);
11307 +       spin_unlock(&ubd_lock);
11308 +       return(err);
11309 +}
11310 +
11311 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
11312 +                             __u64 offset)
11313 +{
11314 +       __u64 bitmap_offset;
11315 +       unsigned long new_bitmap[2];
11316 +       int i, err, n;
11317 +
11318 +       /* If it's not a write access, we can't do anything about it */
11319 +       if(!is_write)
11320 +               return(0);
11321 +
11322 +       /* We have a write */
11323 +       for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
11324 +               struct ubd *dev = &ubd_dev[i];
11325 +
11326 +               if((dev->fd != fd) && (dev->cow.fd != fd))
11327 +                       continue;
11328 +
11329 +               /* It's a write to a ubd device */
11330 +
11331 +               if(!dev->openflags.w){
11332 +                       /* It's a write access on a read-only device - probably
11333 +                        * shouldn't happen.  If the kernel is trying to change
11334 +                        * something with no intention of writing it back out,
11335 +                        * then this message will clue us in that this needs
11336 +                        * fixing
11337 +                        */
11338 +                       printk("Write access to mapped page from readonly ubd "
11339 +                              "device %d\n", i);
11340 +                       return(0);
11341 +               }
11342 +
11343 +               /* It's a write to a writeable ubd device - it must be COWed
11344 +                * because, otherwise, the page would have been mapped in 
11345 +                * writeable
11346 +                */
11347 +
11348 +               if(!dev->cow.file)
11349 +                       panic("Write fault on writeable non-COW ubd device %d",
11350 +                             i);
11351 +
11352 +               /* It should also be an access to the backing file since the 
11353 +                * COW pages should be mapped in read-write
11354 +                */
11355 +
11356 +               if(fd == dev->fd)
11357 +                       panic("Write fault on a backing page of ubd "
11358 +                             "device %d\n", i);
11359 +
11360 +               /* So, we do the write, copying the backing data to the COW 
11361 +                * file... 
11362 +                */
11363 +
11364 +               err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
11365 +               if(err < 0)
11366 +                       panic("Couldn't seek to %lld in COW file of ubd "
11367 +                             "device %d, err = %d", 
11368 +                             offset + dev->cow.data_offset, i, -err);
11369 +
11370 +               n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
11371 +               if(n != PAGE_SIZE)
11372 +                       panic("Couldn't copy data to COW file of ubd "
11373 +                             "device %d, err = %d", i, -n);
11374 +
11375 +               /* ... updating the COW bitmap... */
11376 +
11377 +               cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, 
11378 +                             dev->cow.bitmap, dev->cow.bitmap_offset, 
11379 +                             new_bitmap, dev->cow.bitmap_len);
11380 +
11381 +               err = os_seek_file(dev->fd, bitmap_offset);
11382 +               if(err < 0)
11383 +                       panic("Couldn't seek to %lld in COW file of ubd "
11384 +                             "device %d, err = %d", bitmap_offset, i, -err);
11385 +
11386 +               n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
11387 +               if(n != sizeof(new_bitmap))
11388 +                       panic("Couldn't update bitmap  of ubd device %d, "
11389 +                             "err = %d", i, -n);
11390 +               
11391 +               /* Maybe we can map the COW page in, and maybe we can't.  If
11392 +                * it is a pre-V3 COW file, we can't, since the alignment will 
11393 +                * be wrong.  If it is a V3 or later COW file which has been 
11394 +                * moved to a system with a larger page size, then maybe we 
11395 +                * can't, depending on the exact location of the page.
11396 +                */
11397 +
11398 +               offset += dev->cow.data_offset;
11399 +
11400 +               /* Remove the remapping, putting the original anonymous page
11401 +                * back.  If the COW file can be mapped in, that is done.
11402 +                * Otherwise, the COW page is read in.
11403 +                */
11404 +
11405 +               if(!physmem_remove_mapping((void *) address))
11406 +                       panic("Address 0x%lx not remapped by ubd device %d", 
11407 +                             address, i);
11408 +               if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
11409 +                       physmem_subst_mapping((void *) address, dev->fd, 
11410 +                                             offset, 1);
11411 +               else {
11412 +                       err = os_seek_file(dev->fd, offset);
11413 +                       if(err < 0)
11414 +                               panic("Couldn't seek to %lld in COW file of "
11415 +                                     "ubd device %d, err = %d", offset, i, 
11416 +                                     -err);
11417 +
11418 +                       n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
11419 +                       if(n != PAGE_SIZE)
11420 +                               panic("Failed to read page from offset %llx of "
11421 +                                     "COW file of ubd device %d, err = %d",
11422 +                                     offset, i, -n);
11423 +               }
11424 +
11425 +               return(1);
11426 +       }
11427 +
11428 +       /* It's not a write on a ubd device */
11429 +       return(0);
11430 +}
11431 +
11432 +static struct remapper ubd_remapper = {
11433 +       .list   = LIST_HEAD_INIT(ubd_remapper.list),
11434 +       .proc   = ubd_check_remapped,
11435 +};
11436 +
11437 +static int ubd_remapper_setup(void)
11438 +{
11439 +       if(ubd_do_mmap)
11440 +               register_remapper(&ubd_remapper);
11441 +
11442 +       return(0);
11443 +}
11444 +
11445 +__initcall(ubd_remapper_setup);
11446 +
11447 +/*
11448 + * Overrides for Emacs so that we follow Linus's tabbing style.
11449 + * Emacs will notice this stuff at the end of the file and automatically
11450 + * adjust the settings for this buffer only.  This must remain at the end
11451 + * of the file.
11452 + * ---------------------------------------------------------------------------
11453 + * Local variables:
11454 + * c-file-style: "linux"
11455 + * End:
11456 + */
11457 diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_user.c um/arch/um/drivers/ubd_user.c
11458 --- orig/arch/um/drivers/ubd_user.c     1969-12-31 19:00:00.000000000 -0500
11459 +++ um/arch/um/drivers/ubd_user.c       2003-11-08 07:57:49.000000000 -0500
11460 @@ -0,0 +1,378 @@
11461 +/* 
11462 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
11463 + * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
11464 + * Licensed under the GPL
11465 + */
11466 +
11467 +#include <stddef.h>
11468 +#include <unistd.h>
11469 +#include <errno.h>
11470 +#include <sched.h>
11471 +#include <signal.h>
11472 +#include <string.h>
11473 +#include <netinet/in.h>
11474 +#include <sys/time.h>
11475 +#include <sys/socket.h>
11476 +#include <string.h>
11477 +#include <sys/mman.h>
11478 +#include <sys/param.h>
11479 +#include "asm/types.h"
11480 +#include "user_util.h"
11481 +#include "kern_util.h"
11482 +#include "user.h"
11483 +#include "ubd_user.h"
11484 +#include "os.h"
11485 +#include "cow.h"
11486 +
11487 +#include <endian.h>
11488 +#include <byteswap.h>
11489 +
11490 +static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
11491 +{
11492 +       struct uml_stat buf1, buf2;
11493 +       int err;
11494 +
11495 +       if(from_cmdline == NULL) return(1);
11496 +       if(!strcmp(from_cmdline, from_cow)) return(1);
11497 +
11498 +       err = os_stat_file(from_cmdline, &buf1);
11499 +       if(err < 0){
11500 +               printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
11501 +               return(1);
11502 +       }
11503 +       err = os_stat_file(from_cow, &buf2);
11504 +       if(err < 0){
11505 +               printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
11506 +               return(1);
11507 +       }
11508 +       if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
11509 +               return(1);
11510 +
11511 +       printk("Backing file mismatch - \"%s\" requested,\n"
11512 +              "\"%s\" specified in COW header of \"%s\"\n",
11513 +              from_cmdline, from_cow, cow);
11514 +       return(0);
11515 +}
11516 +
11517 +static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
11518 +{
11519 +       unsigned long modtime;
11520 +       long long actual;
11521 +       int err;
11522 +
11523 +       err = os_file_modtime(file, &modtime);
11524 +       if(err < 0){
11525 +               printk("Failed to get modification time of backing file "
11526 +                      "\"%s\", err = %d\n", file, -err);
11527 +               return(err);
11528 +       }
11529 +
11530 +       err = os_file_size(file, &actual);
11531 +       if(err < 0){
11532 +               printk("Failed to get size of backing file \"%s\", "
11533 +                      "err = %d\n", file, -err);
11534 +               return(err);
11535 +       }
11536 +
11537 +       if(actual != size){
11538 +               printk("Size mismatch (%ld vs %ld) of COW header vs backing "
11539 +                      "file\n", size, actual);
11540 +               return(-EINVAL);
11541 +       }
11542 +       if(modtime != mtime){
11543 +               printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
11544 +                      "file\n", mtime, modtime);
11545 +               return(-EINVAL);
11546 +       }
11547 +       return(0);
11548 +}
11549 +
11550 +int read_cow_bitmap(int fd, void *buf, int offset, int len)
11551 +{
11552 +       int err;
11553 +
11554 +       err = os_seek_file(fd, offset);
11555 +       if(err < 0) 
11556 +               return(err);
11557 +
11558 +       err = os_read_file(fd, buf, len);
11559 +       if(err < 0) 
11560 +               return(err);
11561 +
11562 +       return(0);
11563 +}
11564 +
11565 +int open_ubd_file(char *file, struct openflags *openflags, 
11566 +                 char **backing_file_out, int *bitmap_offset_out, 
11567 +                 unsigned long *bitmap_len_out, int *data_offset_out, 
11568 +                 int *create_cow_out)
11569 +{
11570 +       time_t mtime;
11571 +       __u64 size;
11572 +       __u32 version, align;
11573 +       char *backing_file;
11574 +        int fd, err, sectorsize, same, mode = 0644;
11575 +
11576 +        fd = os_open_file(file, *openflags, mode);
11577 +        if(fd < 0){
11578 +               if((fd == -ENOENT) && (create_cow_out != NULL))
11579 +                       *create_cow_out = 1;
11580 +                if(!openflags->w ||
11581 +                   ((errno != EROFS) && (errno != EACCES))) return(-errno);
11582 +               openflags->w = 0;
11583 +                fd = os_open_file(file, *openflags, mode); 
11584 +                if(fd < 0) 
11585 +                       return(fd);
11586 +        }
11587 +
11588 +       err = os_lock_file(fd, openflags->w);
11589 +       if(err < 0){
11590 +               printk("Failed to lock '%s', err = %d\n", file, -err);
11591 +               goto out_close;
11592 +       }
11593 +       
11594 +       if(backing_file_out == NULL) return(fd);
11595 +
11596 +       err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
11597 +                             &size, &sectorsize, &align, bitmap_offset_out);
11598 +       if(err && (*backing_file_out != NULL)){
11599 +               printk("Failed to read COW header from COW file \"%s\", "
11600 +                      "errno = %d\n", file, -err);
11601 +               goto out_close;
11602 +       }
11603 +       if(err) return(fd);
11604 +
11605 +       if(backing_file_out == NULL) return(fd);
11606 +       
11607 +       same = same_backing_files(*backing_file_out, backing_file, file);
11608 +
11609 +       if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
11610 +               printk("Switching backing file to '%s'\n", *backing_file_out);
11611 +               err = write_cow_header(file, fd, *backing_file_out,
11612 +                                      sectorsize, align, &size);
11613 +               if(err){
11614 +                       printk("Switch failed, errno = %d\n", -err);
11615 +                       return(err);
11616 +               }
11617 +       }
11618 +       else {
11619 +               *backing_file_out = backing_file;
11620 +               err = backing_file_mismatch(*backing_file_out, size, mtime);
11621 +               if(err) goto out_close;
11622 +       }
11623 +
11624 +       cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 
11625 +                 bitmap_len_out, data_offset_out);
11626 +
11627 +        return(fd);
11628 + out_close:
11629 +       os_close_file(fd);
11630 +       return(err);
11631 +}
11632 +
11633 +int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
11634 +                   int sectorsize, int alignment, int *bitmap_offset_out, 
11635 +                   unsigned long *bitmap_len_out, int *data_offset_out)
11636 +{
11637 +       int err, fd;
11638 +
11639 +       flags.c = 1;
11640 +       fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
11641 +       if(fd < 0){
11642 +               err = fd;
11643 +               printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
11644 +                      -err);
11645 +               goto out;
11646 +       }
11647 +
11648 +       err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
11649 +                           bitmap_offset_out, bitmap_len_out, 
11650 +                           data_offset_out);
11651 +       if(!err)
11652 +               return(fd);
11653 +
11654 +       os_close_file(fd);
11655 + out:
11656 +       return(err);
11657 +}
11658 +
11659 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
11660 +int read_ubd_fs(int fd, void *buffer, int len)
11661 +{
11662 +       return(os_read_file(fd, buffer, len));
11663 +}
11664 +
11665 +int write_ubd_fs(int fd, char *buffer, int len)
11666 +{
11667 +       return(os_write_file(fd, buffer, len));
11668 +}
11669 +
11670 +static int update_bitmap(struct io_thread_req *req)
11671 +{
11672 +       int n;
11673 +
11674 +       if(req->cow_offset == -1)
11675 +               return(0);
11676 +
11677 +       n = os_seek_file(req->fds[1], req->cow_offset);
11678 +       if(n < 0){
11679 +               printk("do_io - bitmap lseek failed : err = %d\n", -n);
11680 +               return(1);
11681 +       }
11682 +
11683 +       n = os_write_file(req->fds[1], &req->bitmap_words,
11684 +                         sizeof(req->bitmap_words));
11685 +       if(n != sizeof(req->bitmap_words)){
11686 +               printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
11687 +                      req->fds[1]);
11688 +               return(1);
11689 +       }
11690 +
11691 +       return(0);
11692 +}
11693 +
11694 +void do_io(struct io_thread_req *req)
11695 +{
11696 +       char *buf;
11697 +       unsigned long len;
11698 +       int n, nsectors, start, end, bit;
11699 +       int err;
11700 +       __u64 off;
11701 +
11702 +       if(req->op == UBD_MMAP){
11703 +               /* Touch the page to force the host to do any necessary IO to 
11704 +                * get it into memory 
11705 +                */
11706 +               n = *((volatile int *) req->buffer);
11707 +               req->error = update_bitmap(req);
11708 +               return;
11709 +       }
11710 +
11711 +       nsectors = req->length / req->sectorsize;
11712 +       start = 0;
11713 +       do {
11714 +               bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
11715 +               end = start;
11716 +               while((end < nsectors) && 
11717 +                     (ubd_test_bit(end, (unsigned char *) 
11718 +                                   &req->sector_mask) == bit))
11719 +                       end++;
11720 +
11721 +               off = req->offset + req->offsets[bit] + 
11722 +                       start * req->sectorsize;
11723 +               len = (end - start) * req->sectorsize;
11724 +               buf = &req->buffer[start * req->sectorsize];
11725 +
11726 +               err = os_seek_file(req->fds[bit], off);
11727 +               if(err < 0){
11728 +                       printk("do_io - lseek failed : err = %d\n", -err);
11729 +                       req->error = 1;
11730 +                       return;
11731 +               }
11732 +               if(req->op == UBD_READ){
11733 +                       n = 0;
11734 +                       do {
11735 +                               buf = &buf[n];
11736 +                               len -= n;
11737 +                               n = os_read_file(req->fds[bit], buf, len);
11738 +                               if (n < 0) {
11739 +                                       printk("do_io - read failed, err = %d "
11740 +                                              "fd = %d\n", -n, req->fds[bit]);
11741 +                                       req->error = 1;
11742 +                                       return;
11743 +                               }
11744 +                       } while((n < len) && (n != 0));
11745 +                       if (n < len) memset(&buf[n], 0, len - n);
11746 +               }
11747 +               else {
11748 +                       n = os_write_file(req->fds[bit], buf, len);
11749 +                       if(n != len){
11750 +                               printk("do_io - write failed err = %d "
11751 +                                      "fd = %d\n", -n, req->fds[bit]);
11752 +                               req->error = 1;
11753 +                               return;
11754 +                       }
11755 +               }
11756 +
11757 +               start = end;
11758 +       } while(start < nsectors);
11759 +
11760 +       req->error = update_bitmap(req);
11761 +}
11762 +
11763 +/* Changed in start_io_thread, which is serialized by being called only
11764 + * from ubd_init, which is an initcall.
11765 + */
11766 +int kernel_fd = -1;
11767 +
11768 +/* Only changed by the io thread */
11769 +int io_count = 0;
11770 +
11771 +int io_thread(void *arg)
11772 +{
11773 +       struct io_thread_req req;
11774 +       int n;
11775 +
11776 +       signal(SIGWINCH, SIG_IGN);
11777 +       while(1){
11778 +               n = os_read_file(kernel_fd, &req, sizeof(req));
11779 +               if(n != sizeof(req)){
11780 +                       if(n < 0)
11781 +                               printk("io_thread - read failed, fd = %d, "
11782 +                                      "err = %d\n", kernel_fd, -n);
11783 +                       else {
11784 +                               printk("io_thread - short read, fd = %d, "
11785 +                                      "length = %d\n", kernel_fd, n);
11786 +                       }
11787 +                       continue;
11788 +               }
11789 +               io_count++;
11790 +               do_io(&req);
11791 +               n = os_write_file(kernel_fd, &req, sizeof(req));
11792 +               if(n != sizeof(req))
11793 +                       printk("io_thread - write failed, fd = %d, err = %d\n",
11794 +                              kernel_fd, -n);
11795 +       }
11796 +}
11797 +
11798 +int start_io_thread(unsigned long sp, int *fd_out)
11799 +{
11800 +       int pid, fds[2], err;
11801 +
11802 +       err = os_pipe(fds, 1, 1);
11803 +       if(err < 0){
11804 +               printk("start_io_thread - os_pipe failed, err = %d\n", -err);
11805 +               goto out;
11806 +       }
11807 +
11808 +       kernel_fd = fds[0];
11809 +       *fd_out = fds[1];
11810 +
11811 +       pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
11812 +                   NULL);
11813 +       if(pid < 0){
11814 +               printk("start_io_thread - clone failed : errno = %d\n", errno);
11815 +               goto out_close;
11816 +       }
11817 +
11818 +       return(pid);
11819 +
11820 + out_close:
11821 +       os_close_file(fds[0]);
11822 +       os_close_file(fds[1]);
11823 +       kernel_fd = -1;
11824 +       *fd_out = -1;
11825 + out:
11826 +       return(err);
11827 +}
11828 +
11829 +/*
11830 + * Overrides for Emacs so that we follow Linus's tabbing style.
11831 + * Emacs will notice this stuff at the end of the file and automatically
11832 + * adjust the settings for this buffer only.  This must remain at the end
11833 + * of the file.
11834 + * ---------------------------------------------------------------------------
11835 + * Local variables:
11836 + * c-file-style: "linux"
11837 + * End:
11838 + */
11839 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.c um/arch/um/drivers/xterm.c
11840 --- orig/arch/um/drivers/xterm.c        1969-12-31 19:00:00.000000000 -0500
11841 +++ um/arch/um/drivers/xterm.c  2003-10-21 03:26:06.000000000 -0400
11842 @@ -0,0 +1,201 @@
11843 +/* 
11844 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
11845 + * Licensed under the GPL
11846 + */
11847 +
11848 +#include <stdio.h>
11849 +#include <stdlib.h>
11850 +#include <unistd.h>
11851 +#include <string.h>
11852 +#include <errno.h>
11853 +#include <termios.h>
11854 +#include <signal.h>
11855 +#include <sched.h>
11856 +#include <sys/socket.h>
11857 +#include "kern_util.h"
11858 +#include "chan_user.h"
11859 +#include "helper.h"
11860 +#include "user_util.h"
11861 +#include "user.h"
11862 +#include "os.h"
11863 +#include "xterm.h"
11864 +
11865 +struct xterm_chan {
11866 +       int pid;
11867 +       int helper_pid;
11868 +       char *title;
11869 +       int device;
11870 +       int raw;
11871 +       struct termios tt;
11872 +       unsigned long stack;
11873 +       int direct_rcv;
11874 +};
11875 +
11876 +void *xterm_init(char *str, int device, struct chan_opts *opts)
11877 +{
11878 +       struct xterm_chan *data;
11879 +
11880 +       data = malloc(sizeof(*data));
11881 +       if(data == NULL) return(NULL);
11882 +       *data = ((struct xterm_chan) { .pid             = -1, 
11883 +                                      .helper_pid      = -1,
11884 +                                      .device          = device, 
11885 +                                      .title           = opts->xterm_title,
11886 +                                      .raw             = opts->raw,
11887 +                                      .stack           = opts->tramp_stack,
11888 +                                      .direct_rcv      = !opts->in_kernel } );
11889 +       return(data);
11890 +}
11891 +
11892 +/* Only changed by xterm_setup, which is a setup */
11893 +static char *terminal_emulator = "xterm";
11894 +static char *title_switch = "-T";
11895 +static char *exec_switch = "-e";
11896 +
11897 +static int __init xterm_setup(char *line, int *add)
11898 +{
11899 +       *add = 0;
11900 +       terminal_emulator = line;
11901 +
11902 +       line = strchr(line, ',');
11903 +       if(line == NULL) return(0);
11904 +       *line++ = '\0';
11905 +       if(*line) title_switch = line;
11906 +
11907 +       line = strchr(line, ',');
11908 +       if(line == NULL) return(0);
11909 +       *line++ = '\0';
11910 +       if(*line) exec_switch = line;
11911 +
11912 +       return(0);
11913 +}
11914 +
11915 +__uml_setup("xterm=", xterm_setup,
11916 +"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
11917 +"    Specifies an alternate terminal emulator to use for the debugger,\n"
11918 +"    consoles, and serial lines when they are attached to the xterm channel.\n"
11919 +"    The values are the terminal emulator binary, the switch it uses to set\n"
11920 +"    its title, and the switch it uses to execute a subprocess,\n"
11921 +"    respectively.  The title switch must have the form '<switch> title',\n"
11922 +"    not '<switch>=title'.  Similarly, the exec switch must have the form\n"
11923 +"    '<switch> command arg1 arg2 ...'.\n"
11924 +"    The default values are 'xterm=xterm,-T,-e'.  Values for gnome-terminal\n"
11925 +"    are 'xterm=gnome-terminal,-t,-x'.\n\n"
11926 +);
11927 +
11928 +int xterm_open(int input, int output, int primary, void *d, char **dev_out)
11929 +{
11930 +       struct xterm_chan *data = d;
11931 +       unsigned long stack;
11932 +       int pid, fd, new, err;
11933 +       char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
11934 +       char *argv[] = { terminal_emulator, title_switch, title, exec_switch, 
11935 +                        "/usr/lib/uml/port-helper", "-uml-socket",
11936 +                        file, NULL };
11937 +
11938 +       if(os_access(argv[4], OS_ACC_X_OK) < 0)
11939 +               argv[4] = "port-helper";
11940 +
11941 +       fd = mkstemp(file);
11942 +       if(fd < 0){
11943 +               printk("xterm_open : mkstemp failed, errno = %d\n", errno);
11944 +               return(-errno);
11945 +       }
11946 +
11947 +       if(unlink(file)){
11948 +               printk("xterm_open : unlink failed, errno = %d\n", errno);
11949 +               return(-errno);
11950 +       }
11951 +       os_close_file(fd);
11952 +
11953 +       fd = os_create_unix_socket(file, sizeof(file), 1);
11954 +       if(fd < 0){
11955 +               printk("xterm_open : create_unix_socket failed, errno = %d\n", 
11956 +                      -fd);
11957 +               return(fd);
11958 +       }
11959 +
11960 +       sprintf(title, data->title, data->device);
11961 +       stack = data->stack;
11962 +       pid = run_helper(NULL, NULL, argv, &stack);
11963 +       if(pid < 0){
11964 +               printk("xterm_open : run_helper failed, errno = %d\n", -pid);
11965 +               return(pid);
11966 +       }
11967 +
11968 +       if(data->stack == 0) free_stack(stack, 0);
11969 +
11970 +       if(data->direct_rcv)
11971 +               new = os_rcv_fd(fd, &data->helper_pid);
11972 +       else {
11973 +               err = os_set_fd_block(fd, 0);
11974 +               if(err < 0){
11975 +                       printk("xterm_open : failed to set descriptor "
11976 +                              "non-blocking, err = %d\n", -err);
11977 +                       return(err);
11978 +               }
11979 +               new = xterm_fd(fd, &data->helper_pid);
11980 +       }
11981 +       if(new < 0){
11982 +               printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
11983 +               goto out;
11984 +       }
11985 +
11986 +       tcgetattr(new, &data->tt);
11987 +       if(data->raw) raw(new, 0);
11988 +
11989 +       data->pid = pid;
11990 +       *dev_out = NULL;
11991 + out:
11992 +       unlink(file);
11993 +       return(new);
11994 +}
11995 +
11996 +void xterm_close(int fd, void *d)
11997 +{
11998 +       struct xterm_chan *data = d;
11999 +       
12000 +       if(data->pid != -1) 
12001 +               os_kill_process(data->pid, 1);
12002 +       data->pid = -1;
12003 +       if(data->helper_pid != -1) 
12004 +               os_kill_process(data->helper_pid, 0);
12005 +       data->helper_pid = -1;
12006 +       os_close_file(fd);
12007 +}
12008 +
12009 +void xterm_free(void *d)
12010 +{
12011 +       free(d);
12012 +}
12013 +
12014 +int xterm_console_write(int fd, const char *buf, int n, void *d)
12015 +{
12016 +       struct xterm_chan *data = d;
12017 +
12018 +       return(generic_console_write(fd, buf, n, &data->tt));
12019 +}
12020 +
12021 +struct chan_ops xterm_ops = {
12022 +       .type           = "xterm",
12023 +       .init           = xterm_init,
12024 +       .open           = xterm_open,
12025 +       .close          = xterm_close,
12026 +       .read           = generic_read,
12027 +       .write          = generic_write,
12028 +       .console_write  = xterm_console_write,
12029 +       .window_size    = generic_window_size,
12030 +       .free           = xterm_free,
12031 +       .winch          = 1,
12032 +};
12033 +
12034 +/*
12035 + * Overrides for Emacs so that we follow Linus's tabbing style.
12036 + * Emacs will notice this stuff at the end of the file and automatically
12037 + * adjust the settings for this buffer only.  This must remain at the end
12038 + * of the file.
12039 + * ---------------------------------------------------------------------------
12040 + * Local variables:
12041 + * c-file-style: "linux"
12042 + * End:
12043 + */
12044 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.h um/arch/um/drivers/xterm.h
12045 --- orig/arch/um/drivers/xterm.h        1969-12-31 19:00:00.000000000 -0500
12046 +++ um/arch/um/drivers/xterm.h  2003-10-21 03:26:06.000000000 -0400
12047 @@ -0,0 +1,22 @@
12048 +/* 
12049 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12050 + * Licensed under the GPL
12051 + */
12052 +
12053 +#ifndef __XTERM_H__
12054 +#define __XTERM_H__
12055 +
12056 +extern int xterm_fd(int socket, int *pid_out);
12057 +
12058 +#endif
12059 +
12060 +/*
12061 + * Overrides for Emacs so that we follow Linus's tabbing style.
12062 + * Emacs will notice this stuff at the end of the file and automatically
12063 + * adjust the settings for this buffer only.  This must remain at the end
12064 + * of the file.
12065 + * ---------------------------------------------------------------------------
12066 + * Local variables:
12067 + * c-file-style: "linux"
12068 + * End:
12069 + */
12070 diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm_kern.c um/arch/um/drivers/xterm_kern.c
12071 --- orig/arch/um/drivers/xterm_kern.c   1969-12-31 19:00:00.000000000 -0500
12072 +++ um/arch/um/drivers/xterm_kern.c     2003-10-21 03:26:06.000000000 -0400
12073 @@ -0,0 +1,82 @@
12074 +/* 
12075 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
12076 + * Licensed under the GPL
12077 + */
12078 +
12079 +#include "linux/errno.h"
12080 +#include "linux/slab.h"
12081 +#include "asm/semaphore.h"
12082 +#include "asm/irq.h"
12083 +#include "irq_user.h"
12084 +#include "irq_kern.h"
12085 +#include "kern_util.h"
12086 +#include "os.h"
12087 +#include "xterm.h"
12088 +
12089 +struct xterm_wait {
12090 +       struct semaphore sem;
12091 +       int fd;
12092 +       int pid;
12093 +       int new_fd;
12094 +};
12095 +
12096 +static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
12097 +{
12098 +       struct xterm_wait *xterm = data;
12099 +       int fd;
12100 +
12101 +       fd = os_rcv_fd(xterm->fd, &xterm->pid);
12102 +       if(fd == -EAGAIN)
12103 +               return;
12104 +
12105 +       xterm->new_fd = fd;
12106 +       up(&xterm->sem);
12107 +}
12108 +
12109 +int xterm_fd(int socket, int *pid_out)
12110 +{
12111 +       struct xterm_wait *data;
12112 +       int err, ret;
12113 +
12114 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
12115 +       if(data == NULL){
12116 +               printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
12117 +               return(-ENOMEM);
12118 +       }
12119 +       *data = ((struct xterm_wait) 
12120 +               { .sem          = __SEMAPHORE_INITIALIZER(data->sem, 0),
12121 +                 .fd           = socket,
12122 +                 .pid          = -1,
12123 +                 .new_fd       = -1 });
12124 +
12125 +       err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 
12126 +                            SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
12127 +                            "xterm", data);
12128 +       if(err){
12129 +               printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
12130 +                      "err = %d\n",  err);
12131 +               ret = err;
12132 +               goto out;
12133 +       }
12134 +       down(&data->sem);
12135 +
12136 +       free_irq(XTERM_IRQ, data);
12137 +
12138 +       ret = data->new_fd;
12139 +       *pid_out = data->pid;
12140 + out:
12141 +       kfree(data);
12142 +
12143 +       return(ret);
12144 +}
12145 +
12146 +/*
12147 + * Overrides for Emacs so that we follow Linus's tabbing style.
12148 + * Emacs will notice this stuff at the end of the file and automatically
12149 + * adjust the settings for this buffer only.  This must remain at the end
12150 + * of the file.
12151 + * ---------------------------------------------------------------------------
12152 + * Local variables:
12153 + * c-file-style: "linux"
12154 + * End:
12155 + */
12156 diff -Naur -X ../exclude-files orig/arch/um/dyn_link.ld.in um/arch/um/dyn_link.ld.in
12157 --- orig/arch/um/dyn_link.ld.in 1969-12-31 19:00:00.000000000 -0500
12158 +++ um/arch/um/dyn_link.ld.in   2003-10-21 03:26:06.000000000 -0400
12159 @@ -0,0 +1,172 @@
12160 +OUTPUT_FORMAT("ELF_FORMAT")
12161 +OUTPUT_ARCH(ELF_ARCH)
12162 +ENTRY(_start)
12163 +SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
12164 +/* Do we need any of these for elf?
12165 +   __DYNAMIC = 0;    */
12166 +SECTIONS
12167 +{
12168 +  . = START() + SIZEOF_HEADERS;
12169 +  .interp         : { *(.interp) }
12170 +  . = ALIGN(4096);
12171 +  __binary_start = .;
12172 +  . = ALIGN(4096);             /* Init code and data */
12173 +  _stext = .;
12174 +  __init_begin = .;
12175 +  .text.init : { *(.text.init) }
12176 +
12177 +  . = ALIGN(4096);
12178 +
12179 +  /* Read-only sections, merged into text segment: */
12180 +  .hash           : { *(.hash) }
12181 +  .dynsym         : { *(.dynsym) }
12182 +  .dynstr         : { *(.dynstr) }
12183 +  .gnu.version    : { *(.gnu.version) }
12184 +  .gnu.version_d  : { *(.gnu.version_d) }
12185 +  .gnu.version_r  : { *(.gnu.version_r) }
12186 +  .rel.init       : { *(.rel.init) }
12187 +  .rela.init      : { *(.rela.init) }
12188 +  .rel.text       : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
12189 +  .rela.text      : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
12190 +  .rel.fini       : { *(.rel.fini) }
12191 +  .rela.fini      : { *(.rela.fini) }
12192 +  .rel.rodata     : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
12193 +  .rela.rodata    : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
12194 +  .rel.data       : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
12195 +  .rela.data      : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
12196 +  .rel.tdata     : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
12197 +  .rela.tdata    : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
12198 +  .rel.tbss      : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
12199 +  .rela.tbss     : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
12200 +  .rel.ctors      : { *(.rel.ctors) }
12201 +  .rela.ctors     : { *(.rela.ctors) }
12202 +  .rel.dtors      : { *(.rel.dtors) }
12203 +  .rela.dtors     : { *(.rela.dtors) }
12204 +  .rel.got        : { *(.rel.got) }
12205 +  .rela.got       : { *(.rela.got) }
12206 +  .rel.bss        : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
12207 +  .rela.bss       : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
12208 +  .rel.plt        : { *(.rel.plt) }
12209 +  .rela.plt       : { *(.rela.plt) }
12210 +  .init           : {
12211 +    KEEP (*(.init))
12212 +  } =0x90909090
12213 +  .plt            : { *(.plt) }
12214 +  .text           : {
12215 +    *(.text .stub .text.* .gnu.linkonce.t.*)
12216 +    /* .gnu.warning sections are handled specially by elf32.em.  */
12217 +    *(.gnu.warning)
12218 +  } =0x90909090
12219 +  .fini           : {
12220 +    KEEP (*(.fini))
12221 +  } =0x90909090
12222 +
12223 +  PROVIDE (__etext = .);
12224 +  PROVIDE (_etext = .);
12225 +  PROVIDE (etext = .);
12226 +  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
12227 +  .rodata1        : { *(.rodata1) }
12228 +  .eh_frame_hdr : { *(.eh_frame_hdr) }
12229 +
12230 +
12231 +  . = ALIGN(4096);
12232 +  PROVIDE (_sdata = .);
12233 +
12234 +include(`arch/um/common.ld.in')
12235 +
12236 +  /* Ensure the __preinit_array_start label is properly aligned.  We
12237 +     could instead move the label definition inside the section, but
12238 +     the linker would then create the section even if it turns out to
12239 +     be empty, which isn't pretty.  */
12240 +  . = ALIGN(32 / 8);
12241 +  .preinit_array     : { *(.preinit_array) }
12242 +  .init_array     : { *(.init_array) }
12243 +  .fini_array     : { *(.fini_array) }
12244 +  .data           : {
12245 +    . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
12246 +    *(.data.init_task)
12247 +    *(.data .data.* .gnu.linkonce.d.*)
12248 +    SORT(CONSTRUCTORS)
12249 +  }
12250 +  .data1          : { *(.data1) }
12251 +  .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
12252 +  .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
12253 +  .eh_frame       : { KEEP (*(.eh_frame)) }
12254 +  .gcc_except_table   : { *(.gcc_except_table) }
12255 +  .dynamic        : { *(.dynamic) }
12256 +  .ctors          : {
12257 +    /* gcc uses crtbegin.o to find the start of
12258 +       the constructors, so we make sure it is
12259 +       first.  Because this is a wildcard, it
12260 +       doesn't matter if the user does not
12261 +       actually link against crtbegin.o; the
12262 +       linker won't look for a file to match a
12263 +       wildcard.  The wildcard also means that it
12264 +       doesn't matter which directory crtbegin.o
12265 +       is in.  */
12266 +    KEEP (*crtbegin.o(.ctors))
12267 +    /* We don't want to include the .ctor section from
12268 +       from the crtend.o file until after the sorted ctors.
12269 +       The .ctor section from the crtend file contains the
12270 +       end of ctors marker and it must be last */
12271 +    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
12272 +    KEEP (*(SORT(.ctors.*)))
12273 +    KEEP (*(.ctors))
12274 +  }
12275 +  .dtors          : {
12276 +    KEEP (*crtbegin.o(.dtors))
12277 +    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
12278 +    KEEP (*(SORT(.dtors.*)))
12279 +    KEEP (*(.dtors))
12280 +  }
12281 +  .jcr            : { KEEP (*(.jcr)) }
12282 +  .got            : { *(.got.plt) *(.got) }
12283 +  _edata = .;
12284 +  PROVIDE (edata = .);
12285 +  __bss_start = .;
12286 +  .bss            : {
12287 +   *(.dynbss)
12288 +   *(.bss .bss.* .gnu.linkonce.b.*)
12289 +   *(COMMON)
12290 +   /* Align here to ensure that the .bss section occupies space up to
12291 +      _end.  Align after .bss to ensure correct alignment even if the
12292 +      .bss section disappears because there are no input sections.  */
12293 +   . = ALIGN(32 / 8);
12294 +  . = ALIGN(32 / 8);
12295 +  }
12296 +  _end = .;
12297 +  PROVIDE (end = .);
12298 +   /* Stabs debugging sections.  */
12299 +  .stab          0 : { *(.stab) }
12300 +  .stabstr       0 : { *(.stabstr) }
12301 +  .stab.excl     0 : { *(.stab.excl) }
12302 +  .stab.exclstr  0 : { *(.stab.exclstr) }
12303 +  .stab.index    0 : { *(.stab.index) }
12304 +  .stab.indexstr 0 : { *(.stab.indexstr) }
12305 +  .comment       0 : { *(.comment) }
12306 +  /* DWARF debug sections.
12307 +     Symbols in the DWARF debugging sections are relative to the beginning
12308 +     of the section so we begin them at 0.  */
12309 +  /* DWARF 1 */
12310 +  .debug          0 : { *(.debug) }
12311 +  .line           0 : { *(.line) }
12312 +  /* GNU DWARF 1 extensions */
12313 +  .debug_srcinfo  0 : { *(.debug_srcinfo) }
12314 +  .debug_sfnames  0 : { *(.debug_sfnames) }
12315 +  /* DWARF 1.1 and DWARF 2 */
12316 +  .debug_aranges  0 : { *(.debug_aranges) }
12317 +  .debug_pubnames 0 : { *(.debug_pubnames) }
12318 +  /* DWARF 2 */
12319 +  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
12320 +  .debug_abbrev   0 : { *(.debug_abbrev) }
12321 +  .debug_line     0 : { *(.debug_line) }
12322 +  .debug_frame    0 : { *(.debug_frame) }
12323 +  .debug_str      0 : { *(.debug_str) }
12324 +  .debug_loc      0 : { *(.debug_loc) }
12325 +  .debug_macinfo  0 : { *(.debug_macinfo) }
12326 +  /* SGI/MIPS DWARF 2 extensions */
12327 +  .debug_weaknames 0 : { *(.debug_weaknames) }
12328 +  .debug_funcnames 0 : { *(.debug_funcnames) }
12329 +  .debug_typenames 0 : { *(.debug_typenames) }
12330 +  .debug_varnames  0 : { *(.debug_varnames) }
12331 +}
12332 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs.h um/arch/um/fs/hostfs/hostfs.h
12333 --- orig/arch/um/fs/hostfs/hostfs.h     1969-12-31 19:00:00.000000000 -0500
12334 +++ um/arch/um/fs/hostfs/hostfs.h       2003-12-17 10:52:50.000000000 -0500
12335 @@ -0,0 +1,69 @@
12336 +#ifndef __UM_FS_HOSTFS
12337 +#define __UM_FS_HOSTFS
12338 +
12339 +#include "os.h"
12340 +
12341 +/* These are exactly the same definitions as in fs.h, but the names are 
12342 + * changed so that this file can be included in both kernel and user files.
12343 + */
12344 +
12345 +#define HOSTFS_ATTR_MODE       1
12346 +#define HOSTFS_ATTR_UID        2
12347 +#define HOSTFS_ATTR_GID        4
12348 +#define HOSTFS_ATTR_SIZE       8
12349 +#define HOSTFS_ATTR_ATIME      16
12350 +#define HOSTFS_ATTR_MTIME      32
12351 +#define HOSTFS_ATTR_CTIME      64
12352 +#define HOSTFS_ATTR_ATIME_SET  128
12353 +#define HOSTFS_ATTR_MTIME_SET  256
12354 +#define HOSTFS_ATTR_FORCE      512     /* Not a change, but a change it */
12355 +#define HOSTFS_ATTR_ATTR_FLAG  1024
12356 +
12357 +struct hostfs_iattr {
12358 +       unsigned int    ia_valid;
12359 +       mode_t          ia_mode;
12360 +       uid_t           ia_uid;
12361 +       gid_t           ia_gid;
12362 +       loff_t          ia_size;
12363 +       time_t          ia_atime;
12364 +       time_t          ia_mtime;
12365 +       time_t          ia_ctime;
12366 +       unsigned int    ia_attr_flags;
12367 +};
12368 +
12369 +extern int stat_file(const char *path, int *dev_out, 
12370 +                    unsigned long long *inode_out, int *mode_out, 
12371 +                    int *nlink_out, int *uid_out, int *gid_out, 
12372 +                    unsigned long long *size_out, unsigned long *atime_out, 
12373 +                    unsigned long *mtime_out, unsigned long *ctime_out, 
12374 +                    int *blksize_out, unsigned long long *blocks_out);
12375 +extern int access_file(char *path, int r, int w, int x);
12376 +extern int open_file(char *path, int r, int w, int append);
12377 +extern int file_type(const char *path, int *rdev);
12378 +extern void *open_dir(char *path, int *err_out);
12379 +extern char *read_dir(void *stream, unsigned long long *pos, 
12380 +                     unsigned long long *ino_out, int *len_out);
12381 +extern void close_file(void *stream);
12382 +extern void close_dir(void *stream);
12383 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
12384 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
12385 +                     int len);
12386 +extern int lseek_file(int fd, long long offset, int whence);
12387 +extern int file_create(char *name, int ur, int uw, int ux, int gr, 
12388 +                      int gw, int gx, int or, int ow, int ox);
12389 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
12390 +extern int make_symlink(const char *from, const char *to);
12391 +extern int unlink_file(const char *file);
12392 +extern int do_mkdir(const char *file, int mode);
12393 +extern int do_rmdir(const char *file);
12394 +extern int do_mknod(const char *file, int mode, int dev);
12395 +extern int link_file(const char *from, const char *to);
12396 +extern int do_readlink(char *file, char *buf, int size);
12397 +extern int rename_file(char *from, char *to);
12398 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
12399 +                    long long *bfree_out, long long *bavail_out, 
12400 +                    long long *files_out, long long *ffree_out, 
12401 +                    void *fsid_out, int fsid_size, long *namelen_out, 
12402 +                    long *spare_out);
12403 +
12404 +#endif
12405 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_kern.c um/arch/um/fs/hostfs/hostfs_kern.c
12406 --- orig/arch/um/fs/hostfs/hostfs_kern.c        1969-12-31 19:00:00.000000000 -0500
12407 +++ um/arch/um/fs/hostfs/hostfs_kern.c  2003-10-21 03:26:06.000000000 -0400
12408 @@ -0,0 +1,965 @@
12409 +/* 
12410 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12411 + * Licensed under the GPL
12412 + */
12413 +
12414 +#include <linux/stddef.h>
12415 +#include <linux/fs.h>
12416 +#include <linux/version.h>
12417 +#include <linux/module.h>
12418 +#include <linux/init.h>
12419 +#include <linux/slab.h>
12420 +#include <linux/pagemap.h>
12421 +#include <linux/blkdev.h>
12422 +#include <asm/uaccess.h>
12423 +#include "hostfs.h"
12424 +#include "kern_util.h"
12425 +#include "kern.h"
12426 +#include "user_util.h"
12427 +#include "2_5compat.h"
12428 +#include "init.h"
12429 +
12430 +#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i)
12431 +
12432 +int hostfs_d_delete(struct dentry *dentry)
12433 +{
12434 +       return(1);
12435 +}
12436 +
12437 +struct dentry_operations hostfs_dentry_ops = {
12438 +       .d_delete               = hostfs_d_delete,
12439 +};
12440 +
12441 +#define DEFAULT_ROOT "/"
12442 +
12443 +/* Changed in hostfs_args before the kernel starts running */
12444 +static char *jail_dir = NULL;
12445 +static int append = 0;
12446 +
12447 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
12448 +
12449 +static struct inode_operations hostfs_iops;
12450 +static struct inode_operations hostfs_dir_iops;
12451 +static struct address_space_operations hostfs_link_aops;
12452 +
12453 +static int __init hostfs_args(char *options, int *add)
12454 +{
12455 +       char *ptr;
12456 +
12457 +       ptr = strchr(options, ',');
12458 +       if(ptr != NULL)
12459 +               *ptr++ = '\0';
12460 +       if(*options != '\0')
12461 +               jail_dir = options;
12462 +
12463 +       options = ptr;
12464 +       while(options){
12465 +               ptr = strchr(options, ',');
12466 +               if(ptr != NULL)
12467 +                       *ptr++ = '\0';
12468 +               if(*options != '\0'){
12469 +                       if(!strcmp(options, "append"))
12470 +                               append = 1;
12471 +                       else printf("hostfs_args - unsupported option - %s\n",
12472 +                                   options);
12473 +               }
12474 +               options = ptr;
12475 +       }
12476 +       return(0);
12477 +}
12478 +
12479 +__uml_setup("hostfs=", hostfs_args,
12480 +"hostfs=<root dir>,<flags>,...\n"
12481 +"    This is used to set hostfs parameters.  The root directory argument\n"
12482 +"    is used to confine all hostfs mounts to within the specified directory\n"
12483 +"    tree on the host.  If this isn't specified, then a user inside UML can\n"
12484 +"    mount anything on the host that's accessible to the user that's running\n"
12485 +"    it.\n"
12486 +"    The only flag currently supported is 'append', which specifies that all\n"
12487 +"    files opened by hostfs will be opened in append mode.\n\n"
12488 +);
12489 +
12490 +static char *dentry_name(struct dentry *dentry, int extra)
12491 +{
12492 +       struct dentry *parent;
12493 +       char *root, *name;
12494 +       int len;
12495 +
12496 +       len = 0;
12497 +       parent = dentry;
12498 +       while(parent->d_parent != parent){
12499 +               len += parent->d_name.len + 1;
12500 +               parent = parent->d_parent;
12501 +       }
12502 +       
12503 +       root = parent->d_inode->u.hostfs_i.host_filename;
12504 +       len += strlen(root);
12505 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
12506 +       if(name == NULL) return(NULL);
12507 +
12508 +       name[len] = '\0';
12509 +       parent = dentry;
12510 +       while(parent->d_parent != parent){
12511 +               len -= parent->d_name.len + 1;
12512 +               name[len] = '/';
12513 +               strncpy(&name[len + 1], parent->d_name.name, 
12514 +                       parent->d_name.len);
12515 +               parent = parent->d_parent;
12516 +       }
12517 +       strncpy(name, root, strlen(root));
12518 +       return(name);
12519 +}
12520 +
12521 +static char *inode_name(struct inode *ino, int extra)
12522 +{
12523 +       struct dentry *dentry;
12524 +
12525 +       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
12526 +       return(dentry_name(dentry, extra));
12527 +}
12528 +
12529 +static int read_name(struct inode *ino, char *name)
12530 +{
12531 +       /* The non-int inode fields are copied into ints by stat_file and
12532 +        * then copied into the inode because passing the actual pointers
12533 +        * in and having them treated as int * breaks on big-endian machines
12534 +        */
12535 +       int err;
12536 +       int i_dev, i_mode, i_nlink, i_blksize;
12537 +       unsigned long long i_size;
12538 +       unsigned long long i_ino;
12539 +       unsigned long long i_blocks;
12540 +       err = stat_file(name, &i_dev, &i_ino, &i_mode, &i_nlink, 
12541 +                       &ino->i_uid, &ino->i_gid, &i_size, &ino->i_atime, 
12542 +                       &ino->i_mtime, &ino->i_ctime, &i_blksize, &i_blocks);
12543 +       if(err) return(err);
12544 +       ino->i_ino = i_ino;
12545 +       ino->i_dev = i_dev;
12546 +       ino->i_mode = i_mode;
12547 +       ino->i_nlink = i_nlink;
12548 +       ino->i_size = i_size;
12549 +       ino->i_blksize = i_blksize;
12550 +       ino->i_blocks = i_blocks;
12551 +       if(kdev_same(ino->i_sb->s_dev, ROOT_DEV) && (ino->i_uid == getuid()))
12552 +               ino->i_uid = 0;
12553 +       return(0);
12554 +}
12555 +
12556 +static char *follow_link(char *link)
12557 +{
12558 +       int len, n;
12559 +       char *name, *resolved, *end;
12560 +
12561 +       len = 64;
12562 +       while(1){
12563 +               n = -ENOMEM;
12564 +               name = kmalloc(len, GFP_KERNEL);
12565 +               if(name == NULL)
12566 +                       goto out;
12567 +
12568 +               n = do_readlink(link, name, len);
12569 +               if(n < len)
12570 +                       break;
12571 +               len *= 2;
12572 +               kfree(name);
12573 +       }
12574 +       if(n < 0)
12575 +               goto out_free;
12576 +
12577 +       if(*name == '/')
12578 +               return(name);
12579 +
12580 +       end = strrchr(link, '/');
12581 +       if(end == NULL)
12582 +               return(name);
12583 +
12584 +       *(end + 1) = '\0';
12585 +       len = strlen(link) + strlen(name) + 1;
12586 +
12587 +       resolved = kmalloc(len, GFP_KERNEL);
12588 +       if(resolved == NULL){
12589 +               n = -ENOMEM;
12590 +               goto out_free;
12591 +       }
12592 +
12593 +       sprintf(resolved, "%s%s", link, name);
12594 +       kfree(name);
12595 +       kfree(link);
12596 +       return(resolved);
12597 +
12598 + out_free:
12599 +       kfree(name);
12600 + out:
12601 +       return(ERR_PTR(n));
12602 +}
12603 +
12604 +static int read_inode(struct inode *ino)
12605 +{
12606 +       char *name;
12607 +       int err;
12608 +
12609 +       err = -ENOMEM;
12610 +       name = inode_name(ino, 0);
12611 +       if(name == NULL) 
12612 +               goto out;
12613 +
12614 +       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
12615 +               name = follow_link(name);
12616 +               if(IS_ERR(name)){
12617 +                       err = PTR_ERR(name);
12618 +                       goto out;
12619 +               }
12620 +       }
12621 +       
12622 +       err = read_name(ino, name);
12623 +       kfree(name);
12624 + out:
12625 +       return(err);
12626 +}
12627 +
12628 +void hostfs_delete_inode(struct inode *ino)
12629 +{
12630 +       if(ino->u.hostfs_i.host_filename) 
12631 +               kfree(ino->u.hostfs_i.host_filename);
12632 +       ino->u.hostfs_i.host_filename = NULL;
12633 +
12634 +       if(ino->u.hostfs_i.fd != -1) 
12635 +               close_file(&ino->u.hostfs_i.fd);
12636 +
12637 +       ino->u.hostfs_i.mode = 0;
12638 +       clear_inode(ino);
12639 +}
12640 +
12641 +int hostfs_statfs(struct super_block *sb, struct statfs *sf)
12642 +{
12643 +       /* do_statfs uses struct statfs64 internally, but the linux kernel
12644 +        * struct statfs still has 32-bit versions for most of these fields,
12645 +        * so we convert them here
12646 +        */
12647 +       int err;
12648 +       long long f_blocks;
12649 +       long long f_bfree;
12650 +       long long f_bavail;
12651 +       long long f_files;
12652 +       long long f_ffree;
12653 +
12654 +       err = do_statfs(sb->s_root->d_inode->u.hostfs_i.host_filename,
12655 +                       &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
12656 +                       &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
12657 +                       &sf->f_namelen, sf->f_spare);
12658 +       if(err) return(err);
12659 +       sf->f_blocks = f_blocks;
12660 +       sf->f_bfree = f_bfree;
12661 +       sf->f_bavail = f_bavail;
12662 +       sf->f_files = f_files;
12663 +       sf->f_ffree = f_ffree;
12664 +       sf->f_type = HOSTFS_SUPER_MAGIC;
12665 +       return(0);
12666 +}
12667 +
12668 +static struct super_operations hostfs_sbops = { 
12669 +       .put_inode      = force_delete,
12670 +       .delete_inode   = hostfs_delete_inode,
12671 +       .statfs         = hostfs_statfs,
12672 +};
12673 +
12674 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
12675 +{
12676 +       void *dir;
12677 +       char *name;
12678 +       unsigned long long next, ino;
12679 +       int error, len;
12680 +
12681 +       name = dentry_name(file->f_dentry, 0);
12682 +       if(name == NULL) return(-ENOMEM);
12683 +       dir = open_dir(name, &error);
12684 +       kfree(name);
12685 +       if(dir == NULL) return(-error);
12686 +       next = file->f_pos;
12687 +       while((name = read_dir(dir, &next, &ino, &len)) != NULL){
12688 +               error = (*filldir)(ent, name, len, file->f_pos, 
12689 +                                  ino, DT_UNKNOWN);
12690 +               if(error) break;
12691 +               file->f_pos = next;
12692 +       }
12693 +       close_dir(dir);
12694 +       return(0);
12695 +}
12696 +
12697 +int hostfs_file_open(struct inode *ino, struct file *file)
12698 +{
12699 +       char *name;
12700 +       int mode = 0, r = 0, w = 0, fd;
12701 +
12702 +       mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
12703 +       if((mode & ino->u.hostfs_i.mode) == mode)
12704 +               return(0);
12705 +
12706 +       /* The file may already have been opened, but with the wrong access,
12707 +        * so this resets things and reopens the file with the new access.
12708 +        */
12709 +       if(ino->u.hostfs_i.fd != -1){
12710 +               close_file(&ino->u.hostfs_i.fd);
12711 +               ino->u.hostfs_i.fd = -1;
12712 +       }
12713 +
12714 +       ino->u.hostfs_i.mode |= mode;
12715 +       if(ino->u.hostfs_i.mode & FMODE_READ) 
12716 +               r = 1;
12717 +       if(ino->u.hostfs_i.mode & FMODE_WRITE) 
12718 +               w = 1;
12719 +       if(w) 
12720 +               r = 1;
12721 +
12722 +       name = dentry_name(file->f_dentry, 0);
12723 +       if(name == NULL) 
12724 +               return(-ENOMEM);
12725 +
12726 +       fd = open_file(name, r, w, append);
12727 +       kfree(name);
12728 +       if(fd < 0) return(fd);
12729 +       file_hostfs_i(file)->fd = fd;
12730 +
12731 +       return(0);
12732 +}
12733 +
12734 +int hostfs_dir_open(struct inode *ino, struct file *file)
12735 +{
12736 +       return(0);      
12737 +}
12738 +
12739 +int hostfs_dir_release(struct inode *ino, struct file *file)
12740 +{
12741 +       return(0);
12742 +}
12743 +
12744 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
12745 +{
12746 +       return(0);
12747 +}
12748 +
12749 +static struct file_operations hostfs_file_fops = {
12750 +       .owner          = NULL,
12751 +       .read           = generic_file_read,
12752 +       .write          = generic_file_write,
12753 +       .mmap           = generic_file_mmap,
12754 +       .open           = hostfs_file_open,
12755 +       .release        = NULL,
12756 +       .fsync          = hostfs_fsync,
12757 +};
12758 +
12759 +static struct file_operations hostfs_dir_fops = {
12760 +       .owner          = NULL,
12761 +       .readdir        = hostfs_readdir,
12762 +       .open           = hostfs_dir_open,
12763 +       .release        = hostfs_dir_release,
12764 +       .fsync          = hostfs_fsync,
12765 +};
12766 +
12767 +int hostfs_writepage(struct page *page)
12768 +{
12769 +       struct address_space *mapping = page->mapping;
12770 +       struct inode *inode = mapping->host;
12771 +       char *buffer;
12772 +       unsigned long long base;
12773 +       int count = PAGE_CACHE_SIZE;
12774 +       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
12775 +       int err;
12776 +
12777 +       if (page->index >= end_index)
12778 +               count = inode->i_size & (PAGE_CACHE_SIZE-1);
12779 +
12780 +       buffer = kmap(page);
12781 +       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
12782 +
12783 +       err = write_file(inode->u.hostfs_i.fd, &base, buffer, count);
12784 +       if(err != count){
12785 +               ClearPageUptodate(page);
12786 +               goto out;
12787 +       }
12788 +
12789 +       if (base > inode->i_size)
12790 +               inode->i_size = base;
12791 +
12792 +       if (PageError(page))
12793 +               ClearPageError(page);   
12794 +       err = 0;
12795 +
12796 + out:  
12797 +       kunmap(page);
12798 +
12799 +       UnlockPage(page);
12800 +       return err; 
12801 +}
12802 +
12803 +int hostfs_readpage(struct file *file, struct page *page)
12804 +{
12805 +       char *buffer;
12806 +       long long start;
12807 +       int err = 0;
12808 +
12809 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
12810 +       buffer = kmap(page);
12811 +       err = read_file(file_hostfs_i(file)->fd, &start, buffer,
12812 +                       PAGE_CACHE_SIZE);
12813 +       if(err < 0) goto out;
12814 +
12815 +       memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
12816 +
12817 +       flush_dcache_page(page);
12818 +       SetPageUptodate(page);
12819 +       if (PageError(page)) ClearPageError(page);
12820 +       err = 0;
12821 + out:
12822 +       kunmap(page);
12823 +       UnlockPage(page);
12824 +       return(err);
12825 +}
12826 +
12827 +int hostfs_prepare_write(struct file *file, struct page *page, 
12828 +                        unsigned int from, unsigned int to)
12829 +{
12830 +       char *buffer;
12831 +       long long start, tmp;
12832 +       int err;
12833 +
12834 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
12835 +       buffer = kmap(page);
12836 +       if(from != 0){
12837 +               tmp = start;
12838 +               err = read_file(file_hostfs_i(file)->fd, &tmp, buffer,
12839 +                               from);
12840 +               if(err < 0) goto out;
12841 +       }
12842 +       if(to != PAGE_CACHE_SIZE){
12843 +               start += to;
12844 +               err = read_file(file_hostfs_i(file)->fd, &start, buffer + to,
12845 +                               PAGE_CACHE_SIZE - to);
12846 +               if(err < 0) goto out;           
12847 +       }
12848 +       err = 0;
12849 + out:
12850 +       kunmap(page);
12851 +       return(err);
12852 +}
12853 +
12854 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
12855 +                unsigned to)
12856 +{
12857 +       struct address_space *mapping = page->mapping;
12858 +       struct inode *inode = mapping->host;
12859 +       char *buffer;
12860 +       long long start;
12861 +       int err = 0;
12862 +
12863 +       start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
12864 +       buffer = kmap(page);
12865 +       err = write_file(file_hostfs_i(file)->fd, &start, buffer + from, 
12866 +                        to - from);
12867 +       if(err > 0) err = 0;
12868 +       if(!err && (start > inode->i_size))
12869 +               inode->i_size = start;
12870 +
12871 +       kunmap(page);
12872 +       return(err);
12873 +}
12874 +
12875 +static struct address_space_operations hostfs_aops = {
12876 +       .writepage      = hostfs_writepage,
12877 +       .readpage       = hostfs_readpage,
12878 +/*     .set_page_dirty = __set_page_dirty_nobuffers, */
12879 +       .prepare_write  = hostfs_prepare_write,
12880 +       .commit_write   = hostfs_commit_write
12881 +};
12882 +
12883 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
12884 +                              int *error)
12885 +{
12886 +       struct inode *inode;
12887 +       char *name;
12888 +       int type, err = -ENOMEM, rdev;
12889 +
12890 +       inode = new_inode(sb);
12891 +       if(inode == NULL) 
12892 +               goto out;
12893 +
12894 +       inode->u.hostfs_i.host_filename = NULL;
12895 +       inode->u.hostfs_i.fd = -1;
12896 +       inode->u.hostfs_i.mode = 0;
12897 +       insert_inode_hash(inode);
12898 +       if(dentry){
12899 +               name = dentry_name(dentry, 0);
12900 +               if(name == NULL){
12901 +                       err = -ENOMEM;
12902 +                       goto out_put;
12903 +               }
12904 +               type = file_type(name, &rdev);
12905 +               kfree(name);
12906 +       }
12907 +       else type = OS_TYPE_DIR;
12908 +       inode->i_sb = sb;
12909 +
12910 +       err = 0;
12911 +       if(type == OS_TYPE_SYMLINK)
12912 +               inode->i_op = &page_symlink_inode_operations;
12913 +       else if(type == OS_TYPE_DIR)
12914 +               inode->i_op = &hostfs_dir_iops;
12915 +       else inode->i_op = &hostfs_iops;
12916 +
12917 +       if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
12918 +       else inode->i_fop = &hostfs_file_fops;
12919 +
12920 +       if(type == OS_TYPE_SYMLINK) 
12921 +               inode->i_mapping->a_ops = &hostfs_link_aops;
12922 +       else inode->i_mapping->a_ops = &hostfs_aops;
12923 +
12924 +       switch (type) {
12925 +       case OS_TYPE_CHARDEV:
12926 +               init_special_inode(inode, S_IFCHR, rdev);
12927 +               break;
12928 +       case OS_TYPE_BLOCKDEV:
12929 +               init_special_inode(inode, S_IFBLK, rdev);
12930 +               break;
12931 +       case OS_TYPE_FIFO:
12932 +               init_special_inode(inode, S_IFIFO, 0);
12933 +               break;
12934 +       case OS_TYPE_SOCK:
12935 +               init_special_inode(inode, S_IFSOCK, 0);
12936 +               break;
12937 +       }
12938 +       
12939 +       if(error) *error = err;
12940 +       return(inode);
12941 + out_put:
12942 +       make_bad_inode(inode);
12943 +       iput(inode);
12944 + out:
12945 +       if(error) *error = err;
12946 +       return(NULL);
12947 +}
12948 +
12949 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode)
12950 +{
12951 +       struct inode *inode;
12952 +       char *name;
12953 +       int error, fd;
12954 +
12955 +       inode = get_inode(dir->i_sb, dentry, &error);
12956 +       if(error) return(error);
12957 +       name = dentry_name(dentry, 0);
12958 +       if(name == NULL){
12959 +               iput(inode);
12960 +               return(-ENOMEM);
12961 +       }
12962 +       fd = file_create(name, 
12963 +                        mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
12964 +                        mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
12965 +                        mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
12966 +       if(fd < 0) 
12967 +               error = fd;
12968 +       else error = read_name(inode, name);
12969 +
12970 +       kfree(name);
12971 +       if(error){
12972 +               iput(inode);
12973 +               return(error);
12974 +       }
12975 +       inode->u.hostfs_i.fd = fd;
12976 +       inode->u.hostfs_i.mode = FMODE_READ | FMODE_WRITE;
12977 +       d_instantiate(dentry, inode);
12978 +       return(0);
12979 +}
12980
12981 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry)
12982 +{
12983 +       struct inode *inode;
12984 +       char *name;
12985 +       int error;
12986 +
12987 +       inode = get_inode(ino->i_sb, dentry, &error);
12988 +       if(error != 0) return(ERR_PTR(error));
12989 +       name = dentry_name(dentry, 0);
12990 +       if(name == NULL) return(ERR_PTR(-ENOMEM));
12991 +       error = read_name(inode, name);
12992 +       kfree(name);
12993 +       if(error){
12994 +               iput(inode);
12995 +               if(error == -ENOENT) inode = NULL;
12996 +               else return(ERR_PTR(error));
12997 +       }
12998 +       d_add(dentry, inode);
12999 +       dentry->d_op = &hostfs_dentry_ops;
13000 +       return(NULL);
13001 +}
13002 +
13003 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
13004 +{
13005 +        char *file;
13006 +       int len;
13007 +
13008 +       file = inode_name(ino, dentry->d_name.len + 1);
13009 +       if(file == NULL) return(NULL);
13010 +        strcat(file, "/");
13011 +       len = strlen(file);
13012 +        strncat(file, dentry->d_name.name, dentry->d_name.len);
13013 +       file[len + dentry->d_name.len] = '\0';
13014 +        return(file);
13015 +}
13016 +
13017 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
13018 +{
13019 +        char *from_name, *to_name;
13020 +        int err;
13021 +
13022 +        from_name = inode_dentry_name(ino, from); 
13023 +        if(from_name == NULL) 
13024 +                return(-ENOMEM);
13025 +        to_name = dentry_name(to, 0);
13026 +       if(to_name == NULL){
13027 +               kfree(from_name);
13028 +               return(-ENOMEM);
13029 +       }
13030 +        err = link_file(to_name, from_name);
13031 +        kfree(from_name);
13032 +        kfree(to_name);
13033 +        return(err);
13034 +}
13035 +
13036 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
13037 +{
13038 +       char *file;
13039 +       int err;
13040 +
13041 +       file = inode_dentry_name(ino, dentry);
13042 +       if(file == NULL) return(-ENOMEM);
13043 +       if(append)
13044 +               return(-EPERM);
13045 +
13046 +       err = unlink_file(file);
13047 +       kfree(file);
13048 +       return(err);
13049 +}
13050 +
13051 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
13052 +{
13053 +       char *file;
13054 +       int err;
13055 +
13056 +       file = inode_dentry_name(ino, dentry);
13057 +       if(file == NULL) return(-ENOMEM);
13058 +       err = make_symlink(file, to);
13059 +       kfree(file);
13060 +       return(err);
13061 +}
13062 +
13063 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
13064 +{
13065 +       char *file;
13066 +       int err;
13067 +
13068 +       file = inode_dentry_name(ino, dentry);
13069 +       if(file == NULL) return(-ENOMEM);
13070 +       err = do_mkdir(file, mode);
13071 +       kfree(file);
13072 +       return(err);
13073 +}
13074 +
13075 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
13076 +{
13077 +       char *file;
13078 +       int err;
13079 +
13080 +       file = inode_dentry_name(ino, dentry);
13081 +       if(file == NULL) return(-ENOMEM);
13082 +       err = do_rmdir(file);
13083 +       kfree(file);
13084 +       return(err);
13085 +}
13086 +
13087 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
13088 +{
13089 +       struct inode *inode;
13090 +       char *name;
13091 +       int error;
13092
13093 +       inode = get_inode(dir->i_sb, dentry, &error);
13094 +       if(error) return(error);
13095 +       name = dentry_name(dentry, 0);
13096 +       if(name == NULL){
13097 +               iput(inode);
13098 +               return(-ENOMEM);
13099 +       }
13100 +       init_special_inode(inode, mode, dev);
13101 +       error = do_mknod(name, mode, dev);
13102 +       if(!error) error = read_name(inode, name);
13103 +       kfree(name);
13104 +       if(error){
13105 +               iput(inode);
13106 +               return(error);
13107 +       }
13108 +       d_instantiate(dentry, inode);
13109 +       return(0);
13110 +}
13111 +
13112 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
13113 +                 struct inode *to_ino, struct dentry *to)
13114 +{
13115 +       char *from_name, *to_name;
13116 +       int err;
13117 +
13118 +       from_name = inode_dentry_name(from_ino, from);
13119 +       if(from_name == NULL)
13120 +               return(-ENOMEM);
13121 +       to_name = inode_dentry_name(to_ino, to);
13122 +       if(to_name == NULL){
13123 +               kfree(from_name);
13124 +               return(-ENOMEM);
13125 +       }
13126 +       err = rename_file(from_name, to_name);
13127 +       kfree(from_name);
13128 +       kfree(to_name);
13129 +       return(err);
13130 +}
13131 +
13132 +void hostfs_truncate(struct inode *ino)
13133 +{
13134 +       not_implemented();
13135 +}
13136 +
13137 +int hostfs_permission(struct inode *ino, int desired)
13138 +{
13139 +       char *name;
13140 +       int r = 0, w = 0, x = 0, err;
13141 +
13142 +       if(desired & MAY_READ) r = 1;
13143 +       if(desired & MAY_WRITE) w = 1;
13144 +       if(desired & MAY_EXEC) x = 1;
13145 +       name = inode_name(ino, 0);
13146 +       if(name == NULL) return(-ENOMEM);
13147 +       err = access_file(name, r, w, x);
13148 +       kfree(name);
13149 +       if(!err) err = vfs_permission(ino, desired);
13150 +       return(err);
13151 +}
13152 +
13153 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
13154 +{
13155 +       struct hostfs_iattr attrs;
13156 +       char *name;
13157 +       int err;
13158 +       
13159 +       if(append) 
13160 +               attr->ia_valid &= ~ATTR_SIZE;
13161 +
13162 +       attrs.ia_valid = 0;
13163 +       if(attr->ia_valid & ATTR_MODE){
13164 +               attrs.ia_valid |= HOSTFS_ATTR_MODE;
13165 +               attrs.ia_mode = attr->ia_mode;
13166 +       }
13167 +       if(attr->ia_valid & ATTR_UID){
13168 +               if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) && 
13169 +                  (attr->ia_uid == 0))
13170 +                       attr->ia_uid = getuid();
13171 +               attrs.ia_valid |= HOSTFS_ATTR_UID;
13172 +               attrs.ia_uid = attr->ia_uid;
13173 +       }
13174 +       if(attr->ia_valid & ATTR_GID){
13175 +               if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) && 
13176 +                  (attr->ia_gid == 0))
13177 +                       attr->ia_gid = getuid();
13178 +               attrs.ia_valid |= HOSTFS_ATTR_GID;
13179 +               attrs.ia_gid = attr->ia_gid;
13180 +       }
13181 +       if(attr->ia_valid & ATTR_SIZE){
13182 +               attrs.ia_valid |= HOSTFS_ATTR_SIZE;
13183 +               attrs.ia_size = attr->ia_size;
13184 +       }
13185 +       if(attr->ia_valid & ATTR_ATIME){
13186 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME;
13187 +               attrs.ia_atime = attr->ia_atime;
13188 +       }
13189 +       if(attr->ia_valid & ATTR_MTIME){
13190 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME;
13191 +               attrs.ia_mtime = attr->ia_mtime;
13192 +       }
13193 +       if(attr->ia_valid & ATTR_CTIME){
13194 +               attrs.ia_valid |= HOSTFS_ATTR_CTIME;
13195 +               attrs.ia_ctime = attr->ia_ctime;
13196 +       }
13197 +       if(attr->ia_valid & ATTR_ATIME_SET){
13198 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
13199 +       }
13200 +       if(attr->ia_valid & ATTR_MTIME_SET){
13201 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
13202 +       }
13203 +       name = dentry_name(dentry, 0);
13204 +       if(name == NULL) return(-ENOMEM);
13205 +       err = set_attr(name, &attrs);
13206 +       kfree(name);
13207 +       if(err)
13208 +               return(err);
13209 +
13210 +       return(inode_setattr(dentry->d_inode, attr));
13211 +}
13212 +
13213 +int hostfs_getattr(struct dentry *dentry, struct iattr *attr)
13214 +{
13215 +       not_implemented();
13216 +       return(-EINVAL);
13217 +}
13218 +
13219 +static struct inode_operations hostfs_iops = {
13220 +       .create         = hostfs_create,
13221 +       .link           = hostfs_link,
13222 +       .unlink         = hostfs_unlink,
13223 +       .symlink        = hostfs_symlink,
13224 +       .mkdir          = hostfs_mkdir,
13225 +       .rmdir          = hostfs_rmdir,
13226 +       .mknod          = hostfs_mknod,
13227 +       .rename         = hostfs_rename,
13228 +       .truncate       = hostfs_truncate,
13229 +       .permission     = hostfs_permission,
13230 +       .setattr        = hostfs_setattr,
13231 +       .getattr        = hostfs_getattr,
13232 +};
13233 +
13234 +static struct inode_operations hostfs_dir_iops = {
13235 +       .create         = hostfs_create,
13236 +       .lookup         = hostfs_lookup,
13237 +       .link           = hostfs_link,
13238 +       .unlink         = hostfs_unlink,
13239 +       .symlink        = hostfs_symlink,
13240 +       .mkdir          = hostfs_mkdir,
13241 +       .rmdir          = hostfs_rmdir,
13242 +       .mknod          = hostfs_mknod,
13243 +       .rename         = hostfs_rename,
13244 +       .truncate       = hostfs_truncate,
13245 +       .permission     = hostfs_permission,
13246 +       .setattr        = hostfs_setattr,
13247 +       .getattr        = hostfs_getattr,
13248 +};
13249 +
13250 +int hostfs_link_readpage(struct file *file, struct page *page)
13251 +{
13252 +       char *buffer, *name;
13253 +       long long start;
13254 +       int err;
13255 +
13256 +       start = page->index << PAGE_CACHE_SHIFT;
13257 +       buffer = kmap(page);
13258 +       name = inode_name(page->mapping->host, 0);
13259 +       if(name == NULL) return(-ENOMEM);
13260 +       err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
13261 +       kfree(name);
13262 +       if(err == PAGE_CACHE_SIZE)
13263 +               err = -E2BIG;
13264 +       else if(err > 0){
13265 +               flush_dcache_page(page);
13266 +               SetPageUptodate(page);
13267 +               if (PageError(page)) ClearPageError(page);
13268 +               err = 0;
13269 +       }
13270 +       kunmap(page);
13271 +       UnlockPage(page);
13272 +       return(err);
13273 +}
13274 +
13275 +static struct address_space_operations hostfs_link_aops = {
13276 +       .readpage       = hostfs_link_readpage,
13277 +};
13278 +
13279 +static char *get_root(char *mount_arg)
13280 +{
13281 +       char *root, *slash = "";
13282 +       int len = 0;
13283 +
13284 +       if(jail_dir != NULL){
13285 +               len += strlen(jail_dir);
13286 +               if((*jail_dir == '\0') || 
13287 +                  (jail_dir[strlen(jail_dir) - 1] != '/'))
13288 +                       slash = "/";
13289 +               len += strlen(slash);
13290 +       }
13291 +
13292 +       if((mount_arg == NULL) || (*mount_arg == '\0'))
13293 +               mount_arg = DEFAULT_ROOT;
13294 +
13295 +       len += strlen(mount_arg) + 1;
13296 +
13297 +       root = kmalloc(len, GFP_KERNEL);
13298 +       if(root == NULL)
13299 +               return(NULL);
13300 +
13301 +       if(jail_dir != NULL)
13302 +               sprintf(root, "%s%s%s", jail_dir, slash, mount_arg);
13303 +       else
13304 +               strcpy(root, mount_arg);
13305 +
13306 +       return(root);
13307 +}
13308 +
13309 +struct super_block *hostfs_read_super(struct super_block *sb, void *data, 
13310 +                                     int silent)
13311 +{
13312 +       struct inode *root_inode;
13313 +       char *root_dir;
13314 +
13315 +       sb->s_blocksize = 1024;
13316 +       sb->s_blocksize_bits = 10;
13317 +       sb->s_magic = HOSTFS_SUPER_MAGIC;
13318 +       sb->s_op = &hostfs_sbops;
13319 +
13320 +       root_inode = get_inode(sb, NULL, NULL);
13321 +       if(root_inode == NULL)
13322 +               goto out;
13323 +
13324 +       root_dir = get_root(data);
13325 +       if(root_dir == NULL)
13326 +               goto out_put;
13327 +
13328 +       root_inode->u.hostfs_i.host_filename = root_dir;
13329 +       sb->s_root = d_alloc_root(root_inode);
13330 +       if(sb->s_root == NULL)
13331 +               goto out_free;
13332 +
13333 +       if(read_inode(root_inode))
13334 +               goto out_dput;
13335 +       return(sb);
13336 +
13337 + out_dput:
13338 +       dput(sb->s_root);
13339 + out_free:
13340 +       kfree(root_dir);
13341 + out_put:
13342 +       make_bad_inode(root_inode);
13343 +       iput(root_inode);
13344 + out:
13345 +       return(NULL);
13346 +}
13347 +
13348 +DECLARE_FSTYPE(hostfs_type, "hostfs", hostfs_read_super, 0);
13349 +
13350 +static int __init init_hostfs(void)
13351 +{
13352 +       return(register_filesystem(&hostfs_type));
13353 +}
13354 +
13355 +static void __exit exit_hostfs(void)
13356 +{
13357 +       unregister_filesystem(&hostfs_type);
13358 +}
13359 +
13360 +module_init(init_hostfs)
13361 +module_exit(exit_hostfs)
13362 +MODULE_LICENSE("GPL");
13363 +
13364 +/*
13365 + * Overrides for Emacs so that we follow Linus's tabbing style.
13366 + * Emacs will notice this stuff at the end of the file and automatically
13367 + * adjust the settings for this buffer only.  This must remain at the end
13368 + * of the file.
13369 + * ---------------------------------------------------------------------------
13370 + * Local variables:
13371 + * c-file-style: "linux"
13372 + * End:
13373 + */
13374 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_user.c um/arch/um/fs/hostfs/hostfs_user.c
13375 --- orig/arch/um/fs/hostfs/hostfs_user.c        1969-12-31 19:00:00.000000000 -0500
13376 +++ um/arch/um/fs/hostfs/hostfs_user.c  2003-11-14 08:51:20.000000000 -0500
13377 @@ -0,0 +1,359 @@
13378 +/* 
13379 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13380 + * Licensed under the GPL
13381 + */
13382 +
13383 +#include <unistd.h>
13384 +#include <stdio.h>
13385 +#include <fcntl.h>
13386 +#include <dirent.h>
13387 +#include <errno.h>
13388 +#include <utime.h>
13389 +#include <string.h>
13390 +#include <sys/stat.h>
13391 +#include <sys/time.h>
13392 +#include <sys/vfs.h>
13393 +#include "hostfs.h"
13394 +#include "kern_util.h"
13395 +#include "user.h"
13396 +
13397 +int stat_file(const char *path, int *dev_out, unsigned long long *inode_out,
13398 +             int *mode_out, int *nlink_out, int *uid_out, int *gid_out, 
13399 +             unsigned long long *size_out, unsigned long *atime_out,
13400 +             unsigned long *mtime_out, unsigned long *ctime_out,
13401 +             int *blksize_out, unsigned long long *blocks_out)
13402 +{
13403 +       struct stat64 buf;
13404 +
13405 +       if(lstat64(path, &buf) < 0) 
13406 +               return(-errno);
13407 +       if(dev_out != NULL) *dev_out = buf.st_dev;
13408 +
13409 +       /* See the Makefile for why STAT64_INO_FIELD is passed in
13410 +        * by the build
13411 +        */
13412 +       if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
13413 +       if(mode_out != NULL) *mode_out = buf.st_mode;
13414 +       if(nlink_out != NULL) *nlink_out = buf.st_nlink;
13415 +       if(uid_out != NULL) *uid_out = buf.st_uid;
13416 +       if(gid_out != NULL) *gid_out = buf.st_gid;
13417 +       if(size_out != NULL) *size_out = buf.st_size;
13418 +       if(atime_out != NULL) *atime_out = buf.st_atime;
13419 +       if(mtime_out != NULL) *mtime_out = buf.st_mtime;
13420 +       if(ctime_out != NULL) *ctime_out = buf.st_ctime;
13421 +       if(blksize_out != NULL) *blksize_out = buf.st_blksize;
13422 +       if(blocks_out != NULL) *blocks_out = buf.st_blocks;
13423 +       return(0);
13424 +}
13425 +
13426 +int file_type(const char *path, int *rdev)
13427 +{
13428 +       struct stat64 buf;
13429 +
13430 +       if(lstat64(path, &buf) < 0) 
13431 +               return(-errno);
13432 +       if(rdev != NULL) 
13433 +               *rdev = buf.st_rdev;
13434 +
13435 +       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
13436 +       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
13437 +       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
13438 +       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
13439 +       else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
13440 +       else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
13441 +       else return(OS_TYPE_FILE);
13442 +}
13443 +
13444 +int access_file(char *path, int r, int w, int x)
13445 +{
13446 +       int mode = 0;
13447 +
13448 +       if(r) mode = R_OK;
13449 +       if(w) mode |= W_OK;
13450 +       if(x) mode |= X_OK;
13451 +       if(access(path, mode) != 0) return(-errno);
13452 +       else return(0);
13453 +}
13454 +
13455 +int open_file(char *path, int r, int w, int append)
13456 +{
13457 +       int mode = 0, fd;
13458 +
13459 +       if(r && !w) 
13460 +               mode = O_RDONLY;
13461 +       else if(!r && w) 
13462 +               mode = O_WRONLY;
13463 +       else if(r && w) 
13464 +               mode = O_RDWR;
13465 +       else panic("Impossible mode in open_file");
13466 +
13467 +       if(append)
13468 +               mode |= O_APPEND;
13469 +       fd = open64(path, mode);
13470 +       if(fd < 0) return(-errno);
13471 +       else return(fd);
13472 +}
13473 +
13474 +void *open_dir(char *path, int *err_out)
13475 +{
13476 +       DIR *dir;
13477 +
13478 +       dir = opendir(path);
13479 +       *err_out = errno;
13480 +       if(dir == NULL) return(NULL);
13481 +       return(dir);
13482 +}
13483 +
13484 +char *read_dir(void *stream, unsigned long long *pos, 
13485 +              unsigned long long *ino_out, int *len_out)
13486 +{
13487 +       DIR *dir = stream;
13488 +       struct dirent *ent;
13489 +
13490 +       seekdir(dir, *pos);
13491 +       ent = readdir(dir);
13492 +       if(ent == NULL) return(NULL);
13493 +       *len_out = strlen(ent->d_name);
13494 +       *ino_out = ent->d_ino;
13495 +       *pos = telldir(dir);
13496 +       return(ent->d_name);
13497 +}
13498 +
13499 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
13500 +{
13501 +       int n, err;
13502 +
13503 +       err = os_seek_file(fd, *offset);
13504 +       if(err)
13505 +               return(err);
13506 +
13507 +       n = os_read_file(fd, buf, len);
13508 +       if(n < 0) 
13509 +               return(n);
13510 +
13511 +       *offset += n;
13512 +       return(n);
13513 +}
13514 +
13515 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
13516 +{
13517 +       int n, err;
13518 +
13519 +       err = os_seek_file(fd, *offset);
13520 +       if(err)
13521 +               return(err);
13522 +
13523 +       n = os_write_file(fd, buf, len);
13524 +       if(n < 0) 
13525 +               return(n);
13526 +
13527 +       *offset += n;
13528 +       return(n);
13529 +}
13530 +
13531 +int lseek_file(int fd, long long offset, int whence)
13532 +{
13533 +       int ret;
13534 +
13535 +       ret = lseek64(fd, offset, whence);
13536 +       if(ret < 0) return(-errno);
13537 +       return(0);
13538 +}
13539 +
13540 +void close_file(void *stream)
13541 +{
13542 +       close(*((int *) stream));
13543 +}
13544 +
13545 +void close_dir(void *stream)
13546 +{
13547 +       closedir(stream);
13548 +}
13549 +
13550 +int file_create(char *name, int ur, int uw, int ux, int gr, 
13551 +               int gw, int gx, int or, int ow, int ox)
13552 +{
13553 +       int mode, fd;
13554 +
13555 +       mode = 0;
13556 +       mode |= ur ? S_IRUSR : 0;
13557 +       mode |= uw ? S_IWUSR : 0;
13558 +       mode |= ux ? S_IXUSR : 0;
13559 +       mode |= gr ? S_IRGRP : 0;
13560 +       mode |= gw ? S_IWGRP : 0;
13561 +       mode |= gx ? S_IXGRP : 0;
13562 +       mode |= or ? S_IROTH : 0;
13563 +       mode |= ow ? S_IWOTH : 0;
13564 +       mode |= ox ? S_IXOTH : 0;
13565 +       fd = open64(name, O_CREAT | O_RDWR, mode);
13566 +       if(fd < 0) 
13567 +               return(-errno);
13568 +       return(fd);
13569 +}
13570 +
13571 +int set_attr(const char *file, struct hostfs_iattr *attrs)
13572 +{
13573 +       struct utimbuf buf;
13574 +       int err, ma;
13575 +
13576 +       if(attrs->ia_valid & HOSTFS_ATTR_MODE){
13577 +               if(chmod(file, attrs->ia_mode) != 0) return(-errno);
13578 +       }
13579 +       if(attrs->ia_valid & HOSTFS_ATTR_UID){
13580 +               if(chown(file, attrs->ia_uid, -1)) return(-errno);
13581 +       }
13582 +       if(attrs->ia_valid & HOSTFS_ATTR_GID){
13583 +               if(chown(file, -1, attrs->ia_gid)) return(-errno);
13584 +       }
13585 +       if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
13586 +               if(truncate(file, attrs->ia_size)) return(-errno);
13587 +       }
13588 +       ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
13589 +       if((attrs->ia_valid & ma) == ma){
13590 +               buf.actime = attrs->ia_atime;
13591 +               buf.modtime = attrs->ia_mtime;
13592 +               if(utime(file, &buf) != 0) return(-errno);
13593 +       }
13594 +       else {
13595 +               if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
13596 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13597 +                                       NULL, NULL, NULL, &buf.modtime, NULL,
13598 +                                       NULL, NULL);
13599 +                       if(err != 0) return(err);
13600 +                       buf.actime = attrs->ia_atime;
13601 +                       if(utime(file, &buf) != 0) return(-errno);
13602 +               }
13603 +               if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
13604 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13605 +                                       NULL, NULL, &buf.actime, NULL, NULL, 
13606 +                                       NULL, NULL);
13607 +                       if(err != 0) return(err);
13608 +                       buf.modtime = attrs->ia_mtime;
13609 +                       if(utime(file, &buf) != 0) return(-errno);
13610 +               }
13611 +       }
13612 +       if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
13613 +       if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
13614 +               err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
13615 +                               NULL, NULL, &attrs->ia_atime, &attrs->ia_mtime,
13616 +                               NULL, NULL, NULL);
13617 +               if(err != 0) return(err);
13618 +       }
13619 +       return(0);
13620 +}
13621 +
13622 +int make_symlink(const char *from, const char *to)
13623 +{
13624 +       int err;
13625 +
13626 +       err = symlink(to, from);
13627 +       if(err) return(-errno);
13628 +       return(0);
13629 +}
13630 +
13631 +int unlink_file(const char *file)
13632 +{
13633 +       int err;
13634 +
13635 +       err = unlink(file);
13636 +       if(err) return(-errno);
13637 +       return(0);
13638 +}
13639 +
13640 +int do_mkdir(const char *file, int mode)
13641 +{
13642 +       int err;
13643 +
13644 +       err = mkdir(file, mode);
13645 +       if(err) return(-errno);
13646 +       return(0);
13647 +}
13648 +
13649 +int do_rmdir(const char *file)
13650 +{
13651 +       int err;
13652 +
13653 +       err = rmdir(file);
13654 +       if(err) return(-errno);
13655 +       return(0);
13656 +}
13657 +
13658 +int do_mknod(const char *file, int mode, int dev)
13659 +{
13660 +       int err;
13661 +
13662 +       err = mknod(file, mode, dev);
13663 +       if(err) return(-errno);
13664 +       return(0);
13665 +}
13666 +
13667 +int link_file(const char *to, const char *from)
13668 +{
13669 +       int err;
13670 +
13671 +       err = link(to, from);
13672 +       if(err) return(-errno);
13673 +       return(0);
13674 +}
13675 +
13676 +int do_readlink(char *file, char *buf, int size)
13677 +{
13678 +       int n;
13679 +
13680 +       n = readlink(file, buf, size);
13681 +       if(n < 0) 
13682 +               return(-errno);
13683 +       if(n < size) 
13684 +               buf[n] = '\0';
13685 +       return(n);
13686 +}
13687 +
13688 +int rename_file(char *from, char *to)
13689 +{
13690 +       int err;
13691 +
13692 +       err = rename(from, to);
13693 +       if(err < 0) return(-errno);
13694 +       return(0);      
13695 +}
13696 +
13697 +int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
13698 +             long long *bfree_out, long long *bavail_out, 
13699 +             long long *files_out, long long *ffree_out,
13700 +             void *fsid_out, int fsid_size, long *namelen_out, 
13701 +             long *spare_out)
13702 +{
13703 +       struct statfs64 buf;
13704 +       int err;
13705 +
13706 +       err = statfs64(root, &buf);
13707 +       if(err < 0) return(-errno);
13708 +       *bsize_out = buf.f_bsize;
13709 +       *blocks_out = buf.f_blocks;
13710 +       *bfree_out = buf.f_bfree;
13711 +       *bavail_out = buf.f_bavail;
13712 +       *files_out = buf.f_files;
13713 +       *ffree_out = buf.f_ffree;
13714 +       memcpy(fsid_out, &buf.f_fsid, 
13715 +              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
13716 +              sizeof(buf.f_fsid));
13717 +       *namelen_out = buf.f_namelen;
13718 +       spare_out[0] = buf.f_spare[0];
13719 +       spare_out[1] = buf.f_spare[1];
13720 +       spare_out[2] = buf.f_spare[2];
13721 +       spare_out[3] = buf.f_spare[3];
13722 +       spare_out[4] = buf.f_spare[4];
13723 +       spare_out[5] = buf.f_spare[5];
13724 +       return(0);
13725 +}
13726 +
13727 +/*
13728 + * Overrides for Emacs so that we follow Linus's tabbing style.
13729 + * Emacs will notice this stuff at the end of the file and automatically
13730 + * adjust the settings for this buffer only.  This must remain at the end
13731 + * of the file.
13732 + * ---------------------------------------------------------------------------
13733 + * Local variables:
13734 + * c-file-style: "linux"
13735 + * End:
13736 + */
13737 diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/Makefile um/arch/um/fs/hostfs/Makefile
13738 --- orig/arch/um/fs/hostfs/Makefile     1969-12-31 19:00:00.000000000 -0500
13739 +++ um/arch/um/fs/hostfs/Makefile       2003-10-21 03:26:06.000000000 -0400
13740 @@ -0,0 +1,24 @@
13741 +# 
13742 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
13743 +# Licensed under the GPL
13744 +#
13745 +
13746 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
13747 +# to __st_ino.  It stayed in the same place, so as long as the correct name
13748 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
13749 +
13750 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
13751 +                               echo __)st_ino
13752 +
13753 +USER_CFLAGS := $(USER_CFLAGS) -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
13754 +
13755 +O_TARGET := hostfs.o
13756 +obj-y = hostfs_kern.o hostfs_user.o
13757 +obj-m = $(O_TARGET)
13758 +
13759 +USER_OBJS = $(filter %_user.o,$(obj-y))
13760 +
13761 +include $(TOPDIR)/Rules.make
13762 +
13763 +$(USER_OBJS) : %.o: %.c
13764 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
13765 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/hppfs_kern.c um/arch/um/fs/hppfs/hppfs_kern.c
13766 --- orig/arch/um/fs/hppfs/hppfs_kern.c  1969-12-31 19:00:00.000000000 -0500
13767 +++ um/arch/um/fs/hppfs/hppfs_kern.c    2003-11-08 09:42:49.000000000 -0500
13768 @@ -0,0 +1,727 @@
13769 +/* 
13770 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
13771 + * Licensed under the GPL
13772 + */
13773 +
13774 +#include <linux/fs.h>
13775 +#include <linux/module.h>
13776 +#include <linux/slab.h>
13777 +#include <linux/list.h>
13778 +#include <linux/kernel.h>
13779 +#include <linux/ctype.h>
13780 +#include <asm/uaccess.h>
13781 +#include "os.h"
13782 +
13783 +struct hppfs_data {
13784 +       struct list_head list;
13785 +       char contents[PAGE_SIZE - sizeof(struct list_head)];
13786 +};
13787 +
13788 +struct hppfs_private {
13789 +       struct file proc_file;
13790 +       int host_fd;
13791 +       loff_t len;
13792 +       struct hppfs_data *contents;
13793 +};
13794 +
13795 +#define HPPFS_SUPER_MAGIC 0xb00000ee
13796 +
13797 +static struct super_operations hppfs_sbops;
13798 +
13799 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
13800 +                              int *error);
13801 +
13802 +static int is_pid(struct dentry *dentry)
13803 +{
13804 +       struct super_block *sb;
13805 +       int i;
13806 +
13807 +       sb = dentry->d_sb;
13808 +       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
13809 +               return(0);
13810 +
13811 +       for(i = 0; i < dentry->d_name.len; i++){
13812 +               if(!isdigit(dentry->d_name.name[i]))
13813 +                       return(0);
13814 +       }
13815 +       return(1);
13816 +}
13817 +
13818 +static char *dentry_name(struct dentry *dentry, int extra)
13819 +{
13820 +       struct dentry *parent;
13821 +       char *root, *name;
13822 +       const char *seg_name;
13823 +       int len, seg_len;
13824 +
13825 +       len = 0;
13826 +       parent = dentry;
13827 +       while(parent->d_parent != parent){
13828 +               if(is_pid(parent))
13829 +                       len += strlen("pid") + 1;
13830 +               else len += parent->d_name.len + 1;
13831 +               parent = parent->d_parent;
13832 +       }
13833 +       
13834 +       root = "proc";
13835 +       len += strlen(root);
13836 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
13837 +       if(name == NULL) return(NULL);
13838 +
13839 +       name[len] = '\0';
13840 +       parent = dentry;
13841 +       while(parent->d_parent != parent){
13842 +               if(is_pid(parent)){
13843 +                       seg_name = "pid";
13844 +                       seg_len = strlen("pid");
13845 +               }
13846 +               else {
13847 +                       seg_name = parent->d_name.name;
13848 +                       seg_len = parent->d_name.len;
13849 +               }
13850 +
13851 +               len -= seg_len + 1;
13852 +               name[len] = '/';
13853 +               strncpy(&name[len + 1], seg_name, seg_len);
13854 +               parent = parent->d_parent;
13855 +       }
13856 +       strncpy(name, root, strlen(root));
13857 +       return(name);
13858 +}
13859 +
13860 +struct dentry_operations hppfs_dentry_ops = {
13861 +};
13862 +
13863 +static int file_removed(struct dentry *dentry, const char *file)
13864 +{
13865 +       char *host_file;
13866 +       int extra, fd;
13867 +
13868 +       extra = 0;
13869 +       if(file != NULL) extra += strlen(file) + 1;
13870 +
13871 +       host_file = dentry_name(dentry, extra + strlen("/remove"));
13872 +       if(host_file == NULL){
13873 +               printk("file_removed : allocation failed\n");
13874 +               return(-ENOMEM);
13875 +       }
13876 +
13877 +       if(file != NULL){
13878 +               strcat(host_file, "/");
13879 +               strcat(host_file, file);
13880 +       }
13881 +       strcat(host_file, "/remove");
13882 +
13883 +       fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
13884 +       kfree(host_file);
13885 +       if(fd >= 0){
13886 +               os_close_file(fd);
13887 +               return(1);
13888 +       }
13889 +       return(0);
13890 +}
13891 +
13892 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry)
13893 +{
13894 +       struct dentry *proc_dentry;
13895 +       struct inode *inode;
13896 +       int err, deleted;
13897 +
13898 +       deleted = file_removed(dentry, NULL);
13899 +       if(deleted < 0)
13900 +               return(ERR_PTR(deleted));
13901 +       else if(deleted)
13902 +               return(ERR_PTR(-ENOENT));
13903 +
13904 +       proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry);
13905 +       if(IS_ERR(proc_dentry))
13906 +               return(proc_dentry);
13907 +
13908 +       inode = get_inode(ino->i_sb, proc_dentry, &err);
13909 +       if(err != 0) 
13910 +               return(ERR_PTR(err));
13911 +
13912 +       d_add(dentry, inode);
13913 +       dentry->d_op = &hppfs_dentry_ops;
13914 +       return(NULL);
13915 +}
13916 +
13917 +static struct inode_operations hppfs_file_iops = {
13918 +};
13919 +
13920 +static struct inode_operations hppfs_dir_iops = {
13921 +       .lookup         = hppfs_lookup,
13922 +};
13923 +
13924 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
13925 +                        loff_t *ppos, int is_user)
13926 +{
13927 +       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
13928 +       ssize_t n;
13929 +
13930 +       read = file->f_dentry->d_inode->i_fop->read;
13931 +
13932 +       if(!is_user)
13933 +               set_fs(KERNEL_DS);
13934 +               
13935 +       n = (*read)(file, buf, count, &file->f_pos);
13936 +
13937 +       if(!is_user)
13938 +               set_fs(USER_DS);
13939 +
13940 +       if(ppos) *ppos = file->f_pos;
13941 +       return(n);
13942 +}
13943 +
13944 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
13945 +{
13946 +       ssize_t n;
13947 +       int cur, err;
13948 +       char *new_buf;
13949 +
13950 +       n = -ENOMEM;
13951 +       new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
13952 +       if(new_buf == NULL){
13953 +               printk("hppfs_read_file : kmalloc failed\n");
13954 +               goto out;
13955 +       }
13956 +       n = 0;
13957 +       while(count > 0){
13958 +               cur = min_t(ssize_t, count, PAGE_SIZE);
13959 +               err = os_read_file(fd, new_buf, cur);
13960 +               if(err < 0){
13961 +                       printk("hppfs_read : read failed, err = %d\n", -err);
13962 +                       n = err;
13963 +                       goto out_free;
13964 +               }
13965 +               else if(err == 0)
13966 +                       break;
13967 +
13968 +               if(copy_to_user(buf, new_buf, err)){
13969 +                       n = -EFAULT;
13970 +                       goto out_free;
13971 +               }
13972 +               n += err;
13973 +               count -= err;
13974 +       }
13975 + out_free:
13976 +       kfree(new_buf);
13977 + out:
13978 +       return(n);
13979 +}
13980 +
13981 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
13982 +                         loff_t *ppos)
13983 +{
13984 +       struct hppfs_private *hppfs = file->private_data;
13985 +       struct hppfs_data *data;
13986 +       loff_t off;
13987 +       int err;
13988 +
13989 +       if(hppfs->contents != NULL){
13990 +               if(*ppos >= hppfs->len) return(0);
13991 +
13992 +               data = hppfs->contents;
13993 +               off = *ppos;
13994 +               while(off >= sizeof(data->contents)){
13995 +                       data = list_entry(data->list.next, struct hppfs_data,
13996 +                                         list);
13997 +                       off -= sizeof(data->contents);
13998 +               }
13999 +
14000 +               if(off + count > hppfs->len)
14001 +                       count = hppfs->len - off;
14002 +               copy_to_user(buf, &data->contents[off], count);
14003 +               *ppos += count;
14004 +       }
14005 +       else if(hppfs->host_fd != -1){
14006 +               err = os_seek_file(hppfs->host_fd, *ppos);
14007 +               if(err < 0){
14008 +                       printk("hppfs_read : seek failed, err = %d\n", -err);
14009 +                       return(err);
14010 +               }
14011 +               count = hppfs_read_file(hppfs->host_fd, buf, count);
14012 +               if(count > 0)
14013 +                       *ppos += count;
14014 +       }
14015 +       else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
14016 +
14017 +       return(count);
14018 +}
14019 +
14020 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
14021 +                          loff_t *ppos)
14022 +{
14023 +       struct hppfs_private *data = file->private_data;
14024 +       struct file *proc_file = &data->proc_file;
14025 +       ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
14026 +       int err;
14027 +
14028 +       write = proc_file->f_dentry->d_inode->i_fop->write;
14029 +
14030 +       proc_file->f_pos = file->f_pos;
14031 +       err = (*write)(proc_file, buf, len, &proc_file->f_pos);
14032 +       file->f_pos = proc_file->f_pos;
14033 +
14034 +       return(err);
14035 +}
14036 +
14037 +static int open_host_sock(char *host_file, int *filter_out)
14038 +{
14039 +       char *end;
14040 +       int fd;
14041 +
14042 +       end = &host_file[strlen(host_file)];
14043 +       strcpy(end, "/rw");
14044 +       *filter_out = 1;
14045 +       fd = os_connect_socket(host_file);
14046 +       if(fd >= 0)
14047 +               return(fd);
14048 +
14049 +       strcpy(end, "/r");
14050 +       *filter_out = 0;
14051 +       fd = os_connect_socket(host_file);
14052 +       return(fd);
14053 +}
14054 +
14055 +static void free_contents(struct hppfs_data *head)
14056 +{
14057 +       struct hppfs_data *data;
14058 +       struct list_head *ele, *next;
14059 +
14060 +       if(head == NULL) return;
14061 +
14062 +       list_for_each_safe(ele, next, &head->list){
14063 +               data = list_entry(ele, struct hppfs_data, list);
14064 +               kfree(data);
14065 +       }
14066 +       kfree(head);
14067 +}
14068 +
14069 +static struct hppfs_data *hppfs_get_data(int fd, int filter, 
14070 +                                        struct file *proc_file, 
14071 +                                        struct file *hppfs_file, 
14072 +                                        loff_t *size_out)
14073 +{
14074 +       struct hppfs_data *data, *new, *head;
14075 +       int n, err;
14076 +
14077 +       err = -ENOMEM;
14078 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
14079 +       if(data == NULL){
14080 +               printk("hppfs_get_data : head allocation failed\n");
14081 +               goto failed;
14082 +       }
14083 +
14084 +       INIT_LIST_HEAD(&data->list);
14085 +
14086 +       head = data;
14087 +       *size_out = 0;
14088 +
14089 +       if(filter){
14090 +               while((n = read_proc(proc_file, data->contents,
14091 +                                    sizeof(data->contents), NULL, 0)) > 0) {
14092 +                       err = os_write_file(fd, data->contents, n);
14093 +                       if(err != n)
14094 +                               printk("hppfs_get_data : failed to write out "
14095 +                                      "%d bytes, err = %d\n", n, -err);
14096 +               }
14097 +               err = os_shutdown_socket(fd, 0, 1);
14098 +               if(err < 0){
14099 +                       printk("hppfs_get_data : failed to shut down "
14100 +                              "socket\n");
14101 +                       goto failed_free;
14102 +               }
14103 +       }
14104 +       while(1){
14105 +               n = os_read_file(fd, data->contents, sizeof(data->contents));
14106 +               if(n < 0){
14107 +                       err = n;
14108 +                       printk("hppfs_get_data : read failed, err = %d\n", -n);
14109 +                       goto failed_free;
14110 +               }
14111 +               else if(n == 0)
14112 +                       break;
14113 +
14114 +               *size_out += n;
14115 +
14116 +               if(n < sizeof(data->contents))
14117 +                       break;
14118 +
14119 +               new = kmalloc(sizeof(*data), GFP_KERNEL);
14120 +               if(new == 0){
14121 +                       printk("hppfs_get_data : data allocation failed\n");
14122 +                       err = -ENOMEM;
14123 +                       goto failed_free;
14124 +               }
14125 +       
14126 +               INIT_LIST_HEAD(&new->list);
14127 +               list_add(&new->list, &data->list);
14128 +               data = new;
14129 +       }
14130 +       return(head);
14131 +
14132 + failed_free:
14133 +       free_contents(head);
14134 + failed:               
14135 +       return(ERR_PTR(err));
14136 +}
14137 +
14138 +static struct hppfs_private *hppfs_data(void)
14139 +{
14140 +       struct hppfs_private *data;
14141 +
14142 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
14143 +       if(data == NULL)
14144 +               return(data);
14145 +
14146 +       *data = ((struct hppfs_private ) { .host_fd             = -1,
14147 +                                          .len                 = -1,
14148 +                                          .contents            = NULL } );
14149 +       return(data);
14150 +}
14151 +
14152 +static int hppfs_open(struct inode *inode, struct file *file)
14153 +{
14154 +       struct hppfs_private *data;
14155 +       struct dentry *proc_dentry;
14156 +       char *host_file;
14157 +       int err, fd, type, filter;
14158 +
14159 +       err = -ENOMEM;
14160 +       data = hppfs_data();
14161 +       if(data == NULL)
14162 +               goto out;
14163 +
14164 +       host_file = dentry_name(file->f_dentry, strlen("/rw"));
14165 +       if(host_file == NULL)
14166 +               goto out_free2;
14167 +
14168 +       proc_dentry = inode->u.hppfs_i.proc_dentry;
14169 +       err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
14170 +       if(err)
14171 +               goto out_free1;
14172 +
14173 +       type = os_file_type(host_file);
14174 +       if(type == OS_TYPE_FILE){
14175 +               fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
14176 +               if(fd >= 0) 
14177 +                       data->host_fd = fd;
14178 +               else printk("hppfs_open : failed to open '%s', err = %d\n",
14179 +                           host_file, -fd);
14180 +
14181 +               data->contents = NULL;
14182 +       }
14183 +       else if(type == OS_TYPE_DIR){
14184 +               fd = open_host_sock(host_file, &filter);
14185 +               if(fd >= 0){
14186 +                       data->contents = hppfs_get_data(fd, filter, 
14187 +                                                       &data->proc_file, 
14188 +                                                       file, &data->len);
14189 +                       if(!IS_ERR(data->contents))
14190 +                               data->host_fd = fd;
14191 +               }
14192 +               else printk("hppfs_open : failed to open a socket in "
14193 +                           "'%s', err = %d\n", host_file, -fd);
14194 +       }
14195 +       kfree(host_file);
14196 +
14197 +       file->private_data = data;
14198 +       return(0);
14199 +
14200 + out_free1:
14201 +       kfree(host_file);
14202 + out_free2:
14203 +       free_contents(data->contents);
14204 +       kfree(data);
14205 + out:
14206 +       return(err);
14207 +}
14208 +
14209 +static int hppfs_dir_open(struct inode *inode, struct file *file)
14210 +{
14211 +       struct hppfs_private *data;
14212 +       struct dentry *proc_dentry;
14213 +       int err;
14214 +
14215 +       err = -ENOMEM;
14216 +       data = hppfs_data();
14217 +       if(data == NULL)
14218 +               goto out;
14219 +
14220 +       proc_dentry = inode->u.hppfs_i.proc_dentry;
14221 +       err = init_private_file(&data->proc_file, proc_dentry, file->f_mode);
14222 +       if(err)
14223 +               goto out_free;
14224 +
14225 +       file->private_data = data;
14226 +       return(0);
14227 +
14228 + out_free:
14229 +       kfree(data);
14230 + out:
14231 +       return(err);
14232 +}
14233 +
14234 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
14235 +{
14236 +       struct hppfs_private *data = file->private_data;
14237 +       struct file *proc_file = &data->proc_file;
14238 +       loff_t (*llseek)(struct file *, loff_t, int);
14239 +       loff_t ret;
14240 +
14241 +       llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
14242 +       if(llseek != NULL){
14243 +               ret = (*llseek)(proc_file, off, where);
14244 +               if(ret < 0)
14245 +                       return(ret);
14246 +       }
14247 +
14248 +       return(default_llseek(file, off, where));
14249 +}
14250 +
14251 +struct hppfs_dirent {
14252 +       void *vfs_dirent;
14253 +       filldir_t filldir;
14254 +       struct dentry *dentry;
14255 +};
14256 +
14257 +static int hppfs_filldir(void *d, const char *name, int size, 
14258 +                        loff_t offset, ino_t inode, unsigned int type)
14259 +{
14260 +       struct hppfs_dirent *dirent = d;
14261 +
14262 +       if(file_removed(dirent->dentry, name))
14263 +               return(0);
14264 +
14265 +       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
14266 +                                 inode, type));
14267 +}
14268 +
14269 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
14270 +{
14271 +       struct hppfs_private *data = file->private_data;
14272 +       struct file *proc_file = &data->proc_file;
14273 +       int (*readdir)(struct file *, void *, filldir_t);
14274 +       struct hppfs_dirent dirent = ((struct hppfs_dirent)
14275 +                                     { .vfs_dirent     = ent,
14276 +                                       .filldir        = filldir,
14277 +                                       .dentry         = file->f_dentry } );
14278 +       int err;
14279 +
14280 +       readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
14281 +
14282 +       proc_file->f_pos = file->f_pos;
14283 +       err = (*readdir)(proc_file, &dirent, hppfs_filldir);
14284 +       file->f_pos = proc_file->f_pos;
14285 +
14286 +       return(err);
14287 +}
14288 +
14289 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
14290 +{
14291 +       return(0);
14292 +}
14293 +
14294 +static struct file_operations hppfs_file_fops = {
14295 +       .owner          = NULL,
14296 +       .llseek         = hppfs_llseek,
14297 +       .read           = hppfs_read,
14298 +       .write          = hppfs_write,
14299 +       .open           = hppfs_open,
14300 +};
14301 +
14302 +static struct file_operations hppfs_dir_fops = {
14303 +       .owner          = NULL,
14304 +       .readdir        = hppfs_readdir,
14305 +       .open           = hppfs_dir_open,
14306 +       .fsync          = hppfs_fsync,
14307 +};
14308 +
14309 +static int hppfs_statfs(struct super_block *sb, struct statfs *sf)
14310 +{
14311 +       sf->f_blocks = 0;
14312 +       sf->f_bfree = 0;
14313 +       sf->f_bavail = 0;
14314 +       sf->f_files = 0;
14315 +       sf->f_ffree = 0;
14316 +       sf->f_type = HPPFS_SUPER_MAGIC;
14317 +       return(0);
14318 +}
14319 +
14320 +static struct super_operations hppfs_sbops = { 
14321 +       .put_inode      = force_delete,
14322 +       .delete_inode   = NULL,
14323 +       .statfs         = hppfs_statfs,
14324 +};
14325 +
14326 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
14327 +{
14328 +       struct file proc_file;
14329 +       struct dentry *proc_dentry;
14330 +       int (*readlink)(struct dentry *, char *, int);
14331 +       int err, n;
14332 +
14333 +       proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
14334 +       err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
14335 +       if(err) 
14336 +               return(err);
14337 +
14338 +       readlink = proc_dentry->d_inode->i_op->readlink;
14339 +       n = (*readlink)(proc_dentry, buffer, buflen);
14340 +
14341 +       if(proc_file.f_op->release)
14342 +               (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
14343 +       
14344 +       return(n);
14345 +}
14346 +
14347 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
14348 +{
14349 +       struct file proc_file;
14350 +       struct dentry *proc_dentry;
14351 +       int (*follow_link)(struct dentry *, struct nameidata *);
14352 +       int err, n;
14353 +
14354 +       proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry;
14355 +       err = init_private_file(&proc_file, proc_dentry, FMODE_READ);
14356 +       if(err) 
14357 +               return(err);
14358 +
14359 +       follow_link = proc_dentry->d_inode->i_op->follow_link;
14360 +       n = (*follow_link)(proc_dentry, nd);
14361 +
14362 +       if(proc_file.f_op->release)
14363 +               (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file);
14364 +       
14365 +       return(n);
14366 +}
14367 +
14368 +static struct inode_operations hppfs_link_iops = {
14369 +       .readlink       = hppfs_readlink,
14370 +       .follow_link    = hppfs_follow_link,
14371 +};
14372 +
14373 +static void read_inode(struct inode *ino)
14374 +{
14375 +       struct inode *proc_ino;
14376 +
14377 +       proc_ino = ino->u.hppfs_i.proc_dentry->d_inode;
14378 +       ino->i_uid = proc_ino->i_uid;
14379 +       ino->i_gid = proc_ino->i_gid;
14380 +       ino->i_atime = proc_ino->i_atime;
14381 +       ino->i_mtime = proc_ino->i_mtime;
14382 +       ino->i_ctime = proc_ino->i_ctime;
14383 +       ino->i_ino = proc_ino->i_ino;
14384 +       ino->i_dev = proc_ino->i_dev;
14385 +       ino->i_mode = proc_ino->i_mode;
14386 +       ino->i_nlink = proc_ino->i_nlink;
14387 +       ino->i_size = proc_ino->i_size;
14388 +       ino->i_blksize = proc_ino->i_blksize;
14389 +       ino->i_blocks = proc_ino->i_blocks;
14390 +}
14391 +
14392 +static struct inode *get_inode(struct super_block *sb, struct dentry *dentry,
14393 +                              int *error)
14394 +{
14395 +       struct inode *inode;
14396 +       int err = -ENOMEM;
14397 +
14398 +       inode = new_inode(sb);
14399 +       if(inode == NULL) 
14400 +               goto out;
14401 +
14402 +       insert_inode_hash(inode);
14403 +       if(S_ISDIR(dentry->d_inode->i_mode)){
14404 +               inode->i_op = &hppfs_dir_iops;
14405 +               inode->i_fop = &hppfs_dir_fops;
14406 +       }
14407 +       else if(S_ISLNK(dentry->d_inode->i_mode)){
14408 +               inode->i_op = &hppfs_link_iops;
14409 +               inode->i_fop = &hppfs_file_fops;
14410 +       }
14411 +       else {
14412 +               inode->i_op = &hppfs_file_iops;
14413 +               inode->i_fop = &hppfs_file_fops;
14414 +       }
14415 +
14416 +       inode->i_sb = sb;
14417 +       inode->u.hppfs_i.proc_dentry = dentry;
14418 +
14419 +       read_inode(inode);
14420 +       err = 0;
14421 +
14422 +       if(error) *error = err;
14423 +       return(inode);
14424 + out:
14425 +       if(error) *error = err;
14426 +       return(NULL);
14427 +}
14428 +
14429 +static struct super_block *hppfs_read_super(struct super_block *sb, void *d, 
14430 +                                           int silent)
14431 +{
14432 +       struct inode *root_inode;
14433 +       struct file_system_type *procfs;
14434 +       struct super_block *proc_sb;
14435 +
14436 +       procfs = get_fs_type("proc");
14437 +       if(procfs == NULL) 
14438 +               goto out;
14439 +
14440 +       if(list_empty(&procfs->fs_supers))
14441 +               goto out;
14442 +
14443 +       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
14444 +                            s_instances);
14445 +       
14446 +       sb->s_blocksize = 1024;
14447 +       sb->s_blocksize_bits = 10;
14448 +       sb->s_magic = HPPFS_SUPER_MAGIC;
14449 +       sb->s_op = &hppfs_sbops;
14450 +
14451 +       dget(proc_sb->s_root);
14452 +       root_inode = get_inode(sb, proc_sb->s_root, NULL);
14453 +       if(root_inode == NULL)
14454 +               goto out_dput;
14455 +
14456 +       sb->s_root = d_alloc_root(root_inode);
14457 +       if(sb->s_root == NULL)
14458 +               goto out_put;
14459 +
14460 +       return(sb);
14461 +
14462 + out_put:
14463 +       iput(root_inode);
14464 + out_dput:
14465 +       dput(proc_sb->s_root);
14466 + out:
14467 +       return(NULL);
14468 +}
14469 +
14470 +DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0);
14471 +
14472 +static int __init init_hppfs(void)
14473 +{
14474 +       return(register_filesystem(&hppfs_type));
14475 +}
14476 +
14477 +static void __exit exit_hppfs(void)
14478 +{
14479 +       unregister_filesystem(&hppfs_type);
14480 +}
14481 +
14482 +module_init(init_hppfs)
14483 +module_exit(exit_hppfs)
14484 +MODULE_LICENSE("GPL");
14485 +
14486 +/*
14487 + * Overrides for Emacs so that we follow Linus's tabbing style.
14488 + * Emacs will notice this stuff at the end of the file and automatically
14489 + * adjust the settings for this buffer only.  This must remain at the end
14490 + * of the file.
14491 + * ---------------------------------------------------------------------------
14492 + * Local variables:
14493 + * c-file-style: "linux"
14494 + * End:
14495 + */
14496 diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/Makefile um/arch/um/fs/hppfs/Makefile
14497 --- orig/arch/um/fs/hppfs/Makefile      1969-12-31 19:00:00.000000000 -0500
14498 +++ um/arch/um/fs/hppfs/Makefile        2003-10-21 03:26:06.000000000 -0400
14499 @@ -0,0 +1,10 @@
14500 +O_TARGET := hppfs.o
14501 +obj-y = hppfs_kern.o #hppfs_user.o
14502 +obj-m = $(O_TARGET)
14503 +
14504 +CFLAGS_hppfs_kern.o := $(CFLAGS)
14505 +#CFLAGS_hppfs_user.o := $(USER_CFLAGS)
14506 +
14507 +override CFLAGS =  
14508 +
14509 +include $(TOPDIR)/Rules.make
14510 diff -Naur -X ../exclude-files orig/arch/um/fs/Makefile um/arch/um/fs/Makefile
14511 --- orig/arch/um/fs/Makefile    1969-12-31 19:00:00.000000000 -0500
14512 +++ um/arch/um/fs/Makefile      2003-10-21 03:26:06.000000000 -0400
14513 @@ -0,0 +1,23 @@
14514 +# 
14515 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
14516 +# Licensed under the GPL
14517 +#
14518 +
14519 +O_TARGET := built-in.o
14520 +
14521 +subdir-y =
14522 +subdir-m =
14523 +
14524 +subdir-$(CONFIG_HOSTFS) += hostfs
14525 +subdir-$(CONFIG_HPPFS) += hppfs
14526 +
14527 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
14528 +obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o))
14529 +
14530 +include $(TOPDIR)/Rules.make
14531 +
14532 +dep:
14533 +
14534 +clean:
14535 +
14536 +archmrproper:
14537 diff -Naur -X ../exclude-files orig/arch/um/include/2_5compat.h um/arch/um/include/2_5compat.h
14538 --- orig/arch/um/include/2_5compat.h    1969-12-31 19:00:00.000000000 -0500
14539 +++ um/arch/um/include/2_5compat.h      2003-11-07 02:49:26.000000000 -0500
14540 @@ -0,0 +1,33 @@
14541 +/* 
14542 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
14543 + * Licensed under the GPL
14544 + */
14545 +
14546 +#ifndef __2_5_COMPAT_H__
14547 +#define __2_5_COMPAT_H__
14548 +
14549 +#include "linux/version.h"
14550 +
14551 +#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP)
14552 +
14553 +#define ELV_NOOP ELEVATOR_NOOP
14554 +
14555 +#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes
14556 +
14557 +#define IS_WRITE(req) ((req)->cmd == WRITE)
14558 +
14559 +#define SET_PRI(task) \
14560 +       do { (task)->nice = 20; (task)->counter = -100; } while(0);
14561 +
14562 +#endif
14563 +
14564 +/*
14565 + * Overrides for Emacs so that we follow Linus's tabbing style.
14566 + * Emacs will notice this stuff at the end of the file and automatically
14567 + * adjust the settings for this buffer only.  This must remain at the end
14568 + * of the file.
14569 + * ---------------------------------------------------------------------------
14570 + * Local variables:
14571 + * c-file-style: "linux"
14572 + * End:
14573 + */
14574 diff -Naur -X ../exclude-files orig/arch/um/include/chan_kern.h um/arch/um/include/chan_kern.h
14575 --- orig/arch/um/include/chan_kern.h    1969-12-31 19:00:00.000000000 -0500
14576 +++ um/arch/um/include/chan_kern.h      2003-10-21 03:26:06.000000000 -0400
14577 @@ -0,0 +1,56 @@
14578 +/* 
14579 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
14580 + * Licensed under the GPL
14581 + */
14582 +
14583 +#ifndef __CHAN_KERN_H__
14584 +#define __CHAN_KERN_H__
14585 +
14586 +#include "linux/tty.h"
14587 +#include "linux/list.h"
14588 +#include "chan_user.h"
14589 +
14590 +struct chan {
14591 +       struct list_head list;
14592 +       char *dev;
14593 +       unsigned int primary:1;
14594 +       unsigned int input:1;
14595 +       unsigned int output:1;
14596 +       unsigned int opened:1;
14597 +       int fd;
14598 +       enum chan_init_pri pri;
14599 +       struct chan_ops *ops;
14600 +       void *data;
14601 +};
14602 +
14603 +extern void chan_interrupt(struct list_head *chans, struct tq_struct *task,
14604 +                          struct tty_struct *tty, int irq, void *dev);
14605 +extern int parse_chan_pair(char *str, struct list_head *chans, int pri, 
14606 +                          int device, struct chan_opts *opts);
14607 +extern int open_chan(struct list_head *chans);
14608 +extern int write_chan(struct list_head *chans, const char *buf, int len,
14609 +                            int write_irq);
14610 +extern int console_write_chan(struct list_head *chans, const char *buf, 
14611 +                             int len);
14612 +extern void close_chan(struct list_head *chans);
14613 +extern void chan_enable_winch(struct list_head *chans, void *line);
14614 +extern void enable_chan(struct list_head *chans, void *data);
14615 +extern int chan_window_size(struct list_head *chans, 
14616 +                            unsigned short *rows_out, 
14617 +                            unsigned short *cols_out);
14618 +extern int chan_out_fd(struct list_head *chans);
14619 +extern int chan_config_string(struct list_head *chans, char *str, int size,
14620 +                             char **error_out);
14621 +
14622 +#endif
14623 +
14624 +/*
14625 + * Overrides for Emacs so that we follow Linus's tabbing style.
14626 + * Emacs will notice this stuff at the end of the file and automatically
14627 + * adjust the settings for this buffer only.  This must remain at the end
14628 + * of the file.
14629 + * ---------------------------------------------------------------------------
14630 + * Local variables:
14631 + * c-file-style: "linux"
14632 + * End:
14633 + */
14634 diff -Naur -X ../exclude-files orig/arch/um/include/chan_user.h um/arch/um/include/chan_user.h
14635 --- orig/arch/um/include/chan_user.h    1969-12-31 19:00:00.000000000 -0500
14636 +++ um/arch/um/include/chan_user.h      2003-10-21 03:26:06.000000000 -0400
14637 @@ -0,0 +1,66 @@
14638 +/* 
14639 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
14640 + * Licensed under the GPL
14641 + */
14642 +
14643 +#ifndef __CHAN_USER_H__
14644 +#define __CHAN_USER_H__
14645 +
14646 +#include "init.h"
14647 +
14648 +struct chan_opts {
14649 +       void (*announce)(char *dev_name, int dev);
14650 +       char *xterm_title;
14651 +       int raw;
14652 +       unsigned long tramp_stack;
14653 +       int in_kernel;
14654 +};
14655 +
14656 +enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
14657 +
14658 +struct chan_ops {
14659 +       char *type;
14660 +       void *(*init)(char *, int, struct chan_opts *);
14661 +       int (*open)(int, int, int, void *, char **);
14662 +       void (*close)(int, void *);
14663 +       int (*read)(int, char *, void *);
14664 +       int (*write)(int, const char *, int, void *);
14665 +       int (*console_write)(int, const char *, int, void *);
14666 +       int (*window_size)(int, void *, unsigned short *, unsigned short *);
14667 +       void (*free)(void *);
14668 +       int winch;
14669 +};
14670 +
14671 +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
14672 +       xterm_ops;
14673 +
14674 +extern void generic_close(int fd, void *unused);
14675 +extern int generic_read(int fd, char *c_out, void *unused);
14676 +extern int generic_write(int fd, const char *buf, int n, void *unused);
14677 +extern int generic_console_write(int fd, const char *buf, int n, void *state);
14678 +extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
14679 +                              unsigned short *cols_out);
14680 +extern void generic_free(void *data);
14681 +
14682 +extern void register_winch(int fd, void *device_data);
14683 +extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
14684 +
14685 +#define __channel_help(fn, prefix) \
14686 +__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
14687 +"    Attach a console or serial line to a host channel.  See\n" \
14688 +"    http://user-mode-linux.sourceforge.net/input.html for a complete\n" \
14689 +"    description of this switch.\n\n" \
14690 +);
14691 +
14692 +#endif
14693 +
14694 +/*
14695 + * Overrides for Emacs so that we follow Linus's tabbing style.
14696 + * Emacs will notice this stuff at the end of the file and automatically
14697 + * adjust the settings for this buffer only.  This must remain at the end
14698 + * of the file.
14699 + * ---------------------------------------------------------------------------
14700 + * Local variables:
14701 + * c-file-style: "linux"
14702 + * End:
14703 + */
14704 diff -Naur -X ../exclude-files orig/arch/um/include/choose-mode.h um/arch/um/include/choose-mode.h
14705 --- orig/arch/um/include/choose-mode.h  1969-12-31 19:00:00.000000000 -0500
14706 +++ um/arch/um/include/choose-mode.h    2003-10-21 03:26:06.000000000 -0400
14707 @@ -0,0 +1,35 @@
14708 +/* 
14709 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14710 + * Licensed under the GPL
14711 + */
14712 +
14713 +#ifndef __CHOOSE_MODE_H__
14714 +#define __CHOOSE_MODE_H__
14715 +
14716 +#include "uml-config.h"
14717 +
14718 +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
14719 +#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
14720 +
14721 +#elif defined(UML_CONFIG_MODE_SKAS)
14722 +#define CHOOSE_MODE(tt, skas) (skas)
14723 +
14724 +#elif defined(UML_CONFIG_MODE_TT)
14725 +#define CHOOSE_MODE(tt, skas) (tt)
14726 +#endif
14727 +
14728 +#define CHOOSE_MODE_PROC(tt, skas, args...) \
14729 +       CHOOSE_MODE(tt(args), skas(args))
14730 +
14731 +#endif
14732 +
14733 +/*
14734 + * Overrides for Emacs so that we follow Linus's tabbing style.
14735 + * Emacs will notice this stuff at the end of the file and automatically
14736 + * adjust the settings for this buffer only.  This must remain at the end
14737 + * of the file.
14738 + * ---------------------------------------------------------------------------
14739 + * Local variables:
14740 + * c-file-style: "linux"
14741 + * End:
14742 + */
14743 diff -Naur -X ../exclude-files orig/arch/um/include/frame.h um/arch/um/include/frame.h
14744 --- orig/arch/um/include/frame.h        1969-12-31 19:00:00.000000000 -0500
14745 +++ um/arch/um/include/frame.h  2003-10-21 03:26:06.000000000 -0400
14746 @@ -0,0 +1,53 @@
14747 +/* 
14748 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14749 + * Licensed under the GPL
14750 + */
14751 +
14752 +#ifndef __FRAME_H_
14753 +#define __FRAME_H_
14754 +
14755 +#include "sysdep/frame.h"
14756 +
14757 +struct frame_common {
14758 +       void *data;
14759 +       int len;
14760 +       int sig_index;
14761 +       int sr_index;
14762 +       int sr_relative;
14763 +       int sp_index;
14764 +       struct arch_frame_data arch;
14765 +};
14766 +
14767 +struct sc_frame {
14768 +       struct frame_common common;
14769 +       int sc_index;
14770 +};
14771 +
14772 +extern struct sc_frame signal_frame_sc;
14773 +
14774 +extern struct sc_frame signal_frame_sc_sr;
14775 +
14776 +struct si_frame {
14777 +       struct frame_common common;
14778 +       int sip_index;
14779 +       int si_index;
14780 +       int ucp_index;
14781 +       int uc_index;
14782 +};
14783 +
14784 +extern struct si_frame signal_frame_si;
14785 +
14786 +extern void capture_signal_stack(void);
14787 +
14788 +#endif
14789 +
14790 +/*
14791 + * Overrides for Emacs so that we follow Linus's tabbing style.
14792 + * Emacs will notice this stuff at the end of the file and automatically
14793 + * adjust the settings for this buffer only.  This must remain at the end
14794 + * of the file.
14795 + * ---------------------------------------------------------------------------
14796 + * Local variables:
14797 + * c-file-style: "linux"
14798 + * End:
14799 + */
14800 diff -Naur -X ../exclude-files orig/arch/um/include/frame_kern.h um/arch/um/include/frame_kern.h
14801 --- orig/arch/um/include/frame_kern.h   1969-12-31 19:00:00.000000000 -0500
14802 +++ um/arch/um/include/frame_kern.h     2003-10-21 03:26:06.000000000 -0400
14803 @@ -0,0 +1,34 @@
14804 +/* 
14805 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14806 + * Licensed under the GPL
14807 + */
14808 +
14809 +#ifndef __FRAME_KERN_H_
14810 +#define __FRAME_KERN_H_
14811 +
14812 +#include "frame.h"
14813 +#include "sysdep/frame_kern.h"
14814 +
14815 +extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 
14816 +                                unsigned long handler,
14817 +                                void (*restorer)(void), 
14818 +                                struct pt_regs *regs, 
14819 +                                sigset_t *mask);
14820 +extern int setup_signal_stack_si(unsigned long stack_top, int sig, 
14821 +                                unsigned long handler, 
14822 +                                void (*restorer)(void), 
14823 +                                struct pt_regs *regs, siginfo_t *info, 
14824 +                                sigset_t *mask);
14825 +
14826 +#endif
14827 +
14828 +/*
14829 + * Overrides for Emacs so that we follow Linus's tabbing style.
14830 + * Emacs will notice this stuff at the end of the file and automatically
14831 + * adjust the settings for this buffer only.  This must remain at the end
14832 + * of the file.
14833 + * ---------------------------------------------------------------------------
14834 + * Local variables:
14835 + * c-file-style: "linux"
14836 + * End:
14837 + */
14838 diff -Naur -X ../exclude-files orig/arch/um/include/frame_user.h um/arch/um/include/frame_user.h
14839 --- orig/arch/um/include/frame_user.h   1969-12-31 19:00:00.000000000 -0500
14840 +++ um/arch/um/include/frame_user.h     2003-10-21 03:26:06.000000000 -0400
14841 @@ -0,0 +1,23 @@
14842 +/* 
14843 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14844 + * Licensed under the GPL
14845 + */
14846 +
14847 +#ifndef __FRAME_USER_H_
14848 +#define __FRAME_USER_H_
14849 +
14850 +#include "sysdep/frame_user.h"
14851 +#include "frame.h"
14852 +
14853 +#endif
14854 +
14855 +/*
14856 + * Overrides for Emacs so that we follow Linus's tabbing style.
14857 + * Emacs will notice this stuff at the end of the file and automatically
14858 + * adjust the settings for this buffer only.  This must remain at the end
14859 + * of the file.
14860 + * ---------------------------------------------------------------------------
14861 + * Local variables:
14862 + * c-file-style: "linux"
14863 + * End:
14864 + */
14865 diff -Naur -X ../exclude-files orig/arch/um/include/helper.h um/arch/um/include/helper.h
14866 --- orig/arch/um/include/helper.h       1969-12-31 19:00:00.000000000 -0500
14867 +++ um/arch/um/include/helper.h 2003-10-21 03:26:06.000000000 -0400
14868 @@ -0,0 +1,27 @@
14869 +/* 
14870 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14871 + * Licensed under the GPL
14872 + */
14873 +
14874 +#ifndef __HELPER_H__
14875 +#define __HELPER_H__
14876 +
14877 +extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
14878 +                     unsigned long *stack_out);
14879 +extern int run_helper_thread(int (*proc)(void *), void *arg, 
14880 +                            unsigned int flags, unsigned long *stack_out,
14881 +                            int stack_order);
14882 +extern int helper_wait(int pid);
14883 +
14884 +#endif
14885 +
14886 +/*
14887 + * Overrides for Emacs so that we follow Linus's tabbing style.
14888 + * Emacs will notice this stuff at the end of the file and automatically
14889 + * adjust the settings for this buffer only.  This must remain at the end
14890 + * of the file.
14891 + * ---------------------------------------------------------------------------
14892 + * Local variables:
14893 + * c-file-style: "linux"
14894 + * End:
14895 + */
14896 diff -Naur -X ../exclude-files orig/arch/um/include/hostaudio.h um/arch/um/include/hostaudio.h
14897 --- orig/arch/um/include/hostaudio.h    1969-12-31 19:00:00.000000000 -0500
14898 +++ um/arch/um/include/hostaudio.h      2003-10-21 03:26:06.000000000 -0400
14899 @@ -0,0 +1,48 @@
14900 +/* 
14901 + * Copyright (C) 2002 Steve Schmidtke 
14902 + * Licensed under the GPL
14903 + */
14904 +
14905 +#ifndef HOSTAUDIO_H
14906 +#define HOSTAUDIO_H
14907 +
14908 +#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
14909 +#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
14910 +
14911 +struct hostaudio_state {
14912 +  int fd;
14913 +};
14914 +
14915 +struct hostmixer_state {
14916 +  int fd;
14917 +};
14918 +
14919 +/* UML user-side protoypes */
14920 +extern ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
14921 +                                  size_t count, loff_t *ppos);
14922 +extern ssize_t hostaudio_write_user(struct hostaudio_state *state, 
14923 +                                   const char *buffer, size_t count, 
14924 +                                   loff_t *ppos);
14925 +extern int hostaudio_ioctl_user(struct hostaudio_state *state, 
14926 +                               unsigned int cmd, unsigned long arg);
14927 +extern int hostaudio_open_user(struct hostaudio_state *state, int r, int w, 
14928 +                              char *dsp);
14929 +extern int hostaudio_release_user(struct hostaudio_state *state);
14930 +extern int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
14931 +                               unsigned int cmd, unsigned long arg);
14932 +extern int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, 
14933 +                                     int w, char *mixer);
14934 +extern int hostmixer_release_mixdev_user(struct hostmixer_state *state);
14935 +
14936 +#endif /* HOSTAUDIO_H */
14937 +
14938 +/*
14939 + * Overrides for Emacs so that we follow Linus's tabbing style.
14940 + * Emacs will notice this stuff at the end of the file and automatically
14941 + * adjust the settings for this buffer only.  This must remain at the end
14942 + * of the file.
14943 + * ---------------------------------------------------------------------------
14944 + * Local variables:
14945 + * c-file-style: "linux"
14946 + * End:
14947 + */
14948 diff -Naur -X ../exclude-files orig/arch/um/include/init.h um/arch/um/include/init.h
14949 --- orig/arch/um/include/init.h 1969-12-31 19:00:00.000000000 -0500
14950 +++ um/arch/um/include/init.h   2003-10-21 03:26:06.000000000 -0400
14951 @@ -0,0 +1,114 @@
14952 +#ifndef _LINUX_UML_INIT_H
14953 +#define _LINUX_UML_INIT_H
14954 +
14955 +/* These macros are used to mark some functions or
14956 + * initialized data (doesn't apply to uninitialized data)
14957 + * as `initialization' functions. The kernel can take this
14958 + * as hint that the function is used only during the initialization
14959 + * phase and free up used memory resources after
14960 + *
14961 + * Usage:
14962 + * For functions:
14963 + *
14964 + * You should add __init immediately before the function name, like:
14965 + *
14966 + * static void __init initme(int x, int y)
14967 + * {
14968 + *    extern int z; z = x * y;
14969 + * }
14970 + *
14971 + * If the function has a prototype somewhere, you can also add
14972 + * __init between closing brace of the prototype and semicolon:
14973 + *
14974 + * extern int initialize_foobar_device(int, int, int) __init;
14975 + *
14976 + * For initialized data:
14977 + * You should insert __initdata between the variable name and equal
14978 + * sign followed by value, e.g.:
14979 + *
14980 + * static int init_variable __initdata = 0;
14981 + * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
14982 + *
14983 + * Don't forget to initialize data not at file scope, i.e. within a function,
14984 + * as gcc otherwise puts the data into the bss section and not into the init
14985 + * section.
14986 + *
14987 + * Also note, that this data cannot be "const".
14988 + */
14989 +
14990 +#ifndef _LINUX_INIT_H
14991 +typedef int (*initcall_t)(void);
14992 +typedef void (*exitcall_t)(void);
14993 +
14994 +#define __init          __attribute__ ((__section__ (".text.init")))
14995 +#define __exit          __attribute__ ((unused, __section__(".text.exit")))
14996 +#define __initdata      __attribute__ ((__section__ (".data.init")))
14997 +
14998 +#endif
14999 +
15000 +#ifndef MODULE
15001 +struct uml_param {
15002 +        const char *str;
15003 +        int (*setup_func)(char *, int *);
15004 +};
15005 +
15006 +extern initcall_t __uml_initcall_start, __uml_initcall_end;
15007 +extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
15008 +extern const char *__uml_help_start, *__uml_help_end;
15009 +#endif
15010 +
15011 +#define __uml_initcall(fn)                                             \
15012 +       static initcall_t __uml_initcall_##fn __uml_init_call = fn
15013 +
15014 +#define __uml_exitcall(fn)                                             \
15015 +       static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
15016 +
15017 +extern struct uml_param __uml_setup_start, __uml_setup_end;
15018 +
15019 +#define __uml_postsetup(fn)                                            \
15020 +       static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
15021 +
15022 +#define __non_empty_string(dummyname,string)                           \
15023 +       struct __uml_non_empty_string_struct_##dummyname                \
15024 +       {                                                               \
15025 +               char _string[sizeof(string)-2];                         \
15026 +       }
15027 +
15028 +#ifndef MODULE
15029 +#define __uml_setup(str, fn, help...)                                  \
15030 +       __non_empty_string(fn ##_setup, str);                           \
15031 +       __uml_help(fn, help);                                           \
15032 +       static char __uml_setup_str_##fn[] __initdata = str;            \
15033 +       static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
15034 +#else
15035 +#define __uml_setup(str, fn, help...)                                  \
15036 +
15037 +#endif
15038 +
15039 +#define __uml_help(fn, help...)                                                \
15040 +       __non_empty_string(fn ##__help, help);                          \
15041 +       static char __uml_help_str_##fn[] __initdata = help;            \
15042 +       static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
15043 +
15044 +/*
15045 + * Mark functions and data as being only used at initialization
15046 + * or exit time.
15047 + */
15048 +#define __uml_init_setup       __attribute__ ((unused,__section__ (".uml.setup.init")))
15049 +#define __uml_setup_help       __attribute__ ((unused,__section__ (".uml.help.init")))
15050 +#define __uml_init_call                __attribute__ ((unused,__section__ (".uml.initcall.init")))
15051 +#define __uml_postsetup_call   __attribute__ ((unused,__section__ (".uml.postsetup.init")))
15052 +#define __uml_exit_call                __attribute__ ((unused,__section__ (".uml.exitcall.exit")))
15053 +
15054 +#endif /* _LINUX_UML_INIT_H */
15055 +
15056 +/*
15057 + * Overrides for Emacs so that we follow Linus's tabbing style.
15058 + * Emacs will notice this stuff at the end of the file and automatically
15059 + * adjust the settings for this buffer only.  This must remain at the end
15060 + * of the file.
15061 + * ---------------------------------------------------------------------------
15062 + * Local variables:
15063 + * c-file-style: "linux"
15064 + * End:
15065 + */
15066 diff -Naur -X ../exclude-files orig/arch/um/include/initrd.h um/arch/um/include/initrd.h
15067 --- orig/arch/um/include/initrd.h       1969-12-31 19:00:00.000000000 -0500
15068 +++ um/arch/um/include/initrd.h 2003-10-21 03:26:06.000000000 -0400
15069 @@ -0,0 +1,22 @@
15070 +/*
15071 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15072 + * Licensed under the GPL
15073 + */
15074 +
15075 +#ifndef __INITRD_USER_H__
15076 +#define __INITRD_USER_H__
15077 +
15078 +extern int load_initrd(char *filename, void *buf, int size);
15079 +
15080 +#endif
15081 +
15082 +/*
15083 + * Overrides for Emacs so that we follow Linus's tabbing style.
15084 + * Emacs will notice this stuff at the end of the file and automatically
15085 + * adjust the settings for this buffer only.  This must remain at the end
15086 + * of the file.
15087 + * ---------------------------------------------------------------------------
15088 + * Local variables:
15089 + * c-file-style: "linux"
15090 + * End:
15091 + */
15092 diff -Naur -X ../exclude-files orig/arch/um/include/irq_kern.h um/arch/um/include/irq_kern.h
15093 --- orig/arch/um/include/irq_kern.h     1969-12-31 19:00:00.000000000 -0500
15094 +++ um/arch/um/include/irq_kern.h       2003-10-21 03:26:06.000000000 -0400
15095 @@ -0,0 +1,27 @@
15096 +/* 
15097 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15098 + * Licensed under the GPL
15099 + */
15100 +
15101 +#ifndef __IRQ_KERN_H__
15102 +#define __IRQ_KERN_H__
15103 +
15104 +#include "linux/interrupt.h"
15105 +
15106 +extern int um_request_irq(unsigned int irq, int fd, int type,
15107 +                         void (*handler)(int, void *, struct pt_regs *),
15108 +                         unsigned long irqflags,  const char * devname,
15109 +                         void *dev_id);
15110 +
15111 +#endif
15112 +
15113 +/*
15114 + * Overrides for Emacs so that we follow Linus's tabbing style.
15115 + * Emacs will notice this stuff at the end of the file and automatically
15116 + * adjust the settings for this buffer only.  This must remain at the end
15117 + * of the file.
15118 + * ---------------------------------------------------------------------------
15119 + * Local variables:
15120 + * c-file-style: "linux"
15121 + * End:
15122 + */
15123 diff -Naur -X ../exclude-files orig/arch/um/include/irq_user.h um/arch/um/include/irq_user.h
15124 --- orig/arch/um/include/irq_user.h     1969-12-31 19:00:00.000000000 -0500
15125 +++ um/arch/um/include/irq_user.h       2003-10-21 03:26:06.000000000 -0400
15126 @@ -0,0 +1,35 @@
15127 +/* 
15128 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15129 + * Licensed under the GPL
15130 + */
15131 +
15132 +#ifndef __IRQ_USER_H__
15133 +#define __IRQ_USER_H__
15134 +
15135 +enum { IRQ_READ, IRQ_WRITE };
15136 +
15137 +extern void sigio_handler(int sig, union uml_pt_regs *regs);
15138 +extern int activate_fd(int irq, int fd, int type, void *dev_id);
15139 +extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
15140 +extern void free_irq_by_fd(int fd);
15141 +extern void reactivate_fd(int fd, int irqnum);
15142 +extern void deactivate_fd(int fd, int irqnum);
15143 +extern void forward_interrupts(int pid);
15144 +extern void init_irq_signals(int on_sigstack);
15145 +extern void forward_ipi(int fd, int pid);
15146 +extern void free_irq_later(int irq, void *dev_id);
15147 +extern int activate_ipi(int fd, int pid);
15148 +extern unsigned long irq_lock(void);
15149 +extern void irq_unlock(unsigned long flags);
15150 +#endif
15151 +
15152 +/*
15153 + * Overrides for Emacs so that we follow Linus's tabbing style.
15154 + * Emacs will notice this stuff at the end of the file and automatically
15155 + * adjust the settings for this buffer only.  This must remain at the end
15156 + * of the file.
15157 + * ---------------------------------------------------------------------------
15158 + * Local variables:
15159 + * c-file-style: "linux"
15160 + * End:
15161 + */
15162 diff -Naur -X ../exclude-files orig/arch/um/include/kern.h um/arch/um/include/kern.h
15163 --- orig/arch/um/include/kern.h 1969-12-31 19:00:00.000000000 -0500
15164 +++ um/arch/um/include/kern.h   2003-10-21 03:26:06.000000000 -0400
15165 @@ -0,0 +1,48 @@
15166 +/* 
15167 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
15168 + * Licensed under the GPL
15169 + */
15170 +
15171 +#ifndef __KERN_H__
15172 +#define __KERN_H__
15173 +
15174 +/* These are all user-mode things which are convenient to call directly
15175 + * from kernel code and for which writing a wrapper is too much of a pain.
15176 + * The regular include files can't be included because this file is included
15177 + * only into kernel code, and user-space includes conflict with kernel
15178 + * includes.
15179 + */
15180 +
15181 +extern int errno;
15182 +
15183 +extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
15184 +extern int sleep(int);
15185 +extern int printf(char *fmt, ...);
15186 +extern char *strerror(int errnum);
15187 +extern char *ptsname(int __fd);
15188 +extern int munmap(void *, int);
15189 +extern void *sbrk(int increment);
15190 +extern void *malloc(int size);
15191 +extern void perror(char *err);
15192 +extern int kill(int pid, int sig);
15193 +extern int getuid(void);
15194 +extern int pause(void);
15195 +extern int write(int, const void *, int);
15196 +extern int exit(int);
15197 +extern int close(int);
15198 +extern int read(unsigned int, char *, int);
15199 +extern int pipe(int *);
15200 +extern int sched_yield(void);
15201 +extern int ptrace(int op, int pid, long addr, long data);
15202 +#endif
15203 +
15204 +/*
15205 + * Overrides for Emacs so that we follow Linus's tabbing style.
15206 + * Emacs will notice this stuff at the end of the file and automatically
15207 + * adjust the settings for this buffer only.  This must remain at the end
15208 + * of the file.
15209 + * ---------------------------------------------------------------------------
15210 + * Local variables:
15211 + * c-file-style: "linux"
15212 + * End:
15213 + */
15214 diff -Naur -X ../exclude-files orig/arch/um/include/kern_util.h um/arch/um/include/kern_util.h
15215 --- orig/arch/um/include/kern_util.h    1969-12-31 19:00:00.000000000 -0500
15216 +++ um/arch/um/include/kern_util.h      2003-11-10 00:58:10.000000000 -0500
15217 @@ -0,0 +1,123 @@
15218 +/* 
15219 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15220 + * Licensed under the GPL
15221 + */
15222 +
15223 +#ifndef __KERN_UTIL_H__
15224 +#define __KERN_UTIL_H__
15225 +
15226 +#include "sysdep/ptrace.h"
15227 +
15228 +extern int ncpus;
15229 +extern char *linux_prog;
15230 +extern char *gdb_init;
15231 +extern int kmalloc_ok;
15232 +extern int timer_irq_inited;
15233 +extern int jail;
15234 +extern int nsyscalls;
15235 +
15236 +#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
15237 +#define UML_ROUND_UP(addr) \
15238 +       UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
15239 +
15240 +extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
15241 +extern unsigned long stack_sp(unsigned long page);
15242 +extern int kernel_thread_proc(void *data);
15243 +extern void syscall_segv(int sig);
15244 +extern int current_pid(void);
15245 +extern unsigned long alloc_stack(int order, int atomic);
15246 +extern int do_signal(int error);
15247 +extern int is_stack_fault(unsigned long sp);
15248 +extern unsigned long segv(unsigned long address, unsigned long ip, 
15249 +                         int is_write, int is_user, void *sc);
15250 +extern unsigned long handle_page_fault(unsigned long address, unsigned long ip,
15251 +                                      int is_write, int is_user, 
15252 +                                      int *code_out);
15253 +extern void syscall_ready(void);
15254 +extern int segv_syscall(void);
15255 +extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
15256 +extern int page_size(void);
15257 +extern int page_mask(void);
15258 +extern int need_finish_fork(void);
15259 +extern void free_stack(unsigned long stack, int order);
15260 +extern void add_input_request(int op, void (*proc)(int), void *arg);
15261 +extern int sys_execve(char *file, char **argv, char **env);
15262 +extern char *current_cmd(void);
15263 +extern void timer_handler(int sig, union uml_pt_regs *regs);
15264 +extern int set_signals(int enable);
15265 +extern void force_sigbus(void);
15266 +extern int pid_to_processor_id(int pid);
15267 +extern void block_signals(void);
15268 +extern void unblock_signals(void);
15269 +extern void deliver_signals(void *t);
15270 +extern int next_syscall_index(int max);
15271 +extern int next_trap_index(int max);
15272 +extern void cpu_idle(void);
15273 +extern void finish_fork(void);
15274 +extern void paging_init(void);
15275 +extern void init_flush_vm(void);
15276 +extern void *syscall_sp(void *t);
15277 +extern void syscall_trace(void);
15278 +extern int hz(void);
15279 +extern void idle_timer(void);
15280 +extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
15281 +extern int external_pid(void *t);
15282 +extern void boot_timer_handler(int sig);
15283 +extern void interrupt_end(void);
15284 +extern void initial_thread_cb(void (*proc)(void *), void *arg);
15285 +extern int debugger_signal(int status, int pid);
15286 +extern void debugger_parent_signal(int status, int pid);
15287 +extern void child_signal(int pid, int status);
15288 +extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
15289 +extern int init_parent_proxy(int pid);
15290 +extern void check_stack_overflow(void *ptr);
15291 +extern void relay_signal(int sig, union uml_pt_regs *regs);
15292 +extern void not_implemented(void);
15293 +extern int user_context(unsigned long sp);
15294 +extern void timer_irq(union uml_pt_regs *regs);
15295 +extern void unprotect_stack(unsigned long stack);
15296 +extern void do_uml_exitcalls(void);
15297 +extern int attach_debugger(int idle_pid, int pid, int stop);
15298 +extern void bad_segv(unsigned long address, unsigned long ip, int is_write);
15299 +extern int config_gdb(char *str);
15300 +extern int remove_gdb(void);
15301 +extern char *uml_strdup(char *string);
15302 +extern void unprotect_kernel_mem(void);
15303 +extern void protect_kernel_mem(void);
15304 +extern void set_kmem_end(unsigned long);
15305 +extern void uml_cleanup(void);
15306 +extern void set_current(void *t);
15307 +extern void lock_signalled_task(void *t);
15308 +extern void IPI_handler(int cpu);
15309 +extern int jail_setup(char *line, int *add);
15310 +extern void *get_init_task(void);
15311 +extern int clear_user_proc(void *buf, int size);
15312 +extern int copy_to_user_proc(void *to, void *from, int size);
15313 +extern int copy_from_user_proc(void *to, void *from, int size);
15314 +extern int strlen_user_proc(char *str);
15315 +extern void bus_handler(int sig, union uml_pt_regs *regs);
15316 +extern void winch(int sig, union uml_pt_regs *regs);
15317 +extern long execute_syscall(void *r);
15318 +extern int smp_sigio_handler(void);
15319 +extern void *get_current(void);
15320 +extern struct task_struct *get_task(int pid, int require);
15321 +extern void machine_halt(void);
15322 +extern int is_syscall(unsigned long addr);
15323 +extern void arch_switch(void);
15324 +extern void free_irq(unsigned int, void *);
15325 +extern int um_in_interrupt(void);
15326 +extern int cpu(void);
15327 +extern unsigned long long time_stamp(void);
15328 +
15329 +#endif
15330 +
15331 +/*
15332 + * Overrides for Emacs so that we follow Linus's tabbing style.
15333 + * Emacs will notice this stuff at the end of the file and automatically
15334 + * adjust the settings for this buffer only.  This must remain at the end
15335 + * of the file.
15336 + * ---------------------------------------------------------------------------
15337 + * Local variables:
15338 + * c-file-style: "linux"
15339 + * End:
15340 + */
15341 diff -Naur -X ../exclude-files orig/arch/um/include/line.h um/arch/um/include/line.h
15342 --- orig/arch/um/include/line.h 1969-12-31 19:00:00.000000000 -0500
15343 +++ um/arch/um/include/line.h   2003-11-07 02:25:37.000000000 -0500
15344 @@ -0,0 +1,103 @@
15345 +/* 
15346 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15347 + * Licensed under the GPL
15348 + */
15349 +
15350 +#ifndef __LINE_H__
15351 +#define __LINE_H__
15352 +
15353 +#include "linux/list.h"
15354 +#include "linux/tqueue.h"
15355 +#include "linux/tty.h"
15356 +#include "asm/semaphore.h"
15357 +#include "chan_user.h"
15358 +#include "mconsole_kern.h"
15359 +
15360 +struct line_driver {
15361 +       char *name;
15362 +       char *devfs_name;
15363 +       short major;
15364 +       short minor_start;
15365 +       short type;
15366 +       short subtype;
15367 +       int read_irq;
15368 +       char *read_irq_name;
15369 +       int write_irq;
15370 +       char *write_irq_name;
15371 +       char *symlink_from;
15372 +       char *symlink_to;
15373 +       struct mc_device mc;
15374 +};
15375 +
15376 +struct line {
15377 +       char *init_str;
15378 +       int init_pri;
15379 +       struct list_head chan_list;
15380 +       int valid;
15381 +       int count;
15382 +       struct tty_struct *tty;
15383 +       struct semaphore sem;
15384 +       char *buffer;
15385 +       char *head;
15386 +       char *tail;
15387 +       int sigio;
15388 +       struct tq_struct task;
15389 +       struct line_driver *driver;
15390 +       int have_irq;
15391 +};
15392 +
15393 +#define LINE_INIT(str, d) \
15394 +       { init_str :    str, \
15395 +         init_pri :    INIT_STATIC, \
15396 +         chan_list :   { }, \
15397 +         valid :       1, \
15398 +         count :       0, \
15399 +         tty :         NULL, \
15400 +         sem :         { }, \
15401 +         buffer :      NULL, \
15402 +         head :        NULL, \
15403 +         tail :        NULL, \
15404 +         sigio :       0, \
15405 +         driver :      d, \
15406 +          have_irq :   0 }
15407 +
15408 +struct lines {
15409 +       int num;
15410 +};
15411 +
15412 +#define LINES_INIT(n) {  num :         n }
15413 +
15414 +extern void line_close(struct line *lines, struct tty_struct *tty);
15415 +extern int line_open(struct line *lines, struct tty_struct *tty, 
15416 +                    struct chan_opts *opts);
15417 +extern int line_setup(struct line *lines, int num, char *init, 
15418 +                     int all_allowed);
15419 +extern int line_write(struct line *line, struct tty_struct *tty, int from_user,
15420 +                     const char *buf, int len);
15421 +extern char *add_xterm_umid(char *base);
15422 +extern int line_setup_irq(int fd, int input, int output, void *data);
15423 +extern void line_close_chan(struct line *line);
15424 +extern void line_disable(struct line *line, int current_irq);
15425 +extern void line_register_devfs(struct lines *set, 
15426 +                               struct line_driver *line_driver, 
15427 +                               struct tty_driver *driver, struct line *lines,
15428 +                               int nlines);
15429 +extern void lines_init(struct line *lines, int nlines);
15430 +extern void close_lines(struct line *lines, int nlines);
15431 +extern int line_config(struct line *lines, int num, char *str);
15432 +extern int line_remove(struct line *lines, int num, char *str);
15433 +extern int line_get_config(char *dev, struct line *lines, int num, char *str, 
15434 +                          int size, char **error_out);
15435 +
15436 +#endif
15437 +
15438 +/*
15439 + * Overrides for Emacs so that we follow Linus's tabbing style.
15440 + * Emacs will notice this stuff at the end of the file and automatically
15441 + * adjust the settings for this buffer only.  This must remain at the end
15442 + * of the file.
15443 + * ---------------------------------------------------------------------------
15444 + * Local variables:
15445 + * c-file-style: "linux"
15446 + * End:
15447 + */
15448 diff -Naur -X ../exclude-files orig/arch/um/include/Makefile um/arch/um/include/Makefile
15449 --- orig/arch/um/include/Makefile       1969-12-31 19:00:00.000000000 -0500
15450 +++ um/arch/um/include/Makefile 2003-10-21 03:26:06.000000000 -0400
15451 @@ -0,0 +1,7 @@
15452 +all : sc.h
15453 +
15454 +sc.h : ../util/mk_sc
15455 +       ../util/mk_sc > $@
15456 +
15457 +../util/mk_sc :
15458 +       $(MAKE) -C ../util mk_sc
15459 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole.h um/arch/um/include/mconsole.h
15460 --- orig/arch/um/include/mconsole.h     1969-12-31 19:00:00.000000000 -0500
15461 +++ um/arch/um/include/mconsole.h       2003-10-21 03:26:06.000000000 -0400
15462 @@ -0,0 +1,103 @@
15463 +/*
15464 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
15465 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15466 + * Licensed under the GPL
15467 + */
15468 +
15469 +#ifndef __MCONSOLE_H__
15470 +#define __MCONSOLE_H__
15471 +
15472 +#ifndef __KERNEL__
15473 +#include <stdint.h>
15474 +#define u32 uint32_t
15475 +#endif
15476 +
15477 +#define MCONSOLE_MAGIC (0xcafebabe)
15478 +#define MCONSOLE_MAX_DATA (512)
15479 +#define MCONSOLE_VERSION 2
15480 +
15481 +struct mconsole_request {
15482 +       u32 magic;
15483 +       u32 version;
15484 +       u32 len;
15485 +       char data[MCONSOLE_MAX_DATA];
15486 +};
15487 +
15488 +struct mconsole_reply {
15489 +       u32 err;
15490 +       u32 more;
15491 +       u32 len;
15492 +       char data[MCONSOLE_MAX_DATA];
15493 +};
15494 +
15495 +struct mconsole_notify {
15496 +       u32 magic;
15497 +       u32 version;    
15498 +       enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
15499 +              MCONSOLE_USER_NOTIFY } type;
15500 +       u32 len;
15501 +       char data[MCONSOLE_MAX_DATA];
15502 +};
15503 +
15504 +struct mc_request;
15505 +
15506 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
15507 +
15508 +struct mconsole_command
15509 +{
15510 +       char *command;
15511 +       void (*handler)(struct mc_request *req);
15512 +       enum mc_context context;
15513 +};
15514 +
15515 +struct mc_request
15516 +{
15517 +       int len;
15518 +       int as_interrupt;
15519 +
15520 +       int originating_fd;
15521 +       int originlen;
15522 +       unsigned char origin[128];                      /* sockaddr_un */
15523 +
15524 +       struct mconsole_request request;
15525 +       struct mconsole_command *cmd;
15526 +};
15527 +
15528 +extern char mconsole_socket_name[];
15529 +
15530 +extern int mconsole_unlink_socket(void);
15531 +extern int mconsole_reply(struct mc_request *req, char *reply, int err,
15532 +                         int more);
15533 +
15534 +extern void mconsole_version(struct mc_request *req);
15535 +extern void mconsole_help(struct mc_request *req);
15536 +extern void mconsole_halt(struct mc_request *req);
15537 +extern void mconsole_reboot(struct mc_request *req);
15538 +extern void mconsole_config(struct mc_request *req);
15539 +extern void mconsole_remove(struct mc_request *req);
15540 +extern void mconsole_sysrq(struct mc_request *req);
15541 +extern void mconsole_cad(struct mc_request *req);
15542 +extern void mconsole_stop(struct mc_request *req);
15543 +extern void mconsole_go(struct mc_request *req);
15544 +extern void mconsole_log(struct mc_request *req);
15545 +extern void mconsole_proc(struct mc_request *req);
15546 +
15547 +extern int mconsole_get_request(int fd, struct mc_request *req);
15548 +extern int mconsole_notify(char *sock_name, int type, const void *data, 
15549 +                          int len);
15550 +extern char *mconsole_notify_socket(void);
15551 +extern void lock_notify(void);
15552 +extern void unlock_notify(void);
15553 +
15554 +#endif
15555 +
15556 +/*
15557 + * Overrides for Emacs so that we follow Linus's tabbing style.
15558 + * Emacs will notice this stuff at the end of the file and automatically
15559 + * adjust the settings for this buffer only.  This must remain at the end
15560 + * of the file.
15561 + * ---------------------------------------------------------------------------
15562 + * Local variables:
15563 + * c-file-style: "linux"
15564 + * End:
15565 + */
15566 diff -Naur -X ../exclude-files orig/arch/um/include/mconsole_kern.h um/arch/um/include/mconsole_kern.h
15567 --- orig/arch/um/include/mconsole_kern.h        1969-12-31 19:00:00.000000000 -0500
15568 +++ um/arch/um/include/mconsole_kern.h  2003-10-21 03:26:06.000000000 -0400
15569 @@ -0,0 +1,62 @@
15570 +/*
15571 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
15572 + * Licensed under the GPL
15573 + */
15574 +
15575 +#ifndef __MCONSOLE_KERN_H__
15576 +#define __MCONSOLE_KERN_H__
15577 +
15578 +#include "linux/config.h"
15579 +#include "linux/list.h"
15580 +#include "mconsole.h"
15581 +
15582 +struct mconsole_entry {
15583 +       struct list_head list;
15584 +       struct mc_request request;
15585 +};
15586 +
15587 +struct mc_device {
15588 +       struct list_head list;
15589 +       char *name;
15590 +       int (*config)(char *);
15591 +       int (*get_config)(char *, char *, int, char **);
15592 +       int (*remove)(char *);
15593 +};
15594 +
15595 +#define CONFIG_CHUNK(str, size, current, chunk, end) \
15596 +do { \
15597 +       current += strlen(chunk); \
15598 +       if(current >= size) \
15599 +               str = NULL; \
15600 +       if(str != NULL){ \
15601 +               strcpy(str, chunk); \
15602 +               str += strlen(chunk); \
15603 +       } \
15604 +       if(end) \
15605 +               current++; \
15606 +} while(0)
15607 +
15608 +#ifdef CONFIG_MCONSOLE
15609 +
15610 +extern void mconsole_register_dev(struct mc_device *new);
15611 +
15612 +#else
15613 +
15614 +static inline void mconsole_register_dev(struct mc_device *new)
15615 +{
15616 +}
15617 +
15618 +#endif
15619 +
15620 +#endif
15621 +
15622 +/*
15623 + * Overrides for Emacs so that we follow Linus's tabbing style.
15624 + * Emacs will notice this stuff at the end of the file and automatically
15625 + * adjust the settings for this buffer only.  This must remain at the end
15626 + * of the file.
15627 + * ---------------------------------------------------------------------------
15628 + * Local variables:
15629 + * c-file-style: "linux"
15630 + * End:
15631 + */
15632 diff -Naur -X ../exclude-files orig/arch/um/include/mem.h um/arch/um/include/mem.h
15633 --- orig/arch/um/include/mem.h  1969-12-31 19:00:00.000000000 -0500
15634 +++ um/arch/um/include/mem.h    2003-10-21 03:26:06.000000000 -0400
15635 @@ -0,0 +1,28 @@
15636 +/* 
15637 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
15638 + * Licensed under the GPL
15639 + */
15640 +
15641 +#ifndef __MEM_H__
15642 +#define __MEM_H__
15643 +
15644 +#include "linux/types.h"
15645 +
15646 +extern void set_kmem_end(unsigned long new);
15647 +extern int phys_mapping(unsigned long phys, __u64 *offset_out);
15648 +extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
15649 +extern int is_remapped(void *virt);
15650 +extern int physmem_remove_mapping(void *virt);
15651 +
15652 +#endif
15653 +
15654 +/*
15655 + * Overrides for Emacs so that we follow Linus's tabbing style.
15656 + * Emacs will notice this stuff at the end of the file and automatically
15657 + * adjust the settings for this buffer only.  This must remain at the end
15658 + * of the file.
15659 + * ---------------------------------------------------------------------------
15660 + * Local variables:
15661 + * c-file-style: "linux"
15662 + * End:
15663 + */
15664 diff -Naur -X ../exclude-files orig/arch/um/include/mem_kern.h um/arch/um/include/mem_kern.h
15665 --- orig/arch/um/include/mem_kern.h     1969-12-31 19:00:00.000000000 -0500
15666 +++ um/arch/um/include/mem_kern.h       2003-10-21 03:26:06.000000000 -0400
15667 @@ -0,0 +1,30 @@
15668 +/* 
15669 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
15670 + * Licensed under the GPL
15671 + */
15672 +
15673 +#ifndef __MEM_KERN_H__
15674 +#define __MEM_KERN_H__
15675 +
15676 +#include "linux/list.h"
15677 +#include "linux/types.h"
15678 +
15679 +struct remapper {
15680 +       struct list_head list;
15681 +       int (*proc)(int, unsigned long, int, __u64);
15682 +};
15683 +
15684 +extern void register_remapper(struct remapper *info);
15685 +
15686 +#endif
15687 +
15688 +/*
15689 + * Overrides for Emacs so that we follow Linus's tabbing style.
15690 + * Emacs will notice this stuff at the end of the file and automatically
15691 + * adjust the settings for this buffer only.  This must remain at the end
15692 + * of the file.
15693 + * ---------------------------------------------------------------------------
15694 + * Local variables:
15695 + * c-file-style: "linux"
15696 + * End:
15697 + */
15698 diff -Naur -X ../exclude-files orig/arch/um/include/mem_user.h um/arch/um/include/mem_user.h
15699 --- orig/arch/um/include/mem_user.h     1969-12-31 19:00:00.000000000 -0500
15700 +++ um/arch/um/include/mem_user.h       2003-12-14 11:16:03.000000000 -0500
15701 @@ -0,0 +1,82 @@
15702 +/*
15703 + * arch/um/include/mem_user.h
15704 + *
15705 + * BRIEF MODULE DESCRIPTION
15706 + * user side memory interface for support IO memory inside user mode linux
15707 + *
15708 + * Copyright (C) 2001 RidgeRun, Inc.
15709 + * Author: RidgeRun, Inc.
15710 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
15711 + *
15712 + *  This program is free software; you can redistribute  it and/or modify it
15713 + *  under  the terms of  the GNU General  Public License as published by the
15714 + *  Free Software Foundation;  either version 2 of the  License, or (at your
15715 + *  option) any later version.
15716 + *
15717 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
15718 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
15719 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
15720 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
15721 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15722 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
15723 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
15724 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
15725 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
15726 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15727 + *
15728 + *  You should have received a copy of the  GNU General Public License along
15729 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
15730 + *  675 Mass Ave, Cambridge, MA 02139, USA.
15731 + */
15732 +
15733 +#ifndef _MEM_USER_H
15734 +#define _MEM_USER_H
15735 +
15736 +struct iomem_region {
15737 +       struct iomem_region *next;
15738 +       char *driver;
15739 +       int fd;
15740 +       int size;
15741 +       unsigned long phys;
15742 +       unsigned long virt;
15743 +};
15744 +
15745 +extern struct iomem_region *iomem_regions;
15746 +extern int iomem_size;
15747 +
15748 +#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
15749 +
15750 +extern unsigned long host_task_size;
15751 +extern unsigned long task_size;
15752 +
15753 +extern void check_devanon(void);
15754 +extern int init_mem_user(void);
15755 +extern int create_mem_file(unsigned long len);
15756 +extern void setup_memory(void *entry);
15757 +extern unsigned long find_iomem(char *driver, unsigned long *len_out);
15758 +extern int init_maps(unsigned long physmem, unsigned long iomem, 
15759 +                    unsigned long highmem);
15760 +extern unsigned long get_vm(unsigned long len);
15761 +extern void setup_physmem(unsigned long start, unsigned long usable,
15762 +                         unsigned long len, unsigned long highmem);
15763 +extern void add_iomem(char *name, int fd, unsigned long size);
15764 +extern unsigned long phys_offset(unsigned long phys);
15765 +extern void unmap_physmem(void);
15766 +extern void map_memory(unsigned long virt, unsigned long phys, 
15767 +                      unsigned long len, int r, int w, int x);
15768 +extern int protect_memory(unsigned long addr, unsigned long len, 
15769 +                         int r, int w, int x, int must_succeed);
15770 +extern unsigned long get_kmem_end(void);
15771 +
15772 +#endif
15773 +
15774 +/*
15775 + * Overrides for Emacs so that we follow Linus's tabbing style.
15776 + * Emacs will notice this stuff at the end of the file and automatically
15777 + * adjust the settings for this buffer only.  This must remain at the end
15778 + * of the file.
15779 + * ---------------------------------------------------------------------------
15780 + * Local variables:
15781 + * c-file-style: "linux"
15782 + * End:
15783 + */
15784 diff -Naur -X ../exclude-files orig/arch/um/include/mode.h um/arch/um/include/mode.h
15785 --- orig/arch/um/include/mode.h 1969-12-31 19:00:00.000000000 -0500
15786 +++ um/arch/um/include/mode.h   2003-10-21 03:26:06.000000000 -0400
15787 @@ -0,0 +1,30 @@
15788 +/* 
15789 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15790 + * Licensed under the GPL
15791 + */
15792 +
15793 +#ifndef __MODE_H__
15794 +#define __MODE_H__
15795 +
15796 +#include "uml-config.h"
15797 +
15798 +#ifdef UML_CONFIG_MODE_TT
15799 +#include "../kernel/tt/include/mode.h"
15800 +#endif
15801 +
15802 +#ifdef UML_CONFIG_MODE_SKAS
15803 +#include "../kernel/skas/include/mode.h"
15804 +#endif
15805 +
15806 +#endif
15807 +
15808 +/*
15809 + * Overrides for Emacs so that we follow Linus's tabbing style.
15810 + * Emacs will notice this stuff at the end of the file and automatically
15811 + * adjust the settings for this buffer only.  This must remain at the end
15812 + * of the file.
15813 + * ---------------------------------------------------------------------------
15814 + * Local variables:
15815 + * c-file-style: "linux"
15816 + * End:
15817 + */
15818 diff -Naur -X ../exclude-files orig/arch/um/include/mode_kern.h um/arch/um/include/mode_kern.h
15819 --- orig/arch/um/include/mode_kern.h    1969-12-31 19:00:00.000000000 -0500
15820 +++ um/arch/um/include/mode_kern.h      2003-10-21 03:26:06.000000000 -0400
15821 @@ -0,0 +1,30 @@
15822 +/* 
15823 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15824 + * Licensed under the GPL
15825 + */
15826 +
15827 +#ifndef __MODE_KERN_H__
15828 +#define __MODE_KERN_H__
15829 +
15830 +#include "linux/config.h"
15831 +
15832 +#ifdef CONFIG_MODE_TT
15833 +#include "../kernel/tt/include/mode_kern.h"
15834 +#endif
15835 +
15836 +#ifdef CONFIG_MODE_SKAS
15837 +#include "../kernel/skas/include/mode_kern.h"
15838 +#endif
15839 +
15840 +#endif
15841 +
15842 +/*
15843 + * Overrides for Emacs so that we follow Linus's tabbing style.
15844 + * Emacs will notice this stuff at the end of the file and automatically
15845 + * adjust the settings for this buffer only.  This must remain at the end
15846 + * of the file.
15847 + * ---------------------------------------------------------------------------
15848 + * Local variables:
15849 + * c-file-style: "linux"
15850 + * End:
15851 + */
15852 diff -Naur -X ../exclude-files orig/arch/um/include/net_kern.h um/arch/um/include/net_kern.h
15853 --- orig/arch/um/include/net_kern.h     1969-12-31 19:00:00.000000000 -0500
15854 +++ um/arch/um/include/net_kern.h       2003-10-21 03:26:06.000000000 -0400
15855 @@ -0,0 +1,81 @@
15856 +/* 
15857 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15858 + * Licensed under the GPL
15859 + */
15860 +
15861 +#ifndef __UM_NET_KERN_H
15862 +#define __UM_NET_KERN_H
15863 +
15864 +#include "linux/netdevice.h"
15865 +#include "linux/skbuff.h"
15866 +#include "linux/socket.h"
15867 +#include "linux/list.h"
15868 +
15869 +struct uml_net {
15870 +       struct list_head list;
15871 +       struct net_device *dev;
15872 +       int index;
15873 +       unsigned char mac[ETH_ALEN];
15874 +       int have_mac;
15875 +};
15876 +
15877 +struct uml_net_private {
15878 +       struct list_head list;
15879 +       spinlock_t lock;
15880 +       struct net_device *dev;
15881 +       struct timer_list tl;
15882 +       struct net_device_stats stats;
15883 +       int fd;
15884 +       unsigned char mac[ETH_ALEN];
15885 +       int have_mac;
15886 +       unsigned short (*protocol)(struct sk_buff *);
15887 +       int (*open)(void *);
15888 +       void (*close)(int, void *);
15889 +       void (*remove)(void *);
15890 +       int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
15891 +       int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
15892 +       
15893 +       void (*add_address)(unsigned char *, unsigned char *, void *);
15894 +       void (*delete_address)(unsigned char *, unsigned char *, void *);
15895 +       int (*set_mtu)(int mtu, void *);
15896 +       int user[1];
15897 +};
15898 +
15899 +struct net_kern_info {
15900 +       void (*init)(struct net_device *, void *);
15901 +       unsigned short (*protocol)(struct sk_buff *);
15902 +       int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
15903 +       int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
15904 +};
15905 +
15906 +struct transport {
15907 +       struct list_head list;
15908 +       char *name;
15909 +       int (*setup)(char *, char **, void *);
15910 +       struct net_user_info *user;
15911 +       struct net_kern_info *kern;
15912 +       int private_size;
15913 +       int setup_size;
15914 +};
15915 +
15916 +extern struct net_device *ether_init(int);
15917 +extern unsigned short ether_protocol(struct sk_buff *);
15918 +extern int setup_etheraddr(char *str, unsigned char *addr);
15919 +extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
15920 +extern int tap_setup_common(char *str, char *type, char **dev_name, 
15921 +                           char **mac_out, char **gate_addr);
15922 +extern void register_transport(struct transport *new);
15923 +extern unsigned short eth_protocol(struct sk_buff *skb);
15924 +
15925 +#endif
15926 +
15927 +/*
15928 + * Overrides for Emacs so that we follow Linus's tabbing style.
15929 + * Emacs will notice this stuff at the end of the file and automatically
15930 + * adjust the settings for this buffer only.  This must remain at the end
15931 + * of the file.
15932 + * ---------------------------------------------------------------------------
15933 + * Local variables:
15934 + * c-file-style: "linux"
15935 + * End:
15936 + */
15937 diff -Naur -X ../exclude-files orig/arch/um/include/net_user.h um/arch/um/include/net_user.h
15938 --- orig/arch/um/include/net_user.h     1969-12-31 19:00:00.000000000 -0500
15939 +++ um/arch/um/include/net_user.h       2003-10-21 03:26:06.000000000 -0400
15940 @@ -0,0 +1,66 @@
15941 +/* 
15942 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
15943 + * Licensed under the GPL
15944 + */
15945 +
15946 +#ifndef __UM_NET_USER_H__
15947 +#define __UM_NET_USER_H__
15948 +
15949 +#define ETH_ADDR_LEN (6)
15950 +#define ETH_HEADER_ETHERTAP (16)
15951 +#define ETH_HEADER_OTHER (14)
15952 +#define ETH_MAX_PACKET (1500)
15953 +
15954 +#define UML_NET_VERSION (4)
15955 +
15956 +struct net_user_info {
15957 +       void (*init)(void *, void *);
15958 +       int (*open)(void *);
15959 +       void (*close)(int, void *);
15960 +       void (*remove)(void *);
15961 +       int (*set_mtu)(int mtu, void *);
15962 +       void (*add_address)(unsigned char *, unsigned char *, void *);
15963 +       void (*delete_address)(unsigned char *, unsigned char *, void *);
15964 +       int max_packet;
15965 +};
15966 +
15967 +extern void ether_user_init(void *data, void *dev);
15968 +extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
15969 +extern void set_ether_mac(void *d, unsigned char *addr);
15970 +extern void iter_addresses(void *d, void (*cb)(unsigned char *, 
15971 +                                              unsigned char *, void *), 
15972 +                          void *arg);
15973 +
15974 +extern void *get_output_buffer(int *len_out);
15975 +extern void free_output_buffer(void *buffer);
15976 +
15977 +extern int tap_open_common(void *dev, char *gate_addr);
15978 +extern void tap_check_ips(char *gate_addr, char *eth_addr);
15979 +
15980 +extern void read_output(int fd, char *output_out, int len);
15981 +
15982 +extern int net_read(int fd, void *buf, int len);
15983 +extern int net_recvfrom(int fd, void *buf, int len);
15984 +extern int net_write(int fd, void *buf, int len);
15985 +extern int net_send(int fd, void *buf, int len);
15986 +extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len);
15987 +
15988 +extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg);
15989 +extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg);
15990 +
15991 +extern char *split_if_spec(char *str, ...);
15992 +
15993 +extern int dev_netmask(void *d, void *m);
15994 +
15995 +#endif
15996 +
15997 +/*
15998 + * Overrides for Emacs so that we follow Linus's tabbing style.
15999 + * Emacs will notice this stuff at the end of the file and automatically
16000 + * adjust the settings for this buffer only.  This must remain at the end
16001 + * of the file.
16002 + * ---------------------------------------------------------------------------
16003 + * Local variables:
16004 + * c-file-style: "linux"
16005 + * End:
16006 + */
16007 diff -Naur -X ../exclude-files orig/arch/um/include/os.h um/arch/um/include/os.h
16008 --- orig/arch/um/include/os.h   1969-12-31 19:00:00.000000000 -0500
16009 +++ um/arch/um/include/os.h     2003-12-17 10:48:12.000000000 -0500
16010 @@ -0,0 +1,180 @@
16011 +/* 
16012 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16013 + * Licensed under the GPL
16014 + */
16015 +
16016 +#ifndef __OS_H__
16017 +#define __OS_H__
16018 +
16019 +#include "asm/types.h"
16020 +#include "../os/include/file.h"
16021 +
16022 +#define OS_TYPE_FILE 1 
16023 +#define OS_TYPE_DIR 2 
16024 +#define OS_TYPE_SYMLINK 3 
16025 +#define OS_TYPE_CHARDEV 4
16026 +#define OS_TYPE_BLOCKDEV 5
16027 +#define OS_TYPE_FIFO 6
16028 +#define OS_TYPE_SOCK 7
16029 +
16030 +/* os_access() flags */
16031 +#define OS_ACC_F_OK    0       /* Test for existence.  */
16032 +#define OS_ACC_X_OK    1       /* Test for execute permission.  */
16033 +#define OS_ACC_W_OK    2       /* Test for write permission.  */
16034 +#define OS_ACC_R_OK    4       /* Test for read permission.  */
16035 +#define OS_ACC_RW_OK   (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
16036 +
16037 +/*
16038 + * types taken from stat_file() in hostfs_user.c
16039 + * (if they are wrong here, they are wrong there...).
16040 + */
16041 +struct uml_stat {
16042 +       int                ust_dev;        /* device */
16043 +       unsigned long long ust_ino;        /* inode */
16044 +       int                ust_mode;       /* protection */
16045 +       int                ust_nlink;      /* number of hard links */
16046 +       int                ust_uid;        /* user ID of owner */
16047 +       int                ust_gid;        /* group ID of owner */
16048 +       unsigned long long ust_size;       /* total size, in bytes */
16049 +       int                ust_blksize;    /* blocksize for filesystem I/O */
16050 +       unsigned long long ust_blocks;     /* number of blocks allocated */
16051 +       unsigned long      ust_atime;      /* time of last access */
16052 +       unsigned long      ust_mtime;      /* time of last modification */
16053 +       unsigned long      ust_ctime;      /* time of last change */
16054 +};
16055 +
16056 +struct openflags {
16057 +       unsigned int r : 1;
16058 +       unsigned int w : 1;
16059 +       unsigned int s : 1;     /* O_SYNC */
16060 +       unsigned int c : 1;     /* O_CREAT */
16061 +       unsigned int t : 1;     /* O_TRUNC */
16062 +       unsigned int a : 1;     /* O_APPEND */
16063 +       unsigned int e : 1;     /* O_EXCL */
16064 +       unsigned int cl : 1;    /* FD_CLOEXEC */
16065 +};
16066 +
16067 +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
16068 +                                         .t = 0, .a = 0, .e = 0, .cl = 0 })
16069 +
16070 +static inline struct openflags of_read(struct openflags flags)
16071 +{
16072 +       flags.r = 1; 
16073 +       return(flags);
16074 +}
16075 +
16076 +static inline struct openflags of_write(struct openflags flags)
16077 +{
16078 +       flags.w = 1; 
16079 +       return(flags); 
16080 +}
16081 +
16082 +static inline struct openflags of_rdwr(struct openflags flags)
16083 +{
16084 +       return(of_read(of_write(flags)));
16085 +}
16086 +
16087 +static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
16088 +{
16089 +       flags.r = r;
16090 +       flags.w = w;
16091 +       return(flags);
16092 +}
16093 +
16094 +static inline struct openflags of_sync(struct openflags flags)
16095 +{ 
16096 +       flags.s = 1; 
16097 +       return(flags); 
16098 +}
16099 +
16100 +static inline struct openflags of_create(struct openflags flags)
16101 +{ 
16102 +       flags.c = 1; 
16103 +       return(flags); 
16104 +}
16105
16106 +static inline struct openflags of_trunc(struct openflags flags)
16107 +{ 
16108 +       flags.t = 1; 
16109 +       return(flags); 
16110 +}
16111
16112 +static inline struct openflags of_append(struct openflags flags)
16113 +{ 
16114 +       flags.a = 1; 
16115 +       return(flags); 
16116 +}
16117
16118 +static inline struct openflags of_excl(struct openflags flags)
16119 +{ 
16120 +       flags.e = 1; 
16121 +       return(flags); 
16122 +}
16123 +
16124 +static inline struct openflags of_cloexec(struct openflags flags)
16125 +{ 
16126 +       flags.cl = 1; 
16127 +       return(flags); 
16128 +}
16129
16130 +extern int os_stat_file(const char *file_name, struct uml_stat *buf);
16131 +extern int os_stat_fd(const int fd, struct uml_stat *buf);
16132 +extern int os_access(const char *file, int mode);
16133 +extern void os_print_error(int error, const char* str);
16134 +extern int os_get_exec_close(int fd, int *close_on_exec);
16135 +extern int os_set_exec_close(int fd, int close_on_exec);
16136 +extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
16137 +extern int os_window_size(int fd, int *rows, int *cols);
16138 +extern int os_new_tty_pgrp(int fd, int pid);
16139 +extern int os_get_ifname(int fd, char *namebuf);
16140 +extern int os_set_slip(int fd);
16141 +extern int os_set_owner(int fd, int pid);
16142 +extern int os_sigio_async(int master, int slave);
16143 +extern int os_mode_fd(int fd, int mode);
16144 +
16145 +extern int os_seek_file(int fd, __u64 offset);
16146 +extern int os_open_file(char *file, struct openflags flags, int mode);
16147 +extern int os_read_file(int fd, void *buf, int len);
16148 +extern int os_write_file(int fd, const void *buf, int count);
16149 +extern int os_file_size(char *file, long long *size_out);
16150 +extern int os_file_modtime(char *file, unsigned long *modtime);
16151 +extern int os_pipe(int *fd, int stream, int close_on_exec);
16152 +extern int os_set_fd_async(int fd, int owner);
16153 +extern int os_set_fd_block(int fd, int blocking);
16154 +extern int os_accept_connection(int fd);
16155 +extern int os_create_unix_socket(char *file, int len, int close_on_exec);
16156 +extern int os_shutdown_socket(int fd, int r, int w);
16157 +extern void os_close_file(int fd);
16158 +extern int os_rcv_fd(int fd, int *helper_pid_out);
16159 +extern int create_unix_socket(char *file, int len, int close_on_exec);
16160 +extern int os_connect_socket(char *name);
16161 +extern int os_file_type(char *file);
16162 +extern int os_file_mode(char *file, struct openflags *mode_out);
16163 +extern int os_lock_file(int fd, int excl);
16164 +
16165 +extern unsigned long os_process_pc(int pid);
16166 +extern int os_process_parent(int pid);
16167 +extern void os_stop_process(int pid);
16168 +extern void os_kill_process(int pid, int reap_child);
16169 +extern void os_usr1_process(int pid);
16170 +extern int os_getpid(void);
16171 +
16172 +extern int os_map_memory(void *virt, int fd, unsigned long long off, 
16173 +                        unsigned long len, int r, int w, int x);
16174 +extern int os_protect_memory(void *addr, unsigned long len, 
16175 +                            int r, int w, int x);
16176 +extern int os_unmap_memory(void *addr, int len);
16177 +extern void os_flush_stdout(void);
16178 +
16179 +#endif
16180 +
16181 +/*
16182 + * Overrides for Emacs so that we follow Linus's tabbing style.
16183 + * Emacs will notice this stuff at the end of the file and automatically
16184 + * adjust the settings for this buffer only.  This must remain at the end
16185 + * of the file.
16186 + * ---------------------------------------------------------------------------
16187 + * Local variables:
16188 + * c-file-style: "linux"
16189 + * End:
16190 + */
16191 diff -Naur -X ../exclude-files orig/arch/um/include/process.h um/arch/um/include/process.h
16192 --- orig/arch/um/include/process.h      1969-12-31 19:00:00.000000000 -0500
16193 +++ um/arch/um/include/process.h        2003-10-21 03:26:06.000000000 -0400
16194 @@ -0,0 +1,25 @@
16195 +/* 
16196 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16197 + * Licensed under the GPL
16198 + */
16199 +
16200 +#ifndef __PROCESS_H__
16201 +#define __PROCESS_H__
16202 +
16203 +#include <asm/sigcontext.h>
16204 +
16205 +extern void sig_handler(int sig, struct sigcontext sc);
16206 +extern void alarm_handler(int sig, struct sigcontext sc);
16207 +
16208 +#endif
16209 +
16210 +/*
16211 + * Overrides for Emacs so that we follow Linus's tabbing style.
16212 + * Emacs will notice this stuff at the end of the file and automatically
16213 + * adjust the settings for this buffer only.  This must remain at the end
16214 + * of the file.
16215 + * ---------------------------------------------------------------------------
16216 + * Local variables:
16217 + * c-file-style: "linux"
16218 + * End:
16219 + */
16220 diff -Naur -X ../exclude-files orig/arch/um/include/ptrace_user.h um/arch/um/include/ptrace_user.h
16221 --- orig/arch/um/include/ptrace_user.h  1969-12-31 19:00:00.000000000 -0500
16222 +++ um/arch/um/include/ptrace_user.h    2003-10-21 03:26:06.000000000 -0400
16223 @@ -0,0 +1,18 @@
16224 +/* 
16225 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16226 + * Licensed under the GPL
16227 + */
16228 +
16229 +#ifndef __PTRACE_USER_H__
16230 +#define __PTRACE_USER_H__
16231 +
16232 +#include "sysdep/ptrace_user.h"
16233 +
16234 +extern int ptrace_getregs(long pid, unsigned long *regs_out);
16235 +extern int ptrace_setregs(long pid, unsigned long *regs_in);
16236 +extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
16237 +extern void arch_enter_kernel(void *task, int pid);
16238 +extern void arch_leave_kernel(void *task, int pid);
16239 +extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
16240 +
16241 +#endif
16242 diff -Naur -X ../exclude-files orig/arch/um/include/sigcontext.h um/arch/um/include/sigcontext.h
16243 --- orig/arch/um/include/sigcontext.h   1969-12-31 19:00:00.000000000 -0500
16244 +++ um/arch/um/include/sigcontext.h     2003-10-21 03:26:06.000000000 -0400
16245 @@ -0,0 +1,25 @@
16246 +/* 
16247 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
16248 + * Licensed under the GPL
16249 + */
16250 +
16251 +#ifndef __UML_SIGCONTEXT_H__
16252 +#define __UML_SIGCONTEXT_H__
16253 +
16254 +#include "sysdep/sigcontext.h"
16255 +
16256 +extern int sc_size(void *data);
16257 +extern void sc_to_sc(void *to_ptr, void *from_ptr);
16258 +
16259 +#endif
16260 +
16261 +/*
16262 + * Overrides for Emacs so that we follow Linus's tabbing style.
16263 + * Emacs will notice this stuff at the end of the file and automatically
16264 + * adjust the settings for this buffer only.  This must remain at the end
16265 + * of the file.
16266 + * ---------------------------------------------------------------------------
16267 + * Local variables:
16268 + * c-file-style: "linux"
16269 + * End:
16270 + */
16271 diff -Naur -X ../exclude-files orig/arch/um/include/sigio.h um/arch/um/include/sigio.h
16272 --- orig/arch/um/include/sigio.h        1969-12-31 19:00:00.000000000 -0500
16273 +++ um/arch/um/include/sigio.h  2003-10-21 03:26:06.000000000 -0400
16274 @@ -0,0 +1,28 @@
16275 +/* 
16276 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16277 + * Licensed under the GPL
16278 + */
16279 +
16280 +#ifndef __SIGIO_H__
16281 +#define __SIGIO_H__
16282 +
16283 +extern int write_sigio_irq(int fd);
16284 +extern int register_sigio_fd(int fd);
16285 +extern int read_sigio_fd(int fd);
16286 +extern int add_sigio_fd(int fd, int read);
16287 +extern int ignore_sigio_fd(int fd);
16288 +extern void sigio_lock(void);
16289 +extern void sigio_unlock(void);
16290 +
16291 +#endif
16292 +
16293 +/*
16294 + * Overrides for Emacs so that we follow Linus's tabbing style.
16295 + * Emacs will notice this stuff at the end of the file and automatically
16296 + * adjust the settings for this buffer only.  This must remain at the end
16297 + * of the file.
16298 + * ---------------------------------------------------------------------------
16299 + * Local variables:
16300 + * c-file-style: "linux"
16301 + * End:
16302 + */
16303 diff -Naur -X ../exclude-files orig/arch/um/include/signal_kern.h um/arch/um/include/signal_kern.h
16304 --- orig/arch/um/include/signal_kern.h  1969-12-31 19:00:00.000000000 -0500
16305 +++ um/arch/um/include/signal_kern.h    2003-10-21 03:26:06.000000000 -0400
16306 @@ -0,0 +1,22 @@
16307 +/* 
16308 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
16309 + * Licensed under the GPL
16310 + */
16311 +
16312 +#ifndef __SIGNAL_KERN_H__
16313 +#define __SIGNAL_KERN_H__
16314 +
16315 +extern int have_signals(void *t);
16316 +
16317 +#endif
16318 +
16319 +/*
16320 + * Overrides for Emacs so that we follow Linus's tabbing style.
16321 + * Emacs will notice this stuff at the end of the file and automatically
16322 + * adjust the settings for this buffer only.  This must remain at the end
16323 + * of the file.
16324 + * ---------------------------------------------------------------------------
16325 + * Local variables:
16326 + * c-file-style: "linux"
16327 + * End:
16328 + */
16329 diff -Naur -X ../exclude-files orig/arch/um/include/signal_user.h um/arch/um/include/signal_user.h
16330 --- orig/arch/um/include/signal_user.h  1969-12-31 19:00:00.000000000 -0500
16331 +++ um/arch/um/include/signal_user.h    2003-10-21 03:26:06.000000000 -0400
16332 @@ -0,0 +1,26 @@
16333 +/* 
16334 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
16335 + * Licensed under the GPL
16336 + */
16337 +
16338 +#ifndef __SIGNAL_USER_H__
16339 +#define __SIGNAL_USER_H__
16340 +
16341 +extern int signal_stack_size;
16342 +
16343 +extern int change_sig(int signal, int on);
16344 +extern void set_sigstack(void *stack, int size);
16345 +extern void set_handler(int sig, void (*handler)(int), int flags, ...);
16346 +
16347 +#endif
16348 +
16349 +/*
16350 + * Overrides for Emacs so that we follow Linus's tabbing style.
16351 + * Emacs will notice this stuff at the end of the file and automatically
16352 + * adjust the settings for this buffer only.  This must remain at the end
16353 + * of the file.
16354 + * ---------------------------------------------------------------------------
16355 + * Local variables:
16356 + * c-file-style: "linux"
16357 + * End:
16358 + */
16359 diff -Naur -X ../exclude-files orig/arch/um/include/skas_ptrace.h um/arch/um/include/skas_ptrace.h
16360 --- orig/arch/um/include/skas_ptrace.h  1969-12-31 19:00:00.000000000 -0500
16361 +++ um/arch/um/include/skas_ptrace.h    2003-10-21 03:26:06.000000000 -0400
16362 @@ -0,0 +1,36 @@
16363 +/* 
16364 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16365 + * Licensed under the GPL
16366 + */
16367 +
16368 +#ifndef __SKAS_PTRACE_H
16369 +#define __SKAS_PTRACE_H
16370 +
16371 +struct ptrace_faultinfo {
16372 +       int is_write;
16373 +       unsigned long addr;
16374 +};
16375 +
16376 +struct ptrace_ldt {
16377 +       int func;
16378 +       void *ptr;
16379 +       unsigned long bytecount;
16380 +};
16381 +
16382 +#define PTRACE_FAULTINFO 52
16383 +#define PTRACE_SIGPENDING 53
16384 +#define PTRACE_LDT 54
16385 +#define PTRACE_SWITCH_MM 55
16386 +
16387 +#endif
16388 +
16389 +/*
16390 + * Overrides for Emacs so that we follow Linus's tabbing style.
16391 + * Emacs will notice this stuff at the end of the file and automatically
16392 + * adjust the settings for this buffer only.  This must remain at the end
16393 + * of the file.
16394 + * ---------------------------------------------------------------------------
16395 + * Local variables:
16396 + * c-file-style: "linux"
16397 + * End:
16398 + */
16399 diff -Naur -X ../exclude-files orig/arch/um/include/syscall_user.h um/arch/um/include/syscall_user.h
16400 --- orig/arch/um/include/syscall_user.h 1969-12-31 19:00:00.000000000 -0500
16401 +++ um/arch/um/include/syscall_user.h   2003-10-21 03:26:06.000000000 -0400
16402 @@ -0,0 +1,23 @@
16403 +/* 
16404 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16405 + * Licensed under the GPL
16406 + */
16407 +
16408 +#ifndef __SYSCALL_USER_H
16409 +#define __SYSCALL_USER_H
16410 +
16411 +extern int record_syscall_start(int syscall);
16412 +extern void record_syscall_end(int index, int result);
16413 +
16414 +#endif
16415 +
16416 +/*
16417 + * Overrides for Emacs so that we follow Linus's tabbing style.
16418 + * Emacs will notice this stuff at the end of the file and automatically
16419 + * adjust the settings for this buffer only.  This must remain at the end
16420 + * of the file.
16421 + * ---------------------------------------------------------------------------
16422 + * Local variables:
16423 + * c-file-style: "linux"
16424 + * End:
16425 + */
16426 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/checksum.h um/arch/um/include/sysdep-i386/checksum.h
16427 --- orig/arch/um/include/sysdep-i386/checksum.h 1969-12-31 19:00:00.000000000 -0500
16428 +++ um/arch/um/include/sysdep-i386/checksum.h   2003-10-21 03:26:06.000000000 -0400
16429 @@ -0,0 +1,217 @@
16430 +/* 
16431 + * Licensed under the GPL
16432 + */
16433 +
16434 +#ifndef __UM_SYSDEP_CHECKSUM_H
16435 +#define __UM_SYSDEP_CHECKSUM_H
16436 +
16437 +#include "linux/string.h"
16438 +
16439 +/*
16440 + * computes the checksum of a memory block at buff, length len,
16441 + * and adds in "sum" (32-bit)
16442 + *
16443 + * returns a 32-bit number suitable for feeding into itself
16444 + * or csum_tcpudp_magic
16445 + *
16446 + * this function must be called with even lengths, except
16447 + * for the last fragment, which may be odd
16448 + *
16449 + * it's best to have buff aligned on a 32-bit boundary
16450 + */
16451 +unsigned int csum_partial(const unsigned char * buff, int len, 
16452 +                         unsigned int sum);
16453 +
16454 +/*
16455 + * the same as csum_partial, but copies from src while it
16456 + * checksums, and handles user-space pointer exceptions correctly, when needed.
16457 + *
16458 + * here even more important to align src and dst on a 32-bit (or even
16459 + * better 64-bit) boundary
16460 + */
16461 +
16462 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
16463 +                                 int sum, int *err_ptr);
16464 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
16465 +                                   int sum, int *err_ptr);
16466 +
16467 +/*
16468 + *     Note: when you get a NULL pointer exception here this means someone
16469 + *     passed in an incorrect kernel address to one of these functions.
16470 + *
16471 + *     If you use these functions directly please don't forget the
16472 + *     verify_area().
16473 + */
16474 +
16475 +static __inline__
16476 +unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
16477 +                                      int len, int sum)
16478 +{
16479 +       memcpy(dst, src, len);
16480 +       return(csum_partial(dst, len, sum));
16481 +}
16482 +
16483 +static __inline__
16484 +unsigned int csum_partial_copy_from_user(const char *src, char *dst,
16485 +                                        int len, int sum, int *err_ptr)
16486 +{
16487 +       return csum_partial_copy_from(src, dst, len, sum, err_ptr);
16488 +}
16489 +
16490 +/*
16491 + * These are the old (and unsafe) way of doing checksums, a warning message 
16492 + * will be printed if they are used and an exeption occurs.
16493 + *
16494 + * these functions should go away after some time.
16495 + */
16496 +
16497 +#define csum_partial_copy_fromuser csum_partial_copy_from_user
16498 +unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
16499 +
16500 +/*
16501 + *     This is a version of ip_compute_csum() optimized for IP headers,
16502 + *     which always checksum on 4 octet boundaries.
16503 + *
16504 + *     By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
16505 + *     Arnt Gulbrandsen.
16506 + */
16507 +static inline unsigned short ip_fast_csum(unsigned char * iph,
16508 +                                         unsigned int ihl)
16509 +{
16510 +       unsigned int sum;
16511 +
16512 +       __asm__ __volatile__(
16513 +           "movl (%1), %0      ;\n"
16514 +           "subl $4, %2        ;\n"
16515 +           "jbe 2f             ;\n"
16516 +           "addl 4(%1), %0     ;\n"
16517 +           "adcl 8(%1), %0     ;\n"
16518 +           "adcl 12(%1), %0    ;\n"
16519 +"1:        adcl 16(%1), %0     ;\n"
16520 +           "lea 4(%1), %1      ;\n"
16521 +           "decl %2            ;\n"
16522 +           "jne 1b             ;\n"
16523 +           "adcl $0, %0        ;\n"
16524 +           "movl %0, %2        ;\n"
16525 +           "shrl $16, %0       ;\n"
16526 +           "addw %w2, %w0      ;\n"
16527 +           "adcl $0, %0        ;\n"
16528 +           "notl %0            ;\n"
16529 +"2:                            ;\n"
16530 +       /* Since the input registers which are loaded with iph and ipl
16531 +          are modified, we must also specify them as outputs, or gcc
16532 +          will assume they contain their original values. */
16533 +       : "=r" (sum), "=r" (iph), "=r" (ihl)
16534 +       : "1" (iph), "2" (ihl));
16535 +       return(sum);
16536 +}
16537 +
16538 +/*
16539 + *     Fold a partial checksum
16540 + */
16541 +
16542 +static inline unsigned int csum_fold(unsigned int sum)
16543 +{
16544 +       __asm__(
16545 +               "addl %1, %0            ;\n"
16546 +               "adcl $0xffff, %0       ;\n"
16547 +               : "=r" (sum)
16548 +               : "r" (sum << 16), "0" (sum & 0xffff0000)
16549 +       );
16550 +       return (~sum) >> 16;
16551 +}
16552 +
16553 +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
16554 +                                                  unsigned long daddr,
16555 +                                                  unsigned short len,
16556 +                                                  unsigned short proto,
16557 +                                                  unsigned int sum)
16558 +{
16559 +    __asm__(
16560 +       "addl %1, %0    ;\n"
16561 +       "adcl %2, %0    ;\n"
16562 +       "adcl %3, %0    ;\n"
16563 +       "adcl $0, %0    ;\n"
16564 +       : "=r" (sum)
16565 +       : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
16566 +    return sum;
16567 +}
16568 +
16569 +/*
16570 + * computes the checksum of the TCP/UDP pseudo-header
16571 + * returns a 16-bit checksum, already complemented
16572 + */
16573 +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
16574 +                                                  unsigned long daddr,
16575 +                                                  unsigned short len,
16576 +                                                  unsigned short proto,
16577 +                                                  unsigned int sum)
16578 +{
16579 +       return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
16580 +}
16581 +
16582 +/*
16583 + * this routine is used for miscellaneous IP-like checksums, mainly
16584 + * in icmp.c
16585 + */
16586 +
16587 +static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
16588 +{
16589 +    return csum_fold (csum_partial(buff, len, 0));
16590 +}
16591 +
16592 +#define _HAVE_ARCH_IPV6_CSUM
16593 +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
16594 +                                                    struct in6_addr *daddr,
16595 +                                                    __u32 len,
16596 +                                                    unsigned short proto,
16597 +                                                    unsigned int sum)
16598 +{
16599 +       __asm__(
16600 +               "addl 0(%1), %0         ;\n"
16601 +               "adcl 4(%1), %0         ;\n"
16602 +               "adcl 8(%1), %0         ;\n"
16603 +               "adcl 12(%1), %0        ;\n"
16604 +               "adcl 0(%2), %0         ;\n"
16605 +               "adcl 4(%2), %0         ;\n"
16606 +               "adcl 8(%2), %0         ;\n"
16607 +               "adcl 12(%2), %0        ;\n"
16608 +               "adcl %3, %0            ;\n"
16609 +               "adcl %4, %0            ;\n"
16610 +               "adcl $0, %0            ;\n"
16611 +               : "=&r" (sum)
16612 +               : "r" (saddr), "r" (daddr),
16613 +                 "r"(htonl(len)), "r"(htonl(proto)), "0"(sum));
16614 +
16615 +       return csum_fold(sum);
16616 +}
16617 +
16618 +/*
16619 + *     Copy and checksum to user
16620 + */
16621 +#define HAVE_CSUM_COPY_USER
16622 +static __inline__ unsigned int csum_and_copy_to_user(const char *src, 
16623 +                                                    char *dst, int len,
16624 +                                                    int sum, int *err_ptr)
16625 +{
16626 +       if (access_ok(VERIFY_WRITE, dst, len))
16627 +               return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
16628 +
16629 +       if (len)
16630 +               *err_ptr = -EFAULT;
16631 +
16632 +       return -1; /* invalid checksum */
16633 +}
16634 +
16635 +#endif
16636 +
16637 +/*
16638 + * Overrides for Emacs so that we follow Linus's tabbing style.
16639 + * Emacs will notice this stuff at the end of the file and automatically
16640 + * adjust the settings for this buffer only.  This must remain at the end
16641 + * of the file.
16642 + * ---------------------------------------------------------------------------
16643 + * Local variables:
16644 + * c-file-style: "linux"
16645 + * End:
16646 + */
16647 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame.h um/arch/um/include/sysdep-i386/frame.h
16648 --- orig/arch/um/include/sysdep-i386/frame.h    1969-12-31 19:00:00.000000000 -0500
16649 +++ um/arch/um/include/sysdep-i386/frame.h      2003-10-21 03:26:06.000000000 -0400
16650 @@ -0,0 +1,29 @@
16651 +/* 
16652 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16653 + * Licensed under the GPL
16654 + */
16655 +
16656 +#ifndef __FRAME_I386_H
16657 +#define __FRAME_I386_H
16658 +
16659 +struct arch_frame_data_raw {
16660 +       unsigned long fp_start;
16661 +       unsigned long sr;
16662 +};
16663 +
16664 +struct arch_frame_data {
16665 +       int fpstate_size;
16666 +};
16667 +
16668 +#endif
16669 +
16670 +/*
16671 + * Overrides for Emacs so that we follow Linus's tabbing style.
16672 + * Emacs will notice this stuff at the end of the file and automatically
16673 + * adjust the settings for this buffer only.  This must remain at the end
16674 + * of the file.
16675 + * ---------------------------------------------------------------------------
16676 + * Local variables:
16677 + * c-file-style: "linux"
16678 + * End:
16679 + */
16680 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_kern.h um/arch/um/include/sysdep-i386/frame_kern.h
16681 --- orig/arch/um/include/sysdep-i386/frame_kern.h       1969-12-31 19:00:00.000000000 -0500
16682 +++ um/arch/um/include/sysdep-i386/frame_kern.h 2003-10-21 03:26:06.000000000 -0400
16683 @@ -0,0 +1,69 @@
16684 +/* 
16685 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16686 + * Licensed under the GPL
16687 + */
16688 +
16689 +#ifndef __FRAME_KERN_I386_H
16690 +#define __FRAME_KERN_I386_H
16691 +
16692 +/* This is called from sys_sigreturn.  It takes the sp at the point of the
16693 + * sigreturn system call and returns the address of the sigcontext struct
16694 + * on the stack.
16695 + */
16696 +
16697 +static inline void *sp_to_sc(unsigned long sp)
16698 +{
16699 +       return((void *) sp);
16700 +}
16701 +
16702 +static inline void *sp_to_uc(unsigned long sp)
16703 +{
16704 +       unsigned long uc;
16705 +
16706 +       uc = sp + signal_frame_si.uc_index - 
16707 +               signal_frame_si.common.sp_index - 4;
16708 +       return((void *) uc);
16709 +}
16710 +
16711 +static inline void *sp_to_rt_sc(unsigned long sp)
16712 +{
16713 +       unsigned long sc;
16714 +
16715 +       sc = sp - signal_frame_si.common.sp_index + 
16716 +               signal_frame_si.common.len - 4;
16717 +       return((void *) sc);
16718 +}
16719 +
16720 +static inline void *sp_to_mask(unsigned long sp)
16721 +{
16722 +       unsigned long mask;
16723 +
16724 +       mask = sp - signal_frame_sc.common.sp_index + 
16725 +               signal_frame_sc.common.len - 8;
16726 +       return((void *) mask);
16727 +}
16728 +
16729 +extern int sc_size(void *data);
16730 +
16731 +static inline void *sp_to_rt_mask(unsigned long sp)
16732 +{
16733 +       unsigned long mask;
16734 +
16735 +       mask = sp - signal_frame_si.common.sp_index + 
16736 +               signal_frame_si.common.len + 
16737 +               sc_size(&signal_frame_si.common.arch) - 4;
16738 +       return((void *) mask);
16739 +}
16740 +
16741 +#endif
16742 +
16743 +/*
16744 + * Overrides for Emacs so that we follow Linus's tabbing style.
16745 + * Emacs will notice this stuff at the end of the file and automatically
16746 + * adjust the settings for this buffer only.  This must remain at the end
16747 + * of the file.
16748 + * ---------------------------------------------------------------------------
16749 + * Local variables:
16750 + * c-file-style: "linux"
16751 + * End:
16752 + */
16753 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_user.h um/arch/um/include/sysdep-i386/frame_user.h
16754 --- orig/arch/um/include/sysdep-i386/frame_user.h       1969-12-31 19:00:00.000000000 -0500
16755 +++ um/arch/um/include/sysdep-i386/frame_user.h 2003-10-21 03:26:06.000000000 -0400
16756 @@ -0,0 +1,91 @@
16757 +/* 
16758 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16759 + * Licensed under the GPL
16760 + */
16761 +
16762 +#ifndef __FRAME_USER_I386_H
16763 +#define __FRAME_USER_I386_H
16764 +
16765 +#include <asm/page.h>
16766 +#include "sysdep/frame.h"
16767 +
16768 +/* This stuff is to calculate the size of the fp state struct at runtime
16769 + * because it has changed between 2.2 and 2.4 and it would be good for a
16770 + * UML compiled on one to work on the other.
16771 + * So, setup_arch_frame_raw fills in the arch struct with the raw data, which
16772 + * just contains the address of the end of the sigcontext.  This is invoked
16773 + * from the signal handler.
16774 + * setup_arch_frame uses that data to figure out what 
16775 + * arch_frame_data.fpstate_size should be.  It really has no idea, since it's
16776 + * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
16777 + * everything from the end of the sigcontext up to the top of the stack.  So,
16778 + * it masks off the page number to get the offset within the page and subtracts
16779 + * that from the page size, and that's how big the fpstate struct will be
16780 + * considered to be.
16781 + */
16782 +
16783 +static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
16784 +                                       void *end, unsigned long srp)
16785 +{
16786 +       unsigned long sr = *((unsigned long *) srp);
16787 +
16788 +       data->fp_start = (unsigned long) end;
16789 +       if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
16790 +               data->sr = sr;
16791 +       else data->sr = 0;
16792 +}
16793 +
16794 +static inline void setup_arch_frame(struct arch_frame_data_raw *in, 
16795 +                                   struct arch_frame_data *out)
16796 +{
16797 +       unsigned long fpstate_start = in->fp_start;
16798 +
16799 +       if(in->sr == 0){
16800 +               fpstate_start &= ~PAGE_MASK;
16801 +               out->fpstate_size = PAGE_SIZE - fpstate_start;
16802 +       }
16803 +       else {
16804 +               out->fpstate_size = in->sr - fpstate_start;
16805 +       }
16806 +}
16807 +
16808 +/* This figures out where on the stack the SA_RESTORER function address
16809 + * is stored.  For i386, it's the signal handler return address, so it's
16810 + * located next to the frame pointer.
16811 + * This is inlined, so __builtin_frame_address(0) is correct.  Otherwise,
16812 + * it would have to be __builtin_frame_address(1).
16813 + */
16814 +
16815 +static inline unsigned long frame_restorer(void)
16816 +{
16817 +       unsigned long *fp;
16818 +
16819 +       fp = __builtin_frame_address(0);
16820 +       return((unsigned long) (fp + 1));
16821 +}
16822 +
16823 +/* Similarly, this returns the value of sp when the handler was first
16824 + * entered.  This is used to calculate the proper sp when delivering
16825 + * signals.
16826 + */
16827 +
16828 +static inline unsigned long frame_sp(void)
16829 +{
16830 +       unsigned long *fp;
16831 +
16832 +       fp = __builtin_frame_address(0);
16833 +       return((unsigned long) (fp + 1));
16834 +}
16835 +
16836 +#endif
16837 +
16838 +/*
16839 + * Overrides for Emacs so that we follow Linus's tabbing style.
16840 + * Emacs will notice this stuff at the end of the file and automatically
16841 + * adjust the settings for this buffer only.  This must remain at the end
16842 + * of the file.
16843 + * ---------------------------------------------------------------------------
16844 + * Local variables:
16845 + * c-file-style: "linux"
16846 + * End:
16847 + */
16848 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace.h um/arch/um/include/sysdep-i386/ptrace.h
16849 --- orig/arch/um/include/sysdep-i386/ptrace.h   1969-12-31 19:00:00.000000000 -0500
16850 +++ um/arch/um/include/sysdep-i386/ptrace.h     2003-10-21 03:26:06.000000000 -0400
16851 @@ -0,0 +1,193 @@
16852 +/* 
16853 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
16854 + * Licensed under the GPL
16855 + */
16856 +
16857 +#ifndef __SYSDEP_I386_PTRACE_H
16858 +#define __SYSDEP_I386_PTRACE_H
16859 +
16860 +#include "uml-config.h"
16861 +
16862 +#ifdef UML_CONFIG_MODE_TT
16863 +#include "ptrace-tt.h"
16864 +#endif
16865 +
16866 +#ifdef UML_CONFIG_MODE_SKAS
16867 +#include "ptrace-skas.h"
16868 +#endif
16869 +
16870 +#include "choose-mode.h"
16871 +
16872 +union uml_pt_regs {
16873 +#ifdef UML_CONFIG_MODE_TT
16874 +       struct tt_regs {
16875 +               long syscall;
16876 +               void *sc;
16877 +       } tt;
16878 +#endif
16879 +#ifdef UML_CONFIG_MODE_SKAS
16880 +       struct skas_regs {
16881 +               unsigned long regs[HOST_FRAME_SIZE];
16882 +               unsigned long fp[HOST_FP_SIZE];
16883 +               unsigned long xfp[HOST_XFP_SIZE];
16884 +               unsigned long fault_addr;
16885 +               unsigned long fault_type;
16886 +               unsigned long trap_type;
16887 +               long syscall;
16888 +               int is_user;
16889 +       } skas;
16890 +#endif
16891 +};
16892 +
16893 +#define EMPTY_UML_PT_REGS { }
16894 +
16895 +extern int mode_tt;
16896 +
16897 +#define UPT_SC(r) ((r)->tt.sc)
16898 +#define UPT_IP(r) \
16899 +       CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
16900 +#define UPT_SP(r) \
16901 +       CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
16902 +#define UPT_EFLAGS(r) \
16903 +       CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
16904 +#define UPT_EAX(r) \
16905 +       CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
16906 +#define UPT_EBX(r) \
16907 +       CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
16908 +#define UPT_ECX(r) \
16909 +       CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
16910 +#define UPT_EDX(r) \
16911 +       CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
16912 +#define UPT_ESI(r) \
16913 +       CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
16914 +#define UPT_EDI(r) \
16915 +       CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
16916 +#define UPT_EBP(r) \
16917 +       CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
16918 +#define UPT_ORIG_EAX(r) \
16919 +       CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
16920 +#define UPT_CS(r) \
16921 +       CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
16922 +#define UPT_SS(r) \
16923 +       CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
16924 +#define UPT_DS(r) \
16925 +       CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
16926 +#define UPT_ES(r) \
16927 +       CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
16928 +#define UPT_FS(r) \
16929 +       CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
16930 +#define UPT_GS(r) \
16931 +       CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
16932 +
16933 +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
16934 +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
16935 +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
16936 +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
16937 +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
16938 +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
16939 +
16940 +extern int user_context(unsigned long sp);
16941 +
16942 +#define UPT_IS_USER(r) \
16943 +       CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
16944 +
16945 +struct syscall_args {
16946 +       unsigned long args[6];
16947 +};
16948 +
16949 +#define SYSCALL_ARGS(r) ((struct syscall_args) \
16950 +                        { .args = { UPT_SYSCALL_ARG1(r), \
16951 +                                    UPT_SYSCALL_ARG2(r), \
16952 +                                   UPT_SYSCALL_ARG3(r), \
16953 +                                    UPT_SYSCALL_ARG4(r), \
16954 +                                   UPT_SYSCALL_ARG5(r), \
16955 +                                    UPT_SYSCALL_ARG6(r) } } )
16956 +
16957 +#define UPT_REG(regs, reg) \
16958 +       ({      unsigned long val; \
16959 +               switch(reg){ \
16960 +               case EIP: val = UPT_IP(regs); break; \
16961 +               case UESP: val = UPT_SP(regs); break; \
16962 +               case EAX: val = UPT_EAX(regs); break; \
16963 +               case EBX: val = UPT_EBX(regs); break; \
16964 +               case ECX: val = UPT_ECX(regs); break; \
16965 +               case EDX: val = UPT_EDX(regs); break; \
16966 +               case ESI: val = UPT_ESI(regs); break; \
16967 +               case EDI: val = UPT_EDI(regs); break; \
16968 +               case EBP: val = UPT_EBP(regs); break; \
16969 +               case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \
16970 +               case CS: val = UPT_CS(regs); break; \
16971 +               case SS: val = UPT_SS(regs); break; \
16972 +               case DS: val = UPT_DS(regs); break; \
16973 +               case ES: val = UPT_ES(regs); break; \
16974 +               case FS: val = UPT_FS(regs); break; \
16975 +               case GS: val = UPT_GS(regs); break; \
16976 +               case EFL: val = UPT_EFLAGS(regs); break; \
16977 +               default :  \
16978 +                       panic("Bad register in UPT_REG : %d\n", reg);  \
16979 +                       val = -1; \
16980 +               } \
16981 +               val; \
16982 +       })
16983 +       
16984 +
16985 +#define UPT_SET(regs, reg, val) \
16986 +       do { \
16987 +               switch(reg){ \
16988 +               case EIP: UPT_IP(regs) = val; break; \
16989 +               case UESP: UPT_SP(regs) = val; break; \
16990 +               case EAX: UPT_EAX(regs) = val; break; \
16991 +               case EBX: UPT_EBX(regs) = val; break; \
16992 +               case ECX: UPT_ECX(regs) = val; break; \
16993 +               case EDX: UPT_EDX(regs) = val; break; \
16994 +               case ESI: UPT_ESI(regs) = val; break; \
16995 +               case EDI: UPT_EDI(regs) = val; break; \
16996 +               case EBP: UPT_EBP(regs) = val; break; \
16997 +               case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \
16998 +               case CS: UPT_CS(regs) = val; break; \
16999 +               case SS: UPT_SS(regs) = val; break; \
17000 +               case DS: UPT_DS(regs) = val; break; \
17001 +               case ES: UPT_ES(regs) = val; break; \
17002 +               case FS: UPT_FS(regs) = val; break; \
17003 +               case GS: UPT_GS(regs) = val; break; \
17004 +               case EFL: UPT_EFLAGS(regs) = val; break; \
17005 +               default :  \
17006 +                       panic("Bad register in UPT_SET : %d\n", reg);  \
17007 +                       break; \
17008 +               } \
17009 +       } while (0)
17010 +
17011 +#define UPT_SET_SYSCALL_RETURN(r, res) \
17012 +       CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
17013 +                    REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
17014 +
17015 +#define UPT_RESTART_SYSCALL(r) \
17016 +       CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
17017 +                   REGS_RESTART_SYSCALL((r)->skas.regs))
17018 +
17019 +#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
17020 +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
17021 +#define UPT_SYSCALL_RET(r) UPT_EAX(r)
17022 +
17023 +#define UPT_SEGV_IS_FIXABLE(r) \
17024 +       CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
17025 +                    REGS_SEGV_IS_FIXABLE(&r->skas))
17026 +
17027 +#define UPT_FAULT_ADDR(r) \
17028 +       CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
17029 +
17030 +#define UPT_FAULT_WRITE(r) \
17031 +       CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
17032 +
17033 +#endif
17034 +
17035 +/*
17036 + * Overrides for Emacs so that we follow Linus's tabbing style.
17037 + * Emacs will notice this stuff at the end of the file and automatically
17038 + * adjust the settings for this buffer only.  This must remain at the end
17039 + * of the file.
17040 + * ---------------------------------------------------------------------------
17041 + * Local variables:
17042 + * c-file-style: "linux"
17043 + * End:
17044 + */
17045 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace_user.h um/arch/um/include/sysdep-i386/ptrace_user.h
17046 --- orig/arch/um/include/sysdep-i386/ptrace_user.h      1969-12-31 19:00:00.000000000 -0500
17047 +++ um/arch/um/include/sysdep-i386/ptrace_user.h        2003-10-21 03:26:06.000000000 -0400
17048 @@ -0,0 +1,62 @@
17049 +/* 
17050 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17051 + * Licensed under the GPL
17052 + */
17053 +
17054 +#ifndef __SYSDEP_I386_PTRACE_USER_H__
17055 +#define __SYSDEP_I386_PTRACE_USER_H__
17056 +
17057 +#include <asm/ptrace.h>
17058 +
17059 +#define PT_OFFSET(r) ((r) * sizeof(long))
17060 +
17061 +#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX])
17062 +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX)
17063 +
17064 +#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX)
17065 +#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX)
17066 +#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
17067 +#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
17068 +#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
17069 +
17070 +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
17071 +
17072 +#define PT_IP_OFFSET PT_OFFSET(EIP)
17073 +#define PT_IP(regs) ((regs)[EIP])
17074 +#define PT_SP(regs) ((regs)[UESP])
17075 +
17076 +#ifndef FRAME_SIZE
17077 +#define FRAME_SIZE (17)
17078 +#endif
17079 +#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
17080 +
17081 +#define FP_FRAME_SIZE (27)
17082 +#define FPX_FRAME_SIZE (128)
17083 +
17084 +#ifdef PTRACE_GETREGS
17085 +#define UM_HAVE_GETREGS
17086 +#endif
17087 +
17088 +#ifdef PTRACE_SETREGS
17089 +#define UM_HAVE_SETREGS
17090 +#endif
17091 +
17092 +#ifdef PTRACE_GETFPREGS
17093 +#define UM_HAVE_GETFPREGS
17094 +#endif
17095 +
17096 +#ifdef PTRACE_SETFPREGS
17097 +#define UM_HAVE_SETFPREGS
17098 +#endif
17099 +
17100 +#ifdef PTRACE_GETFPXREGS
17101 +#define UM_HAVE_GETFPXREGS
17102 +#endif
17103 +
17104 +#ifdef PTRACE_SETFPXREGS
17105 +#define UM_HAVE_SETFPXREGS
17106 +#endif
17107 +
17108 +extern void update_debugregs(int seq);
17109 +
17110 +#endif
17111 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/sigcontext.h um/arch/um/include/sysdep-i386/sigcontext.h
17112 --- orig/arch/um/include/sysdep-i386/sigcontext.h       1969-12-31 19:00:00.000000000 -0500
17113 +++ um/arch/um/include/sysdep-i386/sigcontext.h 2003-10-21 03:26:06.000000000 -0400
17114 @@ -0,0 +1,49 @@
17115 +/* 
17116 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17117 + * Licensed under the GPL
17118 + */
17119 +
17120 +#ifndef __SYS_SIGCONTEXT_I386_H
17121 +#define __SYS_SIGCONTEXT_I386_H
17122 +
17123 +#include "sc.h"
17124 +
17125 +#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
17126 +
17127 +#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
17128 +#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
17129 +
17130 +#define SC_FAULT_ADDR(sc) SC_CR2(sc)
17131 +#define SC_FAULT_TYPE(sc) SC_ERR(sc)
17132 +
17133 +#define FAULT_WRITE(err) (err & 2)
17134 +#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0)
17135 +
17136 +#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc)))
17137 +
17138 +#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
17139 +
17140 +/* ptrace expects that, at the start of a system call, %eax contains
17141 + * -ENOSYS, so this makes it so.
17142 + */
17143 +#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
17144 +
17145 +/* This is Page Fault */
17146 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
17147 +
17148 +#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
17149 +
17150 +extern unsigned long *sc_sigmask(void *sc_ptr);
17151 +extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
17152 +
17153 +#endif
17154 +/*
17155 + * Overrides for Emacs so that we follow Linus's tabbing style.
17156 + * Emacs will notice this stuff at the end of the file and automatically
17157 + * adjust the settings for this buffer only.  This must remain at the end
17158 + * of the file.
17159 + * ---------------------------------------------------------------------------
17160 + * Local variables:
17161 + * c-file-style: "linux"
17162 + * End:
17163 + */
17164 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/syscalls.h um/arch/um/include/sysdep-i386/syscalls.h
17165 --- orig/arch/um/include/sysdep-i386/syscalls.h 1969-12-31 19:00:00.000000000 -0500
17166 +++ um/arch/um/include/sysdep-i386/syscalls.h   2003-10-21 03:26:06.000000000 -0400
17167 @@ -0,0 +1,61 @@
17168 +/* 
17169 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17170 + * Licensed under the GPL
17171 + */
17172 +
17173 +#include "asm/unistd.h"
17174 +#include "sysdep/ptrace.h"
17175 +
17176 +typedef long syscall_handler_t(struct pt_regs);
17177 +
17178 +#define EXECUTE_SYSCALL(syscall, regs) \
17179 +       ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
17180 +
17181 +extern syscall_handler_t sys_modify_ldt;
17182 +extern syscall_handler_t old_mmap_i386;
17183 +extern syscall_handler_t old_select;
17184 +extern syscall_handler_t sys_ni_syscall;
17185 +
17186 +#define ARCH_SYSCALLS \
17187 +       [ __NR_mmap ] = old_mmap_i386, \
17188 +       [ __NR_select ] = old_select, \
17189 +       [ __NR_vm86old ] = sys_ni_syscall, \
17190 +        [ __NR_modify_ldt ] = sys_modify_ldt, \
17191 +       [ __NR_lchown32 ] = sys_lchown, \
17192 +       [ __NR_getuid32 ] = sys_getuid, \
17193 +       [ __NR_getgid32 ] = sys_getgid, \
17194 +       [ __NR_geteuid32 ] = sys_geteuid, \
17195 +       [ __NR_getegid32 ] = sys_getegid, \
17196 +       [ __NR_setreuid32 ] = sys_setreuid, \
17197 +       [ __NR_setregid32 ] = sys_setregid, \
17198 +       [ __NR_getgroups32 ] = sys_getgroups, \
17199 +       [ __NR_setgroups32 ] = sys_setgroups, \
17200 +       [ __NR_fchown32 ] = sys_fchown, \
17201 +       [ __NR_setresuid32 ] = sys_setresuid, \
17202 +       [ __NR_getresuid32 ] = sys_getresuid, \
17203 +       [ __NR_setresgid32 ] = sys_setresgid, \
17204 +       [ __NR_getresgid32 ] = sys_getresgid, \
17205 +       [ __NR_chown32 ] = sys_chown, \
17206 +       [ __NR_setuid32 ] = sys_setuid, \
17207 +       [ __NR_setgid32 ] = sys_setgid, \
17208 +       [ __NR_setfsuid32 ] = sys_setfsuid, \
17209 +       [ __NR_setfsgid32 ] = sys_setfsgid, \
17210 +       [ __NR_pivot_root ] = sys_pivot_root, \
17211 +       [ __NR_mincore ] = sys_mincore, \
17212 +       [ __NR_madvise ] = sys_madvise, \
17213 +        [ 222 ] = sys_ni_syscall, 
17214 +        
17215 +/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
17216 +
17217 +#define LAST_ARCH_SYSCALL 222
17218 +
17219 +/*
17220 + * Overrides for Emacs so that we follow Linus's tabbing style.
17221 + * Emacs will notice this stuff at the end of the file and automatically
17222 + * adjust the settings for this buffer only.  This must remain at the end
17223 + * of the file.
17224 + * ---------------------------------------------------------------------------
17225 + * Local variables:
17226 + * c-file-style: "linux"
17227 + * End:
17228 + */
17229 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/ptrace.h um/arch/um/include/sysdep-ia64/ptrace.h
17230 --- orig/arch/um/include/sysdep-ia64/ptrace.h   1969-12-31 19:00:00.000000000 -0500
17231 +++ um/arch/um/include/sysdep-ia64/ptrace.h     2003-10-21 03:26:06.000000000 -0400
17232 @@ -0,0 +1,26 @@
17233 +/* 
17234 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17235 + * Licensed under the GPL
17236 + */
17237 +
17238 +#ifndef __SYSDEP_IA64_PTRACE_H
17239 +#define __SYSDEP_IA64_PTRACE_H
17240 +
17241 +struct sys_pt_regs {
17242 +  int foo;
17243 +};
17244 +
17245 +#define EMPTY_REGS { 0 }
17246 +
17247 +#endif
17248 +
17249 +/*
17250 + * Overrides for Emacs so that we follow Linus's tabbing style.
17251 + * Emacs will notice this stuff at the end of the file and automatically
17252 + * adjust the settings for this buffer only.  This must remain at the end
17253 + * of the file.
17254 + * ---------------------------------------------------------------------------
17255 + * Local variables:
17256 + * c-file-style: "linux"
17257 + * End:
17258 + */
17259 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/sigcontext.h um/arch/um/include/sysdep-ia64/sigcontext.h
17260 --- orig/arch/um/include/sysdep-ia64/sigcontext.h       1969-12-31 19:00:00.000000000 -0500
17261 +++ um/arch/um/include/sysdep-ia64/sigcontext.h 2003-10-21 03:26:06.000000000 -0400
17262 @@ -0,0 +1,20 @@
17263 +/* 
17264 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17265 + * Licensed under the GPL
17266 + */
17267 +
17268 +#ifndef __SYSDEP_IA64_SIGCONTEXT_H
17269 +#define __SYSDEP_IA64_SIGCONTEXT_H
17270 +
17271 +#endif
17272 +
17273 +/*
17274 + * Overrides for Emacs so that we follow Linus's tabbing style.
17275 + * Emacs will notice this stuff at the end of the file and automatically
17276 + * adjust the settings for this buffer only.  This must remain at the end
17277 + * of the file.
17278 + * ---------------------------------------------------------------------------
17279 + * Local variables:
17280 + * c-file-style: "linux"
17281 + * End:
17282 + */
17283 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/syscalls.h um/arch/um/include/sysdep-ia64/syscalls.h
17284 --- orig/arch/um/include/sysdep-ia64/syscalls.h 1969-12-31 19:00:00.000000000 -0500
17285 +++ um/arch/um/include/sysdep-ia64/syscalls.h   2003-10-21 03:26:06.000000000 -0400
17286 @@ -0,0 +1,20 @@
17287 +/* 
17288 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17289 + * Licensed under the GPL
17290 + */
17291 +
17292 +#ifndef __SYSDEP_IA64_SYSCALLS_H
17293 +#define __SYSDEP_IA64_SYSCALLS_H
17294 +
17295 +#endif
17296 +
17297 +/*
17298 + * Overrides for Emacs so that we follow Linus's tabbing style.
17299 + * Emacs will notice this stuff at the end of the file and automatically
17300 + * adjust the settings for this buffer only.  This must remain at the end
17301 + * of the file.
17302 + * ---------------------------------------------------------------------------
17303 + * Local variables:
17304 + * c-file-style: "linux"
17305 + * End:
17306 + */
17307 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/ptrace.h um/arch/um/include/sysdep-ppc/ptrace.h
17308 --- orig/arch/um/include/sysdep-ppc/ptrace.h    1969-12-31 19:00:00.000000000 -0500
17309 +++ um/arch/um/include/sysdep-ppc/ptrace.h      2003-10-21 03:26:06.000000000 -0400
17310 @@ -0,0 +1,104 @@
17311 +/* 
17312 + * Licensed under the GPL
17313 + */
17314 +
17315 +#ifndef __SYS_PTRACE_PPC_H
17316 +#define __SYS_PTRACE_PPC_H
17317 +
17318 +#include "linux/config.h"
17319 +#include "linux/types.h"
17320 +
17321 +/* the following taken from <asm-ppc/ptrace.h> */
17322 +
17323 +#ifdef CONFIG_PPC64
17324 +#define PPC_REG unsigned long /*long*/
17325 +#else
17326 +#define PPC_REG unsigned long
17327 +#endif
17328 +struct sys_pt_regs_s {
17329 +       PPC_REG gpr[32];
17330 +       PPC_REG nip;
17331 +       PPC_REG msr;
17332 +       PPC_REG orig_gpr3;      /* Used for restarting system calls */
17333 +       PPC_REG ctr;
17334 +       PPC_REG link;
17335 +       PPC_REG xer;
17336 +       PPC_REG ccr;
17337 +       PPC_REG mq;             /* 601 only (not used at present) */
17338 +                               /* Used on APUS to hold IPL value. */
17339 +       PPC_REG trap;           /* Reason for being here */
17340 +       PPC_REG dar;            /* Fault registers */
17341 +       PPC_REG dsisr;
17342 +       PPC_REG result;         /* Result of a system call */
17343 +};
17344 +
17345 +#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG))
17346 +
17347 +struct sys_pt_regs {
17348 +    PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)];
17349 +};
17350 +
17351 +#define UM_MAX_REG (PT_FPR0)
17352 +#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG))
17353 +
17354 +#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } }
17355 +
17356 +#define UM_REG(r, n) ((r)->regs[n])
17357 +
17358 +#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3)
17359 +#define UM_SP(r) UM_REG(r, PT_R1)
17360 +#define UM_IP(r) UM_REG(r, PT_NIP)
17361 +#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR)
17362 +#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0)
17363 +#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3)
17364 +#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4)
17365 +#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5)
17366 +#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6)
17367 +#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7)
17368 +#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8)
17369 +
17370 +#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG))
17371 +#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG))
17372 +#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG))
17373 +#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG))
17374 +#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG))
17375 +#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG))
17376 +#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG))
17377 +#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG))
17378 +#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG))
17379 +#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG))
17380 +#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG))
17381 +
17382 +#define UM_SET_SYSCALL_RETURN(_regs, result)           \
17383 +do {                                                    \
17384 +        if (result < 0) {                              \
17385 +               (_regs)->regs[PT_CCR] |= 0x10000000;    \
17386 +               UM_SYSCALL_RET((_regs)) = -result;      \
17387 +        } else {                                       \
17388 +               UM_SYSCALL_RET((_regs)) = result;       \
17389 +        }                                               \
17390 +} while(0)
17391 +
17392 +extern void shove_aux_table(unsigned long sp);
17393 +#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp);
17394 +
17395 +/* These aren't actually defined.  The undefs are just to make sure
17396 + * everyone's clear on the concept.
17397 + */
17398 +#undef UML_HAVE_GETREGS
17399 +#undef UML_HAVE_GETFPREGS
17400 +#undef UML_HAVE_SETREGS
17401 +#undef UML_HAVE_SETFPREGS
17402 +
17403 +#endif
17404 +
17405 +/*
17406 + * Overrides for Emacs so that we follow Linus's tabbing style.
17407 + * Emacs will notice this stuff at the end of the file and automatically
17408 + * adjust the settings for this buffer only.  This must remain at the end
17409 + * of the file.
17410 + * ---------------------------------------------------------------------------
17411 + * Local variables:
17412 + * c-file-style: "linux"
17413 + * End:
17414 + */
17415 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/sigcontext.h um/arch/um/include/sysdep-ppc/sigcontext.h
17416 --- orig/arch/um/include/sysdep-ppc/sigcontext.h        1969-12-31 19:00:00.000000000 -0500
17417 +++ um/arch/um/include/sysdep-ppc/sigcontext.h  2003-10-21 03:26:06.000000000 -0400
17418 @@ -0,0 +1,62 @@
17419 +/* 
17420 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17421 + * Licensed under the GPL
17422 + */
17423 +
17424 +#ifndef __SYS_SIGCONTEXT_PPC_H
17425 +#define __SYS_SIGCONTEXT_PPC_H
17426 +
17427 +#define DSISR_WRITE 0x02000000
17428 +
17429 +#define SC_FAULT_ADDR(sc) ({ \
17430 +               struct sigcontext *_sc = (sc); \
17431 +               long retval = -1; \
17432 +               switch (_sc->regs->trap) { \
17433 +               case 0x300: \
17434 +                       /* data exception */ \
17435 +                       retval = _sc->regs->dar; \
17436 +                       break; \
17437 +               case 0x400: \
17438 +                       /* instruction exception */ \
17439 +                       retval = _sc->regs->nip; \
17440 +                       break; \
17441 +               default: \
17442 +                       panic("SC_FAULT_ADDR: unhandled trap type\n"); \
17443 +               } \
17444 +               retval; \
17445 +       })
17446 +
17447 +#define SC_FAULT_WRITE(sc) ({ \
17448 +               struct sigcontext *_sc = (sc); \
17449 +               long retval = -1; \
17450 +               switch (_sc->regs->trap) { \
17451 +               case 0x300: \
17452 +                       /* data exception */ \
17453 +                       retval = !!(_sc->regs->dsisr & DSISR_WRITE); \
17454 +                       break; \
17455 +               case 0x400: \
17456 +                       /* instruction exception: not a write */ \
17457 +                       retval = 0; \
17458 +                       break; \
17459 +               default: \
17460 +                       panic("SC_FAULT_ADDR: unhandled trap type\n"); \
17461 +               } \
17462 +               retval; \
17463 +       })
17464 +
17465 +#define SC_IP(sc) ((sc)->regs->nip)
17466 +#define SC_SP(sc) ((sc)->regs->gpr[1])
17467 +#define SEGV_IS_FIXABLE(sc) (1)
17468 +
17469 +#endif
17470 +
17471 +/*
17472 + * Overrides for Emacs so that we follow Linus's tabbing style.
17473 + * Emacs will notice this stuff at the end of the file and automatically
17474 + * adjust the settings for this buffer only.  This must remain at the end
17475 + * of the file.
17476 + * ---------------------------------------------------------------------------
17477 + * Local variables:
17478 + * c-file-style: "linux"
17479 + * End:
17480 + */
17481 diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/syscalls.h um/arch/um/include/sysdep-ppc/syscalls.h
17482 --- orig/arch/um/include/sysdep-ppc/syscalls.h  1969-12-31 19:00:00.000000000 -0500
17483 +++ um/arch/um/include/sysdep-ppc/syscalls.h    2003-10-21 03:26:06.000000000 -0400
17484 @@ -0,0 +1,50 @@
17485 +/* 
17486 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17487 + * Licensed under the GPL
17488 + */
17489 +
17490 +typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2,
17491 +                              unsigned long arg3, unsigned long arg4,
17492 +                              unsigned long arg5, unsigned long arg6);
17493 +
17494 +#define EXECUTE_SYSCALL(syscall, regs) \
17495 +        (*sys_call_table[syscall])(UM_SYSCALL_ARG1(&regs), \
17496 +                                  UM_SYSCALL_ARG2(&regs), \
17497 +                                  UM_SYSCALL_ARG3(&regs), \
17498 +                                  UM_SYSCALL_ARG4(&regs), \
17499 +                                  UM_SYSCALL_ARG5(&regs), \
17500 +                                  UM_SYSCALL_ARG6(&regs))
17501 +
17502 +extern syscall_handler_t sys_mincore;
17503 +extern syscall_handler_t sys_madvise;
17504 +
17505 +/* old_mmap needs the correct prototype since syscall_kern.c includes
17506 + * this file.
17507 + */
17508 +int old_mmap(unsigned long addr, unsigned long len,
17509 +            unsigned long prot, unsigned long flags,
17510 +            unsigned long fd, unsigned long offset);
17511 +
17512 +#define ARCH_SYSCALLS \
17513 +       [ __NR_modify_ldt ] = sys_ni_syscall, \
17514 +       [ __NR_pciconfig_read ] = sys_ni_syscall, \
17515 +       [ __NR_pciconfig_write ] = sys_ni_syscall, \
17516 +       [ __NR_pciconfig_iobase ] = sys_ni_syscall, \
17517 +       [ __NR_pivot_root ] = sys_ni_syscall, \
17518 +       [ __NR_multiplexer ] = sys_ni_syscall, \
17519 +       [ __NR_mmap ] = old_mmap, \
17520 +       [ __NR_madvise ] = sys_madvise, \
17521 +       [ __NR_mincore ] = sys_mincore, 
17522 +
17523 +#define LAST_ARCH_SYSCALL __NR_mincore
17524 +
17525 +/*
17526 + * Overrides for Emacs so that we follow Linus's tabbing style.
17527 + * Emacs will notice this stuff at the end of the file and automatically
17528 + * adjust the settings for this buffer only.  This must remain at the end
17529 + * of the file.
17530 + * ---------------------------------------------------------------------------
17531 + * Local variables:
17532 + * c-file-style: "linux"
17533 + * End:
17534 + */
17535 diff -Naur -X ../exclude-files orig/arch/um/include/sysrq.h um/arch/um/include/sysrq.h
17536 --- orig/arch/um/include/sysrq.h        1969-12-31 19:00:00.000000000 -0500
17537 +++ um/arch/um/include/sysrq.h  2003-10-21 03:26:06.000000000 -0400
17538 @@ -0,0 +1,6 @@
17539 +#ifndef __UM_SYSRQ_H
17540 +#define __UM_SYSRQ_H
17541 +
17542 +extern void show_trace(unsigned long *stack);
17543 +
17544 +#endif
17545 diff -Naur -X ../exclude-files orig/arch/um/include/tempfile.h um/arch/um/include/tempfile.h
17546 --- orig/arch/um/include/tempfile.h     1969-12-31 19:00:00.000000000 -0500
17547 +++ um/arch/um/include/tempfile.h       2003-10-21 03:26:06.000000000 -0400
17548 @@ -0,0 +1,21 @@
17549 +/* 
17550 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
17551 + * Licensed under the GPL
17552 + */
17553 +
17554 +#ifndef __TEMPFILE_H__
17555 +#define __TEMPFILE_H__
17556 +
17557 +extern int make_tempfile(const char *template, char **tempname, int do_unlink);
17558 +
17559 +#endif
17560 +/*
17561 + * Overrides for Emacs so that we follow Linus's tabbing style.
17562 + * Emacs will notice this stuff at the end of the file and automatically
17563 + * adjust the settings for this buffer only.  This must remain at the end
17564 + * of the file.
17565 + * ---------------------------------------------------------------------------
17566 + * Local variables:
17567 + * c-file-style: "linux"
17568 + * End:
17569 + */
17570 diff -Naur -X ../exclude-files orig/arch/um/include/time_user.h um/arch/um/include/time_user.h
17571 --- orig/arch/um/include/time_user.h    1969-12-31 19:00:00.000000000 -0500
17572 +++ um/arch/um/include/time_user.h      2003-10-21 03:26:06.000000000 -0400
17573 @@ -0,0 +1,17 @@
17574 +/* 
17575 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17576 + * Licensed under the GPL
17577 + */
17578 +
17579 +#ifndef __TIME_USER_H__
17580 +#define __TIME_USER_H__
17581 +
17582 +extern void timer(void);
17583 +extern void switch_timers(int to_real);
17584 +extern void set_interval(int timer_type);
17585 +extern void idle_sleep(int secs);
17586 +extern void enable_timer(void);
17587 +extern unsigned long time_lock(void);
17588 +extern void time_unlock(unsigned long);
17589 +
17590 +#endif
17591 diff -Naur -X ../exclude-files orig/arch/um/include/tlb.h um/arch/um/include/tlb.h
17592 --- orig/arch/um/include/tlb.h  1969-12-31 19:00:00.000000000 -0500
17593 +++ um/arch/um/include/tlb.h    2003-10-21 03:26:06.000000000 -0400
17594 @@ -0,0 +1,23 @@
17595 +/* 
17596 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17597 + * Licensed under the GPL
17598 + */
17599 +
17600 +#ifndef __TLB_H__
17601 +#define __TLB_H__
17602 +
17603 +extern void mprotect_kernel_vm(int w);
17604 +extern void force_flush_all(void);
17605 +
17606 +#endif
17607 +
17608 +/*
17609 + * Overrides for Emacs so that we follow Linus's tabbing style.
17610 + * Emacs will notice this stuff at the end of the file and automatically
17611 + * adjust the settings for this buffer only.  This must remain at the end
17612 + * of the file.
17613 + * ---------------------------------------------------------------------------
17614 + * Local variables:
17615 + * c-file-style: "linux"
17616 + * End:
17617 + */
17618 diff -Naur -X ../exclude-files orig/arch/um/include/ubd_user.h um/arch/um/include/ubd_user.h
17619 --- orig/arch/um/include/ubd_user.h     1969-12-31 19:00:00.000000000 -0500
17620 +++ um/arch/um/include/ubd_user.h       2003-10-21 03:26:06.000000000 -0400
17621 @@ -0,0 +1,79 @@
17622 +/* 
17623 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17624 + * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
17625 + * Licensed under the GPL
17626 + */
17627 +
17628 +#ifndef __UM_UBD_USER_H
17629 +#define __UM_UBD_USER_H
17630 +
17631 +#include "os.h"
17632 +
17633 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
17634 +
17635 +struct io_thread_req {
17636 +       enum ubd_req op;
17637 +       int fds[2];
17638 +       unsigned long offsets[2];
17639 +       unsigned long long offset;
17640 +       unsigned long length;
17641 +       char *buffer;
17642 +       int sectorsize;
17643 +       unsigned long sector_mask;
17644 +       unsigned long long cow_offset;
17645 +       unsigned long bitmap_words[2];
17646 +       int map_fd;
17647 +       unsigned long long map_offset;
17648 +       int error;
17649 +};
17650 +
17651 +extern int open_ubd_file(char *file, struct openflags *openflags, 
17652 +                        char **backing_file_out, int *bitmap_offset_out, 
17653 +                        unsigned long *bitmap_len_out, int *data_offset_out,
17654 +                        int *create_cow_out);
17655 +extern int create_cow_file(char *cow_file, char *backing_file, 
17656 +                          struct openflags flags, int sectorsize, 
17657 +                          int alignment, int *bitmap_offset_out, 
17658 +                          unsigned long *bitmap_len_out,
17659 +                          int *data_offset_out);
17660 +extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
17661 +extern int read_ubd_fs(int fd, void *buffer, int len);
17662 +extern int write_ubd_fs(int fd, char *buffer, int len);
17663 +extern int start_io_thread(unsigned long sp, int *fds_out);
17664 +extern void do_io(struct io_thread_req *req);
17665 +
17666 +static inline int ubd_test_bit(__u64 bit, unsigned char *data)
17667 +{
17668 +       __u64 n;
17669 +       int bits, off;
17670 +
17671 +       bits = sizeof(data[0]) * 8;
17672 +       n = bit / bits;
17673 +       off = bit % bits;
17674 +       return((data[n] & (1 << off)) != 0);
17675 +}
17676 +
17677 +static inline void ubd_set_bit(__u64 bit, unsigned char *data)
17678 +{
17679 +       __u64 n;
17680 +       int bits, off;
17681 +
17682 +       bits = sizeof(data[0]) * 8;
17683 +       n = bit / bits;
17684 +       off = bit % bits;
17685 +       data[n] |= (1 << off);
17686 +}
17687 +
17688 +
17689 +#endif
17690 +
17691 +/*
17692 + * Overrides for Emacs so that we follow Linus's tabbing style.
17693 + * Emacs will notice this stuff at the end of the file and automatically
17694 + * adjust the settings for this buffer only.  This must remain at the end
17695 + * of the file.
17696 + * ---------------------------------------------------------------------------
17697 + * Local variables:
17698 + * c-file-style: "linux"
17699 + * End:
17700 + */
17701 diff -Naur -X ../exclude-files orig/arch/um/include/umid.h um/arch/um/include/umid.h
17702 --- orig/arch/um/include/umid.h 1969-12-31 19:00:00.000000000 -0500
17703 +++ um/arch/um/include/umid.h   2003-10-21 03:26:06.000000000 -0400
17704 @@ -0,0 +1,22 @@
17705 +/*
17706 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
17707 + * Licensed under the GPL
17708 + */
17709 +
17710 +#ifndef __UMID_H__
17711 +#define __UMID_H__
17712 +
17713 +extern int umid_file_name(char *name, char *buf, int len);
17714 +
17715 +#endif
17716 +
17717 +/*
17718 + * Overrides for Emacs so that we follow Linus's tabbing style.
17719 + * Emacs will notice this stuff at the end of the file and automatically
17720 + * adjust the settings for this buffer only.  This must remain at the end
17721 + * of the file.
17722 + * ---------------------------------------------------------------------------
17723 + * Local variables:
17724 + * c-file-style: "linux"
17725 + * End:
17726 + */
17727 diff -Naur -X ../exclude-files orig/arch/um/include/uml_uaccess.h um/arch/um/include/uml_uaccess.h
17728 --- orig/arch/um/include/uml_uaccess.h  1969-12-31 19:00:00.000000000 -0500
17729 +++ um/arch/um/include/uml_uaccess.h    2003-10-21 03:26:06.000000000 -0400
17730 @@ -0,0 +1,28 @@
17731 +/*
17732 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
17733 + * Licensed under the GPL
17734 + */
17735 +
17736 +#ifndef __UML_UACCESS_H__
17737 +#define __UML_UACCESS_H__
17738 +
17739 +extern int __do_copy_to_user(void *to, const void *from, int n,
17740 +                                 void **fault_addr, void **fault_catcher);
17741 +extern unsigned long __do_user_copy(void *to, const void *from, int n,
17742 +                                   void **fault_addr, void **fault_catcher,
17743 +                                   void (*op)(void *to, const void *from,
17744 +                                              int n), int *faulted_out);
17745 +void __do_copy(void *to, const void *from, int n);
17746 +
17747 +#endif
17748 +
17749 +/*
17750 + * Overrides for Emacs so that we follow Linus's tabbing style.
17751 + * Emacs will notice this stuff at the end of the file and automatically
17752 + * adjust the settings for this buffer only.  This must remain at the end
17753 + * of the file.
17754 + * ---------------------------------------------------------------------------
17755 + * Local variables:
17756 + * c-file-style: "linux"
17757 + * End:
17758 + */
17759 diff -Naur -X ../exclude-files orig/arch/um/include/um_mmu.h um/arch/um/include/um_mmu.h
17760 --- orig/arch/um/include/um_mmu.h       1969-12-31 19:00:00.000000000 -0500
17761 +++ um/arch/um/include/um_mmu.h 2003-10-21 03:26:06.000000000 -0400
17762 @@ -0,0 +1,40 @@
17763 +/* 
17764 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17765 + * Licensed under the GPL
17766 + */
17767 +
17768 +#ifndef __ARCH_UM_MMU_H
17769 +#define __ARCH_UM_MMU_H
17770 +
17771 +#include "linux/config.h"
17772 +#include "choose-mode.h"
17773 +
17774 +#ifdef CONFIG_MODE_TT
17775 +#include "../kernel/tt/include/mmu.h"
17776 +#endif
17777 +
17778 +#ifdef CONFIG_MODE_SKAS
17779 +#include "../kernel/skas/include/mmu.h"
17780 +#endif
17781 +
17782 +typedef union {
17783 +#ifdef CONFIG_MODE_TT
17784 +       struct mmu_context_tt tt;
17785 +#endif
17786 +#ifdef CONFIG_MODE_SKAS
17787 +       struct mmu_context_skas skas;
17788 +#endif
17789 +} mm_context_t;
17790 +
17791 +#endif
17792 +
17793 +/*
17794 + * Overrides for Emacs so that we follow Linus's tabbing style.
17795 + * Emacs will notice this stuff at the end of the file and automatically
17796 + * adjust the settings for this buffer only.  This must remain at the end
17797 + * of the file.
17798 + * ---------------------------------------------------------------------------
17799 + * Local variables:
17800 + * c-file-style: "linux"
17801 + * End:
17802 + */
17803 diff -Naur -X ../exclude-files orig/arch/um/include/umn.h um/arch/um/include/umn.h
17804 --- orig/arch/um/include/umn.h  1969-12-31 19:00:00.000000000 -0500
17805 +++ um/arch/um/include/umn.h    2003-10-21 03:26:06.000000000 -0400
17806 @@ -0,0 +1,27 @@
17807 +/* 
17808 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17809 + * Licensed under the GPL
17810 + */
17811 +
17812 +#ifndef __UMN_H
17813 +#define __UMN_H
17814 +
17815 +extern int open_umn_tty(int *slave_out, int *slipno_out);
17816 +extern void close_umn_tty(int master, int slave);
17817 +extern int umn_send_packet(int fd, void *data, int len);
17818 +extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
17819 +extern void slip_unesc(unsigned char s);
17820 +extern void umn_read(int fd);
17821 +
17822 +#endif
17823 +
17824 +/*
17825 + * Overrides for Emacs so that we follow Linus's tabbing style.
17826 + * Emacs will notice this stuff at the end of the file and automatically
17827 + * adjust the settings for this buffer only.  This must remain at the end
17828 + * of the file.
17829 + * ---------------------------------------------------------------------------
17830 + * Local variables:
17831 + * c-file-style: "linux"
17832 + * End:
17833 + */
17834 diff -Naur -X ../exclude-files orig/arch/um/include/um_uaccess.h um/arch/um/include/um_uaccess.h
17835 --- orig/arch/um/include/um_uaccess.h   1969-12-31 19:00:00.000000000 -0500
17836 +++ um/arch/um/include/um_uaccess.h     2003-10-21 03:26:06.000000000 -0400
17837 @@ -0,0 +1,124 @@
17838 +/* 
17839 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
17840 + * Licensed under the GPL
17841 + */
17842 +
17843 +#ifndef __ARCH_UM_UACCESS_H
17844 +#define __ARCH_UM_UACCESS_H
17845 +
17846 +#include "linux/config.h"
17847 +#include "choose-mode.h"
17848 +
17849 +#ifdef CONFIG_MODE_TT
17850 +#include "../kernel/tt/include/uaccess.h"
17851 +#endif
17852 +
17853 +#ifdef CONFIG_MODE_SKAS
17854 +#include "../kernel/skas/include/uaccess.h"
17855 +#endif
17856 +
17857 +#define access_ok(type, addr, size) \
17858 +       CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
17859 +
17860 +static inline int verify_area(int type, const void * addr, unsigned long size)
17861 +{
17862 +       return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
17863 +                               size));
17864 +}
17865 +
17866 +static inline int copy_from_user(void *to, const void *from, int n)
17867 +{
17868 +       return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
17869 +                               from, n));
17870 +}
17871 +
17872 +static inline int copy_to_user(void *to, const void *from, int n)
17873 +{
17874 +       return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to, 
17875 +                               from, n));
17876 +}
17877 +
17878 +/*
17879 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
17880 + * @dst:   Destination address, in kernel space.  This buffer must be at
17881 + *         least @count bytes long.
17882 + * @src:   Source address, in user space.
17883 + * @count: Maximum number of bytes to copy, including the trailing NUL.
17884 + * 
17885 + * Copies a NUL-terminated string from userspace to kernel space.
17886 + *
17887 + * On success, returns the length of the string (not including the trailing
17888 + * NUL).
17889 + *
17890 + * If access to userspace fails, returns -EFAULT (some data may have been
17891 + * copied).
17892 + *
17893 + * If @count is smaller than the length of the string, copies @count bytes
17894 + * and returns @count.
17895 + */
17896 +
17897 +static inline int strncpy_from_user(char *dst, const char *src, int count)
17898 +{
17899 +       return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
17900 +                               dst, src, count));
17901 +}
17902 +
17903 +/*
17904 + * __clear_user: - Zero a block of memory in user space, with less checking.
17905 + * @to:   Destination address, in user space.
17906 + * @n:    Number of bytes to zero.
17907 + *
17908 + * Zero a block of memory in user space.  Caller must check
17909 + * the specified block with access_ok() before calling this function.
17910 + *
17911 + * Returns number of bytes that could not be cleared.
17912 + * On success, this will be zero.
17913 + */
17914 +static inline int __clear_user(void *mem, int len)
17915 +{
17916 +       return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
17917 +}
17918 +
17919 +/*
17920 + * clear_user: - Zero a block of memory in user space.
17921 + * @to:   Destination address, in user space.
17922 + * @n:    Number of bytes to zero.
17923 + *
17924 + * Zero a block of memory in user space.
17925 + *
17926 + * Returns number of bytes that could not be cleared.
17927 + * On success, this will be zero.
17928 + */
17929 +static inline int clear_user(void *mem, int len)
17930 +{
17931 +       return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
17932 +}
17933 +
17934 +/*
17935 + * strlen_user: - Get the size of a string in user space.
17936 + * @str: The string to measure.
17937 + * @n:   The maximum valid length
17938 + *
17939 + * Get the size of a NUL-terminated string in user space.
17940 + *
17941 + * Returns the size of the string INCLUDING the terminating NUL.
17942 + * On exception, returns 0.
17943 + * If the string is too long, returns a value greater than @n.
17944 + */
17945 +static inline int strnlen_user(const void *str, int len)
17946 +{
17947 +       return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
17948 +}
17949 +
17950 +#endif
17951 +
17952 +/*
17953 + * Overrides for Emacs so that we follow Linus's tabbing style.
17954 + * Emacs will notice this stuff at the end of the file and automatically
17955 + * adjust the settings for this buffer only.  This must remain at the end
17956 + * of the file.
17957 + * ---------------------------------------------------------------------------
17958 + * Local variables:
17959 + * c-file-style: "linux"
17960 + * End:
17961 + */
17962 diff -Naur -X ../exclude-files orig/arch/um/include/user.h um/arch/um/include/user.h
17963 --- orig/arch/um/include/user.h 1969-12-31 19:00:00.000000000 -0500
17964 +++ um/arch/um/include/user.h   2003-10-21 03:26:06.000000000 -0400
17965 @@ -0,0 +1,29 @@
17966 +/* 
17967 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
17968 + * Licensed under the GPL
17969 + */
17970 +
17971 +#ifndef __USER_H__
17972 +#define __USER_H__
17973 +
17974 +extern void panic(const char *fmt, ...);
17975 +extern int printk(const char *fmt, ...);
17976 +extern void schedule(void);
17977 +extern void *um_kmalloc(int size);
17978 +extern void *um_kmalloc_atomic(int size);
17979 +extern void kfree(void *ptr);
17980 +extern int in_aton(char *str);
17981 +extern int open_gdb_chan(void);
17982 +
17983 +#endif
17984 +
17985 +/*
17986 + * Overrides for Emacs so that we follow Linus's tabbing style.
17987 + * Emacs will notice this stuff at the end of the file and automatically
17988 + * adjust the settings for this buffer only.  This must remain at the end
17989 + * of the file.
17990 + * ---------------------------------------------------------------------------
17991 + * Local variables:
17992 + * c-file-style: "linux"
17993 + * End:
17994 + */
17995 diff -Naur -X ../exclude-files orig/arch/um/include/user_util.h um/arch/um/include/user_util.h
17996 --- orig/arch/um/include/user_util.h    1969-12-31 19:00:00.000000000 -0500
17997 +++ um/arch/um/include/user_util.h      2003-11-09 11:36:31.000000000 -0500
17998 @@ -0,0 +1,103 @@
17999 +/* 
18000 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
18001 + * Licensed under the GPL
18002 + */
18003 +
18004 +#ifndef __USER_UTIL_H__
18005 +#define __USER_UTIL_H__
18006 +
18007 +#include "sysdep/ptrace.h"
18008 +
18009 +extern int mode_tt;
18010 +
18011 +extern int grantpt(int __fd);
18012 +extern int unlockpt(int __fd);
18013 +extern char *ptsname(int __fd);
18014 +
18015 +struct cpu_task {
18016 +       int pid;
18017 +       void *task;
18018 +};
18019 +
18020 +extern struct cpu_task cpu_tasks[];
18021 +
18022 +struct signal_info {
18023 +       void (*handler)(int, union uml_pt_regs *);
18024 +       int is_irq;
18025 +};
18026 +
18027 +extern struct signal_info sig_info[];
18028 +
18029 +extern unsigned long low_physmem;
18030 +extern unsigned long high_physmem;
18031 +extern unsigned long uml_physmem;
18032 +extern unsigned long uml_reserved;
18033 +extern unsigned long end_vm;
18034 +extern unsigned long start_vm;
18035 +extern unsigned long highmem;
18036 +
18037 +extern char host_info[];
18038 +
18039 +extern char saved_command_line[];
18040 +extern char command_line[];
18041 +
18042 +extern char *tempdir;
18043 +
18044 +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
18045 +extern unsigned long _unprotected_end;
18046 +extern unsigned long brk_start;
18047 +
18048 +extern int pty_output_sigio;
18049 +extern int pty_close_sigio;
18050 +
18051 +extern void stop(void);
18052 +extern void stack_protections(unsigned long address);
18053 +extern void task_protections(unsigned long address);
18054 +extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
18055 +extern void *add_signal_handler(int sig, void (*handler)(int));
18056 +extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
18057 +                           int clone_flags, int (*tramp)(void *));
18058 +extern int linux_main(int argc, char **argv);
18059 +extern void set_cmdline(char *cmd);
18060 +extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
18061 +extern int get_pty(void);
18062 +extern void *um_kmalloc(int size);
18063 +extern int raw(int fd, int complain);
18064 +extern int switcheroo(int fd, int prot, void *from, void *to, int size);
18065 +extern void setup_machinename(char *machine_out);
18066 +extern void setup_hostinfo(void);
18067 +extern void add_arg(char *cmd_line, char *arg);
18068 +extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
18069 +extern void init_new_thread_signals(int altstack);
18070 +extern void do_exec(int old_pid, int new_pid);
18071 +extern void tracer_panic(char *msg, ...);
18072 +extern char *get_umid(int only_if_set);
18073 +extern void do_longjmp(void *p, int val);
18074 +extern void suspend_new_thread(int fd);
18075 +extern int detach(int pid, int sig);
18076 +extern int attach(int pid);
18077 +extern void kill_child_dead(int pid);
18078 +extern int cont(int pid);
18079 +extern void check_ptrace(void);
18080 +extern void check_sigio(void);
18081 +extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
18082 +extern void write_sigio_workaround(void);
18083 +extern void arch_check_bugs(void);
18084 +extern int cpu_feature(char *what, char *buf, int len);
18085 +extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
18086 +extern int arch_fixup(unsigned long address, void *sc_ptr);
18087 +extern int can_do_skas(void);
18088 +extern void arch_init_thread(void);
18089 +
18090 +#endif
18091 +
18092 +/*
18093 + * Overrides for Emacs so that we follow Linus's tabbing style.
18094 + * Emacs will notice this stuff at the end of the file and automatically
18095 + * adjust the settings for this buffer only.  This must remain at the end
18096 + * of the file.
18097 + * ---------------------------------------------------------------------------
18098 + * Local variables:
18099 + * c-file-style: "linux"
18100 + * End:
18101 + */
18102 diff -Naur -X ../exclude-files orig/arch/um/kernel/checksum.c um/arch/um/kernel/checksum.c
18103 --- orig/arch/um/kernel/checksum.c      1969-12-31 19:00:00.000000000 -0500
18104 +++ um/arch/um/kernel/checksum.c        2003-10-21 03:26:06.000000000 -0400
18105 @@ -0,0 +1,42 @@
18106 +#include "asm/uaccess.h"
18107 +#include "linux/errno.h"
18108 +
18109 +extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
18110 +
18111 +extern unsigned int csum_partial(char *buff, int len, int sum)
18112 +{
18113 +       return(arch_csum_partial(buff, len, sum));
18114 +}
18115 +
18116 +unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
18117 +                                 int sum, int *err_ptr)
18118 +{
18119 +       if(copy_to_user(dst, src, len)){
18120 +               *err_ptr = -EFAULT;
18121 +               return(-1);
18122 +       }
18123 +
18124 +       return(arch_csum_partial(src, len, sum));
18125 +}
18126 +
18127 +unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
18128 +                                   int sum, int *err_ptr)
18129 +{
18130 +       if(copy_from_user(dst, src, len)){
18131 +               *err_ptr = -EFAULT;
18132 +               return(-1);
18133 +       }
18134 +
18135 +       return(arch_csum_partial(dst, len, sum));
18136 +}
18137 +
18138 +/*
18139 + * Overrides for Emacs so that we follow Linus's tabbing style.
18140 + * Emacs will notice this stuff at the end of the file and automatically
18141 + * adjust the settings for this buffer only.  This must remain at the end
18142 + * of the file.
18143 + * ---------------------------------------------------------------------------
18144 + * Local variables:
18145 + * c-file-style: "linux"
18146 + * End:
18147 + */
18148 diff -Naur -X ../exclude-files orig/arch/um/kernel/config.c.in um/arch/um/kernel/config.c.in
18149 --- orig/arch/um/kernel/config.c.in     1969-12-31 19:00:00.000000000 -0500
18150 +++ um/arch/um/kernel/config.c.in       2003-10-21 03:26:06.000000000 -0400
18151 @@ -0,0 +1,32 @@
18152 +/* 
18153 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18154 + * Licensed under the GPL
18155 + */
18156 +
18157 +#include <stdio.h>
18158 +#include <stdlib.h>
18159 +#include "init.h"
18160 +
18161 +static __initdata char *config = "CONFIG";
18162 +
18163 +static int __init print_config(char *line, int *add)
18164 +{
18165 +       printf("%s", config);
18166 +       exit(0);
18167 +}
18168 +
18169 +__uml_setup("--showconfig", print_config,
18170 +"--showconfig\n"
18171 +"    Prints the config file that this UML binary was generated from.\n\n"
18172 +);
18173 +
18174 +/*
18175 + * Overrides for Emacs so that we follow Linus's tabbing style.
18176 + * Emacs will notice this stuff at the end of the file and automatically
18177 + * adjust the settings for this buffer only.  This must remain at the end
18178 + * of the file.
18179 + * ---------------------------------------------------------------------------
18180 + * Local variables:
18181 + * c-file-style: "linux"
18182 + * End:
18183 + */
18184 diff -Naur -X ../exclude-files orig/arch/um/kernel/exec_kern.c um/arch/um/kernel/exec_kern.c
18185 --- orig/arch/um/kernel/exec_kern.c     1969-12-31 19:00:00.000000000 -0500
18186 +++ um/arch/um/kernel/exec_kern.c       2003-10-21 03:26:06.000000000 -0400
18187 @@ -0,0 +1,86 @@
18188 +/* 
18189 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
18190 + * Licensed under the GPL
18191 + */
18192 +
18193 +#include "linux/slab.h"
18194 +#include "linux/smp_lock.h"
18195 +#include "asm/ptrace.h"
18196 +#include "asm/pgtable.h"
18197 +#include "asm/pgalloc.h"
18198 +#include "asm/uaccess.h"
18199 +#include "user_util.h"
18200 +#include "kern_util.h"
18201 +#include "mem_user.h"
18202 +#include "kern.h"
18203 +#include "irq_user.h"
18204 +#include "tlb.h"
18205 +#include "2_5compat.h"
18206 +#include "os.h"
18207 +#include "time_user.h"
18208 +#include "choose-mode.h"
18209 +#include "mode_kern.h"
18210 +
18211 +void flush_thread(void)
18212 +{
18213 +       CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
18214 +}
18215 +
18216 +void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
18217 +{
18218 +       CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
18219 +}
18220 +
18221 +extern void log_exec(char **argv, void *tty);
18222 +
18223 +static int execve1(char *file, char **argv, char **env)
18224 +{
18225 +        int error;
18226 +
18227 +#ifdef CONFIG_TTY_LOG
18228 +       log_exec(argv, current->tty);
18229 +#endif
18230 +        error = do_execve(file, argv, env, &current->thread.regs);
18231 +        if (error == 0){
18232 +                current->ptrace &= ~PT_DTRACE;
18233 +                set_cmdline(current_cmd());
18234 +        }
18235 +        return(error);
18236 +}
18237 +
18238 +int um_execve(char *file, char **argv, char **env)
18239 +{
18240 +       int err;
18241 +
18242 +       err = execve1(file, argv, env);
18243 +       if(!err) 
18244 +               do_longjmp(current->thread.exec_buf, 1);
18245 +       return(err);
18246 +}
18247 +
18248 +int sys_execve(char *file, char **argv, char **env)
18249 +{
18250 +       int error;
18251 +       char *filename;
18252 +
18253 +       lock_kernel();
18254 +       filename = getname((char *) file);
18255 +       error = PTR_ERR(filename);
18256 +       if (IS_ERR(filename)) goto out;
18257 +       error = execve1(filename, argv, env);
18258 +       putname(filename);
18259 + out:
18260 +       unlock_kernel();
18261 +       return(error);
18262 +}
18263 +
18264 +/*
18265 + * Overrides for Emacs so that we follow Linus's tabbing style.
18266 + * Emacs will notice this stuff at the end of the file and automatically
18267 + * adjust the settings for this buffer only.  This must remain at the end
18268 + * of the file.
18269 + * ---------------------------------------------------------------------------
18270 + * Local variables:
18271 + * c-file-style: "linux"
18272 + * End:
18273 + */
18274 diff -Naur -X ../exclude-files orig/arch/um/kernel/exitcode.c um/arch/um/kernel/exitcode.c
18275 --- orig/arch/um/kernel/exitcode.c      1969-12-31 19:00:00.000000000 -0500
18276 +++ um/arch/um/kernel/exitcode.c        2003-10-21 03:26:06.000000000 -0400
18277 @@ -0,0 +1,73 @@
18278 +/* 
18279 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18280 + * Licensed under the GPL
18281 + */
18282 +
18283 +#include "linux/init.h"
18284 +#include "linux/ctype.h"
18285 +#include "linux/proc_fs.h"
18286 +#include "asm/uaccess.h"
18287 +
18288 +/* If read and write race, the read will still atomically read a valid
18289 + * value.
18290 + */
18291 +int uml_exitcode = 0;
18292 +
18293 +static int read_proc_exitcode(char *page, char **start, off_t off,
18294 +                             int count, int *eof, void *data)
18295 +{
18296 +       int len;
18297 +
18298 +       len = sprintf(page, "%d\n", uml_exitcode);
18299 +       len -= off;
18300 +       if(len <= off+count) *eof = 1;
18301 +       *start = page + off;
18302 +       if(len > count) len = count;
18303 +       if(len < 0) len = 0;
18304 +       return(len);
18305 +}
18306 +
18307 +static int write_proc_exitcode(struct file *file, const char *buffer,
18308 +                              unsigned long count, void *data)
18309 +{
18310 +       char *end, buf[sizeof("nnnnn\0")];
18311 +       int tmp;
18312 +
18313 +       if(copy_from_user(buf, buffer, count))
18314 +               return(-EFAULT);
18315 +       tmp = simple_strtol(buf, &end, 0);
18316 +       if((*end != '\0') && !isspace(*end))
18317 +               return(-EINVAL);
18318 +       uml_exitcode = tmp;
18319 +       return(count);
18320 +}
18321 +
18322 +static int make_proc_exitcode(void)
18323 +{
18324 +       struct proc_dir_entry *ent;
18325 +
18326 +       ent = create_proc_entry("exitcode", 0600, &proc_root);
18327 +       if(ent == NULL){
18328 +               printk("make_proc_exitcode : Failed to register "
18329 +                      "/proc/exitcode\n");
18330 +               return(0);
18331 +       }
18332 +
18333 +       ent->read_proc = read_proc_exitcode;
18334 +       ent->write_proc = write_proc_exitcode;
18335 +       
18336 +       return(0);
18337 +}
18338 +
18339 +__initcall(make_proc_exitcode);
18340 +
18341 +/*
18342 + * Overrides for Emacs so that we follow Linus's tabbing style.
18343 + * Emacs will notice this stuff at the end of the file and automatically
18344 + * adjust the settings for this buffer only.  This must remain at the end
18345 + * of the file.
18346 + * ---------------------------------------------------------------------------
18347 + * Local variables:
18348 + * c-file-style: "linux"
18349 + * End:
18350 + */
18351 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame.c um/arch/um/kernel/frame.c
18352 --- orig/arch/um/kernel/frame.c 1969-12-31 19:00:00.000000000 -0500
18353 +++ um/arch/um/kernel/frame.c   2003-10-21 03:26:06.000000000 -0400
18354 @@ -0,0 +1,341 @@
18355 +/* 
18356 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18357 + * Licensed under the GPL
18358 + */
18359 +
18360 +#include <stdio.h>
18361 +#include <stdlib.h>
18362 +#include <unistd.h>
18363 +#include <string.h>
18364 +#include <signal.h>
18365 +#include <wait.h>
18366 +#include <sched.h>
18367 +#include <errno.h>
18368 +#include <sys/ptrace.h>
18369 +#include <sys/syscall.h>
18370 +#include <sys/mman.h>
18371 +#include <asm/page.h>
18372 +#include <asm/ptrace.h>
18373 +#include <asm/sigcontext.h>
18374 +#include "sysdep/ptrace.h"
18375 +#include "sysdep/sigcontext.h"
18376 +#include "frame_user.h"
18377 +#include "kern_util.h"
18378 +#include "ptrace_user.h"
18379 +#include "os.h"
18380 +
18381 +static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
18382 +                        unsigned long top, void **data_out)
18383 +{
18384 +       unsigned long regs[FRAME_SIZE];
18385 +       int pid, status, n, len;
18386 +
18387 +       /* Start the child as a thread */
18388 +       pid = clone(child, sp, CLONE_VM | SIGCHLD, arg);
18389 +       if(pid < 0){
18390 +               printf("capture_stack : clone failed - errno = %d\n", errno);
18391 +               exit(1);
18392 +       }
18393 +
18394 +       /* Wait for it to stop itself and continue it with a SIGUSR1 to force 
18395 +        * it into the signal handler.
18396 +        */
18397 +       n = waitpid(pid, &status, WUNTRACED);
18398 +       if(n < 0){
18399 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
18400 +               exit(1);
18401 +       }
18402 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
18403 +               fprintf(stderr, "capture_stack : Expected SIGSTOP, "
18404 +                       "got status = 0x%x\n", status);
18405 +               exit(1);
18406 +       }
18407 +       if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){
18408 +               printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
18409 +                      errno);
18410 +               exit(1);
18411 +       }
18412 +
18413 +       /* Wait for it to stop itself again and grab its registers again.  
18414 +        * At this point, the handler has stuffed the addresses of
18415 +        * sig, sc, and SA_RESTORER in raw.
18416 +        */
18417 +       n = waitpid(pid, &status, WUNTRACED);
18418 +       if(n < 0){
18419 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
18420 +               exit(1);
18421 +       }
18422 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
18423 +               fprintf(stderr, "capture_stack : Expected SIGSTOP, "
18424 +                       "got status = 0x%x\n", status);
18425 +               exit(1);
18426 +       }
18427 +       if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){
18428 +               printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n", 
18429 +                      errno);
18430 +               exit(1);
18431 +       }
18432 +
18433 +       /* It has outlived its usefulness, so continue it so it can exit */
18434 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){
18435 +               printf("capture_stack : PTRACE_CONT failed - errno = %d\n", 
18436 +                      errno);
18437 +               exit(1);
18438 +       }
18439 +       if(waitpid(pid, &status, 0) < 0){
18440 +               printf("capture_stack : waitpid failed - errno = %d\n", errno);
18441 +               exit(1);
18442 +       }
18443 +       if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){
18444 +               printf("capture_stack : Expected exit signal 9, "
18445 +                      "got status = 0x%x\n", status);
18446 +               exit(1);
18447 +       }
18448 +
18449 +       /* The frame that we want is the top of the signal stack */
18450 +
18451 +       len = top - PT_SP(regs);
18452 +       *data_out = malloc(len);
18453 +       if(*data_out == NULL){
18454 +               printf("capture_stack : malloc failed - errno = %d\n", errno);
18455 +               exit(1);
18456 +       }
18457 +       memcpy(*data_out, (void *) PT_SP(regs), len);
18458 +
18459 +       return(len);
18460 +}
18461 +
18462 +struct common_raw {
18463 +       void *stack;
18464 +       int size;
18465 +       unsigned long sig;
18466 +       unsigned long sr;
18467 +       unsigned long sp;       
18468 +       struct arch_frame_data_raw arch;
18469 +};
18470 +
18471 +#define SA_RESTORER (0x04000000)
18472 +
18473 +typedef unsigned long old_sigset_t;
18474 +
18475 +struct old_sigaction {
18476 +       __sighandler_t handler;
18477 +       old_sigset_t sa_mask;
18478 +       unsigned long sa_flags;
18479 +       void (*sa_restorer)(void);
18480 +};
18481 +
18482 +static void child_common(struct common_raw *common, sighandler_t handler,
18483 +                        int restorer, int flags)
18484 +{
18485 +       stack_t ss = ((stack_t) { .ss_sp        = common->stack,
18486 +                                 .ss_flags     = 0,
18487 +                                 .ss_size      = common->size });
18488 +       int err;
18489 +
18490 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
18491 +               printf("PTRACE_TRACEME failed, errno = %d\n", errno);
18492 +       }
18493 +       if(sigaltstack(&ss, NULL) < 0){
18494 +               printf("sigaltstack failed - errno = %d\n", errno);
18495 +               kill(getpid(), SIGKILL);
18496 +       }
18497 +
18498 +       if(restorer){
18499 +               struct sigaction sa;
18500 +
18501 +               sa.sa_handler = handler;
18502 +               sigemptyset(&sa.sa_mask);
18503 +               sa.sa_flags = SA_ONSTACK | flags;
18504 +               err = sigaction(SIGUSR1, &sa, NULL);
18505 +       }
18506 +       else {
18507 +               struct old_sigaction sa;
18508 +
18509 +               sa.handler = handler;
18510 +               sa.sa_mask = 0;
18511 +               sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER;
18512 +               err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL);
18513 +       }
18514 +       
18515 +       if(err < 0){
18516 +               printf("sigaction failed - errno = %d\n", errno);
18517 +               kill(getpid(), SIGKILL);
18518 +       }
18519 +
18520 +       os_stop_process(os_getpid());
18521 +}
18522 +
18523 +/* Changed only during early boot */
18524 +struct sc_frame signal_frame_sc;
18525 +
18526 +struct sc_frame signal_frame_sc_sr;
18527 +
18528 +struct sc_frame_raw {
18529 +       struct common_raw common;
18530 +       unsigned long sc;
18531 +       int restorer;
18532 +};
18533 +
18534 +/* Changed only during early boot */
18535 +static struct sc_frame_raw *raw_sc = NULL;
18536 +
18537 +static void sc_handler(int sig, struct sigcontext sc)
18538 +{
18539 +       raw_sc->common.sig = (unsigned long) &sig;
18540 +       raw_sc->common.sr = frame_restorer();
18541 +       raw_sc->common.sp = frame_sp();
18542 +       raw_sc->sc = (unsigned long) &sc;
18543 +       setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
18544 +
18545 +       os_stop_process(os_getpid());
18546 +       kill(getpid(), SIGKILL);
18547 +}
18548 +
18549 +static int sc_child(void *arg)
18550 +{
18551 +       raw_sc = arg;
18552 +       child_common(&raw_sc->common, (sighandler_t) sc_handler, 
18553 +                    raw_sc->restorer, 0);
18554 +       return(-1);
18555 +}
18556 +
18557 +/* Changed only during early boot */
18558 +struct si_frame signal_frame_si;
18559 +
18560 +struct si_frame_raw {
18561 +       struct common_raw common;
18562 +       unsigned long sip;
18563 +       unsigned long si;
18564 +       unsigned long ucp;
18565 +       unsigned long uc;
18566 +};
18567 +
18568 +/* Changed only during early boot */
18569 +static struct si_frame_raw *raw_si = NULL;
18570 +
18571 +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
18572 +{
18573 +       raw_si->common.sig = (unsigned long) &sig;
18574 +       raw_si->common.sr = frame_restorer();
18575 +       raw_si->common.sp = frame_sp();
18576 +       raw_si->sip = (unsigned long) &si;
18577 +       raw_si->si = (unsigned long) si;
18578 +       raw_si->ucp = (unsigned long) &ucontext;
18579 +       raw_si->uc = (unsigned long) ucontext;
18580 +       setup_arch_frame_raw(&raw_si->common.arch, 
18581 +                            ucontext->uc_mcontext.fpregs, raw_si->common.sr);
18582 +       
18583 +       os_stop_process(os_getpid());
18584 +       kill(getpid(), SIGKILL);
18585 +}
18586 +
18587 +static int si_child(void *arg)
18588 +{
18589 +       raw_si = arg;
18590 +       child_common(&raw_si->common, (sighandler_t) si_handler, 1, 
18591 +                    SA_SIGINFO);
18592 +       return(-1);
18593 +}
18594 +
18595 +static int relative_sr(unsigned long sr, int sr_index, void *stack, 
18596 +                      void *framep)
18597 +{
18598 +       unsigned long *srp = (unsigned long *) sr;
18599 +       unsigned long frame = (unsigned long) framep;
18600 +
18601 +       if((*srp & PAGE_MASK) == (unsigned long) stack){
18602 +               *srp -= sr;
18603 +               *((unsigned long *) (frame + sr_index)) = *srp;
18604 +               return(1);
18605 +       }
18606 +       else return(0);
18607 +}
18608 +
18609 +static unsigned long capture_stack_common(int (*proc)(void *), void *arg, 
18610 +                                         struct common_raw *common_in, 
18611 +                                         void *top, void *sigstack, 
18612 +                                         int stack_len, 
18613 +                                         struct frame_common *common_out)
18614 +{
18615 +       unsigned long sig_top = (unsigned long) sigstack + stack_len, base;
18616 +
18617 +       common_in->stack = (void *) sigstack;
18618 +       common_in->size = stack_len;
18619 +       common_out->len = capture_stack(proc, arg, top, sig_top, 
18620 +                                       &common_out->data);
18621 +       base = sig_top - common_out->len;
18622 +       common_out->sig_index = common_in->sig - base;
18623 +       common_out->sp_index = common_in->sp - base;
18624 +       common_out->sr_index = common_in->sr - base;
18625 +       common_out->sr_relative = relative_sr(common_in->sr, 
18626 +                                             common_out->sr_index, sigstack, 
18627 +                                             common_out->data);
18628 +       return(base);
18629 +}
18630 +
18631 +void capture_signal_stack(void)
18632 +{
18633 +       struct sc_frame_raw raw_sc;
18634 +       struct si_frame_raw raw_si;
18635 +       void *stack, *sigstack;
18636 +       unsigned long top, base;
18637 +
18638 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
18639 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
18640 +       sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
18641 +                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
18642 +       if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){
18643 +               printf("capture_signal_stack : mmap failed - errno = %d\n", 
18644 +                      errno);
18645 +               exit(1);
18646 +       }
18647 +
18648 +       top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
18649 +
18650 +       /* Get the sigcontext, no sigrestorer layout */
18651 +       raw_sc.restorer = 0;
18652 +       base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
18653 +                                   (void *) top, sigstack, PAGE_SIZE, 
18654 +                                   &signal_frame_sc.common);
18655 +
18656 +       signal_frame_sc.sc_index = raw_sc.sc - base;
18657 +       setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
18658 +
18659 +       /* Ditto for the sigcontext, sigrestorer layout */
18660 +       raw_sc.restorer = 1;
18661 +       base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, 
18662 +                                   (void *) top, sigstack, PAGE_SIZE, 
18663 +                                   &signal_frame_sc_sr.common);
18664 +       signal_frame_sc_sr.sc_index = raw_sc.sc - base;
18665 +       setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
18666 +
18667 +       /* And the siginfo layout */
18668 +
18669 +       base = capture_stack_common(si_child, &raw_si, &raw_si.common, 
18670 +                                   (void *) top, sigstack, PAGE_SIZE, 
18671 +                                   &signal_frame_si.common);
18672 +       signal_frame_si.sip_index = raw_si.sip - base;
18673 +       signal_frame_si.si_index = raw_si.si - base;
18674 +       signal_frame_si.ucp_index = raw_si.ucp - base;
18675 +       signal_frame_si.uc_index = raw_si.uc - base;
18676 +       setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
18677 +
18678 +       if((munmap(stack, PAGE_SIZE) < 0) || 
18679 +          (munmap(sigstack, PAGE_SIZE) < 0)){
18680 +               printf("capture_signal_stack : munmap failed - errno = %d\n", 
18681 +                      errno);
18682 +               exit(1);
18683 +       }
18684 +}
18685 +
18686 +/*
18687 + * Overrides for Emacs so that we follow Linus's tabbing style.
18688 + * Emacs will notice this stuff at the end of the file and automatically
18689 + * adjust the settings for this buffer only.  This must remain at the end
18690 + * of the file.
18691 + * ---------------------------------------------------------------------------
18692 + * Local variables:
18693 + * c-file-style: "linux"
18694 + * End:
18695 + */
18696 diff -Naur -X ../exclude-files orig/arch/um/kernel/frame_kern.c um/arch/um/kernel/frame_kern.c
18697 --- orig/arch/um/kernel/frame_kern.c    1969-12-31 19:00:00.000000000 -0500
18698 +++ um/arch/um/kernel/frame_kern.c      2003-11-19 03:32:43.000000000 -0500
18699 @@ -0,0 +1,174 @@
18700 +/* 
18701 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18702 + * Licensed under the GPL
18703 + */
18704 +
18705 +#include "asm/ptrace.h"
18706 +#include "asm/uaccess.h"
18707 +#include "asm/signal.h"
18708 +#include "asm/uaccess.h"
18709 +#include "asm/ucontext.h"
18710 +#include "frame_kern.h"
18711 +#include "sigcontext.h"
18712 +#include "sysdep/ptrace.h"
18713 +#include "choose-mode.h"
18714 +#include "mode.h"
18715 +
18716 +int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
18717 +{
18718 +       if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
18719 +               return -EFAULT;
18720 +       if (from->si_code < 0)
18721 +               return __copy_to_user(to, from, sizeof(siginfo_t));
18722 +       else {
18723 +               int err;
18724 +
18725 +               /* If you change siginfo_t structure, please be sure
18726 +                  this code is fixed accordingly.
18727 +                  It should never copy any pad contained in the structure
18728 +                  to avoid security leaks, but must copy the generic
18729 +                  3 ints plus the relevant union member.  */
18730 +               err = __put_user(from->si_signo, &to->si_signo);
18731 +               err |= __put_user(from->si_errno, &to->si_errno);
18732 +               err |= __put_user((short)from->si_code, &to->si_code);
18733 +               /* First 32bits of unions are always present.  */
18734 +               err |= __put_user(from->si_pid, &to->si_pid);
18735 +               switch (from->si_code >> 16) {
18736 +               case __SI_FAULT >> 16:
18737 +                       break;
18738 +               case __SI_CHLD >> 16:
18739 +                       err |= __put_user(from->si_utime, &to->si_utime);
18740 +                       err |= __put_user(from->si_stime, &to->si_stime);
18741 +                       err |= __put_user(from->si_status, &to->si_status);
18742 +               default:
18743 +                       err |= __put_user(from->si_uid, &to->si_uid);
18744 +                       break;
18745 +               }
18746 +               return err;
18747 +       }
18748 +}
18749 +
18750 +static int copy_restorer(void (*restorer)(void), unsigned long start, 
18751 +                        unsigned long sr_index, int sr_relative)
18752 +{
18753 +       unsigned long sr;
18754 +
18755 +       if(sr_relative){
18756 +               sr = (unsigned long) restorer;
18757 +               sr += start + sr_index;
18758 +               restorer = (void (*)(void)) sr;
18759 +       }
18760 +
18761 +       return(copy_to_user((void *) (start + sr_index), &restorer, 
18762 +                           sizeof(restorer)));
18763 +}
18764 +
18765 +extern int userspace_pid[];
18766 +
18767 +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
18768 +                          struct arch_frame_data *arch)
18769 +{
18770 +       return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
18771 +                                             arch),
18772 +                          copy_sc_to_user_skas(userspace_pid[0], to, fp, 
18773 +                                               &from->regs,
18774 +                                               current->thread.cr2,
18775 +                                               current->thread.err)));
18776 +}
18777 +
18778 +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
18779 +                                unsigned long sp)
18780 +{
18781 +       int err = 0;
18782 +
18783 +       err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
18784 +       err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
18785 +       err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
18786 +       err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs,
18787 +                              &signal_frame_si.common.arch);
18788 +       err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
18789 +       return(err);
18790 +}
18791 +
18792 +int setup_signal_stack_si(unsigned long stack_top, int sig, 
18793 +                         unsigned long handler, void (*restorer)(void), 
18794 +                         struct pt_regs *regs, siginfo_t *info, 
18795 +                         sigset_t *mask)
18796 +{
18797 +       unsigned long start;
18798 +       void *sip, *ucp, *fp;
18799 +
18800 +       start = stack_top - signal_frame_si.common.len;
18801 +       sip = (void *) (start + signal_frame_si.si_index);
18802 +       ucp = (void *) (start + signal_frame_si.uc_index);
18803 +       fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
18804 +
18805 +       if(restorer == NULL)
18806 +               panic("setup_signal_stack_si - no restorer");
18807 +
18808 +       if(copy_to_user((void *) start, signal_frame_si.common.data,
18809 +                       signal_frame_si.common.len) ||
18810 +          copy_to_user((void *) (start + signal_frame_si.common.sig_index), 
18811 +                       &sig, sizeof(sig)) ||
18812 +          copy_siginfo_to_user(sip, info) ||
18813 +          copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
18814 +                       sizeof(sip)) ||
18815 +          copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
18816 +          copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
18817 +                       sizeof(ucp)) ||
18818 +          copy_restorer(restorer, start, signal_frame_si.common.sr_index,
18819 +                        signal_frame_si.common.sr_relative))
18820 +               return(1);
18821 +       
18822 +       PT_REGS_IP(regs) = handler;
18823 +       PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
18824 +       return(0);
18825 +}
18826 +
18827 +int setup_signal_stack_sc(unsigned long stack_top, int sig, 
18828 +                         unsigned long handler, void (*restorer)(void), 
18829 +                         struct pt_regs *regs, sigset_t *mask)
18830 +{
18831 +       struct frame_common *frame = &signal_frame_sc_sr.common;
18832 +       void *user_sc;
18833 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
18834 +       unsigned long sigs, sr;
18835 +       unsigned long start = stack_top - frame->len - sig_size;
18836 +
18837 +       user_sc = (void *) (start + signal_frame_sc_sr.sc_index);
18838 +       if(restorer == NULL){
18839 +               frame = &signal_frame_sc.common;
18840 +               user_sc = (void *) (start + signal_frame_sc.sc_index);
18841 +               sr = (unsigned long) frame->data;
18842 +               sr += frame->sr_index;
18843 +               sr = *((unsigned long *) sr);
18844 +               restorer = ((void (*)(void)) sr);
18845 +       }
18846 +
18847 +       sigs = start + frame->len;
18848 +       if(copy_to_user((void *) start, frame->data, frame->len) ||
18849 +          copy_to_user((void *) (start + frame->sig_index), &sig, 
18850 +                       sizeof(sig)) ||
18851 +          copy_sc_to_user(user_sc, NULL, regs, 
18852 +                          &signal_frame_sc.common.arch) ||
18853 +          copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
18854 +          copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
18855 +          copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
18856 +               return(1);
18857 +
18858 +       PT_REGS_IP(regs) = handler;
18859 +       PT_REGS_SP(regs) = start + frame->sp_index;
18860 +
18861 +       return(0);
18862 +}
18863 +
18864 +/*
18865 + * Overrides for Emacs so that we follow Linus's tabbing style.
18866 + * Emacs will notice this stuff at the end of the file and automatically
18867 + * adjust the settings for this buffer only.  This must remain at the end
18868 + * of the file.
18869 + * ---------------------------------------------------------------------------
18870 + * Local variables:
18871 + * c-file-style: "linux"
18872 + * End:
18873 + */
18874 diff -Naur -X ../exclude-files orig/arch/um/kernel/gmon_syms.c um/arch/um/kernel/gmon_syms.c
18875 --- orig/arch/um/kernel/gmon_syms.c     1969-12-31 19:00:00.000000000 -0500
18876 +++ um/arch/um/kernel/gmon_syms.c       2003-10-21 03:26:06.000000000 -0400
18877 @@ -0,0 +1,20 @@
18878 +/* 
18879 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18880 + * Licensed under the GPL
18881 + */
18882 +
18883 +#include "linux/module.h"
18884 +
18885 +extern void __bb_init_func(void *);
18886 +EXPORT_SYMBOL(__bb_init_func);
18887 +
18888 +/*
18889 + * Overrides for Emacs so that we follow Linus's tabbing style.
18890 + * Emacs will notice this stuff at the end of the file and automatically
18891 + * adjust the settings for this buffer only.  This must remain at the end
18892 + * of the file.
18893 + * ---------------------------------------------------------------------------
18894 + * Local variables:
18895 + * c-file-style: "linux"
18896 + * End:
18897 + */
18898 diff -Naur -X ../exclude-files orig/arch/um/kernel/gprof_syms.c um/arch/um/kernel/gprof_syms.c
18899 --- orig/arch/um/kernel/gprof_syms.c    1969-12-31 19:00:00.000000000 -0500
18900 +++ um/arch/um/kernel/gprof_syms.c      2003-10-21 03:26:06.000000000 -0400
18901 @@ -0,0 +1,20 @@
18902 +/* 
18903 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
18904 + * Licensed under the GPL
18905 + */
18906 +
18907 +#include "linux/module.h"
18908 +
18909 +extern void mcount(void);
18910 +EXPORT_SYMBOL(mcount);
18911 +
18912 +/*
18913 + * Overrides for Emacs so that we follow Linus's tabbing style.
18914 + * Emacs will notice this stuff at the end of the file and automatically
18915 + * adjust the settings for this buffer only.  This must remain at the end
18916 + * of the file.
18917 + * ---------------------------------------------------------------------------
18918 + * Local variables:
18919 + * c-file-style: "linux"
18920 + * End:
18921 + */
18922 diff -Naur -X ../exclude-files orig/arch/um/kernel/helper.c um/arch/um/kernel/helper.c
18923 --- orig/arch/um/kernel/helper.c        1969-12-31 19:00:00.000000000 -0500
18924 +++ um/arch/um/kernel/helper.c  2003-11-08 07:41:30.000000000 -0500
18925 @@ -0,0 +1,170 @@
18926 +/* 
18927 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18928 + * Licensed under the GPL
18929 + */
18930 +
18931 +#include <stdio.h>
18932 +#include <stdlib.h>
18933 +#include <unistd.h>
18934 +#include <errno.h>
18935 +#include <sched.h>
18936 +#include <sys/signal.h>
18937 +#include <sys/wait.h>
18938 +#include "user.h"
18939 +#include "kern_util.h"
18940 +#include "os.h"
18941 +
18942 +struct helper_data {
18943 +       void (*pre_exec)(void*);
18944 +       void *pre_data;
18945 +       char **argv;
18946 +       int fd;
18947 +};
18948 +
18949 +/* Debugging aid, changed only from gdb */
18950 +int helper_pause = 0;
18951 +
18952 +static void helper_hup(int sig)
18953 +{
18954 +}
18955 +
18956 +static int helper_child(void *arg)
18957 +{
18958 +       struct helper_data *data = arg;
18959 +       char **argv = data->argv;
18960 +       int errval;
18961 +
18962 +       if(helper_pause){
18963 +               signal(SIGHUP, helper_hup);
18964 +               pause();
18965 +       }
18966 +       if(data->pre_exec != NULL)
18967 +               (*data->pre_exec)(data->pre_data);
18968 +       execvp(argv[0], argv);
18969 +       errval = errno;
18970 +       printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
18971 +       os_write_file(data->fd, &errval, sizeof(errval));
18972 +       os_kill_process(os_getpid(), 0);
18973 +       return(0);
18974 +}
18975 +
18976 +/* XXX The alloc_stack here breaks if this is called in the tracing thread */
18977 +
18978 +int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
18979 +              unsigned long *stack_out)
18980 +{
18981 +       struct helper_data data;
18982 +       unsigned long stack, sp;
18983 +       int pid, fds[2], err, n;
18984 +
18985 +       if((stack_out != NULL) && (*stack_out != 0))
18986 +               stack = *stack_out;
18987 +       else stack = alloc_stack(0, um_in_interrupt());
18988 +       if(stack == 0) 
18989 +               return(-ENOMEM);
18990 +
18991 +       err = os_pipe(fds, 1, 0);
18992 +       if(err < 0){
18993 +               printk("run_helper : pipe failed, err = %d\n", -err);
18994 +               goto out_free;
18995 +       }
18996 +
18997 +       err = os_set_exec_close(fds[1], 1);
18998 +       if(err < 0){
18999 +               printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
19000 +                      -err);
19001 +               goto out_close;
19002 +       }
19003 +
19004 +       sp = stack + page_size() - sizeof(void *);
19005 +       data.pre_exec = pre_exec;
19006 +       data.pre_data = pre_data;
19007 +       data.argv = argv;
19008 +       data.fd = fds[1];
19009 +       pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
19010 +       if(pid < 0){
19011 +               printk("run_helper : clone failed, errno = %d\n", errno);
19012 +               err = -errno;
19013 +               goto out_close;
19014 +       }
19015 +
19016 +       os_close_file(fds[1]);
19017 +       n = os_read_file(fds[0], &err, sizeof(err));
19018 +       if(n < 0){
19019 +               printk("run_helper : read on pipe failed, err = %d\n", -n);
19020 +               err = n;
19021 +               goto out_kill;
19022 +       }
19023 +       else if(n != 0){
19024 +               waitpid(pid, NULL, 0);
19025 +               pid = -errno;
19026 +       }
19027 +
19028 +       if(stack_out == NULL) free_stack(stack, 0);
19029 +        else *stack_out = stack;
19030 +       return(pid);
19031 +
19032 + out_kill:
19033 +       os_kill_process(pid, 1);
19034 + out_close:
19035 +       os_close_file(fds[0]);
19036 +       os_close_file(fds[1]);
19037 + out_free:
19038 +       free_stack(stack, 0);
19039 +       return(err);
19040 +}
19041 +
19042 +int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
19043 +                     unsigned long *stack_out, int stack_order)
19044 +{
19045 +       unsigned long stack, sp;
19046 +       int pid, status;
19047 +
19048 +       stack = alloc_stack(stack_order, um_in_interrupt());
19049 +       if(stack == 0) return(-ENOMEM);
19050 +
19051 +       sp = stack + (page_size() << stack_order) - sizeof(void *);
19052 +       pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
19053 +       if(pid < 0){
19054 +               printk("run_helper_thread : clone failed, errno = %d\n", 
19055 +                      errno);
19056 +               return(-errno);
19057 +       }
19058 +       if(stack_out == NULL){
19059 +               pid = waitpid(pid, &status, 0);
19060 +               if(pid < 0){
19061 +                       printk("run_helper_thread - wait failed, errno = %d\n",
19062 +                              errno);
19063 +                       pid = -errno;
19064 +               }
19065 +               if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
19066 +                       printk("run_helper_thread - thread returned status "
19067 +                              "0x%x\n", status);
19068 +               free_stack(stack, stack_order);
19069 +       }
19070 +        else *stack_out = stack;
19071 +       return(pid);
19072 +}
19073 +
19074 +int helper_wait(int pid, int block)
19075 +{
19076 +       int ret;
19077 +
19078 +       ret = waitpid(pid, NULL, WNOHANG);
19079 +       if(ret < 0){
19080 +               printk("helper_wait : waitpid failed, errno = %d\n", errno);
19081 +               return(-errno);
19082 +       }
19083 +       return(ret);
19084 +}
19085 +
19086 +/*
19087 + * Overrides for Emacs so that we follow Linus's tabbing style.
19088 + * Emacs will notice this stuff at the end of the file and automatically
19089 + * adjust the settings for this buffer only.  This must remain at the end
19090 + * of the file.
19091 + * ---------------------------------------------------------------------------
19092 + * Local variables:
19093 + * c-file-style: "linux"
19094 + * End:
19095 + */
19096 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_kern.c um/arch/um/kernel/initrd_kern.c
19097 --- orig/arch/um/kernel/initrd_kern.c   1969-12-31 19:00:00.000000000 -0500
19098 +++ um/arch/um/kernel/initrd_kern.c     2003-10-21 03:26:06.000000000 -0400
19099 @@ -0,0 +1,59 @@
19100 +/*
19101 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
19102 + * Licensed under the GPL
19103 + */
19104 +
19105 +#include "linux/init.h"
19106 +#include "linux/bootmem.h"
19107 +#include "linux/blk.h"
19108 +#include "asm/types.h"
19109 +#include "user_util.h"
19110 +#include "kern_util.h"
19111 +#include "initrd.h"
19112 +#include "init.h"
19113 +#include "os.h"
19114 +
19115 +/* Changed by uml_initrd_setup, which is a setup */
19116 +static char *initrd __initdata = NULL;
19117 +
19118 +static int __init read_initrd(void)
19119 +{
19120 +       void *area;
19121 +       long long size;
19122 +       int err;
19123 +
19124 +       if(initrd == NULL) return 0;
19125 +       err = os_file_size(initrd, &size);
19126 +       if(err) return 0;
19127 +       area = alloc_bootmem(size);
19128 +       if(area == NULL) return 0;
19129 +       if(load_initrd(initrd, area, size) == -1) return 0;
19130 +       initrd_start = (unsigned long) area;
19131 +       initrd_end = initrd_start + size;
19132 +       return 0;
19133 +}
19134 +
19135 +__uml_postsetup(read_initrd);
19136 +
19137 +static int __init uml_initrd_setup(char *line, int *add)
19138 +{
19139 +       initrd = line;
19140 +       return 0;
19141 +}
19142 +
19143 +__uml_setup("initrd=", uml_initrd_setup, 
19144 +"initrd=<initrd image>\n"
19145 +"    This is used to boot UML from an initrd image.  The argument is the\n"
19146 +"    name of the file containing the image.\n\n"
19147 +);
19148 +
19149 +/*
19150 + * Overrides for Emacs so that we follow Linus's tabbing style.
19151 + * Emacs will notice this stuff at the end of the file and automatically
19152 + * adjust the settings for this buffer only.  This must remain at the end
19153 + * of the file.
19154 + * ---------------------------------------------------------------------------
19155 + * Local variables:
19156 + * c-file-style: "linux"
19157 + * End:
19158 + */
19159 diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_user.c um/arch/um/kernel/initrd_user.c
19160 --- orig/arch/um/kernel/initrd_user.c   1969-12-31 19:00:00.000000000 -0500
19161 +++ um/arch/um/kernel/initrd_user.c     2003-10-21 03:26:06.000000000 -0400
19162 @@ -0,0 +1,44 @@
19163 +/*
19164 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
19165 + * Licensed under the GPL
19166 + */
19167 +
19168 +#include <unistd.h>
19169 +#include <sys/types.h>
19170 +#include <sys/stat.h>
19171 +#include <errno.h>
19172 +
19173 +#include "user_util.h"
19174 +#include "kern_util.h"
19175 +#include "user.h"
19176 +#include "initrd.h"
19177 +#include "os.h"
19178 +
19179 +int load_initrd(char *filename, void *buf, int size)
19180 +{
19181 +       int fd, n;
19182 +
19183 +       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
19184 +       if(fd < 0){
19185 +               printk("Opening '%s' failed - err = %d\n", filename, -fd);
19186 +               return(-1);
19187 +       }
19188 +       n = os_read_file(fd, buf, size);
19189 +       if(n != size){
19190 +               printk("Read of %d bytes from '%s' failed, err = %d\n", size, 
19191 +                      filename, -n);
19192 +               return(-1);
19193 +       }
19194 +       return(0);
19195 +}
19196 +
19197 +/*
19198 + * Overrides for Emacs so that we follow Linus's tabbing style.
19199 + * Emacs will notice this stuff at the end of the file and automatically
19200 + * adjust the settings for this buffer only.  This must remain at the end
19201 + * of the file.
19202 + * ---------------------------------------------------------------------------
19203 + * Local variables:
19204 + * c-file-style: "linux"
19205 + * End:
19206 + */
19207 diff -Naur -X ../exclude-files orig/arch/um/kernel/init_task.c um/arch/um/kernel/init_task.c
19208 --- orig/arch/um/kernel/init_task.c     1969-12-31 19:00:00.000000000 -0500
19209 +++ um/arch/um/kernel/init_task.c       2003-10-21 03:26:06.000000000 -0400
19210 @@ -0,0 +1,61 @@
19211 +/* 
19212 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19213 + * Licensed under the GPL
19214 + */
19215 +
19216 +#include "linux/config.h"
19217 +#include "linux/mm.h"
19218 +#include "linux/sched.h"
19219 +#include "linux/version.h"
19220 +#include "asm/uaccess.h"
19221 +#include "asm/pgtable.h"
19222 +#include "user_util.h"
19223 +#include "mem_user.h"
19224 +
19225 +static struct fs_struct init_fs = INIT_FS;
19226 +static struct files_struct init_files = INIT_FILES;
19227 +static struct signal_struct init_signals = INIT_SIGNALS;
19228 +struct mm_struct init_mm = INIT_MM(init_mm);
19229 +
19230 +/*
19231 + * Initial task structure.
19232 + *
19233 + * We need to make sure that this is 16384-byte aligned due to the
19234 + * way process stacks are handled. This is done by having a special
19235 + * "init_task" linker map entry..
19236 + */
19237 +
19238 +union task_union init_task_union 
19239 +__attribute__((__section__(".data.init_task"))) = 
19240 +{ INIT_TASK(init_task_union.task) };
19241 +
19242 +struct task_struct *alloc_task_struct(void)
19243 +{
19244 +       return((struct task_struct *) 
19245 +              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
19246 +}
19247 +
19248 +void unprotect_stack(unsigned long stack)
19249 +{
19250 +       protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
19251 +                      1, 1, 0, 1);
19252 +}
19253 +
19254 +void free_task_struct(struct task_struct *task)
19255 +{
19256 +       /* free_pages decrements the page counter and only actually frees
19257 +        * the pages if they are now not accessed by anything.
19258 +        */
19259 +       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
19260 +}
19261 +
19262 +/*
19263 + * Overrides for Emacs so that we follow Linus's tabbing style.
19264 + * Emacs will notice this stuff at the end of the file and automatically
19265 + * adjust the settings for this buffer only.  This must remain at the end
19266 + * of the file.
19267 + * ---------------------------------------------------------------------------
19268 + * Local variables:
19269 + * c-file-style: "linux"
19270 + * End:
19271 + */
19272 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq.c um/arch/um/kernel/irq.c
19273 --- orig/arch/um/kernel/irq.c   1969-12-31 19:00:00.000000000 -0500
19274 +++ um/arch/um/kernel/irq.c     2003-12-16 22:45:27.000000000 -0500
19275 @@ -0,0 +1,840 @@
19276 +/* 
19277 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
19278 + * Licensed under the GPL
19279 + * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
19280 + *     Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
19281 + */
19282 +
19283 +#include "linux/config.h"
19284 +#include "linux/kernel.h"
19285 +#include "linux/smp.h"
19286 +#include "linux/irq.h"
19287 +#include "linux/kernel_stat.h"
19288 +#include "linux/interrupt.h"
19289 +#include "linux/random.h"
19290 +#include "linux/slab.h"
19291 +#include "linux/file.h"
19292 +#include "linux/proc_fs.h"
19293 +#include "linux/init.h"
19294 +#include "linux/seq_file.h"
19295 +#include "asm/irq.h"
19296 +#include "asm/hw_irq.h"
19297 +#include "asm/hardirq.h"
19298 +#include "asm/atomic.h"
19299 +#include "asm/signal.h"
19300 +#include "asm/system.h"
19301 +#include "asm/errno.h"
19302 +#include "asm/uaccess.h"
19303 +#include "user_util.h"
19304 +#include "kern_util.h"
19305 +#include "irq_user.h"
19306 +#include "irq_kern.h"
19307 +
19308 +static void register_irq_proc (unsigned int irq);
19309 +
19310 +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
19311 +        { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
19312 +
19313 +/*
19314 + * Generic no controller code
19315 + */
19316 +
19317 +static void enable_none(unsigned int irq) { }
19318 +static unsigned int startup_none(unsigned int irq) { return 0; }
19319 +static void disable_none(unsigned int irq) { }
19320 +static void ack_none(unsigned int irq)
19321 +{
19322 +/*
19323 + * 'what should we do if we get a hw irq event on an illegal vector'.
19324 + * each architecture has to answer this themselves, it doesnt deserve
19325 + * a generic callback i think.
19326 + */
19327 +#if CONFIG_X86
19328 +       printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
19329 +#ifdef CONFIG_X86_LOCAL_APIC
19330 +       /*
19331 +        * Currently unexpected vectors happen only on SMP and APIC.
19332 +        * We _must_ ack these because every local APIC has only N
19333 +        * irq slots per priority level, and a 'hanging, unacked' IRQ
19334 +        * holds up an irq slot - in excessive cases (when multiple
19335 +        * unexpected vectors occur) that might lock up the APIC
19336 +        * completely.
19337 +        */
19338 +       ack_APIC_irq();
19339 +#endif
19340 +#endif
19341 +}
19342 +
19343 +/* startup is the same as "enable", shutdown is same as "disable" */
19344 +#define shutdown_none  disable_none
19345 +#define end_none       enable_none
19346 +
19347 +struct hw_interrupt_type no_irq_type = {
19348 +       "none",
19349 +       startup_none,
19350 +       shutdown_none,
19351 +       enable_none,
19352 +       disable_none,
19353 +       ack_none,
19354 +       end_none
19355 +};
19356 +
19357 +/*
19358 + * Generic, controller-independent functions:
19359 + */
19360 +
19361 +int get_irq_list(char *buf)
19362 +{
19363 +       int i, j;
19364 +       unsigned long flags;
19365 +       struct irqaction * action;
19366 +       char *p = buf;
19367 +
19368 +       p += sprintf(p, "           ");
19369 +       for (j=0; j<smp_num_cpus; j++)
19370 +               p += sprintf(p, "CPU%d       ",j);
19371 +       *p++ = '\n';
19372 +
19373 +       for (i = 0 ; i < NR_IRQS ; i++) {
19374 +               spin_lock_irqsave(&irq_desc[i].lock, flags);
19375 +               action = irq_desc[i].action;
19376 +               if (!action) 
19377 +                       goto end;
19378 +               p += sprintf(p, "%3d: ",i);
19379 +#ifndef CONFIG_SMP
19380 +               p += sprintf(p, "%10u ", kstat_irqs(i));
19381 +#else
19382 +               for (j = 0; j < smp_num_cpus; j++)
19383 +                       p += sprintf(p, "%10u ",
19384 +                               kstat.irqs[cpu_logical_map(j)][i]);
19385 +#endif
19386 +               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
19387 +               p += sprintf(p, "  %s", action->name);
19388 +
19389 +               for (action=action->next; action; action = action->next)
19390 +                       p += sprintf(p, ", %s", action->name);
19391 +               *p++ = '\n';
19392 +       end:
19393 +               spin_unlock_irqrestore(&irq_desc[i].lock, flags);
19394 +       }
19395 +       p += sprintf(p, "\n");
19396 +#ifdef notdef
19397 +#if CONFIG_SMP
19398 +       p += sprintf(p, "LOC: ");
19399 +       for (j = 0; j < smp_num_cpus; j++)
19400 +               p += sprintf(p, "%10u ",
19401 +                       apic_timer_irqs[cpu_logical_map(j)]);
19402 +       p += sprintf(p, "\n");
19403 +#endif
19404 +#endif
19405 +       p += sprintf(p, "ERR: %10lu\n", 0L);
19406 +       return p - buf;
19407 +}
19408 +
19409 +/*
19410 + * This should really return information about whether
19411 + * we should do bottom half handling etc. Right now we
19412 + * end up _always_ checking the bottom half, which is a
19413 + * waste of time and is not what some drivers would
19414 + * prefer.
19415 + */
19416 +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, 
19417 +                    struct irqaction * action)
19418 +{
19419 +       int status;
19420 +       int cpu = smp_processor_id();
19421 +
19422 +       irq_enter(cpu, irq);
19423 +
19424 +       status = 1;     /* Force the "do bottom halves" bit */
19425 +
19426 +       if (!(action->flags & SA_INTERRUPT))
19427 +               __sti();
19428 +
19429 +       do {
19430 +               status |= action->flags;
19431 +               action->handler(irq, action->dev_id, regs);
19432 +               action = action->next;
19433 +       } while (action);
19434 +       if (status & SA_SAMPLE_RANDOM)
19435 +               add_interrupt_randomness(irq);
19436 +       __cli();
19437 +
19438 +       irq_exit(cpu, irq);
19439 +
19440 +       return status;
19441 +}
19442 +
19443 +/*
19444 + * Generic enable/disable code: this just calls
19445 + * down into the PIC-specific version for the actual
19446 + * hardware disable after having gotten the irq
19447 + * controller lock. 
19448 + */
19449
19450 +/**
19451 + *     disable_irq_nosync - disable an irq without waiting
19452 + *     @irq: Interrupt to disable
19453 + *
19454 + *     Disable the selected interrupt line. Disables of an interrupt
19455 + *     stack. Unlike disable_irq(), this function does not ensure existing
19456 + *     instances of the IRQ handler have completed before returning.
19457 + *
19458 + *     This function may be called from IRQ context.
19459 + */
19460
19461 +void inline disable_irq_nosync(unsigned int irq)
19462 +{
19463 +       irq_desc_t *desc = irq_desc + irq;
19464 +       unsigned long flags;
19465 +
19466 +       spin_lock_irqsave(&desc->lock, flags);
19467 +       if (!desc->depth++) {
19468 +               desc->status |= IRQ_DISABLED;
19469 +               desc->handler->disable(irq);
19470 +       }
19471 +       spin_unlock_irqrestore(&desc->lock, flags);
19472 +}
19473 +
19474 +/**
19475 + *     disable_irq - disable an irq and wait for completion
19476 + *     @irq: Interrupt to disable
19477 + *
19478 + *     Disable the selected interrupt line. Disables of an interrupt
19479 + *     stack. That is for two disables you need two enables. This
19480 + *     function waits for any pending IRQ handlers for this interrupt
19481 + *     to complete before returning. If you use this function while
19482 + *     holding a resource the IRQ handler may need you will deadlock.
19483 + *
19484 + *     This function may be called - with care - from IRQ context.
19485 + */
19486
19487 +void disable_irq(unsigned int irq)
19488 +{
19489 +       disable_irq_nosync(irq);
19490 +
19491 +       if (!local_irq_count(smp_processor_id())) {
19492 +               do {
19493 +                       barrier();
19494 +               } while (irq_desc[irq].status & IRQ_INPROGRESS);
19495 +       }
19496 +}
19497 +
19498 +/**
19499 + *     enable_irq - enable interrupt handling on an irq
19500 + *     @irq: Interrupt to enable
19501 + *
19502 + *     Re-enables the processing of interrupts on this IRQ line
19503 + *     providing no disable_irq calls are now in effect.
19504 + *
19505 + *     This function may be called from IRQ context.
19506 + */
19507
19508 +void enable_irq(unsigned int irq)
19509 +{
19510 +       irq_desc_t *desc = irq_desc + irq;
19511 +       unsigned long flags;
19512 +
19513 +       spin_lock_irqsave(&desc->lock, flags);
19514 +       switch (desc->depth) {
19515 +       case 1: {
19516 +               unsigned int status = desc->status & ~IRQ_DISABLED;
19517 +               desc->status = status;
19518 +               if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
19519 +                       desc->status = status | IRQ_REPLAY;
19520 +                       hw_resend_irq(desc->handler,irq);
19521 +               }
19522 +               desc->handler->enable(irq);
19523 +               /* fall-through */
19524 +       }
19525 +       default:
19526 +               desc->depth--;
19527 +               break;
19528 +       case 0:
19529 +               printk(KERN_ERR "enable_irq() unbalanced from %p\n",
19530 +                      __builtin_return_address(0));
19531 +       }
19532 +       spin_unlock_irqrestore(&desc->lock, flags);
19533 +}
19534 +
19535 +/*
19536 + * do_IRQ handles all normal device IRQ's (the special
19537 + * SMP cross-CPU interrupts have their own specific
19538 + * handlers).
19539 + */
19540 +unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
19541 +{      
19542 +       /* 
19543 +        * 0 return value means that this irq is already being
19544 +        * handled by some other CPU. (or is disabled)
19545 +        */
19546 +       int cpu = smp_processor_id();
19547 +       irq_desc_t *desc = irq_desc + irq;
19548 +       struct irqaction * action;
19549 +       unsigned int status;
19550 +
19551 +       kstat.irqs[cpu][irq]++;
19552 +       spin_lock(&desc->lock);
19553 +       desc->handler->ack(irq);
19554 +       /*
19555 +          REPLAY is when Linux resends an IRQ that was dropped earlier
19556 +          WAITING is used by probe to mark irqs that are being tested
19557 +          */
19558 +       status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
19559 +       status |= IRQ_PENDING; /* we _want_ to handle it */
19560 +
19561 +       /*
19562 +        * If the IRQ is disabled for whatever reason, we cannot
19563 +        * use the action we have.
19564 +        */
19565 +       action = NULL;
19566 +       if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
19567 +               action = desc->action;
19568 +               status &= ~IRQ_PENDING; /* we commit to handling */
19569 +               status |= IRQ_INPROGRESS; /* we are handling it */
19570 +       }
19571 +       desc->status = status;
19572 +
19573 +       /*
19574 +        * If there is no IRQ handler or it was disabled, exit early.
19575 +          Since we set PENDING, if another processor is handling
19576 +          a different instance of this same irq, the other processor
19577 +          will take care of it.
19578 +        */
19579 +       if (!action)
19580 +               goto out;
19581 +
19582 +       /*
19583 +        * Edge triggered interrupts need to remember
19584 +        * pending events.
19585 +        * This applies to any hw interrupts that allow a second
19586 +        * instance of the same irq to arrive while we are in do_IRQ
19587 +        * or in the handler. But the code here only handles the _second_
19588 +        * instance of the irq, not the third or fourth. So it is mostly
19589 +        * useful for irq hardware that does not mask cleanly in an
19590 +        * SMP environment.
19591 +        */
19592 +       for (;;) {
19593 +               spin_unlock(&desc->lock);
19594 +               handle_IRQ_event(irq, (struct pt_regs *) regs, action);
19595 +               spin_lock(&desc->lock);
19596 +               
19597 +               if (!(desc->status & IRQ_PENDING))
19598 +                       break;
19599 +               desc->status &= ~IRQ_PENDING;
19600 +       }
19601 +       desc->status &= ~IRQ_INPROGRESS;
19602 +out:
19603 +       /*
19604 +        * The ->end() handler has to deal with interrupts which got
19605 +        * disabled while the handler was running.
19606 +        */
19607 +       desc->handler->end(irq);
19608 +       spin_unlock(&desc->lock);
19609 +
19610 +       if (softirq_pending(cpu))
19611 +               do_softirq();
19612 +       return 1;
19613 +}
19614 +
19615 +/**
19616 + *     request_irq - allocate an interrupt line
19617 + *     @irq: Interrupt line to allocate
19618 + *     @handler: Function to be called when the IRQ occurs
19619 + *     @irqflags: Interrupt type flags
19620 + *     @devname: An ascii name for the claiming device
19621 + *     @dev_id: A cookie passed back to the handler function
19622 + *
19623 + *     This call allocates interrupt resources and enables the
19624 + *     interrupt line and IRQ handling. From the point this
19625 + *     call is made your handler function may be invoked. Since
19626 + *     your handler function must clear any interrupt the board 
19627 + *     raises, you must take care both to initialise your hardware
19628 + *     and to set up the interrupt handler in the right order.
19629 + *
19630 + *     Dev_id must be globally unique. Normally the address of the
19631 + *     device data structure is used as the cookie. Since the handler
19632 + *     receives this value it makes sense to use it.
19633 + *
19634 + *     If your interrupt is shared you must pass a non NULL dev_id
19635 + *     as this is required when freeing the interrupt.
19636 + *
19637 + *     Flags:
19638 + *
19639 + *     SA_SHIRQ                Interrupt is shared
19640 + *
19641 + *     SA_INTERRUPT            Disable local interrupts while processing
19642 + *
19643 + *     SA_SAMPLE_RANDOM        The interrupt can be used for entropy
19644 + *
19645 + */
19646
19647 +int request_irq(unsigned int irq,
19648 +               void (*handler)(int, void *, struct pt_regs *),
19649 +               unsigned long irqflags, 
19650 +               const char * devname,
19651 +               void *dev_id)
19652 +{
19653 +       int retval;
19654 +       struct irqaction * action;
19655 +
19656 +#if 1
19657 +       /*
19658 +        * Sanity-check: shared interrupts should REALLY pass in
19659 +        * a real dev-ID, otherwise we'll have trouble later trying
19660 +        * to figure out which interrupt is which (messes up the
19661 +        * interrupt freeing logic etc).
19662 +        */
19663 +       if (irqflags & SA_SHIRQ) {
19664 +               if (!dev_id)
19665 +                       printk(KERN_ERR "Bad boy: %s (at 0x%x) called us "
19666 +                              "without a dev_id!\n", devname, (&irq)[-1]);
19667 +       }
19668 +#endif
19669 +
19670 +       if (irq >= NR_IRQS)
19671 +               return -EINVAL;
19672 +       if (!handler)
19673 +               return -EINVAL;
19674 +
19675 +       action = (struct irqaction *)
19676 +                       kmalloc(sizeof(struct irqaction), GFP_KERNEL);
19677 +       if (!action)
19678 +               return -ENOMEM;
19679 +
19680 +       action->handler = handler;
19681 +       action->flags = irqflags;
19682 +       action->mask = 0;
19683 +       action->name = devname;
19684 +       action->next = NULL;
19685 +       action->dev_id = dev_id;
19686 +
19687 +       retval = setup_irq(irq, action);
19688 +       if (retval)
19689 +               kfree(action);
19690 +       return retval;
19691 +}
19692 +
19693 +int um_request_irq(unsigned int irq, int fd, int type,
19694 +                  void (*handler)(int, void *, struct pt_regs *),
19695 +                  unsigned long irqflags, const char * devname,
19696 +                  void *dev_id)
19697 +{
19698 +       int err;
19699 +
19700 +       err = request_irq(irq, handler, irqflags, devname, dev_id);
19701 +       if(err) 
19702 +               return(err);
19703 +
19704 +       if(fd != -1)
19705 +               err = activate_fd(irq, fd, type, dev_id);
19706 +       return(err);
19707 +}
19708 +
19709 +/* this was setup_x86_irq but it seems pretty generic */
19710 +int setup_irq(unsigned int irq, struct irqaction * new)
19711 +{
19712 +       int shared = 0;
19713 +       unsigned long flags;
19714 +       struct irqaction *old, **p;
19715 +       irq_desc_t *desc = irq_desc + irq;
19716 +
19717 +       /*
19718 +        * Some drivers like serial.c use request_irq() heavily,
19719 +        * so we have to be careful not to interfere with a
19720 +        * running system.
19721 +        */
19722 +       if (new->flags & SA_SAMPLE_RANDOM) {
19723 +               /*
19724 +                * This function might sleep, we want to call it first,
19725 +                * outside of the atomic block.
19726 +                * Yes, this might clear the entropy pool if the wrong
19727 +                * driver is attempted to be loaded, without actually
19728 +                * installing a new handler, but is this really a problem,
19729 +                * only the sysadmin is able to do this.
19730 +                */
19731 +               rand_initialize_irq(irq);
19732 +       }
19733 +
19734 +       /*
19735 +        * The following block of code has to be executed atomically
19736 +        */
19737 +       spin_lock_irqsave(&desc->lock,flags);
19738 +       p = &desc->action;
19739 +       old = *p;
19740 +       if (old != NULL) {
19741 +               /* Can't share interrupts unless both agree to */
19742 +               if (!(old->flags & new->flags & SA_SHIRQ)) {
19743 +                       spin_unlock_irqrestore(&desc->lock,flags);
19744 +                       return -EBUSY;
19745 +               }
19746 +
19747 +               /* add new interrupt at end of irq queue */
19748 +               do {
19749 +                       p = &old->next;
19750 +                       old = *p;
19751 +               } while (old);
19752 +               shared = 1;
19753 +       }
19754 +
19755 +       *p = new;
19756 +
19757 +       if (!shared) {
19758 +               desc->depth = 0;
19759 +               desc->status &= ~IRQ_DISABLED;
19760 +               desc->handler->startup(irq);
19761 +       }
19762 +       spin_unlock_irqrestore(&desc->lock,flags);
19763 +
19764 +       register_irq_proc(irq);
19765 +       return 0;
19766 +}
19767 +
19768 +/**
19769 + *     free_irq - free an interrupt
19770 + *     @irq: Interrupt line to free
19771 + *     @dev_id: Device identity to free
19772 + *
19773 + *     Remove an interrupt handler. The handler is removed and if the
19774 + *     interrupt line is no longer in use by any driver it is disabled.
19775 + *     On a shared IRQ the caller must ensure the interrupt is disabled
19776 + *     on the card it drives before calling this function. The function
19777 + *     does not return until any executing interrupts for this IRQ
19778 + *     have completed.
19779 + *
19780 + *     This function may be called from interrupt context. 
19781 + *
19782 + *     Bugs: Attempting to free an irq in a handler for the same irq hangs
19783 + *           the machine.
19784 + */
19785
19786 +void free_irq(unsigned int irq, void *dev_id)
19787 +{
19788 +       irq_desc_t *desc;
19789 +       struct irqaction **p;
19790 +       unsigned long flags;
19791 +
19792 +       if (irq >= NR_IRQS)
19793 +               return;
19794 +
19795 +       desc = irq_desc + irq;
19796 +       spin_lock_irqsave(&desc->lock,flags);
19797 +       p = &desc->action;
19798 +       for (;;) {
19799 +               struct irqaction * action = *p;
19800 +               if (action) {
19801 +                       struct irqaction **pp = p;
19802 +                       p = &action->next;
19803 +                       if (action->dev_id != dev_id)
19804 +                               continue;
19805 +
19806 +                       /* Found it - now remove it from the list of entries */
19807 +                       *pp = action->next;
19808 +                       if (!desc->action) {
19809 +                               desc->status |= IRQ_DISABLED;
19810 +                               desc->handler->shutdown(irq);
19811 +                       }
19812 +                       free_irq_by_irq_and_dev(irq, dev_id);
19813 +                       spin_unlock_irqrestore(&desc->lock,flags);
19814 +
19815 +#ifdef CONFIG_SMP
19816 +                       /* Wait to make sure it's not being used on another CPU */
19817 +                       while (desc->status & IRQ_INPROGRESS)
19818 +                               barrier();
19819 +#endif
19820 +                       kfree(action);
19821 +                       return;
19822 +               }
19823 +               printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
19824 +               spin_unlock_irqrestore(&desc->lock,flags);
19825 +               return;
19826 +       }
19827 +}
19828 +
19829 +/* These are initialized by sysctl_init, which is called from init/main.c */
19830 +static struct proc_dir_entry * root_irq_dir;
19831 +static struct proc_dir_entry * irq_dir [NR_IRQS];
19832 +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
19833 +
19834 +/* These are read and written as longs, so a read won't see a partial write
19835 + * even during a race.
19836 + */
19837 +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
19838 +
19839 +#define HEX_DIGITS 8
19840 +
19841 +static int irq_affinity_read_proc (char *page, char **start, off_t off,
19842 +                       int count, int *eof, void *data)
19843 +{
19844 +       if (count < HEX_DIGITS+1)
19845 +               return -EINVAL;
19846 +       return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
19847 +}
19848 +
19849 +static unsigned int parse_hex_value (const char *buffer,
19850 +               unsigned long count, unsigned long *ret)
19851 +{
19852 +       unsigned char hexnum [HEX_DIGITS];
19853 +       unsigned long value;
19854 +       int i;
19855 +
19856 +       if (!count)
19857 +               return -EINVAL;
19858 +       if (count > HEX_DIGITS)
19859 +               count = HEX_DIGITS;
19860 +       if (copy_from_user(hexnum, buffer, count))
19861 +               return -EFAULT;
19862 +
19863 +       /*
19864 +        * Parse the first HEX_DIGITS characters as a hex string, any non-hex
19865 +        * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
19866 +        */
19867 +       value = 0;
19868 +
19869 +       for (i = 0; i < count; i++) {
19870 +               unsigned int c = hexnum[i];
19871 +
19872 +               switch (c) {
19873 +                       case '0' ... '9': c -= '0'; break;
19874 +                       case 'a' ... 'f': c -= 'a'-10; break;
19875 +                       case 'A' ... 'F': c -= 'A'-10; break;
19876 +               default:
19877 +                       goto out;
19878 +               }
19879 +               value = (value << 4) | c;
19880 +       }
19881 +out:
19882 +       *ret = value;
19883 +       return 0;
19884 +}
19885 +
19886 +static int irq_affinity_write_proc (struct file *file, const char *buffer,
19887 +                                       unsigned long count, void *data)
19888 +{
19889 +       int irq = (long) data, full_count = count, err;
19890 +       unsigned long new_value;
19891 +
19892 +       if (!irq_desc[irq].handler->set_affinity)
19893 +               return -EIO;
19894 +
19895 +       err = parse_hex_value(buffer, count, &new_value);
19896 +
19897 +#if CONFIG_SMP
19898 +       /*
19899 +        * Do not allow disabling IRQs completely - it's a too easy
19900 +        * way to make the system unusable accidentally :-) At least
19901 +        * one online CPU still has to be targeted.
19902 +        */
19903 +       if (!(new_value & cpu_online_map))
19904 +               return -EINVAL;
19905 +#endif
19906 +
19907 +       irq_affinity[irq] = new_value;
19908 +       irq_desc[irq].handler->set_affinity(irq, new_value);
19909 +
19910 +       return full_count;
19911 +}
19912 +
19913 +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
19914 +                       int count, int *eof, void *data)
19915 +{
19916 +       unsigned long *mask = (unsigned long *) data;
19917 +       if (count < HEX_DIGITS+1)
19918 +               return -EINVAL;
19919 +       return sprintf (page, "%08lx\n", *mask);
19920 +}
19921 +
19922 +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
19923 +                                       unsigned long count, void *data)
19924 +{
19925 +       unsigned long *mask = (unsigned long *) data, full_count = count, err;
19926 +       unsigned long new_value;
19927 +
19928 +       err = parse_hex_value(buffer, count, &new_value);
19929 +       if (err)
19930 +               return err;
19931 +
19932 +       *mask = new_value;
19933 +       return full_count;
19934 +}
19935 +
19936 +#define MAX_NAMELEN 10
19937 +
19938 +static void register_irq_proc (unsigned int irq)
19939 +{
19940 +       struct proc_dir_entry *entry;
19941 +       char name [MAX_NAMELEN];
19942 +
19943 +       if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
19944 +           irq_dir[irq])
19945 +               return;
19946 +
19947 +       memset(name, 0, MAX_NAMELEN);
19948 +       sprintf(name, "%d", irq);
19949 +
19950 +       /* create /proc/irq/1234 */
19951 +       irq_dir[irq] = proc_mkdir(name, root_irq_dir);
19952 +
19953 +       /* create /proc/irq/1234/smp_affinity */
19954 +       entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
19955 +
19956 +       entry->nlink = 1;
19957 +       entry->data = (void *)(long)irq;
19958 +       entry->read_proc = irq_affinity_read_proc;
19959 +       entry->write_proc = irq_affinity_write_proc;
19960 +
19961 +       smp_affinity_entry[irq] = entry;
19962 +}
19963 +
19964 +/* Read and written as a long */
19965 +unsigned long prof_cpu_mask = -1;
19966 +
19967 +void __init init_irq_proc (void)
19968 +{
19969 +       struct proc_dir_entry *entry;
19970 +       int i;
19971 +
19972 +       /* create /proc/irq */
19973 +       root_irq_dir = proc_mkdir("irq", 0);
19974 +
19975 +       /* create /proc/irq/prof_cpu_mask */
19976 +       entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
19977 +
19978 +       entry->nlink = 1;
19979 +       entry->data = (void *)&prof_cpu_mask;
19980 +       entry->read_proc = prof_cpu_mask_read_proc;
19981 +       entry->write_proc = prof_cpu_mask_write_proc;
19982 +
19983 +       /*
19984 +        * Create entries for all existing IRQs.
19985 +        */
19986 +       for (i = 0; i < NR_IRQS; i++)
19987 +               register_irq_proc(i);
19988 +}
19989 +
19990 +static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED;
19991 +
19992 +unsigned long irq_lock(void)
19993 +{
19994 +       unsigned long flags;
19995 +
19996 +       spin_lock_irqsave(&irq_spinlock, flags);
19997 +       return(flags);
19998 +}
19999 +
20000 +void irq_unlock(unsigned long flags)
20001 +{
20002 +       spin_unlock_irqrestore(&irq_spinlock, flags);
20003 +}
20004 +
20005 +unsigned long probe_irq_on(void)
20006 +{
20007 +       return(0);
20008 +}
20009 +
20010 +int probe_irq_off(unsigned long val)
20011 +{
20012 +       return(0);
20013 +}
20014 +
20015 +static unsigned int startup_SIGIO_irq(unsigned int irq)
20016 +{
20017 +       return(0);
20018 +}
20019 +
20020 +static void shutdown_SIGIO_irq(unsigned int irq)
20021 +{
20022 +}
20023 +
20024 +static void enable_SIGIO_irq(unsigned int irq)
20025 +{
20026 +}
20027 +
20028 +static void disable_SIGIO_irq(unsigned int irq)
20029 +{
20030 +}
20031 +
20032 +static void mask_and_ack_SIGIO(unsigned int irq)
20033 +{
20034 +}
20035 +
20036 +static void end_SIGIO_irq(unsigned int irq)
20037 +{
20038 +}
20039 +
20040 +static unsigned int startup_SIGVTALRM_irq(unsigned int irq)
20041 +{
20042 +       return(0);
20043 +}
20044 +
20045 +static void shutdown_SIGVTALRM_irq(unsigned int irq)
20046 +{
20047 +}
20048 +
20049 +static void enable_SIGVTALRM_irq(unsigned int irq)
20050 +{
20051 +}
20052 +
20053 +static void disable_SIGVTALRM_irq(unsigned int irq)
20054 +{
20055 +}
20056 +
20057 +static void mask_and_ack_SIGVTALRM(unsigned int irq)
20058 +{
20059 +}
20060 +
20061 +static void end_SIGVTALRM_irq(unsigned int irq)
20062 +{
20063 +}
20064 +
20065 +static struct hw_interrupt_type SIGIO_irq_type = {
20066 +       "SIGIO",
20067 +       startup_SIGIO_irq,
20068 +       shutdown_SIGIO_irq,
20069 +       enable_SIGIO_irq,
20070 +       disable_SIGIO_irq,
20071 +       mask_and_ack_SIGIO,
20072 +       end_SIGIO_irq,
20073 +       NULL
20074 +};
20075 +
20076 +static struct hw_interrupt_type SIGVTALRM_irq_type = {
20077 +       "SIGVTALRM",
20078 +       startup_SIGVTALRM_irq,
20079 +       shutdown_SIGVTALRM_irq,
20080 +       enable_SIGVTALRM_irq,
20081 +       disable_SIGVTALRM_irq,
20082 +       mask_and_ack_SIGVTALRM,
20083 +       end_SIGVTALRM_irq,
20084 +       NULL
20085 +};
20086 +
20087 +void __init init_IRQ(void)
20088 +{
20089 +       int i;
20090 +
20091 +       irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
20092 +       irq_desc[TIMER_IRQ].action = 0;
20093 +       irq_desc[TIMER_IRQ].depth = 1;
20094 +       irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
20095 +       enable_irq(TIMER_IRQ);
20096 +       for(i=1;i<NR_IRQS;i++){
20097 +               irq_desc[i].status = IRQ_DISABLED;
20098 +               irq_desc[i].action = 0;
20099 +               irq_desc[i].depth = 1;
20100 +               irq_desc[i].handler = &SIGIO_irq_type;
20101 +               enable_irq(i);
20102 +       }
20103 +       init_irq_signals(0);
20104 +}
20105 +
20106 +/*
20107 + * Overrides for Emacs so that we follow Linus's tabbing style.
20108 + * Emacs will notice this stuff at the end of the file and automatically
20109 + * adjust the settings for this buffer only.  This must remain at the end
20110 + * of the file.
20111 + * ---------------------------------------------------------------------------
20112 + * Local variables:
20113 + * c-file-style: "linux"
20114 + * End:
20115 + */
20116 diff -Naur -X ../exclude-files orig/arch/um/kernel/irq_user.c um/arch/um/kernel/irq_user.c
20117 --- orig/arch/um/kernel/irq_user.c      1969-12-31 19:00:00.000000000 -0500
20118 +++ um/arch/um/kernel/irq_user.c        2003-10-21 03:26:06.000000000 -0400
20119 @@ -0,0 +1,424 @@
20120 +/* 
20121 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
20122 + * Licensed under the GPL
20123 + */
20124 +
20125 +#include <stdlib.h>
20126 +#include <unistd.h>
20127 +#include <errno.h>
20128 +#include <signal.h>
20129 +#include <string.h>
20130 +#include <sys/poll.h>
20131 +#include <sys/types.h>
20132 +#include <sys/time.h>
20133 +#include "user_util.h"
20134 +#include "kern_util.h"
20135 +#include "user.h"
20136 +#include "process.h"
20137 +#include "signal_user.h"
20138 +#include "sigio.h"
20139 +#include "irq_user.h"
20140 +#include "os.h"
20141 +
20142 +struct irq_fd {
20143 +       struct irq_fd *next;
20144 +       void *id;
20145 +       int fd;
20146 +       int type;
20147 +       int irq;
20148 +       int pid;
20149 +       int events;
20150 +       int current_events;
20151 +       int freed;
20152 +};
20153 +
20154 +static struct irq_fd *active_fds = NULL;
20155 +static struct irq_fd **last_irq_ptr = &active_fds;
20156 +
20157 +static struct pollfd *pollfds = NULL;
20158 +static int pollfds_num = 0;
20159 +static int pollfds_size = 0;
20160 +
20161 +extern int io_count, intr_count;
20162 +
20163 +void sigio_handler(int sig, union uml_pt_regs *regs)
20164 +{
20165 +       struct irq_fd *irq_fd, *next;
20166 +       int i, n;
20167 +
20168 +       if(smp_sigio_handler()) return;
20169 +       while(1){
20170 +               n = poll(pollfds, pollfds_num, 0);
20171 +               if(n < 0){
20172 +                       if(errno == EINTR) continue;
20173 +                       printk("sigio_handler : poll returned %d, "
20174 +                              "errno = %d\n", n, errno);
20175 +                       break;
20176 +               }
20177 +               if(n == 0) break;
20178 +
20179 +               irq_fd = active_fds;
20180 +               for(i = 0; i < pollfds_num; i++){
20181 +                       if(pollfds[i].revents != 0){
20182 +                               irq_fd->current_events = pollfds[i].revents;
20183 +                               pollfds[i].fd = -1;
20184 +                       }
20185 +                       irq_fd = irq_fd->next;
20186 +               }
20187 +
20188 +               for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
20189 +                       next = irq_fd->next;
20190 +                       if(irq_fd->current_events != 0){
20191 +                               irq_fd->current_events = 0;
20192 +                               do_IRQ(irq_fd->irq, regs);
20193 +
20194 +                               /* This is here because the next irq may be
20195 +                                * freed in the handler.  If a console goes
20196 +                                * away, both the read and write irqs will be
20197 +                                * freed.  After do_IRQ, ->next will point to
20198 +                                * a good IRQ.
20199 +                                * Irqs can't be freed inside their handlers,
20200 +                                * so the next best thing is to have them
20201 +                                * marked as needing freeing, so that they
20202 +                                * can be freed here.
20203 +                                */
20204 +                               next = irq_fd->next;
20205 +                               if(irq_fd->freed)
20206 +                                       free_irq(irq_fd->irq, irq_fd->id);
20207 +                       }
20208 +               }
20209 +       }
20210 +}
20211 +
20212 +int activate_ipi(int fd, int pid)
20213 +{
20214 +       return(os_set_fd_async(fd, pid));
20215 +}
20216 +
20217 +static void maybe_sigio_broken(int fd, int type)
20218 +{
20219 +       if(isatty(fd)){
20220 +               if((type == IRQ_WRITE) && !pty_output_sigio){
20221 +                       write_sigio_workaround();
20222 +                       add_sigio_fd(fd, 0);
20223 +               }
20224 +               else if((type == IRQ_READ) && !pty_close_sigio){
20225 +                       write_sigio_workaround();
20226 +                       add_sigio_fd(fd, 1);                    
20227 +               }
20228 +       }
20229 +}
20230 +
20231 +int activate_fd(int irq, int fd, int type, void *dev_id)
20232 +{
20233 +       struct pollfd *tmp_pfd;
20234 +       struct irq_fd *new_fd, *irq_fd;
20235 +       unsigned long flags;
20236 +       int pid, events, err, n, size;
20237 +
20238 +       pid = os_getpid();
20239 +       err = os_set_fd_async(fd, pid);
20240 +       if(err < 0)
20241 +               goto out;
20242 +
20243 +       new_fd = um_kmalloc(sizeof(*new_fd));
20244 +       err = -ENOMEM;
20245 +       if(new_fd == NULL)
20246 +               goto out;
20247 +
20248 +       if(type == IRQ_READ) events = POLLIN | POLLPRI;
20249 +       else events = POLLOUT;
20250 +       *new_fd = ((struct irq_fd) { .next              = NULL,
20251 +                                    .id                = dev_id,
20252 +                                    .fd                = fd,
20253 +                                    .type              = type,
20254 +                                    .irq               = irq,
20255 +                                    .pid               = pid,
20256 +                                    .events            = events,
20257 +                                    .current_events    = 0,
20258 +                                    .freed             = 0  } );
20259 +
20260 +       /* Critical section - locked by a spinlock because this stuff can
20261 +        * be changed from interrupt handlers.  The stuff above is done 
20262 +        * outside the lock because it allocates memory.
20263 +        */
20264 +
20265 +       /* Actually, it only looks like it can be called from interrupt
20266 +        * context.  The culprit is reactivate_fd, which calls 
20267 +        * maybe_sigio_broken, which calls write_sigio_workaround,
20268 +        * which calls activate_fd.  However, write_sigio_workaround should
20269 +        * only be called once, at boot time.  That would make it clear that
20270 +        * this is called only from process context, and can be locked with
20271 +        * a semaphore.
20272 +        */
20273 +       flags = irq_lock();
20274 +       for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
20275 +               if((irq_fd->fd == fd) && (irq_fd->type == type)){
20276 +                       printk("Registering fd %d twice\n", fd);
20277 +                       printk("Irqs : %d, %d\n", irq_fd->irq, irq);
20278 +                       printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
20279 +                       goto out_unlock;
20280 +               }
20281 +       }
20282 +
20283 +       n = pollfds_num;
20284 +       if(n == pollfds_size){
20285 +               while(1){
20286 +                       /* Here we have to drop the lock in order to call 
20287 +                        * kmalloc, which might sleep.  If something else
20288 +                        * came in and changed the pollfds array, we free
20289 +                        * the buffer and try again.
20290 +                        */
20291 +                       irq_unlock(flags);
20292 +                       size = (pollfds_num + 1) * sizeof(pollfds[0]);
20293 +                       tmp_pfd = um_kmalloc(size);
20294 +                       flags = irq_lock();
20295 +                       if(tmp_pfd == NULL)
20296 +                               goto out_unlock;
20297 +                       if(n == pollfds_size)
20298 +                               break;
20299 +                       kfree(tmp_pfd);
20300 +               }
20301 +               if(pollfds != NULL){
20302 +                       memcpy(tmp_pfd, pollfds,
20303 +                              sizeof(pollfds[0]) * pollfds_size);
20304 +                       kfree(pollfds);
20305 +               }
20306 +               pollfds = tmp_pfd;
20307 +               pollfds_size++;
20308 +       }
20309 +
20310 +       if(type == IRQ_WRITE) 
20311 +               fd = -1;
20312 +
20313 +       pollfds[pollfds_num] = ((struct pollfd) { .fd   = fd,
20314 +                                                 .events       = events,
20315 +                                                 .revents      = 0 });
20316 +       pollfds_num++;
20317 +
20318 +       *last_irq_ptr = new_fd;
20319 +       last_irq_ptr = &new_fd->next;
20320 +
20321 +       irq_unlock(flags);
20322 +
20323 +       /* This calls activate_fd, so it has to be outside the critical
20324 +        * section.
20325 +        */
20326 +       maybe_sigio_broken(fd, type);
20327 +
20328 +       return(0);
20329 +
20330 + out_unlock:
20331 +       irq_unlock(flags);
20332 +       kfree(new_fd);
20333 + out:
20334 +       return(err);
20335 +}
20336 +
20337 +static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
20338 +{
20339 +       struct irq_fd **prev;
20340 +       unsigned long flags;
20341 +       int i = 0;
20342 +
20343 +       flags = irq_lock();
20344 +       prev = &active_fds;
20345 +       while(*prev != NULL){
20346 +               if((*test)(*prev, arg)){
20347 +                       struct irq_fd *old_fd = *prev;
20348 +                       if((pollfds[i].fd != -1) && 
20349 +                          (pollfds[i].fd != (*prev)->fd)){
20350 +                               printk("free_irq_by_cb - mismatch between "
20351 +                                      "active_fds and pollfds, fd %d vs %d\n",
20352 +                                      (*prev)->fd, pollfds[i].fd);
20353 +                               goto out;
20354 +                       }
20355 +                       memcpy(&pollfds[i], &pollfds[i + 1],
20356 +                              (pollfds_num - i - 1) * sizeof(pollfds[0]));
20357 +                       pollfds_num--;
20358 +                       if(last_irq_ptr == &old_fd->next) 
20359 +                               last_irq_ptr = prev;
20360 +                       *prev = (*prev)->next;
20361 +                       if(old_fd->type == IRQ_WRITE) 
20362 +                               ignore_sigio_fd(old_fd->fd);
20363 +                       kfree(old_fd);
20364 +                       continue;
20365 +               }
20366 +               prev = &(*prev)->next;
20367 +               i++;
20368 +       }
20369 + out:
20370 +       irq_unlock(flags);
20371 +}
20372 +
20373 +struct irq_and_dev {
20374 +       int irq;
20375 +       void *dev;
20376 +};
20377 +
20378 +static int same_irq_and_dev(struct irq_fd *irq, void *d)
20379 +{
20380 +       struct irq_and_dev *data = d;
20381 +
20382 +       return((irq->irq == data->irq) && (irq->id == data->dev));
20383 +}
20384 +
20385 +void free_irq_by_irq_and_dev(int irq, void *dev)
20386 +{
20387 +       struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
20388 +                                                         .dev  = dev });
20389 +
20390 +       free_irq_by_cb(same_irq_and_dev, &data);
20391 +}
20392 +
20393 +static int same_fd(struct irq_fd *irq, void *fd)
20394 +{
20395 +       return(irq->fd == *((int *) fd));
20396 +}
20397 +
20398 +void free_irq_by_fd(int fd)
20399 +{
20400 +       free_irq_by_cb(same_fd, &fd);
20401 +}
20402 +
20403 +static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
20404 +{
20405 +       struct irq_fd *irq;
20406 +       int i = 0;
20407 +
20408 +       for(irq=active_fds; irq != NULL; irq = irq->next){
20409 +               if((irq->fd == fd) && (irq->irq == irqnum)) break;
20410 +               i++;
20411 +       }
20412 +       if(irq == NULL){
20413 +               printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
20414 +               goto out;
20415 +       }
20416 +       if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
20417 +               printk("find_irq_by_fd - mismatch between active_fds and "
20418 +                      "pollfds, fd %d vs %d, need %d\n", irq->fd, 
20419 +                      pollfds[i].fd, fd);
20420 +               irq = NULL;
20421 +               goto out;
20422 +       }
20423 +       *index_out = i;
20424 + out:
20425 +       return(irq);
20426 +}
20427 +
20428 +void free_irq_later(int irq, void *dev_id)
20429 +{
20430 +       struct irq_fd *irq_fd;
20431 +       unsigned long flags;
20432 +
20433 +       flags = irq_lock();
20434 +       for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
20435 +               if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
20436 +                       break;
20437 +       }
20438 +       if(irq_fd == NULL){
20439 +               printk("free_irq_later found no irq, irq = %d, "
20440 +                      "dev_id = 0x%p\n", irq, dev_id);
20441 +               goto out;
20442 +       }
20443 +       irq_fd->freed = 1;
20444 + out:
20445 +       irq_unlock(flags);
20446 +}
20447 +
20448 +void reactivate_fd(int fd, int irqnum)
20449 +{
20450 +       struct irq_fd *irq;
20451 +       unsigned long flags;
20452 +       int i;
20453 +
20454 +       flags = irq_lock();
20455 +       irq = find_irq_by_fd(fd, irqnum, &i);
20456 +       if(irq == NULL){
20457 +               irq_unlock(flags);
20458 +               return;
20459 +       }
20460 +
20461 +       pollfds[i].fd = irq->fd;
20462 +
20463 +       irq_unlock(flags);
20464 +
20465 +       /* This calls activate_fd, so it has to be outside the critical
20466 +        * section.
20467 +        */
20468 +       maybe_sigio_broken(fd, irq->type);
20469 +}
20470 +
20471 +void deactivate_fd(int fd, int irqnum)
20472 +{
20473 +       struct irq_fd *irq;
20474 +       unsigned long flags;
20475 +       int i;
20476 +
20477 +       flags = irq_lock();
20478 +       irq = find_irq_by_fd(fd, irqnum, &i);
20479 +       if(irq == NULL)
20480 +               goto out;
20481 +       pollfds[i].fd = -1;
20482 + out:
20483 +       irq_unlock(flags);
20484 +}
20485 +
20486 +void forward_ipi(int fd, int pid)
20487 +{
20488 +       int err;
20489 +
20490 +       err = os_set_owner(fd, pid);
20491 +       if(err < 0)
20492 +               printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
20493 +                      "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
20494 +}
20495 +
20496 +void forward_interrupts(int pid)
20497 +{
20498 +       struct irq_fd *irq;
20499 +       unsigned long flags;
20500 +       int err;
20501 +
20502 +       flags = irq_lock();
20503 +       for(irq=active_fds;irq != NULL;irq = irq->next){
20504 +               err = os_set_owner(irq->fd, pid);
20505 +               if(err < 0){
20506 +                       /* XXX Just remove the irq rather than
20507 +                        * print out an infinite stream of these
20508 +                        */
20509 +                       printk("Failed to forward %d to pid %d, err = %d\n",
20510 +                              irq->fd, pid, -err);
20511 +               }
20512 +
20513 +               irq->pid = pid;
20514 +       }
20515 +       irq_unlock(flags);
20516 +}
20517 +
20518 +void init_irq_signals(int on_sigstack)
20519 +{
20520 +       __sighandler_t h;
20521 +       int flags;
20522 +
20523 +       flags = on_sigstack ? SA_ONSTACK : 0;
20524 +       if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
20525 +       else h = boot_timer_handler;
20526 +
20527 +       set_handler(SIGVTALRM, h, flags | SA_RESTART, 
20528 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
20529 +       set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
20530 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
20531 +       signal(SIGWINCH, SIG_IGN);
20532 +}
20533 +
20534 +/*
20535 + * Overrides for Emacs so that we follow Linus's tabbing style.
20536 + * Emacs will notice this stuff at the end of the file and automatically
20537 + * adjust the settings for this buffer only.  This must remain at the end
20538 + * of the file.
20539 + * ---------------------------------------------------------------------------
20540 + * Local variables:
20541 + * c-file-style: "linux"
20542 + * End:
20543 + */
20544 diff -Naur -X ../exclude-files orig/arch/um/kernel/ksyms.c um/arch/um/kernel/ksyms.c
20545 --- orig/arch/um/kernel/ksyms.c 1969-12-31 19:00:00.000000000 -0500
20546 +++ um/arch/um/kernel/ksyms.c   2003-12-17 03:22:37.000000000 -0500
20547 @@ -0,0 +1,119 @@
20548 +/* 
20549 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
20550 + * Licensed under the GPL
20551 + */
20552 +
20553 +#include "linux/config.h"
20554 +#include "linux/module.h"
20555 +#include "linux/string.h"
20556 +#include "linux/smp_lock.h"
20557 +#include "linux/spinlock.h"
20558 +#include "asm/current.h"
20559 +#include "asm/delay.h"
20560 +#include "asm/processor.h"
20561 +#include "asm/unistd.h"
20562 +#include "asm/pgalloc.h"
20563 +#include "asm/pgtable.h"
20564 +#include "asm/page.h"
20565 +#include "kern_util.h"
20566 +#include "user_util.h"
20567 +#include "os.h"
20568 +#include "helper.h"
20569 +
20570 +EXPORT_SYMBOL(stop);
20571 +EXPORT_SYMBOL(strtok);
20572 +EXPORT_SYMBOL(uml_physmem);
20573 +EXPORT_SYMBOL(set_signals);
20574 +EXPORT_SYMBOL(get_signals);
20575 +EXPORT_SYMBOL(kernel_thread);
20576 +EXPORT_SYMBOL(__const_udelay);
20577 +EXPORT_SYMBOL(__udelay);
20578 +EXPORT_SYMBOL(sys_waitpid);
20579 +EXPORT_SYMBOL(task_size);
20580 +EXPORT_SYMBOL(flush_tlb_range);
20581 +EXPORT_SYMBOL(host_task_size);
20582 +EXPORT_SYMBOL(arch_validate);
20583 +EXPORT_SYMBOL(get_kmem_end);
20584 +
20585 +EXPORT_SYMBOL(high_physmem);
20586 +EXPORT_SYMBOL(empty_zero_page);
20587 +EXPORT_SYMBOL(um_virt_to_phys);
20588 +EXPORT_SYMBOL(__virt_to_page);
20589 +EXPORT_SYMBOL(to_phys);
20590 +EXPORT_SYMBOL(to_virt);
20591 +EXPORT_SYMBOL(mode_tt);
20592 +EXPORT_SYMBOL(handle_page_fault);
20593 +
20594 +#ifdef CONFIG_MODE_TT
20595 +EXPORT_SYMBOL(copy_from_user_tt);
20596 +EXPORT_SYMBOL(copy_to_user_tt);
20597 +#endif
20598 +
20599 +#ifdef CONFIG_MODE_SKAS
20600 +EXPORT_SYMBOL(copy_to_user_skas);
20601 +EXPORT_SYMBOL(copy_from_user_skas);
20602 +#endif
20603 +
20604 +EXPORT_SYMBOL(os_stat_fd);
20605 +EXPORT_SYMBOL(os_stat_file);
20606 +EXPORT_SYMBOL(os_access);
20607 +EXPORT_SYMBOL(os_print_error);
20608 +EXPORT_SYMBOL(os_get_exec_close);
20609 +EXPORT_SYMBOL(os_set_exec_close);
20610 +EXPORT_SYMBOL(os_getpid);
20611 +EXPORT_SYMBOL(os_open_file);
20612 +EXPORT_SYMBOL(os_read_file);
20613 +EXPORT_SYMBOL(os_write_file);
20614 +EXPORT_SYMBOL(os_seek_file);
20615 +EXPORT_SYMBOL(os_lock_file);
20616 +EXPORT_SYMBOL(os_pipe);
20617 +EXPORT_SYMBOL(os_file_type);
20618 +EXPORT_SYMBOL(os_file_mode);
20619 +EXPORT_SYMBOL(os_file_size);
20620 +EXPORT_SYMBOL(os_flush_stdout);
20621 +EXPORT_SYMBOL(os_close_file);
20622 +EXPORT_SYMBOL(os_set_fd_async);
20623 +EXPORT_SYMBOL(os_set_fd_block);
20624 +EXPORT_SYMBOL(helper_wait);
20625 +EXPORT_SYMBOL(os_shutdown_socket);
20626 +EXPORT_SYMBOL(os_create_unix_socket);
20627 +EXPORT_SYMBOL(os_connect_socket);
20628 +EXPORT_SYMBOL(os_accept_connection);
20629 +EXPORT_SYMBOL(os_rcv_fd);
20630 +EXPORT_SYMBOL(run_helper);
20631 +EXPORT_SYMBOL(start_thread);
20632 +EXPORT_SYMBOL(dump_thread);
20633 +
20634 +/* This is here because UML expands open to sys_open, not to a system
20635 + * call instruction.
20636 + */
20637 +EXPORT_SYMBOL(sys_open);
20638 +EXPORT_SYMBOL(sys_lseek);
20639 +EXPORT_SYMBOL(sys_read);
20640 +EXPORT_SYMBOL(sys_wait4);
20641 +
20642 +#ifdef CONFIG_SMP
20643 +
20644 +/* required for SMP */
20645 +
20646 +extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
20647 +EXPORT_SYMBOL_NOVERS(__write_lock_failed);
20648 +
20649 +extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
20650 +EXPORT_SYMBOL_NOVERS(__read_lock_failed);
20651 +
20652 +EXPORT_SYMBOL(kernel_flag_cacheline);
20653 +EXPORT_SYMBOL(smp_num_cpus);
20654 +
20655 +#endif
20656 +
20657 +/*
20658 + * Overrides for Emacs so that we follow Linus's tabbing style.
20659 + * Emacs will notice this stuff at the end of the file and automatically
20660 + * adjust the settings for this buffer only.  This must remain at the end
20661 + * of the file.
20662 + * ---------------------------------------------------------------------------
20663 + * Local variables:
20664 + * c-file-style: "linux"
20665 + * End:
20666 + */
20667 diff -Naur -X ../exclude-files orig/arch/um/kernel/Makefile um/arch/um/kernel/Makefile
20668 --- orig/arch/um/kernel/Makefile        1969-12-31 19:00:00.000000000 -0500
20669 +++ um/arch/um/kernel/Makefile  2003-10-21 03:26:06.000000000 -0400
20670 @@ -0,0 +1,73 @@
20671 +# 
20672 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
20673 +# Licensed under the GPL
20674 +#
20675 +
20676 +O_TARGET = built-in.o
20677 +
20678 +obj-y = config.o checksum.o exec_kern.o exitcode.o frame_kern.o frame.o \
20679 +       helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
20680 +       physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
20681 +       sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
20682 +       syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
20683 +       time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
20684 +       um_arch.o umid.o user_syms.o user_util.o
20685 +
20686 +obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
20687 +obj-$(CONFIG_GPROF) += gprof_syms.o
20688 +obj-$(CONFIG_GCOV) += gmon_syms.o
20689 +obj-$(CONFIG_TTY_LOG) += tty_log.o
20690 +
20691 +subdir-$(CONFIG_MODE_TT) += tt
20692 +subdir-$(CONFIG_MODE_SKAS) += skas
20693 +
20694 +user-objs-$(CONFIG_TTY_LOG) += tty_log.o
20695 +
20696 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
20697 +
20698 +# user_syms.o not included here because Rules.make has its own ideas about
20699 +# building anything in export-objs
20700 +
20701 +USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
20702 +       process.o tempfile.o time.o umid.o user_util.o 
20703 +
20704 +DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__
20705 +DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__
20706 +
20707 +export-objs-$(CONFIG_GPROF) += gprof_syms.o
20708 +export-objs-$(CONFIG_GCOV) += gmon_syms.o
20709 +
20710 +export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y)
20711 +
20712 +CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
20713 +       -I/usr/include -I../include
20714 +
20715 +CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
20716 +
20717 +include $(TOPDIR)/Rules.make
20718 +
20719 +$(USER_OBJS) : %.o: %.c
20720 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
20721 +
20722 +# This has to be separate because it needs be compiled with frame pointers
20723 +# regardless of how the rest of the kernel is built.
20724 +
20725 +frame.o: frame.c
20726 +       $(CC) $(CFLAGS_$@) -c -o $@ $<
20727 +
20728 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
20729 +
20730 +config.c : config.c.in $(TOPDIR)/.config
20731 +       $(PERL) -e $(QUOTE) < config.c.in > $@
20732 +
20733 +clean:
20734 +       $(RM) config.c
20735 +       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
20736 +
20737 +modules:
20738 +
20739 +fastdep:
20740 +
20741 +dep:
20742 +
20743 +archmrproper: clean
20744 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem.c um/arch/um/kernel/mem.c
20745 --- orig/arch/um/kernel/mem.c   1969-12-31 19:00:00.000000000 -0500
20746 +++ um/arch/um/kernel/mem.c     2003-11-13 23:26:35.000000000 -0500
20747 @@ -0,0 +1,336 @@
20748 +/* 
20749 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
20750 + * Licensed under the GPL
20751 + */
20752 +
20753 +#include "linux/stddef.h"
20754 +#include "linux/kernel.h"
20755 +#include "linux/mm.h"
20756 +#include "linux/bootmem.h"
20757 +#include "linux/highmem.h"
20758 +#include "asm/page.h"
20759 +#include "asm/fixmap.h"
20760 +#include "asm/pgalloc.h"
20761 +#include "user_util.h"
20762 +#include "kern_util.h"
20763 +#include "kern.h"
20764 +#include "mem_user.h"
20765 +#include "uml_uaccess.h"
20766 +#include "os.h"
20767 +
20768 +extern char __binary_start;
20769 +
20770 +/* Changed during early boot */
20771 +unsigned long *empty_zero_page = NULL;
20772 +unsigned long *empty_bad_page = NULL;
20773 +pgd_t swapper_pg_dir[1024];
20774 +unsigned long highmem;
20775 +int kmalloc_ok = 0;
20776 +
20777 +static unsigned long brk_end;
20778 +static unsigned long totalram_pages = 0;
20779 +
20780 +void unmap_physmem(void)
20781 +{
20782 +       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
20783 +}
20784 +
20785 +static void map_cb(void *unused)
20786 +{
20787 +       map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
20788 +}
20789 +
20790 +#ifdef CONFIG_HIGHMEM
20791 +static void setup_highmem(unsigned long highmem_start, 
20792 +                         unsigned long highmem_len)
20793 +{
20794 +       struct page *page;
20795 +       unsigned long highmem_pfn;
20796 +       int i;
20797 +
20798 +       highmem_start_page = virt_to_page(highmem_start);
20799 +
20800 +       highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
20801 +       for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
20802 +               page = &mem_map[highmem_pfn + i];
20803 +               ClearPageReserved(page);
20804 +               set_bit(PG_highmem, &page->flags);
20805 +               atomic_set(&page->count, 1);
20806 +               __free_page(page);
20807 +       }
20808 +}
20809 +#endif
20810 +
20811 +void mem_init(void)
20812 +{
20813 +       unsigned long start;
20814 +
20815 +        /* clear the zero-page */
20816 +        memset((void *) empty_zero_page, 0, PAGE_SIZE);
20817 +
20818 +       /* Map in the area just after the brk now that kmalloc is about
20819 +        * to be turned on.
20820 +        */
20821 +       brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
20822 +       map_cb(NULL);
20823 +       initial_thread_cb(map_cb, NULL);
20824 +       free_bootmem(__pa(brk_end), uml_reserved - brk_end);
20825 +       uml_reserved = brk_end;
20826 +
20827 +       /* Fill in any hole at the start of the binary */
20828 +       start = (unsigned long) &__binary_start;
20829 +       if(uml_physmem != start){
20830 +               map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem,
20831 +                   1, 1, 0);
20832 +       }
20833 +
20834 +       /* this will put all low memory onto the freelists */
20835 +       totalram_pages = free_all_bootmem();
20836 +       totalram_pages += highmem >> PAGE_SHIFT;
20837 +       num_physpages = totalram_pages;
20838 +       printk(KERN_INFO "Memory: %luk available\n", 
20839 +              (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
20840 +       kmalloc_ok = 1;
20841 +
20842 +#ifdef CONFIG_HIGHMEM
20843 +       setup_highmem(end_iomem, highmem);
20844 +#endif
20845 +}
20846 +
20847 +static void __init fixrange_init(unsigned long start, unsigned long end, 
20848 +                                pgd_t *pgd_base)
20849 +{
20850 +       pgd_t *pgd;
20851 +       pmd_t *pmd;
20852 +       pte_t *pte;
20853 +       int i, j;
20854 +       unsigned long vaddr;
20855 +
20856 +       vaddr = start;
20857 +       i = __pgd_offset(vaddr);
20858 +       j = __pmd_offset(vaddr);
20859 +       pgd = pgd_base + i;
20860 +
20861 +       for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
20862 +               pmd = (pmd_t *)pgd;
20863 +               for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
20864 +                       if (pmd_none(*pmd)) {
20865 +                               pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
20866 +                               set_pmd(pmd, __pmd(_KERNPG_TABLE + 
20867 +                                                  (unsigned long) __pa(pte)));
20868 +                               if (pte != pte_offset(pmd, 0))
20869 +                                       BUG();
20870 +                       }
20871 +                       vaddr += PMD_SIZE;
20872 +               }
20873 +               j = 0;
20874 +       }
20875 +}
20876 +
20877 +#if CONFIG_HIGHMEM
20878 +pte_t *kmap_pte;
20879 +pgprot_t kmap_prot;
20880 +
20881 +#define kmap_get_fixmap_pte(vaddr)                                     \
20882 +       pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
20883 +
20884 +void __init kmap_init(void)
20885 +{
20886 +       unsigned long kmap_vstart;
20887 +
20888 +       /* cache the first kmap pte */
20889 +       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
20890 +       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
20891 +
20892 +       kmap_prot = PAGE_KERNEL;
20893 +}
20894 +
20895 +static void init_highmem(void)
20896 +{
20897 +       pgd_t *pgd;
20898 +       pmd_t *pmd;
20899 +       pte_t *pte;
20900 +       unsigned long vaddr;
20901 +
20902 +       /*
20903 +        * Permanent kmaps:
20904 +        */
20905 +       vaddr = PKMAP_BASE;
20906 +       fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir);
20907 +
20908 +       pgd = swapper_pg_dir + __pgd_offset(vaddr);
20909 +       pmd = pmd_offset(pgd, vaddr);
20910 +       pte = pte_offset(pmd, vaddr);
20911 +       pkmap_page_table = pte;
20912 +
20913 +       kmap_init();
20914 +}
20915 +
20916 +#endif /* CONFIG_HIGHMEM */
20917 +
20918 +void paging_init(void)
20919 +{
20920 +       unsigned long zones_size[MAX_NR_ZONES], vaddr;
20921 +       int i;
20922 +
20923 +       empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
20924 +       empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
20925 +       for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 
20926 +               zones_size[i] = 0;
20927 +       zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
20928 +       zones_size[2] = highmem >> PAGE_SHIFT;
20929 +       free_area_init(zones_size);
20930 +
20931 +       /*
20932 +        * Fixed mappings, only the page table structure has to be
20933 +        * created - mappings will be set by set_fixmap():
20934 +        */
20935 +       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
20936 +       fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir);
20937 +
20938 +#if CONFIG_HIGHMEM
20939 +       init_highmem();
20940 +#endif
20941 +}
20942 +
20943 +struct page *arch_validate(struct page *page, int mask, int order)
20944 +{
20945 +       unsigned long addr, zero = 0;
20946 +       int i;
20947 +
20948 + again:
20949 +       if(page == NULL) return(page);
20950 +       if(PageHighMem(page)) return(page);
20951 +
20952 +       addr = (unsigned long) page_address(page);
20953 +       for(i = 0; i < (1 << order); i++){
20954 +               current->thread.fault_addr = (void *) addr;
20955 +               if(__do_copy_to_user((void *) addr, &zero, 
20956 +                                    sizeof(zero),
20957 +                                    &current->thread.fault_addr,
20958 +                                    &current->thread.fault_catcher)){
20959 +                       if(!(mask & __GFP_WAIT)) return(NULL);
20960 +                       else break;
20961 +               }
20962 +               addr += PAGE_SIZE;
20963 +       }
20964 +       if(i == (1 << order)) return(page);
20965 +       page = _alloc_pages(mask, order);
20966 +       goto again;
20967 +}
20968 +
20969 +/* This can't do anything because nothing in the kernel image can be freed
20970 + * since it's not in kernel physical memory.
20971 + */
20972 +
20973 +void free_initmem(void)
20974 +{
20975 +}
20976 +
20977 +#ifdef CONFIG_BLK_DEV_INITRD
20978 +
20979 +void free_initrd_mem(unsigned long start, unsigned long end)
20980 +{
20981 +       if (start < end)
20982 +               printk ("Freeing initrd memory: %ldk freed\n", 
20983 +                       (end - start) >> 10);
20984 +       for (; start < end; start += PAGE_SIZE) {
20985 +               ClearPageReserved(virt_to_page(start));
20986 +               set_page_count(virt_to_page(start), 1);
20987 +               free_page(start);
20988 +               totalram_pages++;
20989 +       }
20990 +}
20991 +       
20992 +#endif
20993 +
20994 +int do_check_pgt_cache(int low, int high)
20995 +{
20996 +        int freed = 0;
20997 +        if(pgtable_cache_size > high) {
20998 +                do {
20999 +                        if (pgd_quicklist) {
21000 +                                free_pgd_slow(get_pgd_fast());
21001 +                                freed++;
21002 +                        }
21003 +                        if (pmd_quicklist) {
21004 +                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
21005 +                                freed++;
21006 +                        }
21007 +                        if (pte_quicklist) {
21008 +                                pte_free_slow(pte_alloc_one_fast(NULL, 0));
21009 +                                freed++;
21010 +                        }
21011 +                } while(pgtable_cache_size > low);
21012 +        }
21013 +        return freed;
21014 +}
21015 +
21016 +void show_mem(void)
21017 +{
21018 +        int i, total = 0, reserved = 0;
21019 +        int shared = 0, cached = 0;
21020 +        int highmem = 0;
21021 +
21022 +        printk("Mem-info:\n");
21023 +        show_free_areas();
21024 +        printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
21025 +        i = max_mapnr;
21026 +        while(i-- > 0) {
21027 +                total++;
21028 +                if(PageHighMem(mem_map + i))
21029 +                        highmem++;
21030 +                if(PageReserved(mem_map + i))
21031 +                        reserved++;
21032 +                else if(PageSwapCache(mem_map + i))
21033 +                        cached++;
21034 +                else if(page_count(mem_map + i))
21035 +                        shared += page_count(mem_map + i) - 1;
21036 +        }
21037 +        printk("%d pages of RAM\n", total);
21038 +        printk("%d pages of HIGHMEM\n", highmem);
21039 +        printk("%d reserved pages\n", reserved);
21040 +        printk("%d pages shared\n", shared);
21041 +        printk("%d pages swap cached\n", cached);
21042 +        printk("%ld pages in page table cache\n", pgtable_cache_size);
21043 +        show_buffers();
21044 +}
21045 +
21046 +/* Changed by meminfo_compat, which is a setup */
21047 +static int meminfo_22 = 0;
21048 +
21049 +static int meminfo_compat(char *str)
21050 +{
21051 +       meminfo_22 = 1;
21052 +       return(1);
21053 +}
21054 +
21055 +__setup("22_meminfo", meminfo_compat);
21056 +
21057 +void si_meminfo(struct sysinfo *val)
21058 +{
21059 +       val->totalram = totalram_pages;
21060 +       val->sharedram = 0;
21061 +       val->freeram = nr_free_pages();
21062 +       val->bufferram = atomic_read(&buffermem_pages);
21063 +       val->totalhigh = highmem >> PAGE_SHIFT;
21064 +       val->freehigh = nr_free_highpages();
21065 +       val->mem_unit = PAGE_SIZE;
21066 +       if(meminfo_22){
21067 +               val->freeram <<= PAGE_SHIFT;
21068 +               val->bufferram <<= PAGE_SHIFT;
21069 +               val->totalram <<= PAGE_SHIFT;
21070 +               val->sharedram <<= PAGE_SHIFT;
21071 +       }
21072 +}
21073 +
21074 +/*
21075 + * Overrides for Emacs so that we follow Linus's tabbing style.
21076 + * Emacs will notice this stuff at the end of the file and automatically
21077 + * adjust the settings for this buffer only.  This must remain at the end
21078 + * of the file.
21079 + * ---------------------------------------------------------------------------
21080 + * Local variables:
21081 + * c-file-style: "linux"
21082 + * End:
21083 + */
21084 diff -Naur -X ../exclude-files orig/arch/um/kernel/mem_user.c um/arch/um/kernel/mem_user.c
21085 --- orig/arch/um/kernel/mem_user.c      1969-12-31 19:00:00.000000000 -0500
21086 +++ um/arch/um/kernel/mem_user.c        2003-12-14 11:30:57.000000000 -0500
21087 @@ -0,0 +1,217 @@
21088 +/*
21089 + * arch/um/kernel/mem_user.c
21090 + *
21091 + * BRIEF MODULE DESCRIPTION
21092 + * user side memory routines for supporting IO memory inside user mode linux
21093 + *
21094 + * Copyright (C) 2001 RidgeRun, Inc.
21095 + * Author: RidgeRun, Inc.
21096 + *         Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
21097 + *
21098 + *  This program is free software; you can redistribute  it and/or modify it
21099 + *  under  the terms of  the GNU General  Public License as published by the
21100 + *  Free Software Foundation;  either version 2 of the  License, or (at your
21101 + *  option) any later version.
21102 + *
21103 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
21104 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
21105 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
21106 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
21107 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21108 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
21109 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21110 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
21111 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21112 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21113 + *
21114 + *  You should have received a copy of the  GNU General Public License along
21115 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
21116 + *  675 Mass Ave, Cambridge, MA 02139, USA.
21117 + */
21118 +
21119 +#include <stdio.h>
21120 +#include <stdlib.h>
21121 +#include <stddef.h>
21122 +#include <stdarg.h>
21123 +#include <unistd.h>
21124 +#include <errno.h>
21125 +#include <string.h>
21126 +#include <fcntl.h>
21127 +#include <sys/types.h>
21128 +#include <sys/mman.h>
21129 +#include "kern_util.h"
21130 +#include "user.h"
21131 +#include "user_util.h"
21132 +#include "mem_user.h"
21133 +#include "init.h"
21134 +#include "os.h"
21135 +#include "tempfile.h"
21136 +#include "kern_constants.h"
21137 +
21138 +extern struct mem_region physmem_region;
21139 +
21140 +#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
21141 +
21142 +static int create_tmp_file(unsigned long len)
21143 +{
21144 +       int fd, err;
21145 +       char zero;
21146 +
21147 +       fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
21148 +       if(fd < 0) {
21149 +               os_print_error(fd, "make_tempfile");
21150 +               exit(1);
21151 +       }
21152 +
21153 +       err = os_mode_fd(fd, 0777);
21154 +       if(err < 0){
21155 +               os_print_error(err, "os_mode_fd");
21156 +               exit(1);
21157 +       }
21158 +       err = os_seek_file(fd, len);
21159 +       if(err < 0){
21160 +               os_print_error(err, "os_seek_file");
21161 +               exit(1);
21162 +       }
21163 +       zero = 0;
21164 +       err = os_write_file(fd, &zero, 1);
21165 +       if(err != 1){
21166 +               os_print_error(err, "os_write_file");
21167 +               exit(1);
21168 +       }
21169 +
21170 +       return(fd);
21171 +}
21172 +
21173 +static int have_devanon = 0;
21174 +
21175 +void check_devanon(void)
21176 +{
21177 +       int fd;
21178 +
21179 +       printk("Checking for /dev/anon on the host...");
21180 +       fd = open("/dev/anon", O_RDWR);
21181 +       if(fd < 0){
21182 +               printk("Not available (open failed with errno %d)\n", errno);
21183 +               return;
21184 +       }
21185 +
21186 +       printk("OK\n");
21187 +       have_devanon = 1;
21188 +}
21189 +
21190 +static int create_anon_file(unsigned long len)
21191 +{
21192 +       void *addr;
21193 +       int fd;
21194 +
21195 +       fd = open("/dev/anon", O_RDWR);
21196 +       if(fd < 0) {
21197 +               os_print_error(fd, "opening /dev/anon");
21198 +               exit(1);
21199 +       }
21200 +
21201 +       addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0);
21202 +       if(addr == MAP_FAILED){
21203 +               os_print_error((int) addr, "mapping physmem file");
21204 +               exit(1);
21205 +       }
21206 +       munmap(addr, len);
21207 +
21208 +       return(fd);
21209 +}
21210 +
21211 +int create_mem_file(unsigned long len)
21212 +{
21213 +       int err, fd;
21214 +
21215 +       if(have_devanon)
21216 +               fd = create_anon_file(len);
21217 +       else fd = create_tmp_file(len);
21218 +
21219 +       err = os_set_exec_close(fd, 1);
21220 +       if(err < 0)
21221 +               os_print_error(err, "exec_close");
21222 +       return(fd);
21223 +}
21224 +
21225 +struct iomem_region *iomem_regions = NULL;
21226 +int iomem_size = 0;
21227 +
21228 +static int __init parse_iomem(char *str, int *add)
21229 +{
21230 +       struct iomem_region *new;
21231 +       struct uml_stat buf;
21232 +       char *file, *driver;
21233 +       int fd, err;
21234 +
21235 +       driver = str;
21236 +       file = strchr(str,',');
21237 +       if(file == NULL){
21238 +               printf("parse_iomem : failed to parse iomem\n");
21239 +               goto out;
21240 +       }
21241 +       *file = '\0';
21242 +       file++;
21243 +       fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
21244 +       if(fd < 0){
21245 +               os_print_error(fd, "parse_iomem - Couldn't open io file");
21246 +               goto out;
21247 +       }
21248 +       err = os_stat_fd(fd, &buf);
21249 +       if(err < 0){
21250 +               os_print_error(err, "parse_iomem - cannot stat_fd file");
21251 +               goto out_close;
21252 +       }
21253 +
21254 +       new = malloc(sizeof(*new));
21255 +       if(new == NULL){
21256 +               perror("Couldn't allocate iomem_region struct");
21257 +               goto out_close;
21258 +       }
21259 +
21260 +       *new = ((struct iomem_region) { .next           = iomem_regions,
21261 +                                       .driver         = driver,
21262 +                                       .fd             = fd,
21263 +                                       .size           = buf.ust_size,
21264 +                                       .phys           = 0,
21265 +                                       .virt           = 0 });
21266 +       iomem_regions = new;
21267 +       iomem_size += new->size + UM_KERN_PAGE_SIZE;
21268 +
21269 +       return(0);
21270 + out_close:
21271 +       os_close_file(fd);
21272 + out:
21273 +       return(1);
21274 +}
21275 +
21276 +__uml_setup("iomem=", parse_iomem,
21277 +"iomem=<name>,<file>\n"
21278 +"    Configure <file> as an IO memory region named <name>.\n\n"
21279 +);
21280 +
21281 +int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
21282 +                  int must_succeed)
21283 +{
21284 +       int err;
21285 +
21286 +       err = os_protect_memory((void *) addr, len, r, w, x);
21287 +       if(err < 0){
21288 +                if(must_succeed)
21289 +                        panic("protect failed, err = %d", -err);
21290 +                else return(err);
21291 +       }
21292 +       return(0);
21293 +}
21294 +
21295 +/*
21296 + * Overrides for Emacs so that we follow Linus's tabbing style.
21297 + * Emacs will notice this stuff at the end of the file and automatically
21298 + * adjust the settings for this buffer only.  This must remain at the end
21299 + * of the file.
21300 + * ---------------------------------------------------------------------------
21301 + * Local variables:
21302 + * c-file-style: "linux"
21303 + * End:
21304 + */
21305 diff -Naur -X ../exclude-files orig/arch/um/kernel/mprot.h um/arch/um/kernel/mprot.h
21306 --- orig/arch/um/kernel/mprot.h 1969-12-31 19:00:00.000000000 -0500
21307 +++ um/arch/um/kernel/mprot.h   2003-10-21 03:26:06.000000000 -0400
21308 @@ -0,0 +1,6 @@
21309 +#ifndef __MPROT_H__
21310 +#define __MPROT_H__
21311 +
21312 +extern void no_access(unsigned long addr, unsigned int len);
21313 +
21314 +#endif
21315 diff -Naur -X ../exclude-files orig/arch/um/kernel/physmem.c um/arch/um/kernel/physmem.c
21316 --- orig/arch/um/kernel/physmem.c       1969-12-31 19:00:00.000000000 -0500
21317 +++ um/arch/um/kernel/physmem.c 2003-11-14 02:59:20.000000000 -0500
21318 @@ -0,0 +1,349 @@
21319 +/* 
21320 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
21321 + * Licensed under the GPL
21322 + */
21323 +
21324 +#include "linux/mm.h"
21325 +#include "linux/ghash.h"
21326 +#include "linux/slab.h"
21327 +#include "linux/vmalloc.h"
21328 +#include "linux/bootmem.h"
21329 +#include "asm/types.h"
21330 +#include "asm/pgtable.h"
21331 +#include "kern_util.h"
21332 +#include "user_util.h"
21333 +#include "mode_kern.h"
21334 +#include "mem.h"
21335 +#include "mem_user.h"
21336 +#include "os.h"
21337 +#include "kern.h"
21338 +#include "init.h"
21339 +
21340 +#define PHYS_HASHSIZE (8192)
21341 +
21342 +struct phys_desc;
21343 +
21344 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
21345 +
21346 +struct phys_desc {
21347 +       struct virtmem_ptrs virt_ptrs;
21348 +       int fd;
21349 +       __u64 offset;
21350 +       void *virt;
21351 +       unsigned long phys;
21352 +};
21353 +
21354 +struct virtmem_table virtmem_hash;
21355 +
21356 +static int virt_cmp(void *virt1, void *virt2)
21357 +{
21358 +       return(virt1 != virt2);
21359 +}
21360 +
21361 +static int virt_hash(void *virt)
21362 +{
21363 +       unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
21364 +       return(addr % PHYS_HASHSIZE);
21365 +}
21366 +
21367 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp, 
21368 +        virt_hash);
21369 +
21370 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
21371 +{
21372 +       struct phys_desc *desc;
21373 +       unsigned long phys;
21374 +       int err;
21375 +
21376 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
21377 +       err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
21378 +       if(err)
21379 +               goto out;
21380 +
21381 +       phys = __pa(virt);
21382 +       if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
21383 +               panic("Address 0x%p is already substituted\n", virt);
21384 +
21385 +       err = -ENOMEM;
21386 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
21387 +       if(desc == NULL)
21388 +               goto out;
21389 +
21390 +       *desc = ((struct phys_desc) { .virt_ptrs =      { NULL, NULL },
21391 +                                     .fd =             fd,
21392 +                                     .offset =         offset,
21393 +                                     .virt =           virt,
21394 +                                     .phys =           __pa(virt) });
21395 +       insert_virtmem_hash(&virtmem_hash, desc);
21396 +       err = 0;
21397 + out:
21398 +       return(err);
21399 +}
21400 +
21401 +static int physmem_fd = -1;
21402 +
21403 +int physmem_remove_mapping(void *virt)
21404 +{
21405 +       struct phys_desc *desc;
21406 +       int err;
21407 +
21408 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
21409 +       desc = find_virtmem_hash(&virtmem_hash, virt);
21410 +       if(desc == NULL)
21411 +               return(0);
21412 +
21413 +       remove_virtmem_hash(&virtmem_hash, desc);
21414 +       kfree(desc);
21415 +
21416 +       err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
21417 +       if(err)
21418 +               panic("Failed to unmap block device page from physical memory, "
21419 +                     "errno = %d", -err);
21420 +       return(1);
21421 +}
21422 +
21423 +void arch_free_page(struct page *page, int order)
21424 +{
21425 +       void *virt;
21426 +       int i;
21427 +
21428 +       for(i = 0; i < 1 << order; i++){
21429 +               virt = __va(page_to_phys(page + i));
21430 +               physmem_remove_mapping(virt);
21431 +       }
21432 +}
21433 +
21434 +int is_remapped(void *virt)
21435 +{
21436 +       return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
21437 +}
21438 +
21439 +/* Changed during early boot */
21440 +unsigned long high_physmem;
21441 +
21442 +extern unsigned long physmem_size;
21443 +
21444 +void *to_virt(unsigned long phys)
21445 +{
21446 +       return((void *) uml_physmem + phys);
21447 +}
21448 +
21449 +unsigned long to_phys(void *virt)
21450 +{
21451 +       return(((unsigned long) virt) - uml_physmem);
21452 +}
21453 +
21454 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
21455 +{
21456 +       struct page *p, *map;
21457 +       unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
21458 +       unsigned long iomem_len, iomem_pages, total_len, total_pages;
21459 +       int i;
21460 +
21461 +       phys_pages = physmem >> PAGE_SHIFT;
21462 +       phys_len = phys_pages * sizeof(struct page);
21463 +
21464 +       iomem_pages = iomem >> PAGE_SHIFT;
21465 +       iomem_len = iomem_pages * sizeof(struct page);
21466 +
21467 +       highmem_pages = highmem >> PAGE_SHIFT;
21468 +       highmem_len = highmem_pages * sizeof(struct page);
21469 +
21470 +       total_pages = phys_pages + iomem_pages + highmem_pages;
21471 +       total_len = phys_len + iomem_pages + highmem_len;
21472 +
21473 +       if(kmalloc_ok){
21474 +               map = kmalloc(total_len, GFP_KERNEL);
21475 +               if(map == NULL) 
21476 +                       map = vmalloc(total_len);
21477 +       }
21478 +       else map = alloc_bootmem_low_pages(total_len);
21479 +
21480 +       if(map == NULL)
21481 +               return(-ENOMEM);
21482 +
21483 +       for(i = 0; i < total_pages; i++){
21484 +               p = &map[i];
21485 +               set_page_count(p, 0);
21486 +               SetPageReserved(p);
21487 +               INIT_LIST_HEAD(&p->list);
21488 +       }
21489 +
21490 +       mem_map = map;
21491 +       max_mapnr = total_pages;
21492 +       return(0);
21493 +}
21494 +
21495 +struct page *phys_to_page(const unsigned long phys)
21496 +{
21497 +       return(&mem_map[phys >> PAGE_SHIFT]);
21498 +}
21499 +
21500 +struct page *__virt_to_page(const unsigned long virt)
21501 +{
21502 +       return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
21503 +}
21504 +
21505 +unsigned long page_to_phys(struct page *page)
21506 +{
21507 +       return((page - mem_map) << PAGE_SHIFT);
21508 +}
21509 +
21510 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
21511 +{
21512 +       pte_t pte;
21513 +
21514 +       pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
21515 +       if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
21516 +       return(pte);
21517 +}
21518 +
21519 +/* Changed during early boot */
21520 +static unsigned long kmem_top = 0;
21521 +
21522 +unsigned long get_kmem_end(void)
21523 +{
21524 +       if(kmem_top == 0) 
21525 +               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
21526 +       return(kmem_top);
21527 +}
21528 +
21529 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
21530 +               int r, int w, int x)
21531 +{
21532 +       __u64 offset;
21533 +       int fd, err;
21534 +
21535 +       fd = phys_mapping(phys, &offset);
21536 +       err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
21537 +       if(err)
21538 +               panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
21539 +                     "err = %d\n", virt, fd, offset, len, r, w, x, err);
21540 +}
21541 +
21542 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
21543 +
21544 +void setup_physmem(unsigned long start, unsigned long reserve_end,
21545 +                  unsigned long len, unsigned long highmem)
21546 +{
21547 +       unsigned long reserve = reserve_end - start;
21548 +       int pfn = PFN_UP(__pa(reserve_end));
21549 +       int delta = (len - reserve) >> PAGE_SHIFT;
21550 +       int err, offset, bootmap_size;
21551 +
21552 +       physmem_fd = create_mem_file(len + highmem);
21553 +
21554 +       offset = uml_reserved - uml_physmem;
21555 +       err = os_map_memory((void *) uml_reserved, physmem_fd, offset, 
21556 +                           len - offset, 1, 1, 0);
21557 +       if(err < 0){
21558 +               os_print_error(err, "Mapping memory");
21559 +               exit(1);
21560 +       }
21561 +
21562 +       bootmap_size = init_bootmem(pfn, pfn + delta);
21563 +       free_bootmem(__pa(reserve_end) + bootmap_size,
21564 +                    len - bootmap_size - reserve);
21565 +}
21566 +
21567 +int phys_mapping(unsigned long phys, __u64 *offset_out)
21568 +{
21569 +       struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, 
21570 +                                                  __va(phys & PAGE_MASK));
21571 +       int fd = -1;
21572 +
21573 +       if(desc != NULL){
21574 +               fd = desc->fd;
21575 +               *offset_out = desc->offset;
21576 +       }
21577 +       else if(phys < physmem_size){
21578 +               fd = physmem_fd;
21579 +               *offset_out = phys;
21580 +       }
21581 +       else if(phys < __pa(end_iomem)){
21582 +               struct iomem_region *region = iomem_regions;
21583 +       
21584 +               while(region != NULL){
21585 +                       if((phys >= region->phys) && 
21586 +                          (phys < region->phys + region->size)){
21587 +                               fd = region->fd;
21588 +                               *offset_out = phys - region->phys;
21589 +                               break;
21590 +                       }
21591 +                       region = region->next;
21592 +               }
21593 +       }
21594 +       else if(phys < __pa(end_iomem) + highmem){
21595 +               fd = physmem_fd;
21596 +               *offset_out = phys - iomem_size;
21597 +       }
21598 +
21599 +       return(fd);
21600 +}
21601 +
21602 +static int __init uml_mem_setup(char *line, int *add)
21603 +{
21604 +       char *retptr;
21605 +       physmem_size = memparse(line,&retptr);
21606 +       return 0;
21607 +}
21608 +__uml_setup("mem=", uml_mem_setup,
21609 +"mem=<Amount of desired ram>\n"
21610 +"    This controls how much \"physical\" memory the kernel allocates\n"
21611 +"    for the system. The size is specified as a number followed by\n"
21612 +"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
21613 +"    This is not related to the amount of memory in the host.  It can\n"
21614 +"    be more, and the excess, if it's ever used, will just be swapped out.\n"
21615 +"      Example: mem=64M\n\n"
21616 +);
21617 +
21618 +unsigned long find_iomem(char *driver, unsigned long *len_out)
21619 +{
21620 +       struct iomem_region *region = iomem_regions;
21621 +       
21622 +       while(region != NULL){
21623 +               if(!strcmp(region->driver, driver)){
21624 +                       *len_out = region->size;
21625 +                       return(region->virt);
21626 +               }
21627 +       }
21628 +
21629 +       return(0);
21630 +}
21631 +
21632 +int setup_iomem(void)
21633 +{
21634 +       struct iomem_region *region = iomem_regions;
21635 +       unsigned long iomem_start = high_physmem + PAGE_SIZE;
21636 +       int err;
21637 +
21638 +       while(region != NULL){
21639 +               err = os_map_memory((void *) iomem_start, region->fd, 0, 
21640 +                                   region->size, 1, 1, 0);
21641 +               if(err)
21642 +                       printk("Mapping iomem region for driver '%s' failed, "
21643 +                              "errno = %d\n", region->driver, -err);
21644 +               else {
21645 +                       region->virt = iomem_start;
21646 +                       region->phys = __pa(region->virt);
21647 +               }
21648 +
21649 +               iomem_start += region->size + PAGE_SIZE;
21650 +               region = region->next;
21651 +       }
21652 +
21653 +       return(0);
21654 +}
21655 +
21656 +__initcall(setup_iomem);
21657 +
21658 +/*
21659 + * Overrides for Emacs so that we follow Linus's tabbing style.
21660 + * Emacs will notice this stuff at the end of the file and automatically
21661 + * adjust the settings for this buffer only.  This must remain at the end
21662 + * of the file.
21663 + * ---------------------------------------------------------------------------
21664 + * Local variables:
21665 + * c-file-style: "linux"
21666 + * End:
21667 + */
21668 diff -Naur -X ../exclude-files orig/arch/um/kernel/process.c um/arch/um/kernel/process.c
21669 --- orig/arch/um/kernel/process.c       1969-12-31 19:00:00.000000000 -0500
21670 +++ um/arch/um/kernel/process.c 2003-11-07 02:09:21.000000000 -0500
21671 @@ -0,0 +1,288 @@
21672 +/* 
21673 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
21674 + * Licensed under the GPL
21675 + */
21676 +
21677 +#include <stdio.h>
21678 +#include <unistd.h>
21679 +#include <signal.h>
21680 +#include <sched.h>
21681 +#include <errno.h>
21682 +#include <stdarg.h>
21683 +#include <stdlib.h>
21684 +#include <setjmp.h>
21685 +#include <sys/time.h>
21686 +#include <sys/ptrace.h>
21687 +#include <sys/wait.h>
21688 +#include <sys/mman.h>
21689 +#include <asm/ptrace.h>
21690 +#include <asm/sigcontext.h>
21691 +#include <asm/unistd.h>
21692 +#include <asm/page.h>
21693 +#include "user_util.h"
21694 +#include "kern_util.h"
21695 +#include "user.h"
21696 +#include "process.h"
21697 +#include "signal_kern.h"
21698 +#include "signal_user.h"
21699 +#include "sysdep/ptrace.h"
21700 +#include "sysdep/sigcontext.h"
21701 +#include "irq_user.h"
21702 +#include "ptrace_user.h"
21703 +#include "time_user.h"
21704 +#include "init.h"
21705 +#include "os.h"
21706 +#include "uml-config.h"
21707 +#include "choose-mode.h"
21708 +#include "mode.h"
21709 +#ifdef UML_CONFIG_MODE_SKAS
21710 +#include "skas.h"
21711 +#include "skas_ptrace.h"
21712 +#endif
21713 +
21714 +void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
21715 +{
21716 +       int flags = 0, pages;
21717 +
21718 +       if(sig_stack != NULL){
21719 +               pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
21720 +               set_sigstack(sig_stack, pages * page_size());
21721 +               flags = SA_ONSTACK;
21722 +       }
21723 +       if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1);
21724 +}
21725 +
21726 +void init_new_thread_signals(int altstack)
21727 +{
21728 +       int flags = altstack ? SA_ONSTACK : 0;
21729 +
21730 +       /* NODEFER is set here because SEGV isn't turned back on when the 
21731 +        * handler is ready to receive signals.  This causes any segfault
21732 +        * during a copy_user to kill the process because the fault is blocked.
21733 +        */
21734 +       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER,
21735 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21736 +       set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, 
21737 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21738 +       set_handler(SIGFPE, (__sighandler_t) sig_handler, flags, 
21739 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21740 +       set_handler(SIGILL, (__sighandler_t) sig_handler, flags, 
21741 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21742 +       set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, 
21743 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21744 +       set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, 
21745 +                   SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
21746 +       set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
21747 +                   SA_NOMASK | flags, -1);
21748 +       signal(SIGHUP, SIG_IGN);
21749 +
21750 +       init_irq_signals(altstack);
21751 +}
21752 +
21753 +struct tramp {
21754 +       int (*tramp)(void *);
21755 +       void *tramp_data;
21756 +       unsigned long temp_stack;
21757 +       int flags;
21758 +       int pid;
21759 +};
21760 +
21761 +/* See above for why sigkill is here */
21762 +
21763 +int sigkill = SIGKILL;
21764 +
21765 +int outer_tramp(void *arg)
21766 +{
21767 +       struct tramp *t;
21768 +       int sig = sigkill;
21769 +
21770 +       t = arg;
21771 +       t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
21772 +                      t->flags, t->tramp_data);
21773 +       if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
21774 +       kill(os_getpid(), sig);
21775 +       _exit(0);
21776 +}
21777 +
21778 +int start_fork_tramp(void *thread_arg, unsigned long temp_stack, 
21779 +                    int clone_flags, int (*tramp)(void *))
21780 +{
21781 +       struct tramp arg;
21782 +       unsigned long sp;
21783 +       int new_pid, status, err;
21784 +
21785 +       /* The trampoline will run on the temporary stack */
21786 +       sp = stack_sp(temp_stack);
21787 +
21788 +       clone_flags |= CLONE_FILES | SIGCHLD;
21789 +
21790 +       arg.tramp = tramp;
21791 +       arg.tramp_data = thread_arg;
21792 +       arg.temp_stack = temp_stack;
21793 +       arg.flags = clone_flags;
21794 +
21795 +       /* Start the process and wait for it to kill itself */
21796 +       new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
21797 +       if(new_pid < 0) return(-errno);
21798 +       while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ;
21799 +       if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
21800 +                         errno);
21801 +       if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
21802 +               panic("outer trampoline didn't exit with SIGKILL");
21803 +
21804 +       return(arg.pid);
21805 +}
21806 +
21807 +void suspend_new_thread(int fd)
21808 +{
21809 +       char c;
21810 +
21811 +       os_stop_process(os_getpid());
21812 +
21813 +       if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
21814 +               panic("read failed in suspend_new_thread");
21815 +}
21816 +
21817 +static int ptrace_child(void *arg)
21818 +{
21819 +       int pid = os_getpid();
21820 +
21821 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
21822 +               perror("ptrace");
21823 +               os_kill_process(pid, 0);
21824 +       }
21825 +       os_stop_process(pid);
21826 +       _exit(os_getpid() == pid);
21827 +}
21828 +
21829 +static int start_ptraced_child(void **stack_out)
21830 +{
21831 +       void *stack;
21832 +       unsigned long sp;
21833 +       int pid, n, status;
21834 +       
21835 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
21836 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
21837 +       if(stack == MAP_FAILED)
21838 +               panic("check_ptrace : mmap failed, errno = %d", errno);
21839 +       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
21840 +       pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
21841 +       if(pid < 0)
21842 +               panic("check_ptrace : clone failed, errno = %d", errno);
21843 +       n = waitpid(pid, &status, WUNTRACED);
21844 +       if(n < 0)
21845 +               panic("check_ptrace : wait failed, errno = %d", errno);
21846 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
21847 +               panic("check_ptrace : expected SIGSTOP, got status = %d",
21848 +                     status);
21849 +
21850 +       *stack_out = stack;
21851 +       return(pid);
21852 +}
21853 +
21854 +static void stop_ptraced_child(int pid, void *stack, int exitcode)
21855 +{
21856 +       int status, n;
21857 +
21858 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
21859 +               panic("check_ptrace : ptrace failed, errno = %d", errno);
21860 +       n = waitpid(pid, &status, 0);
21861 +       if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
21862 +               panic("check_ptrace : child exited with status 0x%x", status);
21863 +
21864 +       if(munmap(stack, PAGE_SIZE) < 0)
21865 +               panic("check_ptrace : munmap failed, errno = %d", errno);
21866 +}
21867 +
21868 +void __init check_ptrace(void)
21869 +{
21870 +       void *stack;
21871 +       int pid, syscall, n, status;
21872 +
21873 +       printk("Checking that ptrace can change system call numbers...");
21874 +       pid = start_ptraced_child(&stack);
21875 +
21876 +       while(1){
21877 +               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
21878 +                       panic("check_ptrace : ptrace failed, errno = %d", 
21879 +                             errno);
21880 +               n = waitpid(pid, &status, WUNTRACED);
21881 +               if(n < 0)
21882 +                       panic("check_ptrace : wait failed, errno = %d", errno);
21883 +               if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
21884 +                       panic("check_ptrace : expected SIGTRAP, "
21885 +                             "got status = %d", status);
21886 +               
21887 +               syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET,
21888 +                                0);
21889 +               if(syscall == __NR_getpid){
21890 +                       n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET,
21891 +                                  __NR_getppid);
21892 +                       if(n < 0)
21893 +                               panic("check_ptrace : failed to modify system "
21894 +                                     "call, errno = %d", errno);
21895 +                       break;
21896 +               }
21897 +       }
21898 +       stop_ptraced_child(pid, stack, 0);
21899 +       printk("OK\n");
21900 +}
21901 +
21902 +int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
21903 +{
21904 +       jmp_buf buf;
21905 +       int n;
21906 +
21907 +       *jmp_ptr = &buf;
21908 +       n = sigsetjmp(buf, 1);
21909 +       if(n != 0)
21910 +               return(n);
21911 +       (*fn)(arg);
21912 +       return(0);
21913 +}
21914 +
21915 +int can_do_skas(void)
21916 +{
21917 +#ifdef UML_CONFIG_MODE_SKAS
21918 +       struct ptrace_faultinfo fi;
21919 +       void *stack;
21920 +       int pid, n, ret = 1;
21921 +
21922 +       printf("Checking for the skas3 patch in the host...");
21923 +       pid = start_ptraced_child(&stack);
21924 +
21925 +       n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
21926 +       if(n < 0){
21927 +               if(errno == EIO)
21928 +                       printf("not found\n");
21929 +               else printf("No (unexpected errno - %d)\n", errno);
21930 +               ret = 0;
21931 +       }
21932 +       else printf("found\n");
21933 +
21934 +       init_registers(pid);
21935 +       stop_ptraced_child(pid, stack, 1);
21936 +
21937 +       printf("Checking for /proc/mm...");
21938 +       if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
21939 +               printf("not found\n");
21940 +               ret = 0;
21941 +       }
21942 +       else printf("found\n");
21943 +
21944 +       return(ret);
21945 +#else
21946 +       return(0);
21947 +#endif
21948 +}
21949 +
21950 +/*
21951 + * Overrides for Emacs so that we follow Linus's tabbing style.
21952 + * Emacs will notice this stuff at the end of the file and automatically
21953 + * adjust the settings for this buffer only.  This must remain at the end
21954 + * of the file.
21955 + * ---------------------------------------------------------------------------
21956 + * Local variables:
21957 + * c-file-style: "linux"
21958 + * End:
21959 + */
21960 diff -Naur -X ../exclude-files orig/arch/um/kernel/process_kern.c um/arch/um/kernel/process_kern.c
21961 --- orig/arch/um/kernel/process_kern.c  1969-12-31 19:00:00.000000000 -0500
21962 +++ um/arch/um/kernel/process_kern.c    2003-11-08 08:37:04.000000000 -0500
21963 @@ -0,0 +1,396 @@
21964 +/* 
21965 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
21966 + * Licensed under the GPL
21967 + */
21968 +
21969 +#include "linux/config.h"
21970 +#include "linux/kernel.h"
21971 +#include "linux/sched.h"
21972 +#include "linux/interrupt.h"
21973 +#include "linux/mm.h"
21974 +#include "linux/slab.h"
21975 +#include "linux/utsname.h"
21976 +#include "linux/fs.h"
21977 +#include "linux/utime.h"
21978 +#include "linux/smp_lock.h"
21979 +#include "linux/module.h"
21980 +#include "linux/init.h"
21981 +#include "linux/capability.h"
21982 +#include "asm/unistd.h"
21983 +#include "asm/mman.h"
21984 +#include "asm/segment.h"
21985 +#include "asm/stat.h"
21986 +#include "asm/pgtable.h"
21987 +#include "asm/processor.h"
21988 +#include "asm/pgalloc.h"
21989 +#include "asm/spinlock.h"
21990 +#include "asm/uaccess.h"
21991 +#include "asm/user.h"
21992 +#include "user_util.h"
21993 +#include "kern_util.h"
21994 +#include "kern.h"
21995 +#include "signal_kern.h"
21996 +#include "signal_user.h"
21997 +#include "init.h"
21998 +#include "irq_user.h"
21999 +#include "mem_user.h"
22000 +#include "time_user.h"
22001 +#include "tlb.h"
22002 +#include "frame_kern.h"
22003 +#include "sigcontext.h"
22004 +#include "2_5compat.h"
22005 +#include "os.h"
22006 +#include "mode.h"
22007 +#include "mode_kern.h"
22008 +#include "choose-mode.h"
22009 +
22010 +/* This is a per-cpu array.  A processor only modifies its entry and it only
22011 + * cares about its entry, so it's OK if another processor is modifying its
22012 + * entry.
22013 + */
22014 +struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
22015 +
22016 +struct task_struct *get_task(int pid, int require)
22017 +{
22018 +        struct task_struct *ret;
22019 +
22020 +        read_lock(&tasklist_lock);
22021 +       ret = find_task_by_pid(pid);
22022 +        read_unlock(&tasklist_lock);
22023 +
22024 +        if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
22025 +        return(ret);
22026 +}
22027 +
22028 +int external_pid(void *t)
22029 +{
22030 +       struct task_struct *task = t ? t : current;
22031 +
22032 +       return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
22033 +}
22034 +
22035 +int pid_to_processor_id(int pid)
22036 +{
22037 +       int i;
22038 +
22039 +       for(i = 0; i < smp_num_cpus; i++){
22040 +               if(cpu_tasks[i].pid == pid) return(i);
22041 +       }
22042 +       return(-1);
22043 +}
22044 +
22045 +void free_stack(unsigned long stack, int order)
22046 +{
22047 +       free_pages(stack, order);
22048 +}
22049 +
22050 +unsigned long alloc_stack(int order, int atomic)
22051 +{
22052 +       unsigned long page;
22053 +       int flags = GFP_KERNEL;
22054 +
22055 +       if(atomic) flags |= GFP_ATOMIC;
22056 +       page = __get_free_pages(flags, order);
22057 +       if(page == 0)
22058 +               return(0);
22059 +       stack_protections(page);
22060 +       return(page);
22061 +}
22062 +
22063 +int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
22064 +{
22065 +       int pid;
22066 +
22067 +       current->thread.request.u.thread.proc = fn;
22068 +       current->thread.request.u.thread.arg = arg;
22069 +       pid = do_fork(CLONE_VM | flags, 0, NULL, 0);
22070 +#if 0 /* CLONE_UNTRACED for 2.6 */
22071 +       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0);
22072 +#endif
22073 +       if(pid < 0) 
22074 +               panic("do_fork failed in kernel_thread, errno = %d", pid);
22075 +       return(pid);
22076 +}
22077 +
22078 +void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
22079 +              struct task_struct *tsk, unsigned cpu)
22080 +{
22081 +       if (prev != next) 
22082 +               clear_bit(cpu, &prev->cpu_vm_mask);
22083 +       set_bit(cpu, &next->cpu_vm_mask);
22084 +}
22085 +
22086 +void set_current(void *t)
22087 +{
22088 +       struct task_struct *task = t;
22089 +
22090 +       cpu_tasks[task->processor] = ((struct cpu_task) 
22091 +               { external_pid(task), task });
22092 +}
22093 +
22094 +void *_switch_to(void *prev, void *next)
22095 +{
22096 +       return(CHOOSE_MODE(_switch_to_tt(prev, next), 
22097 +                          _switch_to_skas(prev, next)));
22098 +}
22099 +
22100 +void interrupt_end(void)
22101 +{
22102 +       if(current->need_resched) schedule();
22103 +       if(current->sigpending != 0) do_signal(0);
22104 +}
22105 +
22106 +void release_thread(struct task_struct *task)
22107 +{
22108 +       CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
22109 +}
22110 +
22111 +void exit_thread(void)
22112 +{
22113 +       CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
22114 +       unprotect_stack((unsigned long) current);
22115 +}
22116 +
22117 +void *get_current(void)
22118 +{
22119 +       return(current);
22120 +}
22121 +
22122 +int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
22123 +               unsigned long stack_top, struct task_struct * p, 
22124 +               struct pt_regs *regs)
22125 +{
22126 +       p->thread = (struct thread_struct) INIT_THREAD;
22127 +       p->thread.kernel_stack = (unsigned long) p + 2 * PAGE_SIZE;
22128 +
22129 +       return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, 
22130 +                               clone_flags, sp, stack_top, p, regs));
22131 +}
22132 +
22133 +void initial_thread_cb(void (*proc)(void *), void *arg)
22134 +{
22135 +       int save_kmalloc_ok = kmalloc_ok;
22136 +
22137 +       kmalloc_ok = 0;
22138 +       CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, 
22139 +                        arg);
22140 +       kmalloc_ok = save_kmalloc_ok;
22141 +}
22142 +
22143 +unsigned long stack_sp(unsigned long page)
22144 +{
22145 +       return(page + PAGE_SIZE - sizeof(void *));
22146 +}
22147 +
22148 +int current_pid(void)
22149 +{
22150 +       return(current->pid);
22151 +}
22152 +
22153 +void cpu_idle(void)
22154 +{
22155 +       CHOOSE_MODE(init_idle_tt(), init_idle_skas());
22156 +
22157 +       atomic_inc(&init_mm.mm_count);
22158 +       current->mm = &init_mm;
22159 +       current->active_mm = &init_mm;
22160 +
22161 +       while(1){
22162 +               /* endless idle loop with no priority at all */
22163 +               SET_PRI(current);
22164 +
22165 +               /*
22166 +                * although we are an idle CPU, we do not want to
22167 +                * get into the scheduler unnecessarily.
22168 +                */
22169 +               if (current->need_resched) {
22170 +                       schedule();
22171 +                       check_pgt_cache();
22172 +               }
22173 +               idle_sleep(10);
22174 +       }
22175 +}
22176 +
22177 +int page_size(void)
22178 +{
22179 +       return(PAGE_SIZE);
22180 +}
22181 +
22182 +int page_mask(void)
22183 +{
22184 +       return(PAGE_MASK);
22185 +}
22186 +
22187 +void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
22188 +                     pte_t *pte_out)
22189 +{
22190 +       pgd_t *pgd;
22191 +       pmd_t *pmd;
22192 +       pte_t *pte;
22193 +
22194 +       if(task->mm == NULL) 
22195 +               return(ERR_PTR(-EINVAL));
22196 +       pgd = pgd_offset(task->mm, addr);
22197 +       pmd = pmd_offset(pgd, addr);
22198 +       if(!pmd_present(*pmd)) 
22199 +               return(ERR_PTR(-EINVAL));
22200 +       pte = pte_offset(pmd, addr);
22201 +       if(!pte_present(*pte)) 
22202 +               return(ERR_PTR(-EINVAL));
22203 +       if(pte_out != NULL)
22204 +               *pte_out = *pte;
22205 +       return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
22206 +}
22207 +
22208 +char *current_cmd(void)
22209 +{
22210 +#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
22211 +       return("(Unknown)");
22212 +#else
22213 +       void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
22214 +       return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
22215 +#endif
22216 +}
22217 +
22218 +void force_sigbus(void)
22219 +{
22220 +       printk(KERN_ERR "Killing pid %d because of a lack of memory\n", 
22221 +              current->pid);
22222 +       lock_kernel();
22223 +       sigaddset(&current->pending.signal, SIGBUS);
22224 +       recalc_sigpending(current);
22225 +       current->flags |= PF_SIGNALED;
22226 +       do_exit(SIGBUS | 0x80);
22227 +}
22228 +
22229 +void dump_thread(struct pt_regs *regs, struct user *u)
22230 +{
22231 +}
22232 +
22233 +void enable_hlt(void)
22234 +{
22235 +       panic("enable_hlt");
22236 +}
22237 +
22238 +void disable_hlt(void)
22239 +{
22240 +       panic("disable_hlt");
22241 +}
22242 +
22243 +extern int signal_frame_size;
22244 +
22245 +void *um_kmalloc(int size)
22246 +{
22247 +       return(kmalloc(size, GFP_KERNEL));
22248 +}
22249 +
22250 +void *um_kmalloc_atomic(int size)
22251 +{
22252 +       return(kmalloc(size, GFP_ATOMIC));
22253 +}
22254 +
22255 +unsigned long get_fault_addr(void)
22256 +{
22257 +       return((unsigned long) current->thread.fault_addr);
22258 +}
22259 +
22260 +EXPORT_SYMBOL(get_fault_addr);
22261 +
22262 +void not_implemented(void)
22263 +{
22264 +       printk(KERN_DEBUG "Something isn't implemented in here\n");
22265 +}
22266 +
22267 +EXPORT_SYMBOL(not_implemented);
22268 +
22269 +int user_context(unsigned long sp)
22270 +{
22271 +       unsigned long stack;
22272 +
22273 +       stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
22274 +       stack += 2 * PAGE_SIZE;
22275 +       return(stack != current->thread.kernel_stack);
22276 +}
22277 +
22278 +extern void remove_umid_dir(void);
22279 +
22280 +__uml_exitcall(remove_umid_dir);
22281 +
22282 +extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
22283 +
22284 +void do_uml_exitcalls(void)
22285 +{
22286 +       exitcall_t *call;
22287 +
22288 +       call = &__uml_exitcall_end;
22289 +       while (--call >= &__uml_exitcall_begin)
22290 +               (*call)();
22291 +}
22292 +
22293 +char *uml_strdup(char *string)
22294 +{
22295 +       char *new;
22296 +
22297 +       new = kmalloc(strlen(string) + 1, GFP_KERNEL);
22298 +       if(new == NULL) return(NULL);
22299 +       strcpy(new, string);
22300 +       return(new);
22301 +}
22302 +
22303 +void *get_init_task(void)
22304 +{
22305 +       return(&init_task_union.task);
22306 +}
22307 +
22308 +int copy_to_user_proc(void *to, void *from, int size)
22309 +{
22310 +       return(copy_to_user(to, from, size));
22311 +}
22312 +
22313 +int copy_from_user_proc(void *to, void *from, int size)
22314 +{
22315 +       return(copy_from_user(to, from, size));
22316 +}
22317 +
22318 +int clear_user_proc(void *buf, int size)
22319 +{
22320 +       return(clear_user(buf, size));
22321 +}
22322 +
22323 +int strlen_user_proc(char *str)
22324 +{
22325 +       return(strlen_user(str));
22326 +}
22327 +
22328 +int smp_sigio_handler(void)
22329 +{
22330 +#ifdef CONFIG_SMP
22331 +       int cpu = current->processor;
22332 +
22333 +       IPI_handler(cpu);
22334 +       if(cpu != 0)
22335 +               return(1);
22336 +#endif
22337 +       return(0);
22338 +}
22339 +
22340 +int um_in_interrupt(void)
22341 +{
22342 +       return(in_interrupt());
22343 +}
22344 +
22345 +int cpu(void)
22346 +{
22347 +        return(current->processor);
22348 +}
22349 +
22350 +/*
22351 + * Overrides for Emacs so that we follow Linus's tabbing style.
22352 + * Emacs will notice this stuff at the end of the file and automatically
22353 + * adjust the settings for this buffer only.  This must remain at the end
22354 + * of the file.
22355 + * ---------------------------------------------------------------------------
22356 + * Local variables:
22357 + * c-file-style: "linux"
22358 + * End:
22359 + */
22360 diff -Naur -X ../exclude-files orig/arch/um/kernel/ptrace.c um/arch/um/kernel/ptrace.c
22361 --- orig/arch/um/kernel/ptrace.c        1969-12-31 19:00:00.000000000 -0500
22362 +++ um/arch/um/kernel/ptrace.c  2003-10-21 03:26:06.000000000 -0400
22363 @@ -0,0 +1,325 @@
22364 +/* 
22365 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22366 + * Licensed under the GPL
22367 + */
22368 +
22369 +#include "linux/sched.h"
22370 +#include "linux/mm.h"
22371 +#include "linux/errno.h"
22372 +#include "linux/smp_lock.h"
22373 +#ifdef CONFIG_PROC_MM
22374 +#include "linux/proc_mm.h"
22375 +#endif
22376 +#include "asm/ptrace.h"
22377 +#include "asm/uaccess.h"
22378 +#include "kern_util.h"
22379 +#include "ptrace_user.h"
22380 +
22381 +/*
22382 + * Called by kernel/ptrace.c when detaching..
22383 + */
22384 +void ptrace_disable(struct task_struct *child)
22385 +{ 
22386 +}
22387 +
22388 +extern long do_mmap2(struct task_struct *task, unsigned long addr, 
22389 +                    unsigned long len, unsigned long prot, 
22390 +                    unsigned long flags, unsigned long fd,
22391 +                    unsigned long pgoff);
22392 +
22393 +int sys_ptrace(long request, long pid, long addr, long data)
22394 +{
22395 +       struct task_struct *child;
22396 +       int i, ret;
22397 +
22398 +       lock_kernel();
22399 +       ret = -EPERM;
22400 +       if (request == PTRACE_TRACEME) {
22401 +               /* are we already being traced? */
22402 +               if (current->ptrace & PT_PTRACED)
22403 +                       goto out;
22404 +               /* set the ptrace bit in the process flags. */
22405 +               current->ptrace |= PT_PTRACED;
22406 +               ret = 0;
22407 +               goto out;
22408 +       }
22409 +       ret = -ESRCH;
22410 +       read_lock(&tasklist_lock);
22411 +       child = find_task_by_pid(pid);
22412 +       if (child)
22413 +               get_task_struct(child);
22414 +       read_unlock(&tasklist_lock);
22415 +       if (!child)
22416 +               goto out;
22417 +
22418 +       ret = -EPERM;
22419 +       if (pid == 1)           /* you may not mess with init */
22420 +               goto out_tsk;
22421 +
22422 +       if (request == PTRACE_ATTACH) {
22423 +               ret = ptrace_attach(child);
22424 +               goto out_tsk;
22425 +       }
22426 +
22427 +       ret = ptrace_check_attach(child, request == PTRACE_KILL);
22428 +       if (ret < 0)
22429 +               goto out_tsk;
22430 +
22431 +       switch (request) {
22432 +               /* when I and D space are separate, these will need to be fixed. */
22433 +       case PTRACE_PEEKTEXT: /* read word at location addr. */ 
22434 +       case PTRACE_PEEKDATA: {
22435 +               unsigned long tmp;
22436 +               int copied;
22437 +
22438 +               ret = -EIO;
22439 +               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
22440 +               if (copied != sizeof(tmp))
22441 +                       break;
22442 +               ret = put_user(tmp,(unsigned long *) data);
22443 +               break;
22444 +       }
22445 +
22446 +       /* read the word at location addr in the USER area. */
22447 +       case PTRACE_PEEKUSR: {
22448 +               unsigned long tmp;
22449 +
22450 +               ret = -EIO;
22451 +               if ((addr & 3) || addr < 0) 
22452 +                       break;
22453 +
22454 +               tmp = 0;  /* Default return condition */
22455 +               if(addr < FRAME_SIZE_OFFSET){
22456 +                       tmp = getreg(child, addr);
22457 +               }
22458 +               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
22459 +                       (addr <= offsetof(struct user, u_debugreg[7]))){
22460 +                       addr -= offsetof(struct user, u_debugreg[0]);
22461 +                       addr = addr >> 2;
22462 +                       tmp = child->thread.arch.debugregs[addr];
22463 +               }
22464 +               ret = put_user(tmp, (unsigned long *) data);
22465 +               break;
22466 +       }
22467 +
22468 +       /* when I and D space are separate, this will have to be fixed. */
22469 +       case PTRACE_POKETEXT: /* write the word at location addr. */
22470 +       case PTRACE_POKEDATA:
22471 +               ret = -EIO;
22472 +               if (access_process_vm(child, addr, &data, sizeof(data), 
22473 +                                     1) != sizeof(data))
22474 +                       break;
22475 +               ret = 0;
22476 +               break;
22477 +
22478 +       case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
22479 +               ret = -EIO;
22480 +               if ((addr & 3) || addr < 0)
22481 +                       break;
22482 +
22483 +               if (addr < FRAME_SIZE_OFFSET) {
22484 +                       ret = putreg(child, addr, data);
22485 +                       break;
22486 +               }
22487 +               else if((addr >= offsetof(struct user, u_debugreg[0])) &&
22488 +                       (addr <= offsetof(struct user, u_debugreg[7]))){
22489 +                         addr -= offsetof(struct user, u_debugreg[0]);
22490 +                         addr = addr >> 2;
22491 +                         if((addr == 4) || (addr == 5)) break;
22492 +                         child->thread.arch.debugregs[addr] = data;
22493 +                         ret = 0;
22494 +               }
22495 +
22496 +               break;
22497 +
22498 +       case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
22499 +       case PTRACE_CONT: { /* restart after signal. */
22500 +               ret = -EIO;
22501 +               if ((unsigned long) data > _NSIG)
22502 +                       break;
22503 +               if (request == PTRACE_SYSCALL)
22504 +                       child->ptrace |= PT_TRACESYS;
22505 +               else
22506 +                       child->ptrace &= ~PT_TRACESYS;
22507 +               child->exit_code = data;
22508 +               wake_up_process(child);
22509 +               ret = 0;
22510 +               break;
22511 +       }
22512 +
22513 +/*
22514 + * make the child exit.  Best I can do is send it a sigkill. 
22515 + * perhaps it should be put in the status that it wants to 
22516 + * exit.
22517 + */
22518 +       case PTRACE_KILL: {
22519 +               ret = 0;
22520 +               if (child->state == TASK_ZOMBIE)        /* already dead */
22521 +                       break;
22522 +               child->exit_code = SIGKILL;
22523 +               wake_up_process(child);
22524 +               break;
22525 +       }
22526 +
22527 +       case PTRACE_SINGLESTEP: {  /* set the trap flag. */
22528 +               ret = -EIO;
22529 +               if ((unsigned long) data > _NSIG)
22530 +                       break;
22531 +               child->ptrace &= ~PT_TRACESYS;
22532 +               child->ptrace |= PT_DTRACE;
22533 +               child->exit_code = data;
22534 +               /* give it a chance to run. */
22535 +               wake_up_process(child);
22536 +               ret = 0;
22537 +               break;
22538 +       }
22539 +
22540 +       case PTRACE_DETACH:
22541 +               /* detach a process that was attached. */
22542 +               ret = ptrace_detach(child, data);
22543 +               break;
22544 +
22545 +#ifdef PTRACE_GETREGS
22546 +       case PTRACE_GETREGS: { /* Get all gp regs from the child. */
22547 +               if (!access_ok(VERIFY_WRITE, (unsigned long *)data, 
22548 +                              FRAME_SIZE_OFFSET)) {
22549 +                       ret = -EIO;
22550 +                       break;
22551 +               }
22552 +               for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
22553 +                       __put_user(getreg(child, i), (unsigned long *) data);
22554 +                       data += sizeof(long);
22555 +               }
22556 +               ret = 0;
22557 +               break;
22558 +       }
22559 +#endif
22560 +#ifdef PTRACE_SETREGS
22561 +       case PTRACE_SETREGS: { /* Set all gp regs in the child. */
22562 +               unsigned long tmp = 0;
22563 +               if (!access_ok(VERIFY_READ, (unsigned *)data, 
22564 +                              FRAME_SIZE_OFFSET)) {
22565 +                       ret = -EIO;
22566 +                       break;
22567 +               }
22568 +               for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
22569 +                       __get_user(tmp, (unsigned long *) data);
22570 +                       putreg(child, i, tmp);
22571 +                       data += sizeof(long);
22572 +               }
22573 +               ret = 0;
22574 +               break;
22575 +       }
22576 +#endif
22577 +#ifdef PTRACE_GETFPREGS
22578 +       case PTRACE_GETFPREGS: /* Get the child FPU state. */
22579 +               ret = get_fpregs(data, child);
22580 +               break;
22581 +#endif
22582 +#ifdef PTRACE_SETFPREGS
22583 +       case PTRACE_SETFPREGS: /* Set the child FPU state. */
22584 +               ret = set_fpregs(data, child);
22585 +               break;
22586 +#endif
22587 +#ifdef PTRACE_GETFPXREGS
22588 +       case PTRACE_GETFPXREGS: /* Get the child FPU state. */
22589 +               ret = get_fpxregs(data, child);
22590 +               break;
22591 +#endif
22592 +#ifdef PTRACE_SETFPXREGS
22593 +       case PTRACE_SETFPXREGS: /* Set the child FPU state. */
22594 +               ret = set_fpxregs(data, child);
22595 +               break;
22596 +#endif
22597 +       case PTRACE_FAULTINFO: {
22598 +               struct ptrace_faultinfo fault;
22599 +
22600 +               fault = ((struct ptrace_faultinfo) 
22601 +                       { .is_write     = child->thread.err,
22602 +                         .addr         = child->thread.cr2 });
22603 +               ret = copy_to_user((unsigned long *) data, &fault, 
22604 +                                  sizeof(fault));
22605 +               if(ret)
22606 +                       break;
22607 +               break;
22608 +       }
22609 +       case PTRACE_SIGPENDING:
22610 +               ret = copy_to_user((unsigned long *) data, 
22611 +                                  &child->pending.signal,
22612 +                                  sizeof(child->pending.signal));
22613 +               break;
22614 +
22615 +       case PTRACE_LDT: {
22616 +               struct ptrace_ldt ldt;
22617 +
22618 +               if(copy_from_user(&ldt, (unsigned long *) data, 
22619 +                                 sizeof(ldt))){
22620 +                       ret = -EIO;
22621 +                       break;
22622 +               }
22623 +
22624 +               /* This one is confusing, so just punt and return -EIO for 
22625 +                * now
22626 +                */
22627 +               ret = -EIO;
22628 +               break;
22629 +       }
22630 +#ifdef CONFIG_PROC_MM
22631 +       case PTRACE_SWITCH_MM: {
22632 +               struct mm_struct *old = child->mm;
22633 +               struct mm_struct *new = proc_mm_get_mm(data);
22634 +
22635 +               if(IS_ERR(new)){
22636 +                       ret = PTR_ERR(new);
22637 +                       break;
22638 +               }
22639 +
22640 +               atomic_inc(&new->mm_users);
22641 +               child->mm = new;
22642 +               child->active_mm = new;
22643 +               mmput(old);
22644 +               ret = 0;
22645 +               break;
22646 +       }
22647 +#endif
22648 +       default:
22649 +               ret = -EIO;
22650 +               break;
22651 +       }
22652 + out_tsk:
22653 +       free_task_struct(child);
22654 + out:
22655 +       unlock_kernel();
22656 +       return ret;
22657 +}
22658 +
22659 +void syscall_trace(void)
22660 +{
22661 +       if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
22662 +           != (PT_PTRACED|PT_TRACESYS))
22663 +               return;
22664 +       current->exit_code = SIGTRAP;
22665 +       current->state = TASK_STOPPED;
22666 +       notify_parent(current, SIGCHLD);
22667 +       schedule();
22668 +       /*
22669 +        * this isn't the same as continuing with a signal, but it will do
22670 +        * for normal use.  strace only continues with a signal if the
22671 +        * stopping signal is not SIGTRAP.  -brl
22672 +        */
22673 +       if (current->exit_code) {
22674 +               send_sig(current->exit_code, current, 1);
22675 +               current->exit_code = 0;
22676 +       }
22677 +}
22678 +
22679 +/*
22680 + * Overrides for Emacs so that we follow Linus's tabbing style.
22681 + * Emacs will notice this stuff at the end of the file and automatically
22682 + * adjust the settings for this buffer only.  This must remain at the end
22683 + * of the file.
22684 + * ---------------------------------------------------------------------------
22685 + * Local variables:
22686 + * c-file-style: "linux"
22687 + * End:
22688 + */
22689 diff -Naur -X ../exclude-files orig/arch/um/kernel/reboot.c um/arch/um/kernel/reboot.c
22690 --- orig/arch/um/kernel/reboot.c        1969-12-31 19:00:00.000000000 -0500
22691 +++ um/arch/um/kernel/reboot.c  2003-10-21 03:26:06.000000000 -0400
22692 @@ -0,0 +1,73 @@
22693 +/* 
22694 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
22695 + * Licensed under the GPL
22696 + */
22697 +
22698 +#include "linux/sched.h"
22699 +#include "user_util.h"
22700 +#include "kern_util.h"
22701 +#include "kern.h"
22702 +#include "os.h"
22703 +#include "mode.h"
22704 +#include "choose-mode.h"
22705 +
22706 +#ifdef CONFIG_SMP
22707 +static void kill_idlers(int me)
22708 +{
22709 +#ifdef CONFIG_MODE_TT
22710 +       struct task_struct *p;
22711 +       int i;
22712 +
22713 +       for(i = 0; i < sizeof(init_tasks)/sizeof(init_tasks[0]); i++){
22714 +               p = init_tasks[i];
22715 +               if((p != NULL) && (p->thread.mode.tt.extern_pid != me) &&
22716 +                  (p->thread.mode.tt.extern_pid != -1))
22717 +                       os_kill_process(p->thread.mode.tt.extern_pid, 0);
22718 +       }
22719 +#endif
22720 +}
22721 +#endif
22722 +
22723 +static void kill_off_processes(void)
22724 +{
22725 +       CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
22726 +#ifdef CONFIG_SMP
22727 +       kill_idlers(os_getpid());
22728 +#endif
22729 +}
22730 +
22731 +void uml_cleanup(void)
22732 +{
22733 +       kill_off_processes();
22734 +       do_uml_exitcalls();
22735 +}
22736 +
22737 +void machine_restart(char * __unused)
22738 +{
22739 +       do_uml_exitcalls();
22740 +       kill_off_processes();
22741 +       CHOOSE_MODE(reboot_tt(), reboot_skas());
22742 +}
22743 +
22744 +void machine_power_off(void)
22745 +{
22746 +       do_uml_exitcalls();
22747 +       kill_off_processes();
22748 +       CHOOSE_MODE(halt_tt(), halt_skas());
22749 +}
22750 +
22751 +void machine_halt(void)
22752 +{
22753 +       machine_power_off();
22754 +}
22755 +
22756 +/*
22757 + * Overrides for Emacs so that we follow Linus's tabbing style.
22758 + * Emacs will notice this stuff at the end of the file and automatically
22759 + * adjust the settings for this buffer only.  This must remain at the end
22760 + * of the file.
22761 + * ---------------------------------------------------------------------------
22762 + * Local variables:
22763 + * c-file-style: "linux"
22764 + * End:
22765 + */
22766 diff -Naur -X ../exclude-files orig/arch/um/kernel/resource.c um/arch/um/kernel/resource.c
22767 --- orig/arch/um/kernel/resource.c      1969-12-31 19:00:00.000000000 -0500
22768 +++ um/arch/um/kernel/resource.c        2003-10-21 03:26:06.000000000 -0400
22769 @@ -0,0 +1,23 @@
22770 +/* 
22771 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
22772 + * Licensed under the GPL
22773 + */
22774 +
22775 +#include "linux/pci.h"
22776 +
22777 +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
22778 +                            unsigned long start, unsigned long size)
22779 +{
22780 +       return start;
22781 +}
22782 +
22783 +/*
22784 + * Overrides for Emacs so that we follow Linus's tabbing style.
22785 + * Emacs will notice this stuff at the end of the file and automatically
22786 + * adjust the settings for this buffer only.  This must remain at the end
22787 + * of the file.
22788 + * ---------------------------------------------------------------------------
22789 + * Local variables:
22790 + * c-file-style: "linux"
22791 + * End:
22792 + */
22793 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_kern.c um/arch/um/kernel/sigio_kern.c
22794 --- orig/arch/um/kernel/sigio_kern.c    1969-12-31 19:00:00.000000000 -0500
22795 +++ um/arch/um/kernel/sigio_kern.c      2003-10-21 03:26:07.000000000 -0400
22796 @@ -0,0 +1,57 @@
22797 +/* 
22798 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22799 + * Licensed under the GPL
22800 + */
22801 +
22802 +#include "linux/kernel.h"
22803 +#include "linux/list.h"
22804 +#include "linux/slab.h"
22805 +#include "asm/irq.h"
22806 +#include "init.h"
22807 +#include "sigio.h"
22808 +#include "irq_user.h"
22809 +#include "irq_kern.h"
22810 +
22811 +/* Protected by sigio_lock() called from write_sigio_workaround */
22812 +static int sigio_irq_fd = -1;
22813 +
22814 +void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
22815 +{
22816 +       read_sigio_fd(sigio_irq_fd);
22817 +       reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
22818 +}
22819 +
22820 +int write_sigio_irq(int fd)
22821 +{
22822 +       if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
22823 +                         SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", 
22824 +                         NULL)){
22825 +               printk("write_sigio_irq : um_request_irq failed\n");
22826 +               return(-1);
22827 +       }
22828 +       sigio_irq_fd = fd;
22829 +       return(0);
22830 +}
22831 +
22832 +static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED;
22833 +
22834 +void sigio_lock(void)
22835 +{
22836 +       spin_lock(&sigio_spinlock);
22837 +}
22838 +
22839 +void sigio_unlock(void)
22840 +{
22841 +       spin_unlock(&sigio_spinlock);
22842 +}
22843 +
22844 +/*
22845 + * Overrides for Emacs so that we follow Linus's tabbing style.
22846 + * Emacs will notice this stuff at the end of the file and automatically
22847 + * adjust the settings for this buffer only.  This must remain at the end
22848 + * of the file.
22849 + * ---------------------------------------------------------------------------
22850 + * Local variables:
22851 + * c-file-style: "linux"
22852 + * End:
22853 + */
22854 diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_user.c um/arch/um/kernel/sigio_user.c
22855 --- orig/arch/um/kernel/sigio_user.c    1969-12-31 19:00:00.000000000 -0500
22856 +++ um/arch/um/kernel/sigio_user.c      2003-11-07 01:41:13.000000000 -0500
22857 @@ -0,0 +1,438 @@
22858 +/* 
22859 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
22860 + * Licensed under the GPL
22861 + */
22862 +
22863 +#include <unistd.h>
22864 +#include <stdlib.h>
22865 +#include <termios.h>
22866 +#include <pty.h>
22867 +#include <signal.h>
22868 +#include <errno.h>
22869 +#include <string.h>
22870 +#include <sched.h>
22871 +#include <sys/socket.h>
22872 +#include <sys/poll.h>
22873 +#include "init.h"
22874 +#include "user.h"
22875 +#include "kern_util.h"
22876 +#include "sigio.h"
22877 +#include "helper.h"
22878 +#include "os.h"
22879 +
22880 +/* Changed during early boot */
22881 +int pty_output_sigio = 0;
22882 +int pty_close_sigio = 0;
22883 +
22884 +/* Used as a flag during SIGIO testing early in boot */
22885 +static volatile int got_sigio = 0;
22886 +
22887 +void __init handler(int sig)
22888 +{
22889 +       got_sigio = 1;
22890 +}
22891 +
22892 +struct openpty_arg {
22893 +       int master;
22894 +       int slave;
22895 +       int err;
22896 +};
22897 +
22898 +static void openpty_cb(void *arg)
22899 +{
22900 +       struct openpty_arg *info = arg;
22901 +
22902 +       info->err = 0;
22903 +       if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
22904 +               info->err = -errno;
22905 +}
22906 +
22907 +void __init check_one_sigio(void (*proc)(int, int))
22908 +{
22909 +       struct sigaction old, new;
22910 +       struct termios tt;
22911 +       struct openpty_arg pty = { .master = -1, .slave = -1 };
22912 +       int master, slave, err;
22913 +
22914 +       initial_thread_cb(openpty_cb, &pty);
22915 +       if(pty.err){
22916 +               printk("openpty failed, errno = %d\n", -pty.err);
22917 +               return;
22918 +       }
22919 +
22920 +       master = pty.master;
22921 +       slave = pty.slave;
22922 +
22923 +       if((master == -1) || (slave == -1)){
22924 +               printk("openpty failed to allocate a pty\n");
22925 +               return;
22926 +       }
22927 +
22928 +       /* XXX These can fail with EINTR */
22929 +       if(tcgetattr(master, &tt) < 0)
22930 +               panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
22931 +       cfmakeraw(&tt);
22932 +       if(tcsetattr(master, TCSADRAIN, &tt) < 0)
22933 +               panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
22934 +
22935 +       err = os_sigio_async(master, slave);
22936 +       if(err < 0)
22937 +               panic("tty_fds : sigio_async failed, err = %d\n", -err);
22938 +
22939 +       if(sigaction(SIGIO, NULL, &old) < 0)
22940 +               panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
22941 +       new = old;
22942 +       new.sa_handler = handler;
22943 +       if(sigaction(SIGIO, &new, NULL) < 0)
22944 +               panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
22945 +
22946 +       got_sigio = 0;
22947 +       (*proc)(master, slave);
22948 +               
22949 +       os_close_file(master);
22950 +       os_close_file(slave);
22951 +
22952 +       if(sigaction(SIGIO, &old, NULL) < 0)
22953 +               panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
22954 +}
22955 +
22956 +static void tty_output(int master, int slave)
22957 +{
22958 +       int n;
22959 +       char buf[512];
22960 +
22961 +       printk("Checking that host ptys support output SIGIO...");
22962 +
22963 +       memset(buf, 0, sizeof(buf));
22964 +
22965 +       while(os_write_file(master, buf, sizeof(buf)) > 0) ;
22966 +       if(errno != EAGAIN)
22967 +               panic("check_sigio : write failed, errno = %d\n", errno);
22968 +       while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
22969 +
22970 +       if(got_sigio){
22971 +               printk("Yes\n");
22972 +               pty_output_sigio = 1;
22973 +       }
22974 +       else if(n == -EAGAIN) printk("No, enabling workaround\n");
22975 +       else panic("check_sigio : read failed, err = %d\n", n);
22976 +}
22977 +
22978 +static void tty_close(int master, int slave)
22979 +{
22980 +       printk("Checking that host ptys support SIGIO on close...");
22981 +
22982 +       os_close_file(slave);
22983 +       if(got_sigio){
22984 +               printk("Yes\n");
22985 +               pty_close_sigio = 1;
22986 +       }
22987 +       else printk("No, enabling workaround\n");
22988 +}
22989 +
22990 +void __init check_sigio(void)
22991 +{
22992 +       if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
22993 +          (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
22994 +               printk("No pseudo-terminals available - skipping pty SIGIO "
22995 +                      "check\n");
22996 +               return;
22997 +       }
22998 +       check_one_sigio(tty_output);
22999 +       check_one_sigio(tty_close);
23000 +}
23001 +
23002 +/* Protected by sigio_lock(), also used by sigio_cleanup, which is an 
23003 + * exitcall.
23004 + */
23005 +static int write_sigio_pid = -1;
23006 +
23007 +/* These arrays are initialized before the sigio thread is started, and
23008 + * the descriptors closed after it is killed.  So, it can't see them change.
23009 + * On the UML side, they are changed under the sigio_lock.
23010 + */
23011 +static int write_sigio_fds[2] = { -1, -1 };
23012 +static int sigio_private[2] = { -1, -1 };
23013 +
23014 +struct pollfds {
23015 +       struct pollfd *poll;
23016 +       int size;
23017 +       int used;
23018 +};
23019 +
23020 +/* Protected by sigio_lock().  Used by the sigio thread, but the UML thread
23021 + * synchronizes with it.
23022 + */
23023 +struct pollfds current_poll = {
23024 +       .poll           = NULL,
23025 +       .size           = 0,
23026 +       .used           = 0
23027 +};
23028 +
23029 +struct pollfds next_poll = {
23030 +       .poll           = NULL,
23031 +       .size           = 0,
23032 +       .used           = 0
23033 +};
23034 +
23035 +static int write_sigio_thread(void *unused)
23036 +{
23037 +       struct pollfds *fds, tmp;
23038 +       struct pollfd *p;
23039 +       int i, n, respond_fd;
23040 +       char c;
23041 +
23042 +       fds = &current_poll;
23043 +       while(1){
23044 +               n = poll(fds->poll, fds->used, -1);
23045 +               if(n < 0){
23046 +                       if(errno == EINTR) continue;
23047 +                       printk("write_sigio_thread : poll returned %d, "
23048 +                              "errno = %d\n", n, errno);
23049 +               }
23050 +               for(i = 0; i < fds->used; i++){
23051 +                       p = &fds->poll[i];
23052 +                       if(p->revents == 0) continue;
23053 +                       if(p->fd == sigio_private[1]){
23054 +                               n = os_read_file(sigio_private[1], &c, sizeof(c));
23055 +                               if(n != sizeof(c))
23056 +                                       printk("write_sigio_thread : "
23057 +                                              "read failed, err = %d\n", -n);
23058 +                               tmp = current_poll;
23059 +                               current_poll = next_poll;
23060 +                               next_poll = tmp;
23061 +                               respond_fd = sigio_private[1];
23062 +                       }
23063 +                       else {
23064 +                               respond_fd = write_sigio_fds[1];
23065 +                               fds->used--;
23066 +                               memmove(&fds->poll[i], &fds->poll[i + 1],
23067 +                                       (fds->used - i) * sizeof(*fds->poll));
23068 +                       }
23069 +
23070 +                       n = os_write_file(respond_fd, &c, sizeof(c));
23071 +                       if(n != sizeof(c))
23072 +                               printk("write_sigio_thread : write failed, "
23073 +                                      "err = %d\n", -n);
23074 +               }
23075 +       }
23076 +}
23077 +
23078 +static int need_poll(int n)
23079 +{
23080 +       if(n <= next_poll.size){
23081 +               next_poll.used = n;
23082 +               return(0);
23083 +       }
23084 +       if(next_poll.poll != NULL) kfree(next_poll.poll);
23085 +       next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
23086 +       if(next_poll.poll == NULL){
23087 +               printk("need_poll : failed to allocate new pollfds\n");
23088 +               next_poll.size = 0;
23089 +               next_poll.used = 0;
23090 +               return(-1);
23091 +       }
23092 +       next_poll.size = n;
23093 +       next_poll.used = n;
23094 +       return(0);
23095 +}
23096 +
23097 +static void update_thread(void)
23098 +{
23099 +       unsigned long flags;
23100 +       int n;
23101 +       char c;
23102 +
23103 +       flags = set_signals(0);
23104 +       n = os_write_file(sigio_private[0], &c, sizeof(c));
23105 +       if(n != sizeof(c)){
23106 +               printk("update_thread : write failed, err = %d\n", -n);
23107 +               goto fail;
23108 +       }
23109 +
23110 +       n = os_read_file(sigio_private[0], &c, sizeof(c));
23111 +       if(n != sizeof(c)){
23112 +               printk("update_thread : read failed, err = %d\n", -n);
23113 +               goto fail;
23114 +       }
23115 +
23116 +       set_signals(flags);
23117 +       return;
23118 + fail:
23119 +       sigio_lock();
23120 +       if(write_sigio_pid != -1) 
23121 +               os_kill_process(write_sigio_pid, 1);
23122 +       write_sigio_pid = -1;
23123 +       os_close_file(sigio_private[0]);
23124 +       os_close_file(sigio_private[1]);        
23125 +       os_close_file(write_sigio_fds[0]);
23126 +       os_close_file(write_sigio_fds[1]);
23127 +       sigio_unlock();
23128 +       set_signals(flags);
23129 +}
23130 +
23131 +int add_sigio_fd(int fd, int read)
23132 +{
23133 +       int err = 0, i, n, events;
23134 +
23135 +       sigio_lock();
23136 +       for(i = 0; i < current_poll.used; i++){
23137 +               if(current_poll.poll[i].fd == fd) 
23138 +                       goto out;
23139 +       }
23140 +
23141 +       n = current_poll.used + 1;
23142 +       err = need_poll(n);
23143 +       if(err) 
23144 +               goto out;
23145 +
23146 +       for(i = 0; i < current_poll.used; i++)
23147 +               next_poll.poll[i] = current_poll.poll[i];
23148 +
23149 +       if(read) events = POLLIN;
23150 +       else events = POLLOUT;
23151 +
23152 +       next_poll.poll[n - 1] = ((struct pollfd) { .fd          = fd,
23153 +                                                  .events      = events,
23154 +                                                  .revents     = 0 });
23155 +       update_thread();
23156 + out:
23157 +       sigio_unlock();
23158 +       return(err);
23159 +}
23160 +
23161 +int ignore_sigio_fd(int fd)
23162 +{
23163 +       struct pollfd *p;
23164 +       int err = 0, i, n = 0;
23165 +
23166 +       sigio_lock();
23167 +       for(i = 0; i < current_poll.used; i++){
23168 +               if(current_poll.poll[i].fd == fd) break;
23169 +       }
23170 +       if(i == current_poll.used)
23171 +               goto out;
23172 +       
23173 +       err = need_poll(current_poll.used - 1);
23174 +       if(err)
23175 +               goto out;
23176 +
23177 +       for(i = 0; i < current_poll.used; i++){
23178 +               p = &current_poll.poll[i];
23179 +               if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i];
23180 +       }
23181 +       if(n == i){
23182 +               printk("ignore_sigio_fd : fd %d not found\n", fd);
23183 +               err = -1;
23184 +               goto out;
23185 +       }
23186 +
23187 +       update_thread();
23188 + out:
23189 +       sigio_unlock();
23190 +       return(err);
23191 +}
23192 +
23193 +static int setup_initial_poll(int fd)
23194 +{
23195 +       struct pollfd *p;
23196 +
23197 +       p = um_kmalloc(sizeof(struct pollfd));
23198 +       if(p == NULL){
23199 +               printk("setup_initial_poll : failed to allocate poll\n");
23200 +               return(-1);
23201 +       }
23202 +       *p = ((struct pollfd) { .fd     = fd,
23203 +                               .events         = POLLIN,
23204 +                               .revents        = 0 });
23205 +       current_poll = ((struct pollfds) { .poll        = p,
23206 +                                          .used        = 1,
23207 +                                          .size        = 1 });
23208 +       return(0);
23209 +}
23210 +
23211 +void write_sigio_workaround(void)
23212 +{
23213 +       unsigned long stack;
23214 +       int err;
23215 +
23216 +       sigio_lock();
23217 +       if(write_sigio_pid != -1)
23218 +               goto out;
23219 +
23220 +       err = os_pipe(write_sigio_fds, 1, 1);
23221 +       if(err < 0){
23222 +               printk("write_sigio_workaround - os_pipe 1 failed, "
23223 +                      "err = %d\n", -err);
23224 +               goto out;
23225 +       }
23226 +       err = os_pipe(sigio_private, 1, 1);
23227 +       if(err < 0){
23228 +               printk("write_sigio_workaround - os_pipe 2 failed, "
23229 +                      "err = %d\n", -err);
23230 +               goto out_close1;
23231 +       }
23232 +       if(setup_initial_poll(sigio_private[1]))
23233 +               goto out_close2;
23234 +
23235 +       write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, 
23236 +                                           CLONE_FILES | CLONE_VM, &stack, 0);
23237 +
23238 +       if(write_sigio_pid < 0) goto out_close2;
23239 +
23240 +       if(write_sigio_irq(write_sigio_fds[0])) 
23241 +               goto out_kill;
23242 +
23243 + out:
23244 +       sigio_unlock();
23245 +       return;
23246 +
23247 + out_kill:
23248 +       os_kill_process(write_sigio_pid, 1);
23249 +       write_sigio_pid = -1;
23250 + out_close2:
23251 +       os_close_file(sigio_private[0]);
23252 +       os_close_file(sigio_private[1]);        
23253 + out_close1:
23254 +       os_close_file(write_sigio_fds[0]);
23255 +       os_close_file(write_sigio_fds[1]);
23256 +       sigio_unlock();
23257 +}
23258 +
23259 +int read_sigio_fd(int fd)
23260 +{
23261 +       int n;
23262 +       char c;
23263 +
23264 +       n = os_read_file(fd, &c, sizeof(c));
23265 +       if(n != sizeof(c)){
23266 +               if(n < 0) {
23267 +                       printk("read_sigio_fd - read failed, err = %d\n", -n);
23268 +                       return(n);
23269 +               } 
23270 +               else { 
23271 +                       printk("read_sigio_fd - short read, bytes = %d\n", n);
23272 +                       return(-EIO);
23273 +               }
23274 +       }
23275 +       return(n);
23276 +}
23277 +
23278 +static void sigio_cleanup(void)
23279 +{
23280 +       if(write_sigio_pid != -1)
23281 +               os_kill_process(write_sigio_pid, 1);
23282 +}
23283 +
23284 +__uml_exitcall(sigio_cleanup);
23285 +
23286 +/*
23287 + * Overrides for Emacs so that we follow Linus's tabbing style.
23288 + * Emacs will notice this stuff at the end of the file and automatically
23289 + * adjust the settings for this buffer only.  This must remain at the end
23290 + * of the file.
23291 + * ---------------------------------------------------------------------------
23292 + * Local variables:
23293 + * c-file-style: "linux"
23294 + * End:
23295 + */
23296 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_kern.c um/arch/um/kernel/signal_kern.c
23297 --- orig/arch/um/kernel/signal_kern.c   1969-12-31 19:00:00.000000000 -0500
23298 +++ um/arch/um/kernel/signal_kern.c     2003-11-19 03:50:58.000000000 -0500
23299 @@ -0,0 +1,369 @@
23300 +/* 
23301 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
23302 + * Licensed under the GPL
23303 + */
23304 +
23305 +#include "linux/config.h"
23306 +#include "linux/stddef.h"
23307 +#include "linux/sys.h"
23308 +#include "linux/sched.h"
23309 +#include "linux/wait.h"
23310 +#include "linux/kernel.h"
23311 +#include "linux/smp_lock.h"
23312 +#include "linux/module.h"
23313 +#include "linux/slab.h"
23314 +#include "asm/signal.h"
23315 +#include "asm/uaccess.h"
23316 +#include "asm/ucontext.h"
23317 +#include "user_util.h"
23318 +#include "kern_util.h"
23319 +#include "signal_kern.h"
23320 +#include "signal_user.h"
23321 +#include "kern.h"
23322 +#include "frame_kern.h"
23323 +#include "sigcontext.h"
23324 +#include "mode.h"
23325 +
23326 +EXPORT_SYMBOL(block_signals);
23327 +EXPORT_SYMBOL(unblock_signals);
23328 +
23329 +static void force_segv(int sig)
23330 +{
23331 +       if(sig == SIGSEGV){
23332 +               struct k_sigaction *ka;
23333 +
23334 +               ka = &current->sig->action[SIGSEGV - 1];
23335 +               ka->sa.sa_handler = SIG_DFL;
23336 +       }
23337 +       force_sig(SIGSEGV, current);
23338 +}
23339 +
23340 +#define _S(nr) (1<<((nr)-1))
23341 +
23342 +#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
23343 +
23344 +/*
23345 + * OK, we're invoking a handler
23346 + */    
23347 +static int handle_signal(struct pt_regs *regs, unsigned long signr, 
23348 +                        struct k_sigaction *ka, siginfo_t *info, 
23349 +                        sigset_t *oldset, int error)
23350 +{
23351 +        __sighandler_t handler;
23352 +       void (*restorer)(void);
23353 +       unsigned long sp;
23354 +       sigset_t save;
23355 +       int err, ret;
23356 +
23357 +       ret = 0;
23358 +       switch(error){
23359 +       case -ERESTARTNOHAND:
23360 +               ret = -EINTR;
23361 +               break;
23362 +
23363 +       case -ERESTARTSYS:
23364 +               if (!(ka->sa.sa_flags & SA_RESTART)) {
23365 +                       ret = -EINTR;
23366 +                       break;
23367 +               }
23368 +               /* fallthrough */
23369 +       case -ERESTARTNOINTR:
23370 +               PT_REGS_RESTART_SYSCALL(regs);
23371 +               PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
23372 +
23373 +               /* This is because of the UM_SET_SYSCALL_RETURN and the fact
23374 +                * that on i386 the system call number and return value are
23375 +                * in the same register.  When the system call restarts, %eax
23376 +                * had better have the system call number in it.  Since the
23377 +                * return value doesn't matter (except that it shouldn't be
23378 +                * -ERESTART*), we'll stick the system call number there.
23379 +                */
23380 +               ret = PT_REGS_SYSCALL_NR(regs);
23381 +               break;
23382 +       }
23383 +
23384 +       handler = ka->sa.sa_handler;
23385 +       save = *oldset;
23386 +
23387 +       if (ka->sa.sa_flags & SA_ONESHOT)
23388 +               ka->sa.sa_handler = SIG_DFL;
23389 +
23390 +       if (!(ka->sa.sa_flags & SA_NODEFER)) {
23391 +               spin_lock_irq(&current->sigmask_lock);
23392 +               sigorsets(&current->blocked, &current->blocked, 
23393 +                         &ka->sa.sa_mask);
23394 +               sigaddset(&current->blocked, signr);
23395 +               recalc_sigpending(current);
23396 +               spin_unlock_irq(&current->sigmask_lock);
23397 +       }
23398 +
23399 +       sp = PT_REGS_SP(regs);
23400 +
23401 +       if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
23402 +               sp = current->sas_ss_sp + current->sas_ss_size;
23403 +       
23404 +       if(error != 0) PT_REGS_SET_SYSCALL_RETURN(regs, ret);
23405 +
23406 +       if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer;
23407 +       else restorer = NULL;
23408 +
23409 +       if(ka->sa.sa_flags & SA_SIGINFO)
23410 +               err = setup_signal_stack_si(sp, signr, (unsigned long) handler,
23411 +                                           restorer, regs, info, &save);
23412 +       else
23413 +               err = setup_signal_stack_sc(sp, signr, (unsigned long) handler,
23414 +                                           restorer, regs, &save);
23415 +       if(err) goto segv;
23416 +
23417 +       return(0);
23418 + segv:
23419 +       force_segv(signr);
23420 +       return(1);
23421 +}
23422 +
23423 +/*
23424 + * Note that 'init' is a special process: it doesn't get signals it doesn't
23425 + * want to handle. Thus you cannot kill init even with a SIGKILL even by
23426 + * mistake.
23427 + */
23428 +
23429 +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
23430 +{
23431 +       siginfo_t info;
23432 +       struct k_sigaction *ka;
23433 +       int err;
23434 +
23435 +       if (!oldset)
23436 +               oldset = &current->blocked;
23437 +
23438 +       for (;;) {
23439 +               unsigned long signr;
23440 +
23441 +               spin_lock_irq(&current->sigmask_lock);
23442 +               signr = dequeue_signal(&current->blocked, &info);
23443 +               spin_unlock_irq(&current->sigmask_lock);
23444 +
23445 +               if (!signr)
23446 +                       break;
23447 +
23448 +               if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
23449 +                       /* Let the debugger run.  */
23450 +                       current->exit_code = signr;
23451 +                       current->state = TASK_STOPPED;
23452 +                       notify_parent(current, SIGCHLD);
23453 +                       schedule();
23454 +
23455 +                       /* We're back.  Did the debugger cancel the sig?  */
23456 +                       signr = current->exit_code;
23457 +                       if (!signr)
23458 +                               continue;
23459 +                       current->exit_code = 0;
23460 +
23461 +                       /* The debugger continued.  Ignore SIGSTOP.  */
23462 +                       if (signr == SIGSTOP)
23463 +                               continue;
23464 +
23465 +                       /* Update the siginfo structure.  Is this good?  */
23466 +                       if (signr != info.si_signo) {
23467 +                               info.si_signo = signr;
23468 +                               info.si_errno = 0;
23469 +                               info.si_code = SI_USER;
23470 +                               info.si_pid = current->p_pptr->pid;
23471 +                               info.si_uid = current->p_pptr->uid;
23472 +                       }
23473 +
23474 +                       /* If the (new) signal is now blocked, requeue it.  */
23475 +                       if (sigismember(&current->blocked, signr)) {
23476 +                               send_sig_info(signr, &info, current);
23477 +                               continue;
23478 +                       }
23479 +               }
23480 +
23481 +               ka = &current->sig->action[signr-1];
23482 +               if (ka->sa.sa_handler == SIG_IGN) {
23483 +                       if (signr != SIGCHLD)
23484 +                               continue;
23485 +                       /* Check for SIGCHLD: it's special.  */
23486 +                       while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
23487 +                               /* nothing */;
23488 +                       continue;
23489 +               }
23490 +
23491 +               if (ka->sa.sa_handler == SIG_DFL) {
23492 +                       int exit_code = signr;
23493 +
23494 +                       /* Init gets no signals it doesn't want.  */
23495 +                       if (current->pid == 1)
23496 +                               continue;
23497 +
23498 +                       switch (signr) {
23499 +                       case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
23500 +                               continue;
23501 +
23502 +                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
23503 +                               if (is_orphaned_pgrp(current->pgrp))
23504 +                                       continue;
23505 +                               /* FALLTHRU */
23506 +
23507 +                        case SIGSTOP: {
23508 +                                struct signal_struct *sig;
23509 +                               current->state = TASK_STOPPED;
23510 +                               current->exit_code = signr;
23511 +                                sig = current->p_pptr->sig;
23512 +                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
23513 +                                       notify_parent(current, SIGCHLD);
23514 +                               schedule();
23515 +                               continue;
23516 +                       }
23517 +                       case SIGQUIT: case SIGILL: case SIGTRAP:
23518 +                       case SIGABRT: case SIGFPE: case SIGSEGV:
23519 +                       case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
23520 +                               if (do_coredump(signr, &current->thread.regs))
23521 +                                       exit_code |= 0x80;
23522 +                               /* FALLTHRU */
23523 +
23524 +                       default:
23525 +                               sig_exit(signr, exit_code, &info);
23526 +                               /* NOTREACHED */
23527 +                       }
23528 +               }
23529 +
23530 +               /* Whee!  Actually deliver the signal.  */
23531 +               err = handle_signal(regs, signr, ka, &info, oldset, error);
23532 +               if(!err) return(1);
23533 +       }
23534 +
23535 +       /* Did we come from a system call? */
23536 +       if(PT_REGS_SYSCALL_NR(regs) >= 0){
23537 +               /* Restart the system call - no handlers present */
23538 +               if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND ||
23539 +                  PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS ||
23540 +                  PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){
23541 +                       PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs);
23542 +                       PT_REGS_RESTART_SYSCALL(regs);
23543 +               }
23544 +       }
23545 +
23546 +       /* This closes a way to execute a system call on the host.  If
23547 +        * you set a breakpoint on a system call instruction and singlestep
23548 +        * from it, the tracing thread used to PTRACE_SINGLESTEP the process
23549 +        * rather than PTRACE_SYSCALL it, allowing the system call to execute
23550 +        * on the host.  The tracing thread will check this flag and 
23551 +        * PTRACE_SYSCALL if necessary.
23552 +        */
23553 +       if((current->ptrace & PT_DTRACE) && 
23554 +          is_syscall(PT_REGS_IP(&current->thread.regs)))
23555 +               (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0);
23556 +
23557 +       return(0);
23558 +}
23559 +
23560 +int do_signal(int error)
23561 +{
23562 +       return(kern_do_signal(&current->thread.regs, NULL, error));
23563 +}
23564 +
23565 +/*
23566 + * Atomically swap in the new signal mask, and wait for a signal.
23567 + */
23568 +int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
23569 +{
23570 +       sigset_t saveset;
23571 +
23572 +       mask &= _BLOCKABLE;
23573 +       spin_lock_irq(&current->sigmask_lock);
23574 +       saveset = current->blocked;
23575 +       siginitset(&current->blocked, mask);
23576 +       recalc_sigpending(current);
23577 +       spin_unlock_irq(&current->sigmask_lock);
23578 +
23579 +       while (1) {
23580 +               current->state = TASK_INTERRUPTIBLE;
23581 +               schedule();
23582 +               if(kern_do_signal(&current->thread.regs, &saveset, -EINTR))
23583 +                       return(-EINTR);
23584 +       }
23585 +}
23586 +
23587 +int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
23588 +{
23589 +       sigset_t saveset, newset;
23590 +
23591 +       /* XXX: Don't preclude handling different sized sigset_t's.  */
23592 +       if (sigsetsize != sizeof(sigset_t))
23593 +               return -EINVAL;
23594 +
23595 +       if (copy_from_user(&newset, unewset, sizeof(newset)))
23596 +               return -EFAULT;
23597 +       sigdelsetmask(&newset, ~_BLOCKABLE);
23598 +
23599 +       spin_lock_irq(&current->sigmask_lock);
23600 +       saveset = current->blocked;
23601 +       current->blocked = newset;
23602 +       recalc_sigpending(current);
23603 +       spin_unlock_irq(&current->sigmask_lock);
23604 +
23605 +       while (1) {
23606 +               current->state = TASK_INTERRUPTIBLE;
23607 +               schedule();
23608 +               if (kern_do_signal(&current->thread.regs, &saveset, -EINTR))
23609 +                       return(-EINTR);
23610 +       }
23611 +}
23612 +
23613 +extern int userspace_pid[];
23614 +
23615 +static int copy_sc_from_user(struct pt_regs *to, void *from, 
23616 +                            struct arch_frame_data *arch)
23617 +{
23618 +       int ret;
23619 +
23620 +       ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
23621 +                         copy_sc_from_user_skas(userspace_pid[0], 
23622 +                                                &to->regs, from));
23623 +       return(ret);
23624 +}
23625 +
23626 +int sys_sigreturn(struct pt_regs regs)
23627 +{
23628 +       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
23629 +       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
23630 +       int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
23631 +
23632 +       spin_lock_irq(&current->sigmask_lock);
23633 +       copy_from_user(&current->blocked.sig[0], sc_sigmask(sc), 
23634 +                      sizeof(current->blocked.sig[0]));
23635 +       copy_from_user(&current->blocked.sig[1], mask, sig_size);
23636 +       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
23637 +       recalc_sigpending(current);
23638 +       spin_unlock_irq(&current->sigmask_lock);
23639 +       copy_sc_from_user(&current->thread.regs, sc, 
23640 +                         &signal_frame_sc.common.arch);
23641 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
23642 +}
23643 +
23644 +int sys_rt_sigreturn(struct pt_regs regs)
23645 +{
23646 +       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
23647 +       int sig_size = _NSIG_WORDS * sizeof(unsigned long);
23648 +
23649 +       spin_lock_irq(&current->sigmask_lock);
23650 +       copy_from_user(&current->blocked, &uc->uc_sigmask, sig_size);
23651 +       sigdelsetmask(&current->blocked, ~_BLOCKABLE);
23652 +       recalc_sigpending(current);
23653 +       spin_unlock_irq(&current->sigmask_lock);
23654 +       copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
23655 +                         &signal_frame_si.common.arch);
23656 +       return(PT_REGS_SYSCALL_RET(&current->thread.regs));
23657 +}
23658 +
23659 +/*
23660 + * Overrides for Emacs so that we follow Linus's tabbing style.
23661 + * Emacs will notice this stuff at the end of the file and automatically
23662 + * adjust the settings for this buffer only.  This must remain at the end
23663 + * of the file.
23664 + * ---------------------------------------------------------------------------
23665 + * Local variables:
23666 + * c-file-style: "linux"
23667 + * End:
23668 + */
23669 diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_user.c um/arch/um/kernel/signal_user.c
23670 --- orig/arch/um/kernel/signal_user.c   1969-12-31 19:00:00.000000000 -0500
23671 +++ um/arch/um/kernel/signal_user.c     2003-10-21 03:26:07.000000000 -0400
23672 @@ -0,0 +1,142 @@
23673 +/* 
23674 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
23675 + * Licensed under the GPL
23676 + */
23677 +
23678 +#include <stdio.h>
23679 +#include <unistd.h>
23680 +#include <stdlib.h>
23681 +#include <signal.h>
23682 +#include <errno.h>
23683 +#include <stdarg.h>
23684 +#include <string.h>
23685 +#include <sys/mman.h>
23686 +#include "user_util.h"
23687 +#include "kern_util.h"
23688 +#include "user.h"
23689 +#include "signal_user.h"
23690 +#include "signal_kern.h"
23691 +#include "sysdep/sigcontext.h"
23692 +#include "sigcontext.h"
23693 +
23694 +void set_sigstack(void *sig_stack, int size)
23695 +{
23696 +       stack_t stack = ((stack_t) { .ss_flags  = 0,
23697 +                                    .ss_sp     = (__ptr_t) sig_stack,
23698 +                                    .ss_size   = size - sizeof(void *) });
23699 +
23700 +       if(sigaltstack(&stack, NULL) != 0)
23701 +               panic("enabling signal stack failed, errno = %d\n", errno);
23702 +}
23703 +
23704 +void set_handler(int sig, void (*handler)(int), int flags, ...)
23705 +{
23706 +       struct sigaction action;
23707 +       va_list ap;
23708 +       int mask;
23709 +
23710 +       va_start(ap, flags);
23711 +       action.sa_handler = handler;
23712 +       sigemptyset(&action.sa_mask);
23713 +       while((mask = va_arg(ap, int)) != -1){
23714 +               sigaddset(&action.sa_mask, mask);
23715 +       }
23716 +       action.sa_flags = flags;
23717 +       action.sa_restorer = NULL;
23718 +       if(sigaction(sig, &action, NULL) < 0)
23719 +               panic("sigaction failed");
23720 +}
23721 +
23722 +int change_sig(int signal, int on)
23723 +{
23724 +       sigset_t sigset, old;
23725 +
23726 +       sigemptyset(&sigset);
23727 +       sigaddset(&sigset, signal);
23728 +       sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
23729 +       return(!sigismember(&old, signal));
23730 +}
23731 +
23732 +static void change_signals(int type)
23733 +{
23734 +       sigset_t mask;
23735 +
23736 +       sigemptyset(&mask);
23737 +       sigaddset(&mask, SIGVTALRM);
23738 +       sigaddset(&mask, SIGALRM);
23739 +       sigaddset(&mask, SIGIO);
23740 +       sigaddset(&mask, SIGPROF);
23741 +       if(sigprocmask(type, &mask, NULL) < 0)
23742 +               panic("Failed to change signal mask - errno = %d", errno);
23743 +}
23744 +
23745 +void block_signals(void)
23746 +{
23747 +       change_signals(SIG_BLOCK);
23748 +}
23749 +
23750 +void unblock_signals(void)
23751 +{
23752 +       change_signals(SIG_UNBLOCK);
23753 +}
23754 +
23755 +#define SIGIO_BIT 0
23756 +#define SIGVTALRM_BIT 1
23757 +
23758 +static int enable_mask(sigset_t *mask)
23759 +{
23760 +       int sigs;
23761 +
23762 +       sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
23763 +       sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
23764 +       sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
23765 +       return(sigs);
23766 +}
23767 +
23768 +int get_signals(void)
23769 +{
23770 +       sigset_t mask;
23771 +       
23772 +       if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
23773 +               panic("Failed to get signal mask");
23774 +       return(enable_mask(&mask));
23775 +}
23776 +
23777 +int set_signals(int enable)
23778 +{
23779 +       sigset_t mask;
23780 +       int ret;
23781 +
23782 +       sigemptyset(&mask);
23783 +       if(enable & (1 << SIGIO_BIT)) 
23784 +               sigaddset(&mask, SIGIO);
23785 +       if(enable & (1 << SIGVTALRM_BIT)){
23786 +               sigaddset(&mask, SIGVTALRM);
23787 +               sigaddset(&mask, SIGALRM);
23788 +       }
23789 +       if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
23790 +               panic("Failed to enable signals");
23791 +       ret = enable_mask(&mask);
23792 +       sigemptyset(&mask);
23793 +       if((enable & (1 << SIGIO_BIT)) == 0) 
23794 +               sigaddset(&mask, SIGIO);
23795 +       if((enable & (1 << SIGVTALRM_BIT)) == 0){
23796 +               sigaddset(&mask, SIGVTALRM);
23797 +               sigaddset(&mask, SIGALRM);
23798 +       }
23799 +       if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
23800 +               panic("Failed to block signals");
23801 +
23802 +       return(ret);
23803 +}
23804 +
23805 +/*
23806 + * Overrides for Emacs so that we follow Linus's tabbing style.
23807 + * Emacs will notice this stuff at the end of the file and automatically
23808 + * adjust the settings for this buffer only.  This must remain at the end
23809 + * of the file.
23810 + * ---------------------------------------------------------------------------
23811 + * Local variables:
23812 + * c-file-style: "linux"
23813 + * End:
23814 + */
23815 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_kern.c um/arch/um/kernel/skas/exec_kern.c
23816 --- orig/arch/um/kernel/skas/exec_kern.c        1969-12-31 19:00:00.000000000 -0500
23817 +++ um/arch/um/kernel/skas/exec_kern.c  2003-10-21 03:26:07.000000000 -0400
23818 @@ -0,0 +1,41 @@
23819 +/* 
23820 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23821 + * Licensed under the GPL
23822 + */
23823 +
23824 +#include "linux/kernel.h"
23825 +#include "asm/current.h"
23826 +#include "asm/page.h"
23827 +#include "asm/signal.h"
23828 +#include "asm/ptrace.h"
23829 +#include "asm/uaccess.h"
23830 +#include "asm/mmu_context.h"
23831 +#include "tlb.h"
23832 +#include "skas.h"
23833 +#include "mmu.h"
23834 +#include "os.h"
23835 +
23836 +void flush_thread_skas(void)
23837 +{
23838 +       force_flush_all();
23839 +       switch_mm_skas(current->mm->context.skas.mm_fd);
23840 +}
23841 +
23842 +void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
23843 +                      unsigned long esp)
23844 +{
23845 +       set_fs(USER_DS);
23846 +        PT_REGS_IP(regs) = eip;
23847 +       PT_REGS_SP(regs) = esp;
23848 +}
23849 +
23850 +/*
23851 + * Overrides for Emacs so that we follow Linus's tabbing style.
23852 + * Emacs will notice this stuff at the end of the file and automatically
23853 + * adjust the settings for this buffer only.  This must remain at the end
23854 + * of the file.
23855 + * ---------------------------------------------------------------------------
23856 + * Local variables:
23857 + * c-file-style: "linux"
23858 + * End:
23859 + */
23860 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_user.c um/arch/um/kernel/skas/exec_user.c
23861 --- orig/arch/um/kernel/skas/exec_user.c        1969-12-31 19:00:00.000000000 -0500
23862 +++ um/arch/um/kernel/skas/exec_user.c  2003-10-21 03:26:07.000000000 -0400
23863 @@ -0,0 +1,61 @@
23864 +/* 
23865 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23866 + * Licensed under the GPL
23867 + */
23868 +
23869 +#include <stdlib.h>
23870 +#include <errno.h>
23871 +#include <signal.h>
23872 +#include <sched.h>
23873 +#include <sys/wait.h>
23874 +#include <sys/ptrace.h>
23875 +#include "user.h"
23876 +#include "kern_util.h"
23877 +#include "os.h"
23878 +#include "time_user.h"
23879 +
23880 +static int user_thread_tramp(void *arg)
23881 +{
23882 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
23883 +               panic("user_thread_tramp - PTRACE_TRACEME failed, "
23884 +                     "errno = %d\n", errno);
23885 +       enable_timer();
23886 +       os_stop_process(os_getpid());
23887 +       return(0);
23888 +}
23889 +
23890 +int user_thread(unsigned long stack, int flags)
23891 +{
23892 +       int pid, status;
23893 +
23894 +       pid = clone(user_thread_tramp, (void *) stack_sp(stack), 
23895 +                   flags | CLONE_FILES | SIGCHLD, NULL);
23896 +       if(pid < 0){
23897 +               printk("user_thread - clone failed, errno = %d\n", errno);
23898 +               return(pid);
23899 +       }
23900 +
23901 +       if(waitpid(pid, &status, WUNTRACED) < 0){
23902 +               printk("user_thread - waitpid failed, errno = %d\n", errno);
23903 +               return(-errno);
23904 +       }
23905 +
23906 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){
23907 +               printk("user_thread - trampoline didn't stop, status = %d\n", 
23908 +                      status);
23909 +               return(-EINVAL);
23910 +       }
23911 +
23912 +       return(pid);
23913 +}
23914 +
23915 +/*
23916 + * Overrides for Emacs so that we follow Linus's tabbing style.
23917 + * Emacs will notice this stuff at the end of the file and automatically
23918 + * adjust the settings for this buffer only.  This must remain at the end
23919 + * of the file.
23920 + * ---------------------------------------------------------------------------
23921 + * Local variables:
23922 + * c-file-style: "linux"
23923 + * End:
23924 + */
23925 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mmu.h um/arch/um/kernel/skas/include/mmu.h
23926 --- orig/arch/um/kernel/skas/include/mmu.h      1969-12-31 19:00:00.000000000 -0500
23927 +++ um/arch/um/kernel/skas/include/mmu.h        2003-10-21 03:26:07.000000000 -0400
23928 @@ -0,0 +1,27 @@
23929 +/* 
23930 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23931 + * Licensed under the GPL
23932 + */
23933 +
23934 +#ifndef __SKAS_MMU_H
23935 +#define __SKAS_MMU_H
23936 +
23937 +#include "linux/list.h"
23938 +#include "linux/spinlock.h"
23939 +
23940 +struct mmu_context_skas {
23941 +       int mm_fd;
23942 +};
23943 +
23944 +#endif
23945 +
23946 +/*
23947 + * Overrides for Emacs so that we follow Linus's tabbing style.
23948 + * Emacs will notice this stuff at the end of the file and automatically
23949 + * adjust the settings for this buffer only.  This must remain at the end
23950 + * of the file.
23951 + * ---------------------------------------------------------------------------
23952 + * Local variables:
23953 + * c-file-style: "linux"
23954 + * End:
23955 + */
23956 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode.h um/arch/um/kernel/skas/include/mode.h
23957 --- orig/arch/um/kernel/skas/include/mode.h     1969-12-31 19:00:00.000000000 -0500
23958 +++ um/arch/um/kernel/skas/include/mode.h       2003-11-19 03:27:36.000000000 -0500
23959 @@ -0,0 +1,37 @@
23960 +/* 
23961 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
23962 + * Licensed under the GPL
23963 + */
23964 +
23965 +#ifndef __MODE_SKAS_H__
23966 +#define __MODE_SKAS_H__
23967 +
23968 +extern unsigned long exec_regs[];
23969 +extern unsigned long exec_fp_regs[];
23970 +extern unsigned long exec_fpx_regs[];
23971 +extern int have_fpx_regs;
23972 +
23973 +extern void user_time_init_skas(void);
23974 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, 
23975 +                                 void *from_ptr);
23976 +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
23977 +                               union uml_pt_regs *regs, 
23978 +                               unsigned long fault_addr, int fault_type);
23979 +extern void sig_handler_common_skas(int sig, void *sc_ptr);
23980 +extern void halt_skas(void);
23981 +extern void reboot_skas(void);
23982 +extern void kill_off_processes_skas(void);
23983 +extern int is_skas_winch(int pid, int fd, void *data);
23984 +
23985 +#endif
23986 +
23987 +/*
23988 + * Overrides for Emacs so that we follow Linus's tabbing style.
23989 + * Emacs will notice this stuff at the end of the file and automatically
23990 + * adjust the settings for this buffer only.  This must remain at the end
23991 + * of the file.
23992 + * ---------------------------------------------------------------------------
23993 + * Local variables:
23994 + * c-file-style: "linux"
23995 + * End:
23996 + */
23997 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode_kern.h um/arch/um/kernel/skas/include/mode_kern.h
23998 --- orig/arch/um/kernel/skas/include/mode_kern.h        1969-12-31 19:00:00.000000000 -0500
23999 +++ um/arch/um/kernel/skas/include/mode_kern.h  2003-10-21 03:26:07.000000000 -0400
24000 @@ -0,0 +1,51 @@
24001 +/* 
24002 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24003 + * Licensed under the GPL
24004 + */
24005 +
24006 +#ifndef __SKAS_MODE_KERN_H__
24007 +#define __SKAS_MODE_KERN_H__
24008 +
24009 +#include "linux/sched.h"
24010 +#include "asm/page.h"
24011 +#include "asm/ptrace.h"
24012 +
24013 +extern void flush_thread_skas(void);
24014 +extern void *_switch_to_skas(void *prev, void *next);
24015 +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
24016 +                             unsigned long esp);
24017 +extern int copy_thread_skas(int nr, unsigned long clone_flags, 
24018 +                           unsigned long sp, unsigned long stack_top, 
24019 +                           struct task_struct *p, struct pt_regs *regs);
24020 +extern void release_thread_skas(struct task_struct *task);
24021 +extern void exit_thread_skas(void);
24022 +extern void initial_thread_cb_skas(void (*proc)(void *), void *arg);
24023 +extern void init_idle_skas(void);
24024 +extern void flush_tlb_kernel_vm_skas(void);
24025 +extern void __flush_tlb_one_skas(unsigned long addr);
24026 +extern void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, 
24027 +                                unsigned long end);
24028 +extern void flush_tlb_mm_skas(struct mm_struct *mm);
24029 +extern void force_flush_all_skas(void);
24030 +extern long execute_syscall_skas(void *r);
24031 +extern void before_mem_skas(unsigned long unused);
24032 +extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
24033 +                                        unsigned long *task_size_out);
24034 +extern int start_uml_skas(void);
24035 +extern int external_pid_skas(struct task_struct *task);
24036 +extern int thread_pid_skas(struct thread_struct *thread);
24037 +
24038 +#define kmem_end_skas (host_task_size - 1024 * 1024)
24039 +
24040 +#endif
24041 +
24042 +/*
24043 + * Overrides for Emacs so that we follow Linus's tabbing style.
24044 + * Emacs will notice this stuff at the end of the file and automatically
24045 + * adjust the settings for this buffer only.  This must remain at the end
24046 + * of the file.
24047 + * ---------------------------------------------------------------------------
24048 + * Local variables:
24049 + * c-file-style: "linux"
24050 + * End:
24051 + */
24052 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/proc_mm.h um/arch/um/kernel/skas/include/proc_mm.h
24053 --- orig/arch/um/kernel/skas/include/proc_mm.h  1969-12-31 19:00:00.000000000 -0500
24054 +++ um/arch/um/kernel/skas/include/proc_mm.h    2003-10-21 03:26:07.000000000 -0400
24055 @@ -0,0 +1,55 @@
24056 +/* 
24057 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24058 + * Licensed under the GPL
24059 + */
24060 +
24061 +#ifndef __SKAS_PROC_MM_H
24062 +#define __SKAS_PROC_MM_H
24063 +
24064 +#define MM_MMAP 54
24065 +#define MM_MUNMAP 55
24066 +#define MM_MPROTECT 56
24067 +#define MM_COPY_SEGMENTS 57
24068 +
24069 +struct mm_mmap {
24070 +       unsigned long addr;
24071 +       unsigned long len;
24072 +       unsigned long prot;
24073 +       unsigned long flags;
24074 +       unsigned long fd;
24075 +       unsigned long offset;
24076 +};
24077 +
24078 +struct mm_munmap {
24079 +       unsigned long addr;
24080 +       unsigned long len;      
24081 +};
24082 +
24083 +struct mm_mprotect {
24084 +       unsigned long addr;
24085 +       unsigned long len;
24086 +        unsigned int prot;
24087 +};
24088 +
24089 +struct proc_mm_op {
24090 +       int op;
24091 +       union {
24092 +               struct mm_mmap mmap;
24093 +               struct mm_munmap munmap;
24094 +               struct mm_mprotect mprotect;
24095 +               int copy_segments;
24096 +       } u;
24097 +};
24098 +
24099 +#endif
24100 +
24101 +/*
24102 + * Overrides for Emacs so that we follow Linus's tabbing style.
24103 + * Emacs will notice this stuff at the end of the file and automatically
24104 + * adjust the settings for this buffer only.  This must remain at the end
24105 + * of the file.
24106 + * ---------------------------------------------------------------------------
24107 + * Local variables:
24108 + * c-file-style: "linux"
24109 + * End:
24110 + */
24111 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/ptrace-skas.h um/arch/um/kernel/skas/include/ptrace-skas.h
24112 --- orig/arch/um/kernel/skas/include/ptrace-skas.h      1969-12-31 19:00:00.000000000 -0500
24113 +++ um/arch/um/kernel/skas/include/ptrace-skas.h        2003-10-21 03:26:07.000000000 -0400
24114 @@ -0,0 +1,57 @@
24115 +/* 
24116 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24117 + * Licensed under the GPL
24118 + */
24119 +
24120 +#ifndef __PTRACE_SKAS_H
24121 +#define __PTRACE_SKAS_H
24122 +
24123 +#include "uml-config.h"
24124 +
24125 +#ifdef UML_CONFIG_MODE_SKAS
24126 +
24127 +#include "skas_ptregs.h"
24128 +
24129 +#define HOST_FRAME_SIZE 17
24130 +
24131 +#define REGS_IP(r) ((r)[HOST_IP])
24132 +#define REGS_SP(r) ((r)[HOST_SP])
24133 +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
24134 +#define REGS_EAX(r) ((r)[HOST_EAX])
24135 +#define REGS_EBX(r) ((r)[HOST_EBX])
24136 +#define REGS_ECX(r) ((r)[HOST_ECX])
24137 +#define REGS_EDX(r) ((r)[HOST_EDX])
24138 +#define REGS_ESI(r) ((r)[HOST_ESI])
24139 +#define REGS_EDI(r) ((r)[HOST_EDI])
24140 +#define REGS_EBP(r) ((r)[HOST_EBP])
24141 +#define REGS_CS(r) ((r)[HOST_CS])
24142 +#define REGS_SS(r) ((r)[HOST_SS])
24143 +#define REGS_DS(r) ((r)[HOST_DS])
24144 +#define REGS_ES(r) ((r)[HOST_ES])
24145 +#define REGS_FS(r) ((r)[HOST_FS])
24146 +#define REGS_GS(r) ((r)[HOST_GS])
24147 +
24148 +#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
24149 +
24150 +#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
24151 +
24152 +#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
24153 +
24154 +#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
24155 +
24156 +#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
24157 +
24158 +#endif
24159 +
24160 +#endif
24161 +
24162 +/*
24163 + * Overrides for Emacs so that we follow Linus's tabbing style.
24164 + * Emacs will notice this stuff at the end of the file and automatically
24165 + * adjust the settings for this buffer only.  This must remain at the end
24166 + * of the file.
24167 + * ---------------------------------------------------------------------------
24168 + * Local variables:
24169 + * c-file-style: "linux"
24170 + * End:
24171 + */
24172 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/skas.h um/arch/um/kernel/skas/include/skas.h
24173 --- orig/arch/um/kernel/skas/include/skas.h     1969-12-31 19:00:00.000000000 -0500
24174 +++ um/arch/um/kernel/skas/include/skas.h       2003-11-19 03:00:51.000000000 -0500
24175 @@ -0,0 +1,49 @@
24176 +/* 
24177 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24178 + * Licensed under the GPL
24179 + */
24180 +
24181 +#ifndef __SKAS_H
24182 +#define __SKAS_H
24183 +
24184 +#include "sysdep/ptrace.h"
24185 +
24186 +extern int userspace_pid[];
24187 +
24188 +extern void switch_threads(void *me, void *next);
24189 +extern void thread_wait(void *sw, void *fb);
24190 +extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
24191 +                       void (*handler)(int));
24192 +extern int start_idle_thread(void *stack, void *switch_buf_ptr, 
24193 +                            void **fork_buf_ptr);
24194 +extern int user_thread(unsigned long stack, int flags);
24195 +extern void userspace(union uml_pt_regs *regs);
24196 +extern void new_thread_proc(void *stack, void (*handler)(int sig));
24197 +extern void remove_sigstack(void);
24198 +extern void new_thread_handler(int sig);
24199 +extern void handle_syscall(union uml_pt_regs *regs);
24200 +extern void map(int fd, unsigned long virt, unsigned long phys, 
24201 +               unsigned long len, int r, int w, int x);
24202 +extern int unmap(int fd, void *addr, int len);
24203 +extern int protect(int fd, unsigned long addr, unsigned long len, 
24204 +                  int r, int w, int x, int must_succeed);
24205 +extern void user_signal(int sig, union uml_pt_regs *regs);
24206 +extern int singlestepping_skas(void);
24207 +extern int new_mm(int from);
24208 +extern void save_registers(union uml_pt_regs *regs);
24209 +extern void restore_registers(union uml_pt_regs *regs);
24210 +extern void start_userspace(int cpu);
24211 +extern void init_registers(int pid);
24212 +
24213 +#endif
24214 +
24215 +/*
24216 + * Overrides for Emacs so that we follow Linus's tabbing style.
24217 + * Emacs will notice this stuff at the end of the file and automatically
24218 + * adjust the settings for this buffer only.  This must remain at the end
24219 + * of the file.
24220 + * ---------------------------------------------------------------------------
24221 + * Local variables:
24222 + * c-file-style: "linux"
24223 + * End:
24224 + */
24225 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/uaccess.h um/arch/um/kernel/skas/include/uaccess.h
24226 --- orig/arch/um/kernel/skas/include/uaccess.h  1969-12-31 19:00:00.000000000 -0500
24227 +++ um/arch/um/kernel/skas/include/uaccess.h    2003-12-17 01:19:45.000000000 -0500
24228 @@ -0,0 +1,38 @@
24229 +/* 
24230 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24231 + * Licensed under the GPL
24232 + */
24233 +
24234 +#ifndef __SKAS_UACCESS_H
24235 +#define __SKAS_UACCESS_H
24236 +
24237 +#define access_ok_skas(type, addr, size) \
24238 +       ((segment_eq(get_fs(), KERNEL_DS)) || \
24239 +        (((unsigned long) (addr) < TASK_SIZE) && \
24240 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)))
24241 +
24242 +static inline int verify_area_skas(int type, const void * addr, 
24243 +                                  unsigned long size)
24244 +{
24245 +       return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
24246 +}
24247 +
24248 +#endif
24249 +
24250 +extern int copy_from_user_skas(void *to, const void *from, int n);
24251 +extern int copy_to_user_skas(void *to, const void *from, int n);
24252 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
24253 +extern int __clear_user_skas(void *mem, int len);
24254 +extern int clear_user_skas(void *mem, int len);
24255 +extern int strnlen_user_skas(const void *str, int len);
24256 +
24257 +/*
24258 + * Overrides for Emacs so that we follow Linus's tabbing style.
24259 + * Emacs will notice this stuff at the end of the file and automatically
24260 + * adjust the settings for this buffer only.  This must remain at the end
24261 + * of the file.
24262 + * ---------------------------------------------------------------------------
24263 + * Local variables:
24264 + * c-file-style: "linux"
24265 + * End:
24266 + */
24267 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/Makefile um/arch/um/kernel/skas/Makefile
24268 --- orig/arch/um/kernel/skas/Makefile   1969-12-31 19:00:00.000000000 -0500
24269 +++ um/arch/um/kernel/skas/Makefile     2003-11-11 06:36:12.000000000 -0500
24270 @@ -0,0 +1,31 @@
24271 +# 
24272 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24273 +# Licensed under the GPL
24274 +#
24275 +
24276 +O_TARGET = skas.o
24277 +
24278 +obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
24279 +       process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
24280 +       uaccess.o
24281 +
24282 +subdir-y = sys-$(SUBARCH)
24283 +
24284 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
24285 +
24286 +USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
24287 +
24288 +include $(TOPDIR)/Rules.make
24289 +
24290 +include/skas_ptregs.h : util/mk_ptregs
24291 +       util/mk_ptregs > $@
24292 +
24293 +util/mk_ptregs :
24294 +       $(MAKE) -C util
24295 +
24296 +$(USER_OBJS) : %.o: %.c
24297 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
24298 +
24299 +clean :
24300 +       $(MAKE) -C util clean
24301 +       $(RM) -f include/skas_ptregs.h
24302 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem.c um/arch/um/kernel/skas/mem.c
24303 --- orig/arch/um/kernel/skas/mem.c      1969-12-31 19:00:00.000000000 -0500
24304 +++ um/arch/um/kernel/skas/mem.c        2003-10-21 03:26:07.000000000 -0400
24305 @@ -0,0 +1,30 @@
24306 +/* 
24307 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24308 + * Licensed under the GPL
24309 + */
24310 +
24311 +#include "linux/config.h"
24312 +#include "linux/mm.h"
24313 +#include "mem_user.h"
24314 +
24315 +unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, 
24316 +                                 unsigned long *task_size_out)
24317 +{
24318 +       /* Round up to the nearest 4M */
24319 +       unsigned long top = ROUND_4M((unsigned long) &arg);
24320 +
24321 +       *host_size_out = top;
24322 +       *task_size_out = top;
24323 +       return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
24324 +}
24325 +
24326 +/*
24327 + * Overrides for Emacs so that we follow Linus's tabbing style.
24328 + * Emacs will notice this stuff at the end of the file and automatically
24329 + * adjust the settings for this buffer only.  This must remain at the end
24330 + * of the file.
24331 + * ---------------------------------------------------------------------------
24332 + * Local variables:
24333 + * c-file-style: "linux"
24334 + * End:
24335 + */
24336 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem_user.c um/arch/um/kernel/skas/mem_user.c
24337 --- orig/arch/um/kernel/skas/mem_user.c 1969-12-31 19:00:00.000000000 -0500
24338 +++ um/arch/um/kernel/skas/mem_user.c   2003-10-21 03:26:07.000000000 -0400
24339 @@ -0,0 +1,105 @@
24340 +/* 
24341 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24342 + * Licensed under the GPL
24343 + */
24344 +
24345 +#include <errno.h>
24346 +#include <sys/mman.h>
24347 +#include <sys/ptrace.h>
24348 +#include "mem_user.h"
24349 +#include "mem.h"
24350 +#include "user.h"
24351 +#include "os.h"
24352 +#include "proc_mm.h"
24353 +
24354 +void map(int fd, unsigned long virt, unsigned long phys, unsigned long len, 
24355 +        int r, int w, int x)
24356 +{
24357 +       struct proc_mm_op map;
24358 +       __u64 offset;
24359 +       int prot, n, phys_fd;
24360 +
24361 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
24362 +               (x ? PROT_EXEC : 0);
24363 +       phys_fd = phys_mapping(phys, &offset);
24364 +
24365 +       map = ((struct proc_mm_op) { .op        = MM_MMAP,
24366 +                                    .u         = 
24367 +                                    { .mmap    = 
24368 +                                      { .addr          = virt,
24369 +                                        .len           = len,
24370 +                                        .prot          = prot,
24371 +                                        .flags         = MAP_SHARED | 
24372 +                                                         MAP_FIXED,
24373 +                                        .fd            = phys_fd,
24374 +                                        .offset        = offset
24375 +                                      } } } );
24376 +       n = os_write_file(fd, &map, sizeof(map));
24377 +       if(n != sizeof(map)) 
24378 +               printk("map : /proc/mm map failed, err = %d\n", -n);
24379 +}
24380 +
24381 +int unmap(int fd, void *addr, int len)
24382 +{
24383 +       struct proc_mm_op unmap;
24384 +       int n;
24385 +
24386 +       unmap = ((struct proc_mm_op) { .op      = MM_MUNMAP,
24387 +                                      .u       = 
24388 +                                      { .munmap        = 
24389 +                                        { .addr        = (unsigned long) addr,
24390 +                                          .len         = len } } } );
24391 +       n = os_write_file(fd, &unmap, sizeof(unmap));
24392 +       if(n != sizeof(unmap)) {
24393 +               if(n < 0) 
24394 +                       return(n);
24395 +               else if(n > 0) 
24396 +                       return(-EIO);
24397 +       }
24398 +
24399 +       return(0);
24400 +}
24401 +
24402 +int protect(int fd, unsigned long addr, unsigned long len, int r, int w, 
24403 +           int x, int must_succeed)
24404 +{
24405 +       struct proc_mm_op protect;
24406 +       int prot, n;
24407 +
24408 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
24409 +               (x ? PROT_EXEC : 0);
24410 +
24411 +       protect = ((struct proc_mm_op) { .op    = MM_MPROTECT,
24412 +                                      .u       = 
24413 +                                      { .mprotect      = 
24414 +                                        { .addr        = (unsigned long) addr,
24415 +                                          .len         = len,
24416 +                                          .prot        = prot } } } );
24417 +
24418 +       n = os_write_file(fd, &protect, sizeof(protect));
24419 +       if(n != sizeof(protect)) {
24420 +               if(n == 0) return(0);
24421 +
24422 +               if(must_succeed)
24423 +                       panic("protect failed, err = %d", -n);
24424 +
24425 +               return(-EIO);
24426 +       }
24427 +
24428 +       return(0);
24429 +}
24430 +
24431 +void before_mem_skas(unsigned long unused)
24432 +{
24433 +}
24434 +
24435 +/*
24436 + * Overrides for Emacs so that we follow Linus's tabbing style.
24437 + * Emacs will notice this stuff at the end of the file and automatically
24438 + * adjust the settings for this buffer only.  This must remain at the end
24439 + * of the file.
24440 + * ---------------------------------------------------------------------------
24441 + * Local variables:
24442 + * c-file-style: "linux"
24443 + * End:
24444 + */
24445 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mmu.c um/arch/um/kernel/skas/mmu.c
24446 --- orig/arch/um/kernel/skas/mmu.c      1969-12-31 19:00:00.000000000 -0500
24447 +++ um/arch/um/kernel/skas/mmu.c        2003-11-15 22:25:20.000000000 -0500
24448 @@ -0,0 +1,46 @@
24449 +/* 
24450 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24451 + * Licensed under the GPL
24452 + */
24453 +
24454 +#include "linux/list.h"
24455 +#include "linux/spinlock.h"
24456 +#include "linux/slab.h"
24457 +#include "asm/segment.h"
24458 +#include "asm/mmu.h"
24459 +#include "os.h"
24460 +#include "skas.h"
24461 +
24462 +int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
24463 +{
24464 +       int from;
24465 +
24466 +       if((current->mm != NULL) && (current->mm != &init_mm))
24467 +               from = current->mm->context.skas.mm_fd;
24468 +       else from = -1;
24469 +
24470 +       mm->context.skas.mm_fd = new_mm(from);
24471 +       if(mm->context.skas.mm_fd < 0){
24472 +               printk("init_new_context_skas - new_mm failed, errno = %d\n",
24473 +                      mm->context.skas.mm_fd);
24474 +               return(mm->context.skas.mm_fd);
24475 +       }
24476 +
24477 +       return(0);
24478 +}
24479 +
24480 +void destroy_context_skas(struct mm_struct *mm)
24481 +{
24482 +       os_close_file(mm->context.skas.mm_fd);
24483 +}
24484 +
24485 +/*
24486 + * Overrides for Emacs so that we follow Linus's tabbing style.
24487 + * Emacs will notice this stuff at the end of the file and automatically
24488 + * adjust the settings for this buffer only.  This must remain at the end
24489 + * of the file.
24490 + * ---------------------------------------------------------------------------
24491 + * Local variables:
24492 + * c-file-style: "linux"
24493 + * End:
24494 + */
24495 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process.c um/arch/um/kernel/skas/process.c
24496 --- orig/arch/um/kernel/skas/process.c  1969-12-31 19:00:00.000000000 -0500
24497 +++ um/arch/um/kernel/skas/process.c    2003-11-19 03:00:01.000000000 -0500
24498 @@ -0,0 +1,417 @@
24499 +/* 
24500 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24501 + * Licensed under the GPL
24502 + */
24503 +
24504 +#include <stdlib.h>
24505 +#include <unistd.h>
24506 +#include <errno.h>
24507 +#include <signal.h>
24508 +#include <setjmp.h>
24509 +#include <sched.h>
24510 +#include <sys/wait.h>
24511 +#include <sys/ptrace.h>
24512 +#include <sys/mman.h>
24513 +#include <sys/user.h>
24514 +#include <asm/unistd.h>
24515 +#include "user.h"
24516 +#include "ptrace_user.h"
24517 +#include "time_user.h"
24518 +#include "sysdep/ptrace.h"
24519 +#include "user_util.h"
24520 +#include "kern_util.h"
24521 +#include "skas.h"
24522 +#include "sysdep/sigcontext.h"
24523 +#include "os.h"
24524 +#include "proc_mm.h"
24525 +#include "skas_ptrace.h"
24526 +#include "chan_user.h"
24527 +
24528 +int is_skas_winch(int pid, int fd, void *data)
24529 +{
24530 +       if(pid != getpid())
24531 +               return(0);
24532 +
24533 +       register_winch_irq(-1, fd, -1, data);
24534 +       return(1);
24535 +}
24536 +
24537 +/* These are set once at boot time and not changed thereafter */
24538 +
24539 +unsigned long exec_regs[FRAME_SIZE];
24540 +unsigned long exec_fp_regs[HOST_FP_SIZE];
24541 +unsigned long exec_fpx_regs[HOST_XFP_SIZE];
24542 +int have_fpx_regs = 1;
24543 +
24544 +static void handle_segv(int pid)
24545 +{
24546 +       struct ptrace_faultinfo fault;
24547 +       int err;
24548 +
24549 +       err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault);
24550 +       if(err)
24551 +               panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n",
24552 +                     errno);
24553 +
24554 +       segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
24555 +}
24556 +
24557 +static void handle_trap(int pid, union uml_pt_regs *regs)
24558 +{
24559 +       int err, syscall_nr, status;
24560 +
24561 +       syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
24562 +       UPT_SYSCALL_NR(regs) = syscall_nr;
24563 +       if(syscall_nr < 1){
24564 +               relay_signal(SIGTRAP, regs);
24565 +               return;
24566 +       }
24567 +
24568 +       err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
24569 +       if(err < 0)
24570 +               panic("handle_trap - nullifying syscall failed errno = %d\n", 
24571 +                     errno);
24572 +
24573 +       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
24574 +       if(err < 0)
24575 +               panic("handle_trap - continuing to end of syscall failed, "
24576 +                     "errno = %d\n", errno);
24577 +
24578 +       err = waitpid(pid, &status, WUNTRACED);
24579 +       if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
24580 +               panic("handle_trap - failed to wait at end of syscall, "
24581 +                     "errno = %d, status = %d\n", errno, status);
24582 +
24583 +       handle_syscall(regs);
24584 +}
24585 +
24586 +static int userspace_tramp(void *arg)
24587 +{
24588 +       init_new_thread_signals(0);
24589 +       enable_timer();
24590 +       ptrace(PTRACE_TRACEME, 0, 0, 0);
24591 +       os_stop_process(os_getpid());
24592 +       return(0);
24593 +}
24594 +
24595 +/* Each element set once, and only accessed by a single processor anyway */
24596 +#define NR_CPUS 1
24597 +int userspace_pid[NR_CPUS];
24598 +
24599 +void start_userspace(int cpu)
24600 +{
24601 +       void *stack;
24602 +       unsigned long sp;
24603 +       int pid, status, n;
24604 +
24605 +       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
24606 +                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
24607 +       if(stack == MAP_FAILED)
24608 +               panic("start_userspace : mmap failed, errno = %d", errno);
24609 +       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
24610 +
24611 +       pid = clone(userspace_tramp, (void *) sp, 
24612 +                   CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
24613 +       if(pid < 0)
24614 +               panic("start_userspace : clone failed, errno = %d", errno);
24615 +
24616 +       do {
24617 +               n = waitpid(pid, &status, WUNTRACED);
24618 +               if(n < 0)
24619 +                       panic("start_userspace : wait failed, errno = %d", 
24620 +                             errno);
24621 +       } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
24622 +
24623 +       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
24624 +               panic("start_userspace : expected SIGSTOP, got status = %d",
24625 +                     status);
24626 +
24627 +       if(munmap(stack, PAGE_SIZE) < 0)
24628 +               panic("start_userspace : munmap failed, errno = %d\n", errno);
24629 +
24630 +       userspace_pid[cpu] = pid;
24631 +}
24632 +
24633 +void userspace(union uml_pt_regs *regs)
24634 +{
24635 +       int err, status, op, pid = userspace_pid[0];
24636 +
24637 +       restore_registers(regs);
24638 +               
24639 +       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
24640 +       if(err)
24641 +               panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
24642 +                      errno);
24643 +       while(1){
24644 +               err = waitpid(pid, &status, WUNTRACED);
24645 +               if(err < 0)
24646 +                       panic("userspace - waitpid failed, errno = %d\n", 
24647 +                             errno);
24648 +
24649 +               regs->skas.is_user = 1;
24650 +               save_registers(regs);
24651 +
24652 +               if(WIFSTOPPED(status)){
24653 +                       switch(WSTOPSIG(status)){
24654 +                       case SIGSEGV:
24655 +                               handle_segv(pid);
24656 +                               break;
24657 +                       case SIGTRAP:
24658 +                               handle_trap(pid, regs);
24659 +                               break;
24660 +                       case SIGIO:
24661 +                       case SIGVTALRM:
24662 +                       case SIGILL:
24663 +                       case SIGBUS:
24664 +                       case SIGFPE:
24665 +                       case SIGWINCH:
24666 +                               user_signal(WSTOPSIG(status), regs);
24667 +                               break;
24668 +                       default:
24669 +                               printk("userspace - child stopped with signal "
24670 +                                      "%d\n", WSTOPSIG(status));
24671 +                       }
24672 +                       interrupt_end();
24673 +               }
24674 +
24675 +               restore_registers(regs);
24676 +
24677 +               op = singlestepping_skas() ? PTRACE_SINGLESTEP : 
24678 +                       PTRACE_SYSCALL;
24679 +               err = ptrace(op, pid, 0, 0);
24680 +               if(err)
24681 +                       panic("userspace - PTRACE_SYSCALL failed, "
24682 +                             "errno = %d\n", errno);
24683 +       }
24684 +}
24685 +
24686 +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
24687 +               void (*handler)(int))
24688 +{
24689 +       jmp_buf switch_buf, fork_buf;
24690 +
24691 +       *switch_buf_ptr = &switch_buf;
24692 +       *fork_buf_ptr = &fork_buf;
24693 +
24694 +       if(sigsetjmp(fork_buf, 1) == 0)
24695 +               new_thread_proc(stack, handler);
24696 +
24697 +       remove_sigstack();
24698 +}
24699 +
24700 +void thread_wait(void *sw, void *fb)
24701 +{
24702 +       jmp_buf buf, **switch_buf = sw, *fork_buf;
24703 +
24704 +       *switch_buf = &buf;
24705 +       fork_buf = fb;
24706 +       if(sigsetjmp(buf, 1) == 0)
24707 +               siglongjmp(*fork_buf, 1);
24708 +}
24709 +
24710 +static int move_registers(int pid, int int_op, int fp_op, 
24711 +                         union uml_pt_regs *regs, unsigned long *fp_regs)
24712 +{
24713 +       if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
24714 +               return(-errno);
24715 +       if(ptrace(fp_op, pid, 0, fp_regs) < 0)
24716 +               return(-errno);
24717 +       return(0);
24718 +}
24719 +
24720 +void save_registers(union uml_pt_regs *regs)
24721 +{
24722 +       unsigned long *fp_regs;
24723 +       int err, fp_op;
24724 +
24725 +       if(have_fpx_regs){
24726 +               fp_op = PTRACE_GETFPXREGS;
24727 +               fp_regs = regs->skas.xfp;
24728 +       }
24729 +       else {
24730 +               fp_op = PTRACE_GETFPREGS;
24731 +               fp_regs = regs->skas.fp;
24732 +       }
24733 +
24734 +       err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, 
24735 +                            fp_regs);
24736 +       if(err)
24737 +               panic("save_registers - saving registers failed, errno = %d\n",
24738 +                     -err);
24739 +}
24740 +
24741 +void restore_registers(union uml_pt_regs *regs)
24742 +{
24743 +       unsigned long *fp_regs;
24744 +       int err, fp_op;
24745 +
24746 +       if(have_fpx_regs){
24747 +               fp_op = PTRACE_SETFPXREGS;
24748 +               fp_regs = regs->skas.xfp;
24749 +       }
24750 +       else {
24751 +               fp_op = PTRACE_SETFPREGS;
24752 +               fp_regs = regs->skas.fp;
24753 +       }
24754 +
24755 +       err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, 
24756 +                            fp_regs);
24757 +       if(err)
24758 +               panic("restore_registers - saving registers failed, "
24759 +                     "errno = %d\n", -err);
24760 +}
24761 +
24762 +void switch_threads(void *me, void *next)
24763 +{
24764 +       jmp_buf my_buf, **me_ptr = me, *next_buf = next;
24765 +       
24766 +       *me_ptr = &my_buf;
24767 +       if(sigsetjmp(my_buf, 1) == 0)
24768 +               siglongjmp(*next_buf, 1);
24769 +}
24770 +
24771 +static jmp_buf initial_jmpbuf;
24772 +
24773 +/* XXX Make these percpu */
24774 +static void (*cb_proc)(void *arg);
24775 +static void *cb_arg;
24776 +static jmp_buf *cb_back;
24777 +
24778 +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
24779 +{
24780 +       jmp_buf **switch_buf = switch_buf_ptr;
24781 +       int n;
24782 +
24783 +       *fork_buf_ptr = &initial_jmpbuf;
24784 +       n = sigsetjmp(initial_jmpbuf, 1);
24785 +       if(n == 0)
24786 +               new_thread_proc((void *) stack, new_thread_handler);
24787 +       else if(n == 1)
24788 +               remove_sigstack();
24789 +       else if(n == 2){
24790 +               (*cb_proc)(cb_arg);
24791 +               siglongjmp(*cb_back, 1);
24792 +       }
24793 +       else if(n == 3){
24794 +               kmalloc_ok = 0;
24795 +               return(0);
24796 +       }
24797 +       else if(n == 4){
24798 +               kmalloc_ok = 0;
24799 +               return(1);
24800 +       }
24801 +       siglongjmp(**switch_buf, 1);
24802 +}
24803 +
24804 +void remove_sigstack(void)
24805 +{
24806 +       stack_t stack = ((stack_t) { .ss_flags  = SS_DISABLE,
24807 +                                    .ss_sp     = NULL,
24808 +                                    .ss_size   = 0 });
24809 +
24810 +       if(sigaltstack(&stack, NULL) != 0)
24811 +               panic("disabling signal stack failed, errno = %d\n", errno);
24812 +}
24813 +
24814 +void initial_thread_cb_skas(void (*proc)(void *), void *arg)
24815 +{
24816 +       jmp_buf here;
24817 +
24818 +       cb_proc = proc;
24819 +       cb_arg = arg;
24820 +       cb_back = &here;
24821 +
24822 +       block_signals();
24823 +       if(sigsetjmp(here, 1) == 0)
24824 +               siglongjmp(initial_jmpbuf, 2);
24825 +       unblock_signals();
24826 +
24827 +       cb_proc = NULL;
24828 +       cb_arg = NULL;
24829 +       cb_back = NULL;
24830 +}
24831 +
24832 +void halt_skas(void)
24833 +{
24834 +       block_signals();
24835 +       siglongjmp(initial_jmpbuf, 3);
24836 +}
24837 +
24838 +void reboot_skas(void)
24839 +{
24840 +       block_signals();
24841 +       siglongjmp(initial_jmpbuf, 4);
24842 +}
24843 +
24844 +int new_mm(int from)
24845 +{
24846 +       struct proc_mm_op copy;
24847 +       int n, fd = os_open_file("/proc/mm", 
24848 +                                of_cloexec(of_write(OPENFLAGS())), 0);
24849 +
24850 +       if(fd < 0)
24851 +               return(fd);
24852 +
24853 +       if(from != -1){
24854 +               copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
24855 +                                             .u        = 
24856 +                                             { .copy_segments  = from } } );
24857 +               n = os_write_file(fd, &copy, sizeof(copy));
24858 +               if(n != sizeof(copy)) 
24859 +                       printk("new_mm : /proc/mm copy_segments failed, "
24860 +                              "err = %d\n", -n);
24861 +       }
24862 +
24863 +       return(fd);
24864 +}
24865 +
24866 +void switch_mm_skas(int mm_fd)
24867 +{
24868 +       int err;
24869 +
24870 +#warning need cpu pid in switch_mm_skas
24871 +       err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
24872 +       if(err)
24873 +               panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
24874 +                     errno);
24875 +}
24876 +
24877 +void kill_off_processes_skas(void)
24878 +{
24879 +#warning need to loop over userspace_pids in kill_off_processes_skas
24880 +       os_kill_process(userspace_pid[0], 1);
24881 +}
24882 +
24883 +void init_registers(int pid)
24884 +{
24885 +       int err;
24886 +
24887 +       if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
24888 +               panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 
24889 +                     errno);
24890 +
24891 +       err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
24892 +       if(!err)
24893 +               return;
24894 +
24895 +       have_fpx_regs = 0;
24896 +       if(errno != EIO)
24897 +               panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", 
24898 +                     errno);
24899 +
24900 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
24901 +       if(err)
24902 +               panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", 
24903 +                     errno);
24904 +}
24905 +
24906 +/*
24907 + * Overrides for Emacs so that we follow Linus's tabbing style.
24908 + * Emacs will notice this stuff at the end of the file and automatically
24909 + * adjust the settings for this buffer only.  This must remain at the end
24910 + * of the file.
24911 + * ---------------------------------------------------------------------------
24912 + * Local variables:
24913 + * c-file-style: "linux"
24914 + * End:
24915 + */
24916 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process_kern.c um/arch/um/kernel/skas/process_kern.c
24917 --- orig/arch/um/kernel/skas/process_kern.c     1969-12-31 19:00:00.000000000 -0500
24918 +++ um/arch/um/kernel/skas/process_kern.c       2003-11-19 03:18:25.000000000 -0500
24919 @@ -0,0 +1,196 @@
24920 +/* 
24921 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
24922 + * Licensed under the GPL
24923 + */
24924 +
24925 +#include "linux/sched.h"
24926 +#include "linux/slab.h"
24927 +#include "kern_util.h"
24928 +#include "time_user.h"
24929 +#include "signal_user.h"
24930 +#include "skas.h"
24931 +#include "os.h"
24932 +#include "user_util.h"
24933 +#include "tlb.h"
24934 +#include "frame.h"
24935 +#include "kern.h"
24936 +#include "mode.h"
24937 +
24938 +int singlestepping_skas(void)
24939 +{
24940 +       int ret = current->ptrace & PT_DTRACE;
24941 +
24942 +       current->ptrace &= ~PT_DTRACE;
24943 +       return(ret);
24944 +}
24945 +
24946 +void *_switch_to_skas(void *prev, void *next)
24947 +{
24948 +       struct task_struct *from, *to;
24949 +
24950 +       from = prev;
24951 +       to = next;
24952 +
24953 +       /* XXX need to check runqueues[cpu].idle */
24954 +       if(current->pid == 0)
24955 +               switch_timers(0);
24956 +
24957 +       to->thread.prev_sched = from;
24958 +       set_current(to);
24959 +
24960 +       switch_threads(&from->thread.mode.skas.switch_buf, 
24961 +                      to->thread.mode.skas.switch_buf);
24962 +
24963 +       if(current->pid == 0)
24964 +               switch_timers(1);
24965 +
24966 +       return(current->thread.prev_sched);
24967 +}
24968 +
24969 +extern void schedule_tail(struct task_struct *prev);
24970 +
24971 +void new_thread_handler(int sig)
24972 +{
24973 +       int (*fn)(void *), n;
24974 +       void *arg;
24975 +
24976 +       fn = current->thread.request.u.thread.proc;
24977 +       arg = current->thread.request.u.thread.arg;
24978 +       change_sig(SIGUSR1, 1);
24979 +       thread_wait(&current->thread.mode.skas.switch_buf, 
24980 +                   current->thread.mode.skas.fork_buf);
24981 +
24982 +       if(current->thread.prev_sched != NULL)
24983 +               schedule_tail(current->thread.prev_sched);
24984 +       current->thread.prev_sched = NULL;
24985 +
24986 +       /* The return value is 1 if the kernel thread execs a process,
24987 +        * 0 if it just exits
24988 +        */
24989 +       n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
24990 +       if(n == 1)
24991 +               userspace(&current->thread.regs.regs);
24992 +       else do_exit(0);
24993 +}
24994 +
24995 +void new_thread_proc(void *stack, void (*handler)(int sig))
24996 +{
24997 +       init_new_thread_stack(stack, handler);
24998 +       os_usr1_process(os_getpid());
24999 +}
25000 +
25001 +void release_thread_skas(struct task_struct *task)
25002 +{
25003 +}
25004 +
25005 +void exit_thread_skas(void)
25006 +{
25007 +}
25008 +
25009 +void fork_handler(int sig)
25010 +{
25011 +        change_sig(SIGUSR1, 1);
25012 +       thread_wait(&current->thread.mode.skas.switch_buf, 
25013 +                   current->thread.mode.skas.fork_buf);
25014 +       
25015 +       force_flush_all();
25016 +       if(current->thread.prev_sched != NULL)
25017 +               schedule_tail(current->thread.prev_sched);
25018 +       current->thread.prev_sched = NULL;
25019 +       unblock_signals();
25020 +
25021 +       userspace(&current->thread.regs.regs);
25022 +}
25023 +
25024 +int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
25025 +                    unsigned long stack_top, struct task_struct * p, 
25026 +                    struct pt_regs *regs)
25027 +{
25028 +       void (*handler)(int);
25029 +
25030 +       if(current->thread.forking){
25031 +               memcpy(&p->thread.regs.regs.skas, 
25032 +                      &current->thread.regs.regs.skas, 
25033 +                      sizeof(p->thread.regs.regs.skas));
25034 +               REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
25035 +               if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
25036 +
25037 +               handler = fork_handler;
25038 +       }
25039 +       else {
25040 +               memcpy(p->thread.regs.regs.skas.regs, exec_regs, 
25041 +                      sizeof(p->thread.regs.regs.skas.regs));
25042 +               memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, 
25043 +                      sizeof(p->thread.regs.regs.skas.fp));
25044 +               memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, 
25045 +                      sizeof(p->thread.regs.regs.skas.xfp));
25046 +                p->thread.request.u.thread = current->thread.request.u.thread;
25047 +               handler = new_thread_handler;
25048 +       }
25049 +
25050 +       new_thread((void *) p->thread.kernel_stack, 
25051 +                  &p->thread.mode.skas.switch_buf, 
25052 +                  &p->thread.mode.skas.fork_buf, handler);
25053 +       return(0);
25054 +}
25055 +
25056 +void init_idle_skas(void)
25057 +{
25058 +       cpu_tasks[current->processor].pid = os_getpid();
25059 +}
25060 +
25061 +extern void start_kernel(void);
25062 +
25063 +static int start_kernel_proc(void *unused)
25064 +{
25065 +       int pid;
25066 +
25067 +       block_signals();
25068 +       pid = os_getpid();
25069 +
25070 +       cpu_tasks[0].pid = pid;
25071 +       cpu_tasks[0].task = current;
25072 +#ifdef CONFIG_SMP
25073 +       cpu_online_map = 1;
25074 +#endif
25075 +       start_kernel();
25076 +       return(0);
25077 +}
25078 +
25079 +int start_uml_skas(void)
25080 +{
25081 +       start_userspace(0);
25082 +       capture_signal_stack();
25083 +       idle_timer();
25084 +
25085 +       init_new_thread_signals(1);
25086 +
25087 +       init_task.thread.request.u.thread.proc = start_kernel_proc;
25088 +       init_task.thread.request.u.thread.arg = NULL;
25089 +       return(start_idle_thread((void *) init_task.thread.kernel_stack,
25090 +                                &init_task.thread.mode.skas.switch_buf,
25091 +                                &init_task.thread.mode.skas.fork_buf));
25092 +}
25093 +
25094 +int external_pid_skas(struct task_struct *task)
25095 +{
25096 +#warning Need to look up userspace_pid by cpu  
25097 +       return(userspace_pid[0]);
25098 +}
25099 +
25100 +int thread_pid_skas(struct thread_struct *thread)
25101 +{
25102 +#warning Need to look up userspace_pid by cpu  
25103 +       return(userspace_pid[0]);
25104 +}
25105 +
25106 +/*
25107 + * Overrides for Emacs so that we follow Linus's tabbing style.
25108 + * Emacs will notice this stuff at the end of the file and automatically
25109 + * adjust the settings for this buffer only.  This must remain at the end
25110 + * of the file.
25111 + * ---------------------------------------------------------------------------
25112 + * Local variables:
25113 + * c-file-style: "linux"
25114 + * End:
25115 + */
25116 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_kern.c um/arch/um/kernel/skas/syscall_kern.c
25117 --- orig/arch/um/kernel/skas/syscall_kern.c     1969-12-31 19:00:00.000000000 -0500
25118 +++ um/arch/um/kernel/skas/syscall_kern.c       2003-10-21 03:26:07.000000000 -0400
25119 @@ -0,0 +1,42 @@
25120 +/* 
25121 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25122 + * Licensed under the GPL
25123 + */
25124 +
25125 +#include "linux/sys.h"
25126 +#include "asm/errno.h"
25127 +#include "asm/unistd.h"
25128 +#include "asm/ptrace.h"
25129 +#include "asm/current.h"
25130 +#include "sysdep/syscalls.h"
25131 +#include "kern_util.h"
25132 +
25133 +extern syscall_handler_t *sys_call_table[];
25134 +
25135 +long execute_syscall_skas(void *r)
25136 +{
25137 +       struct pt_regs *regs = r;
25138 +       long res;
25139 +       int syscall;
25140 +
25141 +       current->thread.nsyscalls++;
25142 +       nsyscalls++;
25143 +       syscall = UPT_SYSCALL_NR(&regs->regs);
25144 +
25145 +       if((syscall >= NR_syscalls) || (syscall < 0))
25146 +               res = -ENOSYS;
25147 +       else res = EXECUTE_SYSCALL(syscall, regs);
25148 +
25149 +       return(res);
25150 +}
25151 +
25152 +/*
25153 + * Overrides for Emacs so that we follow Linus's tabbing style.
25154 + * Emacs will notice this stuff at the end of the file and automatically
25155 + * adjust the settings for this buffer only.  This must remain at the end
25156 + * of the file.
25157 + * ---------------------------------------------------------------------------
25158 + * Local variables:
25159 + * c-file-style: "linux"
25160 + * End:
25161 + */
25162 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_user.c um/arch/um/kernel/skas/syscall_user.c
25163 --- orig/arch/um/kernel/skas/syscall_user.c     1969-12-31 19:00:00.000000000 -0500
25164 +++ um/arch/um/kernel/skas/syscall_user.c       2003-10-21 03:26:07.000000000 -0400
25165 @@ -0,0 +1,46 @@
25166 +/* 
25167 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25168 + * Licensed under the GPL
25169 + */
25170 +
25171 +#include <stdlib.h>
25172 +#include <signal.h>
25173 +#include "kern_util.h"
25174 +#include "syscall_user.h"
25175 +#include "sysdep/ptrace.h"
25176 +#include "sysdep/sigcontext.h"
25177 +
25178 +/* XXX Bogus */
25179 +#define ERESTARTSYS    512
25180 +#define ERESTARTNOINTR 513
25181 +#define ERESTARTNOHAND 514
25182 +
25183 +void handle_syscall(union uml_pt_regs *regs)
25184 +{
25185 +       long result;
25186 +       int index;
25187 +
25188 +       index = record_syscall_start(UPT_SYSCALL_NR(regs));
25189 +
25190 +       syscall_trace();
25191 +       result = execute_syscall(regs);
25192 +
25193 +       REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
25194 +       if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
25195 +          (result == -ERESTARTNOINTR))
25196 +               do_signal(result);
25197 +
25198 +       syscall_trace();
25199 +       record_syscall_end(index, result);
25200 +}
25201 +
25202 +/*
25203 + * Overrides for Emacs so that we follow Linus's tabbing style.
25204 + * Emacs will notice this stuff at the end of the file and automatically
25205 + * adjust the settings for this buffer only.  This must remain at the end
25206 + * of the file.
25207 + * ---------------------------------------------------------------------------
25208 + * Local variables:
25209 + * c-file-style: "linux"
25210 + * End:
25211 + */
25212 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/Makefile um/arch/um/kernel/skas/sys-i386/Makefile
25213 --- orig/arch/um/kernel/skas/sys-i386/Makefile  1969-12-31 19:00:00.000000000 -0500
25214 +++ um/arch/um/kernel/skas/sys-i386/Makefile    2003-10-21 03:26:07.000000000 -0400
25215 @@ -0,0 +1,17 @@
25216 +# 
25217 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25218 +# Licensed under the GPL
25219 +#
25220 +
25221 +O_TARGET = sys-i386.o
25222 +
25223 +obj-y = sigcontext.o
25224 +
25225 +USER_OBJS = sigcontext.o
25226 +
25227 +include $(TOPDIR)/Rules.make
25228 +
25229 +$(USER_OBJS) : %.o: %.c
25230 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
25231 +
25232 +clean :
25233 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/sigcontext.c um/arch/um/kernel/skas/sys-i386/sigcontext.c
25234 --- orig/arch/um/kernel/skas/sys-i386/sigcontext.c      1969-12-31 19:00:00.000000000 -0500
25235 +++ um/arch/um/kernel/skas/sys-i386/sigcontext.c        2003-11-19 03:27:43.000000000 -0500
25236 @@ -0,0 +1,114 @@
25237 +/* 
25238 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25239 + * Licensed under the GPL
25240 + */
25241 +
25242 +#include <errno.h>
25243 +#include <asm/sigcontext.h>
25244 +#include <sys/ptrace.h>
25245 +#include <linux/ptrace.h>
25246 +#include "sysdep/ptrace.h"
25247 +#include "sysdep/ptrace_user.h"
25248 +#include "kern_util.h"
25249 +#include "user.h"
25250 +#include "sigcontext.h"
25251 +#include "mode.h"
25252 +
25253 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
25254 +{
25255 +       struct sigcontext sc, *from = from_ptr;
25256 +       unsigned long fpregs[FP_FRAME_SIZE];
25257 +       int err;
25258 +
25259 +       err = copy_from_user_proc(&sc, from, sizeof(sc));
25260 +       err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
25261 +       if(err)
25262 +               return(err);
25263 +
25264 +       regs->skas.regs[GS] = sc.gs;
25265 +       regs->skas.regs[FS] = sc.fs;
25266 +       regs->skas.regs[ES] = sc.es;
25267 +       regs->skas.regs[DS] = sc.ds;
25268 +       regs->skas.regs[EDI] = sc.edi;
25269 +       regs->skas.regs[ESI] = sc.esi;
25270 +       regs->skas.regs[EBP] = sc.ebp;
25271 +       regs->skas.regs[UESP] = sc.esp;
25272 +       regs->skas.regs[EBX] = sc.ebx;
25273 +       regs->skas.regs[EDX] = sc.edx;
25274 +       regs->skas.regs[ECX] = sc.ecx;
25275 +       regs->skas.regs[EAX] = sc.eax;
25276 +       regs->skas.regs[EIP] = sc.eip;
25277 +       regs->skas.regs[CS] = sc.cs;
25278 +       regs->skas.regs[EFL] = sc.eflags;
25279 +       regs->skas.regs[SS] = sc.ss;
25280 +       regs->skas.fault_addr = sc.cr2;
25281 +       regs->skas.fault_type = FAULT_WRITE(sc.err);
25282 +       regs->skas.trap_type = sc.trapno;
25283 +
25284 +       err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
25285 +       if(err < 0){
25286 +               printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
25287 +                      "errno = %d\n", errno);
25288 +               return(1);
25289 +       }
25290 +
25291 +       return(0);
25292 +}
25293 +
25294 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
25295 +                        union uml_pt_regs *regs, unsigned long fault_addr, 
25296 +                        int fault_type)
25297 +{
25298 +       struct sigcontext sc, *to = to_ptr;
25299 +       struct _fpstate *to_fp;
25300 +       unsigned long fpregs[FP_FRAME_SIZE];
25301 +       int err;
25302 +
25303 +       sc.gs = regs->skas.regs[GS];
25304 +       sc.fs = regs->skas.regs[FS];
25305 +       sc.es = regs->skas.regs[ES];
25306 +       sc.ds = regs->skas.regs[DS];
25307 +       sc.edi = regs->skas.regs[EDI];
25308 +       sc.esi = regs->skas.regs[ESI];
25309 +       sc.ebp = regs->skas.regs[EBP];
25310 +       sc.esp = regs->skas.regs[UESP];
25311 +       sc.ebx = regs->skas.regs[EBX];
25312 +       sc.edx = regs->skas.regs[EDX];
25313 +       sc.ecx = regs->skas.regs[ECX];
25314 +       sc.eax = regs->skas.regs[EAX];
25315 +       sc.eip = regs->skas.regs[EIP];
25316 +       sc.cs = regs->skas.regs[CS];
25317 +       sc.eflags = regs->skas.regs[EFL];
25318 +       sc.esp_at_signal = regs->skas.regs[UESP];
25319 +       sc.ss = regs->skas.regs[SS];
25320 +       sc.cr2 = fault_addr;
25321 +       sc.err = TO_SC_ERR(fault_type);
25322 +       sc.trapno = regs->skas.trap_type;
25323 +
25324 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
25325 +       if(err < 0){
25326 +               printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
25327 +                      "errno = %d\n", errno);
25328 +               return(1);
25329 +       }
25330 +       to_fp = (struct _fpstate *) 
25331 +               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
25332 +       sc.fpstate = to_fp;
25333 +
25334 +       if(err)
25335 +               return(err);
25336 +
25337 +       return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
25338 +              copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
25339 +}
25340 +
25341 +/*
25342 + * Overrides for Emacs so that we follow Linus's tabbing style.
25343 + * Emacs will notice this stuff at the end of the file and automatically
25344 + * adjust the settings for this buffer only.  This must remain at the end
25345 + * of the file.
25346 + * ---------------------------------------------------------------------------
25347 + * Local variables:
25348 + * c-file-style: "linux"
25349 + * End:
25350 + */
25351 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/time.c um/arch/um/kernel/skas/time.c
25352 --- orig/arch/um/kernel/skas/time.c     1969-12-31 19:00:00.000000000 -0500
25353 +++ um/arch/um/kernel/skas/time.c       2003-10-21 03:26:07.000000000 -0400
25354 @@ -0,0 +1,30 @@
25355 +/* 
25356 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25357 + * Licensed under the GPL
25358 + */
25359 +
25360 +#include <sys/signal.h>
25361 +#include <sys/time.h>
25362 +#include "time_user.h"
25363 +#include "process.h"
25364 +#include "user.h"
25365 +
25366 +void user_time_init_skas(void)
25367 +{
25368 +        if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
25369 +                panic("Couldn't set SIGALRM handler");
25370 +       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
25371 +               panic("Couldn't set SIGVTALRM handler");
25372 +       set_interval(ITIMER_VIRTUAL);
25373 +}
25374 +
25375 +/*
25376 + * Overrides for Emacs so that we follow Linus's tabbing style.
25377 + * Emacs will notice this stuff at the end of the file and automatically
25378 + * adjust the settings for this buffer only.  This must remain at the end
25379 + * of the file.
25380 + * ---------------------------------------------------------------------------
25381 + * Local variables:
25382 + * c-file-style: "linux"
25383 + * End:
25384 + */
25385 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/tlb.c um/arch/um/kernel/skas/tlb.c
25386 --- orig/arch/um/kernel/skas/tlb.c      1969-12-31 19:00:00.000000000 -0500
25387 +++ um/arch/um/kernel/skas/tlb.c        2003-10-21 03:26:07.000000000 -0400
25388 @@ -0,0 +1,153 @@
25389 +/* 
25390 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
25391 + * Licensed under the GPL
25392 + */
25393 +
25394 +#include "linux/stddef.h"
25395 +#include "linux/sched.h"
25396 +#include "asm/page.h"
25397 +#include "asm/pgtable.h"
25398 +#include "asm/mmu.h"
25399 +#include "user_util.h"
25400 +#include "mem_user.h"
25401 +#include "skas.h"
25402 +#include "os.h"
25403 +
25404 +static void fix_range(struct mm_struct *mm, unsigned long start_addr,
25405 +                     unsigned long end_addr, int force)
25406 +{
25407 +       pgd_t *npgd;
25408 +       pmd_t *npmd;
25409 +       pte_t *npte;
25410 +       unsigned long addr;
25411 +       int r, w, x, err, fd;
25412 +
25413 +       if(mm == NULL) return;
25414 +       fd = mm->context.skas.mm_fd;
25415 +       for(addr = start_addr; addr < end_addr;){
25416 +               npgd = pgd_offset(mm, addr);
25417 +               npmd = pmd_offset(npgd, addr);
25418 +               if(pmd_present(*npmd)){
25419 +                       npte = pte_offset(npmd, addr);
25420 +                       r = pte_read(*npte);
25421 +                       w = pte_write(*npte);
25422 +                       x = pte_exec(*npte);
25423 +                       if(!pte_dirty(*npte)) w = 0;
25424 +                       if(!pte_young(*npte)){
25425 +                               r = 0;
25426 +                               w = 0;
25427 +                       }
25428 +                       if(force || pte_newpage(*npte)){
25429 +                               err = unmap(fd, (void *) addr, PAGE_SIZE);
25430 +                               if(err < 0)
25431 +                                       panic("munmap failed, errno = %d\n",
25432 +                                             -err);
25433 +                               if(pte_present(*npte))
25434 +                                       map(fd, addr, 
25435 +                                           pte_val(*npte) & PAGE_MASK,
25436 +                                           PAGE_SIZE, r, w, x);
25437 +                       }
25438 +                       else if(pte_newprot(*npte)){
25439 +                               protect(fd, addr, PAGE_SIZE, r, w, x, 1);
25440 +                       }
25441 +                       *npte = pte_mkuptodate(*npte);
25442 +                       addr += PAGE_SIZE;
25443 +               }
25444 +               else {
25445 +                       if(force || pmd_newpage(*npmd)){
25446 +                               err = unmap(fd, (void *) addr, PMD_SIZE);
25447 +                               if(err < 0)
25448 +                                       panic("munmap failed, errno = %d\n",
25449 +                                             -err);
25450 +                               pmd_mkuptodate(*npmd);
25451 +                       }
25452 +                       addr += PMD_SIZE;
25453 +               }
25454 +       }
25455 +}
25456 +
25457 +static void flush_kernel_vm_range(unsigned long start, unsigned long end)
25458 +{
25459 +       struct mm_struct *mm;
25460 +       pgd_t *pgd;
25461 +       pmd_t *pmd;
25462 +       pte_t *pte;
25463 +       unsigned long addr;
25464 +       int updated = 0, err;
25465 +
25466 +       mm = &init_mm;
25467 +       for(addr = start_vm; addr < end_vm;){
25468 +               pgd = pgd_offset(mm, addr);
25469 +               pmd = pmd_offset(pgd, addr);
25470 +               if(pmd_present(*pmd)){
25471 +                       pte = pte_offset(pmd, addr);
25472 +                       if(!pte_present(*pte) || pte_newpage(*pte)){
25473 +                               updated = 1;
25474 +                               err = os_unmap_memory((void *) addr, 
25475 +                                                     PAGE_SIZE);
25476 +                               if(err < 0)
25477 +                                       panic("munmap failed, errno = %d\n",
25478 +                                             -err);
25479 +                               if(pte_present(*pte))
25480 +                                       map_memory(addr, 
25481 +                                                  pte_val(*pte) & PAGE_MASK,
25482 +                                                  PAGE_SIZE, 1, 1, 1);
25483 +                       }
25484 +                       else if(pte_newprot(*pte)){
25485 +                               updated = 1;
25486 +                               protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
25487 +                       }
25488 +                       addr += PAGE_SIZE;
25489 +               }
25490 +               else {
25491 +                       if(pmd_newpage(*pmd)){
25492 +                               updated = 1;
25493 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
25494 +                               if(err < 0)
25495 +                                       panic("munmap failed, errno = %d\n",
25496 +                                             -err);
25497 +                       }
25498 +                       addr += PMD_SIZE;
25499 +               }
25500 +       }
25501 +}
25502 +
25503 +void flush_tlb_kernel_vm_skas(void)
25504 +{
25505 +       flush_kernel_vm_range(start_vm, end_vm);
25506 +}
25507 +
25508 +void __flush_tlb_one_skas(unsigned long addr)
25509 +{
25510 +       flush_kernel_vm_range(addr, addr + PAGE_SIZE);
25511 +}
25512 +
25513 +void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, 
25514 +                    unsigned long end)
25515 +{
25516 +       if(mm == NULL)
25517 +               flush_kernel_vm_range(start, end);
25518 +       else fix_range(mm, start, end, 0);
25519 +}
25520 +
25521 +void flush_tlb_mm_skas(struct mm_struct *mm)
25522 +{
25523 +       flush_tlb_kernel_vm_skas();
25524 +       fix_range(mm, 0, host_task_size, 0);
25525 +}
25526 +
25527 +void force_flush_all_skas(void)
25528 +{
25529 +       fix_range(current->mm, 0, host_task_size, 1);
25530 +}
25531 +
25532 +/*
25533 + * Overrides for Emacs so that we follow Linus's tabbing style.
25534 + * Emacs will notice this stuff at the end of the file and automatically
25535 + * adjust the settings for this buffer only.  This must remain at the end
25536 + * of the file.
25537 + * ---------------------------------------------------------------------------
25538 + * Local variables:
25539 + * c-file-style: "linux"
25540 + * End:
25541 + */
25542 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/trap_user.c um/arch/um/kernel/skas/trap_user.c
25543 --- orig/arch/um/kernel/skas/trap_user.c        1969-12-31 19:00:00.000000000 -0500
25544 +++ um/arch/um/kernel/skas/trap_user.c  2003-12-14 11:17:37.000000000 -0500
25545 @@ -0,0 +1,63 @@
25546 +/* 
25547 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25548 + * Licensed under the GPL
25549 + */
25550 +
25551 +#include <signal.h>
25552 +#include <errno.h>
25553 +#include <asm/sigcontext.h>
25554 +#include "sysdep/ptrace.h"
25555 +#include "signal_user.h"
25556 +#include "user_util.h"
25557 +#include "kern_util.h"
25558 +#include "task.h"
25559 +#include "sigcontext.h"
25560 +
25561 +void sig_handler_common_skas(int sig, void *sc_ptr)
25562 +{
25563 +       struct sigcontext *sc = sc_ptr;
25564 +       struct skas_regs *r;
25565 +       struct signal_info *info;
25566 +       int save_errno = errno;
25567 +
25568 +       r = &TASK_REGS(get_current())->skas;
25569 +       r->is_user = 0;
25570 +       r->fault_addr = SC_FAULT_ADDR(sc);
25571 +       r->fault_type = SC_FAULT_TYPE(sc);
25572 +       r->trap_type = SC_TRAP_TYPE(sc);
25573 +
25574 +       change_sig(SIGUSR1, 1);
25575 +       info = &sig_info[sig];
25576 +       if(!info->is_irq) unblock_signals();
25577 +
25578 +       (*info->handler)(sig, (union uml_pt_regs *) r);
25579 +
25580 +       errno = save_errno;
25581 +}
25582 +
25583 +extern int missed_ticks[];
25584 +
25585 +void user_signal(int sig, union uml_pt_regs *regs)
25586 +{
25587 +       struct signal_info *info;
25588 +
25589 +       regs->skas.is_user = 1;
25590 +       regs->skas.fault_addr = 0;
25591 +       regs->skas.fault_type = 0;
25592 +       regs->skas.trap_type = 0;
25593 +       info = &sig_info[sig];
25594 +       (*info->handler)(sig, regs);
25595 +
25596 +       unblock_signals();
25597 +}
25598 +
25599 +/*
25600 + * Overrides for Emacs so that we follow Linus's tabbing style.
25601 + * Emacs will notice this stuff at the end of the file and automatically
25602 + * adjust the settings for this buffer only.  This must remain at the end
25603 + * of the file.
25604 + * ---------------------------------------------------------------------------
25605 + * Local variables:
25606 + * c-file-style: "linux"
25607 + * End:
25608 + */
25609 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/uaccess.c um/arch/um/kernel/skas/uaccess.c
25610 --- orig/arch/um/kernel/skas/uaccess.c  1969-12-31 19:00:00.000000000 -0500
25611 +++ um/arch/um/kernel/skas/uaccess.c    2003-11-11 11:11:26.000000000 -0500
25612 @@ -0,0 +1,217 @@
25613 +/* 
25614 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
25615 + * Licensed under the GPL
25616 + */
25617 +
25618 +#include "linux/stddef.h"
25619 +#include "linux/kernel.h"
25620 +#include "linux/string.h"
25621 +#include "linux/fs.h"
25622 +#include "linux/highmem.h"
25623 +#include "asm/page.h"
25624 +#include "asm/pgtable.h"
25625 +#include "asm/uaccess.h"
25626 +#include "kern_util.h"
25627 +
25628 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
25629 +                            pte_t *pte_out);
25630 +
25631 +static unsigned long maybe_map(unsigned long virt, int is_write)
25632 +{
25633 +       pte_t pte;
25634 +
25635 +       void *phys = um_virt_to_phys(current, virt, &pte);
25636 +       int dummy_code;
25637 +
25638 +       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
25639 +               if(!handle_page_fault(virt, 0, is_write, 0, &dummy_code))
25640 +                       return(0);
25641 +               phys = um_virt_to_phys(current, virt, NULL);
25642 +       }
25643 +       return((unsigned long) phys);
25644 +}
25645 +
25646 +static int do_op(unsigned long addr, int len, int is_write, 
25647 +                int (*op)(unsigned long addr, int len, void *arg), void *arg)
25648 +{
25649 +       struct page *page;
25650 +       int n;
25651 +
25652 +       addr = maybe_map(addr, is_write);
25653 +       if(addr == -1)
25654 +               return(-1);
25655 +
25656 +       page = phys_to_page(addr);
25657 +       addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
25658 +       n = (*op)(addr, len, arg);
25659 +       kunmap(page);
25660 +
25661 +       return(n);
25662 +}
25663 +
25664 +static int buffer_op(unsigned long addr, int len, int is_write,
25665 +                    int (*op)(unsigned long addr, int len, void *arg),
25666 +                    void *arg)
25667 +{
25668 +       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
25669 +       int remain = len, n;
25670 +
25671 +       n = do_op(addr, size, is_write, op, arg);
25672 +       if(n != 0)
25673 +               return(n < 0 ? remain : 0);
25674 +
25675 +       addr += size;
25676 +       remain -= size;
25677 +       if(remain == 0) 
25678 +               return(0);
25679 +
25680 +       while(addr < ((addr + remain) & PAGE_MASK)){
25681 +               n = do_op(addr, PAGE_SIZE, is_write, op, arg);
25682 +               if(n != 0)
25683 +                       return(n < 0 ? remain : 0);
25684 +
25685 +               addr += PAGE_SIZE;
25686 +               remain -= PAGE_SIZE;
25687 +       }
25688 +       if(remain == 0)
25689 +               return(0);
25690 +
25691 +       n = do_op(addr, remain, is_write, op, arg);
25692 +       if(n != 0)
25693 +               return(n < 0 ? remain : 0);
25694 +       return(0);
25695 +}
25696 +
25697 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
25698 +{
25699 +       unsigned long *to_ptr = arg, to = *to_ptr;
25700 +
25701 +       memcpy((void *) to, (void *) from, len);
25702 +       *to_ptr += len;
25703 +       return(0);
25704 +}
25705 +
25706 +int copy_from_user_skas(void *to, const void *from, int n)
25707 +{
25708 +       if(segment_eq(get_fs(), KERNEL_DS)){
25709 +               memcpy(to, from, n);
25710 +               return(0);
25711 +       }
25712 +
25713 +       return(access_ok_skas(VERIFY_READ, from, n) ?
25714 +              buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
25715 +              n);
25716 +}
25717 +
25718 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
25719 +{
25720 +       unsigned long *from_ptr = arg, from = *from_ptr;
25721 +
25722 +       memcpy((void *) to, (void *) from, len);
25723 +       *from_ptr += len;
25724 +       return(0);
25725 +}
25726 +
25727 +int copy_to_user_skas(void *to, const void *from, int n)
25728 +{
25729 +       if(segment_eq(get_fs(), KERNEL_DS)){
25730 +               memcpy(to, from, n);
25731 +               return(0);
25732 +       }
25733 +
25734 +       return(access_ok_skas(VERIFY_WRITE, to, n) ?
25735 +              buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
25736 +              n);
25737 +}
25738 +
25739 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
25740 +{
25741 +        char **to_ptr = arg, *to = *to_ptr;
25742 +       int n;
25743 +
25744 +       strncpy(to, (void *) from, len);
25745 +       n = strnlen(to, len);
25746 +       *to_ptr += n;
25747 +
25748 +       if(n < len) 
25749 +               return(1);
25750 +       return(0);
25751 +}
25752 +
25753 +int strncpy_from_user_skas(char *dst, const char *src, int count)
25754 +{
25755 +       int n;
25756 +       char *ptr = dst;
25757 +
25758 +       if(segment_eq(get_fs(), KERNEL_DS)){
25759 +               strncpy(dst, src, count);
25760 +               return(strnlen(dst, count));
25761 +       }
25762 +
25763 +       if(!access_ok_skas(VERIFY_READ, src, 1))
25764 +               return(-EFAULT);
25765 +
25766 +       n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 
25767 +                     &ptr);
25768 +       if(n != 0)
25769 +               return(-EFAULT);
25770 +       return(strnlen(dst, count));
25771 +}
25772 +
25773 +static int clear_chunk(unsigned long addr, int len, void *unused)
25774 +{
25775 +       memset((void *) addr, 0, len);
25776 +       return(0);
25777 +}
25778 +
25779 +int __clear_user_skas(void *mem, int len)
25780 +{
25781 +       return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
25782 +}
25783 +
25784 +int clear_user_skas(void *mem, int len)
25785 +{
25786 +       if(segment_eq(get_fs(), KERNEL_DS)){
25787 +               memset(mem, 0, len);
25788 +               return(0);
25789 +       }
25790 +
25791 +       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
25792 +              buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
25793 +}
25794 +
25795 +static int strnlen_chunk(unsigned long str, int len, void *arg)
25796 +{
25797 +       int *len_ptr = arg, n;
25798 +
25799 +       n = strnlen((void *) str, len);
25800 +       *len_ptr += n;
25801 +
25802 +       if(n < len)
25803 +               return(1);
25804 +       return(0);
25805 +}
25806 +
25807 +int strnlen_user_skas(const void *str, int len)
25808 +{
25809 +       int count = 0, n;
25810 +
25811 +       if(segment_eq(get_fs(), KERNEL_DS))
25812 +               return(strnlen(str, len) + 1);
25813 +
25814 +       n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
25815 +       if(n == 0)
25816 +               return(count + 1);
25817 +       return(-EFAULT);
25818 +}
25819 +
25820 +/*
25821 + * Overrides for Emacs so that we follow Linus's tabbing style.
25822 + * Emacs will notice this stuff at the end of the file and automatically
25823 + * adjust the settings for this buffer only.  This must remain at the end
25824 + * of the file.
25825 + * ---------------------------------------------------------------------------
25826 + * Local variables:
25827 + * c-file-style: "linux"
25828 + * End:
25829 + */
25830 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/Makefile um/arch/um/kernel/skas/util/Makefile
25831 --- orig/arch/um/kernel/skas/util/Makefile      1969-12-31 19:00:00.000000000 -0500
25832 +++ um/arch/um/kernel/skas/util/Makefile        2003-11-08 02:52:22.000000000 -0500
25833 @@ -0,0 +1,10 @@
25834 +all: mk_ptregs
25835 +
25836 +mk_ptregs : mk_ptregs.o
25837 +       $(HOSTCC) -o mk_ptregs mk_ptregs.o
25838 +
25839 +mk_ptregs.o : mk_ptregs.c
25840 +       $(HOSTCC) -c $< 
25841 +
25842 +clean : 
25843 +       $(RM) -f mk_ptregs *.o *~
25844 diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/mk_ptregs.c um/arch/um/kernel/skas/util/mk_ptregs.c
25845 --- orig/arch/um/kernel/skas/util/mk_ptregs.c   1969-12-31 19:00:00.000000000 -0500
25846 +++ um/arch/um/kernel/skas/util/mk_ptregs.c     2003-10-21 03:26:07.000000000 -0400
25847 @@ -0,0 +1,50 @@
25848 +#include <asm/ptrace.h>
25849 +#include <asm/user.h>
25850 +
25851 +#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val))
25852 +
25853 +int main(int argc, char **argv)
25854 +{
25855 +       printf("/* Automatically generated by "
25856 +              "arch/um/kernel/skas/util/mk_ptregs */\n");
25857 +       printf("\n");
25858 +       printf("#ifndef __SKAS_PT_REGS_\n");
25859 +       printf("#define __SKAS_PT_REGS_\n");
25860 +       printf("\n");
25861 +       printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
25862 +       printf("#define HOST_FP_SIZE %d\n", 
25863 +              sizeof(struct user_i387_struct) / sizeof(unsigned long));
25864 +       printf("#define HOST_XFP_SIZE %d\n", 
25865 +              sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
25866 +
25867 +       PRINT_REG("IP", EIP);
25868 +       PRINT_REG("SP", UESP);
25869 +       PRINT_REG("EFLAGS", EFL);
25870 +       PRINT_REG("EAX", EAX);
25871 +       PRINT_REG("EBX", EBX);
25872 +       PRINT_REG("ECX", ECX);
25873 +       PRINT_REG("EDX", EDX);
25874 +       PRINT_REG("ESI", ESI);
25875 +       PRINT_REG("EDI", EDI);
25876 +       PRINT_REG("EBP", EBP);
25877 +       PRINT_REG("CS", CS);
25878 +       PRINT_REG("SS", SS);
25879 +       PRINT_REG("DS", DS);
25880 +       PRINT_REG("FS", FS);
25881 +       PRINT_REG("ES", ES);
25882 +       PRINT_REG("GS", GS);
25883 +       printf("\n");
25884 +       printf("#endif\n");
25885 +       return(0);
25886 +}
25887 +
25888 +/*
25889 + * Overrides for Emacs so that we follow Linus's tabbing style.
25890 + * Emacs will notice this stuff at the end of the file and automatically
25891 + * adjust the settings for this buffer only.  This must remain at the end
25892 + * of the file.
25893 + * ---------------------------------------------------------------------------
25894 + * Local variables:
25895 + * c-file-style: "linux"
25896 + * End:
25897 + */
25898 diff -Naur -X ../exclude-files orig/arch/um/kernel/smp.c um/arch/um/kernel/smp.c
25899 --- orig/arch/um/kernel/smp.c   1969-12-31 19:00:00.000000000 -0500
25900 +++ um/arch/um/kernel/smp.c     2003-11-15 02:59:25.000000000 -0500
25901 @@ -0,0 +1,328 @@
25902 +/* 
25903 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
25904 + * Licensed under the GPL
25905 + */
25906 +
25907 +#include "linux/config.h"
25908 +
25909 +#ifdef CONFIG_SMP
25910 +
25911 +#include "linux/sched.h"
25912 +#include "linux/threads.h"
25913 +#include "linux/interrupt.h"
25914 +#include "asm/smp.h"
25915 +#include "asm/processor.h"
25916 +#include "asm/spinlock.h"
25917 +#include "asm/softirq.h"
25918 +#include "asm/hardirq.h"
25919 +#include "asm/tlb.h"
25920 +#include "user_util.h"
25921 +#include "kern_util.h"
25922 +#include "irq_user.h"
25923 +#include "kern.h"
25924 +#include "os.h"
25925 +
25926 +/* Total count of live CPUs, set by smp_boot_cpus */
25927 +int smp_num_cpus = 1;
25928 +
25929 +/* The 'big kernel lock' */
25930 +spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
25931 +
25932 +/* Per CPU bogomips and other parameters */
25933 +
25934 +/* The only piece used here is the ipi pipe, which is set before SMP is
25935 + * started and never changed.
25936 + */
25937 +struct cpuinfo_um cpu_data[NR_CPUS];
25938 +
25939 +/* CPU online map, set by smp_boot_cpus */
25940 +unsigned long cpu_online_map;
25941 +
25942 +atomic_t global_bh_count;
25943 +
25944 +/* Set when the idlers are all forked */
25945 +int smp_threads_ready = 0;
25946 +
25947 +/* Not used by UML */
25948 +unsigned char global_irq_holder = 0;
25949 +unsigned volatile long global_irq_lock;
25950 +
25951 +/* A statistic, can be a little off */
25952 +static int num_reschedules_sent = 0;
25953 +
25954 +mmu_gather_t mmu_gathers[NR_CPUS];
25955 +
25956 +void smp_send_reschedule(int cpu)
25957 +{
25958 +       os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
25959 +       num_reschedules_sent++;
25960 +}
25961 +
25962 +static void show(char * str)
25963 +{
25964 +       int cpu = smp_processor_id();
25965 +
25966 +       printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
25967 +}
25968 +       
25969 +#define MAXCOUNT 100000000
25970 +
25971 +static inline void wait_on_bh(void)
25972 +{
25973 +       int count = MAXCOUNT;
25974 +       do {
25975 +               if (!--count) {
25976 +                       show("wait_on_bh");
25977 +                       count = ~0;
25978 +               }
25979 +               /* nothing .. wait for the other bh's to go away */
25980 +       } while (atomic_read(&global_bh_count) != 0);
25981 +}
25982 +
25983 +/*
25984 + * This is called when we want to synchronize with
25985 + * bottom half handlers. We need to wait until
25986 + * no other CPU is executing any bottom half handler.
25987 + *
25988 + * Don't wait if we're already running in an interrupt
25989 + * context or are inside a bh handler. 
25990 + */
25991 +void synchronize_bh(void)
25992 +{
25993 +       if (atomic_read(&global_bh_count) && !in_interrupt())
25994 +               wait_on_bh();
25995 +}
25996 +
25997 +void smp_send_stop(void)
25998 +{
25999 +       int i;
26000
26001 +       printk(KERN_INFO "Stopping all CPUs...");
26002 +       for(i = 0; i < ncpus; i++){
26003 +               if(i == current->processor)
26004 +                       continue;
26005 +               os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
26006 +       }
26007 +       printk("done\n");
26008 +}
26009 +
26010 +
26011 +static atomic_t smp_commenced = ATOMIC_INIT(0);
26012 +static volatile unsigned long smp_callin_map = 0;
26013 +
26014 +void smp_commence(void)
26015 +{
26016 +       printk("All CPUs are go!\n");
26017 +
26018 +       wmb();
26019 +       atomic_set(&smp_commenced, 1);
26020 +}
26021 +
26022 +static int idle_proc(void *unused)
26023 +{
26024 +       int cpu, err;
26025 +
26026 +       set_current(current);
26027 +       del_from_runqueue(current);
26028 +       unhash_process(current);
26029 +
26030 +       cpu = current->processor;
26031 +       err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
26032 +       if(err < 0)
26033 +               panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
26034 +
26035 +       activate_ipi(cpu_data[cpu].ipi_pipe[0], 
26036 +                    current->thread.mode.tt.extern_pid);
26037
26038 +       wmb();
26039 +       if (test_and_set_bit(current->processor, &smp_callin_map)) {
26040 +               printk("huh, CPU#%d already present??\n", current->processor);
26041 +               BUG();
26042 +       }
26043 +
26044 +       while (!atomic_read(&smp_commenced))
26045 +               cpu_relax();
26046 +
26047 +       init_idle();
26048 +       cpu_idle();
26049 +       return(0);
26050 +}
26051 +
26052 +static int idle_thread(int (*fn)(void *), int cpu)
26053 +{
26054 +       struct task_struct *new_task;
26055 +       int pid;
26056 +       unsigned char c;
26057 +
26058 +        current->thread.request.u.thread.proc = fn;
26059 +        current->thread.request.u.thread.arg = NULL;
26060 +       pid = do_fork(CLONE_VM | CLONE_PID, 0, NULL, 0);
26061 +       if(pid < 0) 
26062 +               panic("do_fork failed in idle_thread");
26063 +       new_task = get_task(pid, 1);
26064 +
26065 +       cpu_tasks[cpu] = ((struct cpu_task) 
26066 +                         { .pid =      new_task->thread.mode.tt.extern_pid,
26067 +                           .task =     new_task } );
26068 +       init_tasks[cpu] = new_task;
26069 +       new_task->processor = cpu;
26070 +       new_task->cpus_allowed = 1 << cpu;
26071 +       new_task->cpus_runnable = new_task->cpus_allowed;
26072 +       CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, 
26073 +                         sizeof(c)),
26074 +                   ({ panic("skas mode doesn't support SMP"); }));
26075 +       return(new_task->thread.mode.tt.extern_pid);
26076 +}
26077 +
26078 +void smp_boot_cpus(void)
26079 +{
26080 +       int err;
26081 +
26082 +       set_bit(0, &cpu_online_map);
26083 +       set_bit(0, &smp_callin_map);
26084 +
26085 +       err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
26086 +       if(err < 0) 
26087 +               panic("CPU#0 failed to create IPI pipe, err = %d", -err);
26088 +
26089 +       activate_ipi(cpu_data[0].ipi_pipe[0], 
26090 +                    current->thread.mode.tt.extern_pid);
26091 +
26092 +       if(ncpus < 1){
26093 +               printk(KERN_INFO "ncpus set to 1\n");
26094 +               ncpus = 1;
26095 +       }
26096 +       else if(ncpus > NR_CPUS){
26097 +               printk(KERN_INFO 
26098 +                      "ncpus can't be greater than NR_CPUS, set to %d\n",
26099 +                      NR_CPUS);
26100 +               ncpus = NR_CPUS;
26101 +       }
26102 +
26103 +       if(ncpus > 1){
26104 +               int i, pid;
26105 +
26106 +               printk(KERN_INFO "Starting up other processors:\n");
26107 +               for(i=1;i<ncpus;i++){
26108 +                       int waittime;
26109 +
26110 +                       /* Do this early, for hard_smp_processor_id()  */
26111 +                       cpu_tasks[i].pid = -1;
26112 +                       set_bit(i, &cpu_online_map);
26113 +                       smp_num_cpus++;
26114 +
26115 +                       pid = idle_thread(idle_proc, i);
26116 +                       printk(KERN_INFO "\t#%d - idle thread pid = %d.. ",
26117 +                              i, pid);
26118 +
26119 +                       waittime = 200000000;
26120 +                       while (waittime-- && !test_bit(i, &smp_callin_map))
26121 +                               cpu_relax();
26122 +
26123 +                       if (test_bit(i, &smp_callin_map))
26124 +                               printk("online\n");
26125 +                       else {
26126 +                               printk("failed\n");
26127 +                               clear_bit(i, &cpu_online_map);
26128 +                       }
26129 +               }
26130 +       }
26131 +}
26132 +
26133 +int setup_profiling_timer(unsigned int multiplier)
26134 +{
26135 +       printk(KERN_INFO "setup_profiling_timer\n");
26136 +       return(0);
26137 +}
26138 +
26139 +void smp_call_function_slave(int cpu);
26140 +
26141 +void IPI_handler(int cpu)
26142 +{
26143 +       unsigned char c;
26144 +       int fd;
26145 +
26146 +       fd = cpu_data[cpu].ipi_pipe[0];
26147 +       while (os_read_file(fd, &c, 1) == 1) {
26148 +               switch (c) {
26149 +               case 'C':
26150 +                       smp_call_function_slave(cpu);
26151 +                       break;
26152 +
26153 +               case 'R':
26154 +                       current->need_resched = 1;
26155 +                       break;
26156 +
26157 +               case 'S':
26158 +                       printk("CPU#%d stopping\n", cpu);
26159 +                       while(1)
26160 +                               pause();
26161 +                       break;
26162 +
26163 +               default:
26164 +                       printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
26165 +                       break;
26166 +               }
26167 +       }
26168 +}
26169 +
26170 +int hard_smp_processor_id(void)
26171 +{
26172 +       return(pid_to_processor_id(os_getpid()));
26173 +}
26174 +
26175 +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
26176 +static atomic_t scf_started;
26177 +static atomic_t scf_finished;
26178 +static void (*func)(void *info);
26179 +static void *info;
26180 +
26181 +void smp_call_function_slave(int cpu)
26182 +{
26183 +       atomic_inc(&scf_started);
26184 +       (*func)(info);
26185 +       atomic_inc(&scf_finished);
26186 +}
26187 +
26188 +int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 
26189 +                     int wait)
26190 +{
26191 +       int cpus = smp_num_cpus - 1;
26192 +       int i;
26193 +
26194 +       if (!cpus)
26195 +               return 0;
26196 +
26197 +       spin_lock_bh(&call_lock);
26198 +       atomic_set(&scf_started, 0);
26199 +       atomic_set(&scf_finished, 0);
26200 +       func = _func;
26201 +       info = _info;
26202 +
26203 +       for (i=0;i<NR_CPUS;i++)
26204 +               if (i != current->processor && test_bit(i, &cpu_online_map))
26205 +                       os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
26206 +
26207 +       while (atomic_read(&scf_started) != cpus)
26208 +               barrier();
26209 +
26210 +       if (wait)
26211 +               while (atomic_read(&scf_finished) != cpus)
26212 +                       barrier();
26213 +
26214 +       spin_unlock_bh(&call_lock);
26215 +       return 0;
26216 +}
26217 +
26218 +#endif
26219 +
26220 +/*
26221 + * Overrides for Emacs so that we follow Linus's tabbing style.
26222 + * Emacs will notice this stuff at the end of the file and automatically
26223 + * adjust the settings for this buffer only.  This must remain at the end
26224 + * of the file.
26225 + * ---------------------------------------------------------------------------
26226 + * Local variables:
26227 + * c-file-style: "linux"
26228 + * End:
26229 + */
26230 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_kern.c um/arch/um/kernel/syscall_kern.c
26231 --- orig/arch/um/kernel/syscall_kern.c  1969-12-31 19:00:00.000000000 -0500
26232 +++ um/arch/um/kernel/syscall_kern.c    2003-11-07 01:41:13.000000000 -0500
26233 @@ -0,0 +1,343 @@
26234 +/* 
26235 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
26236 + * Licensed under the GPL
26237 + */
26238 +
26239 +#include "linux/sched.h"
26240 +#include "linux/file.h"
26241 +#include "linux/smp_lock.h"
26242 +#include "linux/mm.h"
26243 +#include "linux/utsname.h"
26244 +#include "linux/msg.h"
26245 +#include "linux/shm.h"
26246 +#include "linux/sys.h"
26247 +#include "linux/unistd.h"
26248 +#include "linux/slab.h"
26249 +#include "linux/utime.h"
26250 +#include "asm/mman.h"
26251 +#include "asm/uaccess.h"
26252 +#include "asm/ipc.h"
26253 +#include "kern_util.h"
26254 +#include "user_util.h"
26255 +#include "sysdep/syscalls.h"
26256 +#include "mode_kern.h"
26257 +#include "choose-mode.h"
26258 +
26259 +/*  Unlocked, I don't care if this is a bit off */
26260 +int nsyscalls = 0;
26261 +
26262 +long um_mount(char * dev_name, char * dir_name, char * type,
26263 +             unsigned long new_flags, void * data)
26264 +{
26265 +       if(type == NULL) type = "";
26266 +       return(sys_mount(dev_name, dir_name, type, new_flags, data));
26267 +}
26268 +
26269 +long sys_fork(void)
26270 +{
26271 +       long ret;
26272 +
26273 +       current->thread.forking = 1;
26274 +        ret = do_fork(SIGCHLD, 0, NULL, 0);
26275 +       current->thread.forking = 0;
26276 +       return(ret);
26277 +}
26278 +
26279 +long sys_clone(unsigned long clone_flags, unsigned long newsp)
26280 +{
26281 +       long ret;
26282 +
26283 +       current->thread.forking = 1;
26284 +       ret = do_fork(clone_flags, newsp, NULL, 0);
26285 +       current->thread.forking = 0;
26286 +       return(ret);
26287 +}
26288 +
26289 +long sys_vfork(void)
26290 +{
26291 +       long ret;
26292 +
26293 +       current->thread.forking = 1;
26294 +       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0);
26295 +       current->thread.forking = 0;
26296 +       return(ret);
26297 +}
26298 +
26299 +/* common code for old and new mmaps */
26300 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
26301 +             unsigned long prot, unsigned long flags, unsigned long fd,
26302 +             unsigned long pgoff)
26303 +{
26304 +       int error = -EBADF;
26305 +       struct file * file = NULL;
26306 +
26307 +       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
26308 +       if (!(flags & MAP_ANONYMOUS)) {
26309 +               file = fget(fd);
26310 +               if (!file)
26311 +                       goto out;
26312 +       }
26313 +
26314 +       down_write(&mm->mmap_sem);
26315 +       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
26316 +       up_write(&mm->mmap_sem);
26317 +
26318 +       if (file)
26319 +               fput(file);
26320 + out:
26321 +       return error;
26322 +}
26323 +
26324 +long sys_mmap2(unsigned long addr, unsigned long len,
26325 +              unsigned long prot, unsigned long flags,
26326 +              unsigned long fd, unsigned long pgoff)
26327 +{
26328 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
26329 +}
26330 +
26331 +/*
26332 + * Perform the select(nd, in, out, ex, tv) and mmap() system
26333 + * calls. Linux/i386 didn't use to be able to handle more than
26334 + * 4 system call parameters, so these system calls used a memory
26335 + * block for parameter passing..
26336 + */
26337 +
26338 +struct mmap_arg_struct {
26339 +       unsigned long addr;
26340 +       unsigned long len;
26341 +       unsigned long prot;
26342 +       unsigned long flags;
26343 +       unsigned long fd;
26344 +       unsigned long offset;
26345 +};
26346 +
26347 +int old_mmap(unsigned long addr, unsigned long len,
26348 +            unsigned long prot, unsigned long flags,
26349 +            unsigned long fd, unsigned long offset)
26350 +{
26351 +       int err = -EINVAL;
26352 +       if (offset & ~PAGE_MASK)
26353 +               goto out;
26354 +
26355 +       err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
26356 +                      offset >> PAGE_SHIFT);
26357 + out:
26358 +       return err;
26359 +}
26360 +/*
26361 + * sys_pipe() is the normal C calling standard for creating
26362 + * a pipe. It's not the way unix traditionally does this, though.
26363 + */
26364 +int sys_pipe(unsigned long * fildes)
26365 +{
26366 +        int fd[2];
26367 +        int error;
26368 +
26369 +        error = do_pipe(fd);
26370 +        if (!error) {
26371 +                if (copy_to_user(fildes, fd, sizeof(fd)))
26372 +                        error = -EFAULT;
26373 +        }
26374 +        return error;
26375 +}
26376 +
26377 +int sys_pause(void)
26378 +{
26379 +       current->state = TASK_INTERRUPTIBLE;
26380 +       schedule();
26381 +       return -ERESTARTNOHAND;
26382 +}
26383 +
26384 +int sys_sigaction(int sig, const struct old_sigaction *act,
26385 +                        struct old_sigaction *oact)
26386 +{
26387 +       struct k_sigaction new_ka, old_ka;
26388 +       int ret;
26389 +
26390 +       if (act) {
26391 +               old_sigset_t mask;
26392 +               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
26393 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
26394 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
26395 +                       return -EFAULT;
26396 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
26397 +               __get_user(mask, &act->sa_mask);
26398 +               siginitset(&new_ka.sa.sa_mask, mask);
26399 +       }
26400 +
26401 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
26402 +
26403 +       if (!ret && oact) {
26404 +               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
26405 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
26406 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
26407 +                       return -EFAULT;
26408 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
26409 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
26410 +       }
26411 +
26412 +       return ret;
26413 +}
26414 +
26415 +/*
26416 + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
26417 + *
26418 + * This is really horribly ugly.
26419 + */
26420 +int sys_ipc (uint call, int first, int second,
26421 +            int third, void *ptr, long fifth)
26422 +{
26423 +       int version, ret;
26424 +
26425 +       version = call >> 16; /* hack for backward compatibility */
26426 +       call &= 0xffff;
26427 +
26428 +       switch (call) {
26429 +       case SEMOP:
26430 +               return sys_semop (first, (struct sembuf *)ptr, second);
26431 +       case SEMGET:
26432 +               return sys_semget (first, second, third);
26433 +       case SEMCTL: {
26434 +               union semun fourth;
26435 +               if (!ptr)
26436 +                       return -EINVAL;
26437 +               if (get_user(fourth.__pad, (void **) ptr))
26438 +                       return -EFAULT;
26439 +               return sys_semctl (first, second, third, fourth);
26440 +       }
26441 +
26442 +       case MSGSND:
26443 +               return sys_msgsnd (first, (struct msgbuf *) ptr, 
26444 +                                  second, third);
26445 +       case MSGRCV:
26446 +               switch (version) {
26447 +               case 0: {
26448 +                       struct ipc_kludge tmp;
26449 +                       if (!ptr)
26450 +                               return -EINVAL;
26451 +                       
26452 +                       if (copy_from_user(&tmp,
26453 +                                          (struct ipc_kludge *) ptr, 
26454 +                                          sizeof (tmp)))
26455 +                               return -EFAULT;
26456 +                       return sys_msgrcv (first, tmp.msgp, second,
26457 +                                          tmp.msgtyp, third);
26458 +               }
26459 +               default:
26460 +                       panic("msgrcv with version != 0");
26461 +                       return sys_msgrcv (first,
26462 +                                          (struct msgbuf *) ptr,
26463 +                                          second, fifth, third);
26464 +               }
26465 +       case MSGGET:
26466 +               return sys_msgget ((key_t) first, second);
26467 +       case MSGCTL:
26468 +               return sys_msgctl (first, second, (struct msqid_ds *) ptr);
26469 +
26470 +       case SHMAT:
26471 +               switch (version) {
26472 +               default: {
26473 +                       ulong raddr;
26474 +                       ret = sys_shmat (first, (char *) ptr, second, &raddr);
26475 +                       if (ret)
26476 +                               return ret;
26477 +                       return put_user (raddr, (ulong *) third);
26478 +               }
26479 +               case 1: /* iBCS2 emulator entry point */
26480 +                       if (!segment_eq(get_fs(), get_ds()))
26481 +                               return -EINVAL;
26482 +                       return sys_shmat (first, (char *) ptr, second, (ulong *) third);
26483 +               }
26484 +       case SHMDT: 
26485 +               return sys_shmdt ((char *)ptr);
26486 +       case SHMGET:
26487 +               return sys_shmget (first, second, third);
26488 +       case SHMCTL:
26489 +               return sys_shmctl (first, second,
26490 +                                  (struct shmid_ds *) ptr);
26491 +       default:
26492 +               return -EINVAL;
26493 +       }
26494 +}
26495 +
26496 +int sys_uname(struct old_utsname * name)
26497 +{
26498 +       int err;
26499 +       if (!name)
26500 +               return -EFAULT;
26501 +       down_read(&uts_sem);
26502 +       err=copy_to_user(name, &system_utsname, sizeof (*name));
26503 +       up_read(&uts_sem);
26504 +       return err?-EFAULT:0;
26505 +}
26506 +
26507 +int sys_olduname(struct oldold_utsname * name)
26508 +{
26509 +       int error;
26510 +
26511 +       if (!name)
26512 +               return -EFAULT;
26513 +       if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
26514 +               return -EFAULT;
26515 +  
26516 +       down_read(&uts_sem);
26517 +       
26518 +       error = __copy_to_user(&name->sysname,&system_utsname.sysname,
26519 +                              __OLD_UTS_LEN);
26520 +       error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
26521 +       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
26522 +                               __OLD_UTS_LEN);
26523 +       error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
26524 +       error |= __copy_to_user(&name->release,&system_utsname.release,
26525 +                               __OLD_UTS_LEN);
26526 +       error |= __put_user(0,name->release+__OLD_UTS_LEN);
26527 +       error |= __copy_to_user(&name->version,&system_utsname.version,
26528 +                               __OLD_UTS_LEN);
26529 +       error |= __put_user(0,name->version+__OLD_UTS_LEN);
26530 +       error |= __copy_to_user(&name->machine,&system_utsname.machine,
26531 +                               __OLD_UTS_LEN);
26532 +       error |= __put_user(0,name->machine+__OLD_UTS_LEN);
26533 +       
26534 +       up_read(&uts_sem);
26535 +       
26536 +       error = error ? -EFAULT : 0;
26537 +
26538 +       return error;
26539 +}
26540 +
26541 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
26542 +{
26543 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
26544 +}
26545 +
26546 +long execute_syscall(void *r)
26547 +{
26548 +       return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
26549 +}
26550 +
26551 +spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
26552 +
26553 +static int syscall_index = 0;
26554 +
26555 +int next_syscall_index(int limit)
26556 +{
26557 +       int ret;
26558 +
26559 +       spin_lock(&syscall_lock);
26560 +       ret = syscall_index;
26561 +       if(++syscall_index == limit)
26562 +               syscall_index = 0;
26563 +       spin_unlock(&syscall_lock);
26564 +       return(ret);
26565 +}
26566 +
26567 +/*
26568 + * Overrides for Emacs so that we follow Linus's tabbing style.
26569 + * Emacs will notice this stuff at the end of the file and automatically
26570 + * adjust the settings for this buffer only.  This must remain at the end
26571 + * of the file.
26572 + * ---------------------------------------------------------------------------
26573 + * Local variables:
26574 + * c-file-style: "linux"
26575 + * End:
26576 + */
26577 diff -Naur -X ../exclude-files orig/arch/um/kernel/sys_call_table.c um/arch/um/kernel/sys_call_table.c
26578 --- orig/arch/um/kernel/sys_call_table.c        1969-12-31 19:00:00.000000000 -0500
26579 +++ um/arch/um/kernel/sys_call_table.c  2003-10-21 03:26:07.000000000 -0400
26580 @@ -0,0 +1,496 @@
26581 +/* 
26582 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
26583 + * Licensed under the GPL
26584 + */
26585 +
26586 +#include "linux/unistd.h"
26587 +#include "linux/version.h"
26588 +#include "linux/sys.h"
26589 +#include "asm/signal.h"
26590 +#include "sysdep/syscalls.h"
26591 +#include "kern_util.h"
26592 +
26593 +extern syscall_handler_t sys_ni_syscall;
26594 +extern syscall_handler_t sys_exit;
26595 +extern syscall_handler_t sys_fork;
26596 +extern syscall_handler_t sys_creat;
26597 +extern syscall_handler_t sys_link;
26598 +extern syscall_handler_t sys_unlink;
26599 +extern syscall_handler_t sys_chdir;
26600 +extern syscall_handler_t sys_mknod;
26601 +extern syscall_handler_t sys_chmod;
26602 +extern syscall_handler_t sys_lchown16;
26603 +extern syscall_handler_t sys_ni_syscall;
26604 +extern syscall_handler_t sys_stat;
26605 +extern syscall_handler_t sys_getpid;
26606 +extern syscall_handler_t sys_oldumount;
26607 +extern syscall_handler_t sys_setuid16;
26608 +extern syscall_handler_t sys_getuid16;
26609 +extern syscall_handler_t sys_ptrace;
26610 +extern syscall_handler_t sys_alarm;
26611 +extern syscall_handler_t sys_fstat;
26612 +extern syscall_handler_t sys_pause;
26613 +extern syscall_handler_t sys_utime;
26614 +extern syscall_handler_t sys_ni_syscall;
26615 +extern syscall_handler_t sys_ni_syscall;
26616 +extern syscall_handler_t sys_access;
26617 +extern syscall_handler_t sys_nice;
26618 +extern syscall_handler_t sys_ni_syscall;
26619 +extern syscall_handler_t sys_sync;
26620 +extern syscall_handler_t sys_kill;
26621 +extern syscall_handler_t sys_rename;
26622 +extern syscall_handler_t sys_mkdir;
26623 +extern syscall_handler_t sys_rmdir;
26624 +extern syscall_handler_t sys_pipe;
26625 +extern syscall_handler_t sys_times;
26626 +extern syscall_handler_t sys_ni_syscall;
26627 +extern syscall_handler_t sys_brk;
26628 +extern syscall_handler_t sys_setgid16;
26629 +extern syscall_handler_t sys_getgid16;
26630 +extern syscall_handler_t sys_signal;
26631 +extern syscall_handler_t sys_geteuid16;
26632 +extern syscall_handler_t sys_getegid16;
26633 +extern syscall_handler_t sys_acct;
26634 +extern syscall_handler_t sys_umount;
26635 +extern syscall_handler_t sys_ni_syscall;
26636 +extern syscall_handler_t sys_ioctl;
26637 +extern syscall_handler_t sys_fcntl;
26638 +extern syscall_handler_t sys_ni_syscall;
26639 +extern syscall_handler_t sys_setpgid;
26640 +extern syscall_handler_t sys_ni_syscall;
26641 +extern syscall_handler_t sys_olduname;
26642 +extern syscall_handler_t sys_umask;
26643 +extern syscall_handler_t sys_chroot;
26644 +extern syscall_handler_t sys_ustat;
26645 +extern syscall_handler_t sys_dup2;
26646 +extern syscall_handler_t sys_getppid;
26647 +extern syscall_handler_t sys_getpgrp;
26648 +extern syscall_handler_t sys_sigaction;
26649 +extern syscall_handler_t sys_sgetmask;
26650 +extern syscall_handler_t sys_ssetmask;
26651 +extern syscall_handler_t sys_setreuid16;
26652 +extern syscall_handler_t sys_setregid16;
26653 +extern syscall_handler_t sys_sigsuspend;
26654 +extern syscall_handler_t sys_sigpending;
26655 +extern syscall_handler_t sys_sethostname;
26656 +extern syscall_handler_t sys_setrlimit;
26657 +extern syscall_handler_t sys_old_getrlimit;
26658 +extern syscall_handler_t sys_getrusage;
26659 +extern syscall_handler_t sys_gettimeofday;
26660 +extern syscall_handler_t sys_settimeofday;
26661 +extern syscall_handler_t sys_getgroups16;
26662 +extern syscall_handler_t sys_setgroups16;
26663 +extern syscall_handler_t sys_symlink;
26664 +extern syscall_handler_t sys_lstat;
26665 +extern syscall_handler_t sys_readlink;
26666 +extern syscall_handler_t sys_uselib;
26667 +extern syscall_handler_t sys_swapon;
26668 +extern syscall_handler_t sys_reboot;
26669 +extern syscall_handler_t old_readdir;
26670 +extern syscall_handler_t sys_munmap;
26671 +extern syscall_handler_t sys_truncate;
26672 +extern syscall_handler_t sys_ftruncate;
26673 +extern syscall_handler_t sys_fchmod;
26674 +extern syscall_handler_t sys_fchown16;
26675 +extern syscall_handler_t sys_getpriority;
26676 +extern syscall_handler_t sys_setpriority;
26677 +extern syscall_handler_t sys_ni_syscall;
26678 +extern syscall_handler_t sys_statfs;
26679 +extern syscall_handler_t sys_fstatfs;
26680 +extern syscall_handler_t sys_ni_syscall;
26681 +extern syscall_handler_t sys_socketcall;
26682 +extern syscall_handler_t sys_syslog;
26683 +extern syscall_handler_t sys_setitimer;
26684 +extern syscall_handler_t sys_getitimer;
26685 +extern syscall_handler_t sys_newstat;
26686 +extern syscall_handler_t sys_newlstat;
26687 +extern syscall_handler_t sys_newfstat;
26688 +extern syscall_handler_t sys_uname;
26689 +extern syscall_handler_t sys_ni_syscall;
26690 +extern syscall_handler_t sys_vhangup;
26691 +extern syscall_handler_t sys_ni_syscall;
26692 +extern syscall_handler_t sys_ni_syscall;
26693 +extern syscall_handler_t sys_swapoff;
26694 +extern syscall_handler_t sys_sysinfo;
26695 +extern syscall_handler_t sys_ipc;
26696 +extern syscall_handler_t sys_fsync;
26697 +extern syscall_handler_t sys_sigreturn;
26698 +extern syscall_handler_t sys_rt_sigreturn;
26699 +extern syscall_handler_t sys_clone;
26700 +extern syscall_handler_t sys_setdomainname;
26701 +extern syscall_handler_t sys_newuname;
26702 +extern syscall_handler_t sys_ni_syscall;
26703 +extern syscall_handler_t sys_adjtimex;
26704 +extern syscall_handler_t sys_mprotect;
26705 +extern syscall_handler_t sys_sigprocmask;
26706 +extern syscall_handler_t sys_create_module;
26707 +extern syscall_handler_t sys_init_module;
26708 +extern syscall_handler_t sys_delete_module;
26709 +extern syscall_handler_t sys_get_kernel_syms;
26710 +extern syscall_handler_t sys_quotactl;
26711 +extern syscall_handler_t sys_getpgid;
26712 +extern syscall_handler_t sys_fchdir;
26713 +extern syscall_handler_t sys_bdflush;
26714 +extern syscall_handler_t sys_sysfs;
26715 +extern syscall_handler_t sys_personality;
26716 +extern syscall_handler_t sys_ni_syscall;
26717 +extern syscall_handler_t sys_setfsuid16;
26718 +extern syscall_handler_t sys_setfsgid16;
26719 +extern syscall_handler_t sys_llseek;
26720 +extern syscall_handler_t sys_getdents;
26721 +extern syscall_handler_t sys_flock;
26722 +extern syscall_handler_t sys_msync;
26723 +extern syscall_handler_t sys_readv;
26724 +extern syscall_handler_t sys_writev;
26725 +extern syscall_handler_t sys_getsid;
26726 +extern syscall_handler_t sys_fdatasync;
26727 +extern syscall_handler_t sys_sysctl;
26728 +extern syscall_handler_t sys_mlock;
26729 +extern syscall_handler_t sys_munlock;
26730 +extern syscall_handler_t sys_mlockall;
26731 +extern syscall_handler_t sys_munlockall;
26732 +extern syscall_handler_t sys_sched_setparam;
26733 +extern syscall_handler_t sys_sched_getparam;
26734 +extern syscall_handler_t sys_sched_setscheduler;
26735 +extern syscall_handler_t sys_sched_getscheduler;
26736 +extern syscall_handler_t sys_sched_get_priority_max;
26737 +extern syscall_handler_t sys_sched_get_priority_min;
26738 +extern syscall_handler_t sys_sched_rr_get_interval;
26739 +extern syscall_handler_t sys_nanosleep;
26740 +extern syscall_handler_t sys_mremap;
26741 +extern syscall_handler_t sys_setresuid16;
26742 +extern syscall_handler_t sys_getresuid16;
26743 +extern syscall_handler_t sys_ni_syscall;
26744 +extern syscall_handler_t sys_query_module;
26745 +extern syscall_handler_t sys_poll;
26746 +extern syscall_handler_t sys_nfsservctl;
26747 +extern syscall_handler_t sys_setresgid16;
26748 +extern syscall_handler_t sys_getresgid16;
26749 +extern syscall_handler_t sys_prctl;
26750 +extern syscall_handler_t sys_ni_syscall;
26751 +extern syscall_handler_t sys_rt_sigaction;
26752 +extern syscall_handler_t sys_rt_sigprocmask;
26753 +extern syscall_handler_t sys_rt_sigpending;
26754 +extern syscall_handler_t sys_rt_sigtimedwait;
26755 +extern syscall_handler_t sys_rt_sigqueueinfo;
26756 +extern syscall_handler_t sys_rt_sigsuspend;
26757 +extern syscall_handler_t sys_pread;
26758 +extern syscall_handler_t sys_pwrite;
26759 +extern syscall_handler_t sys_chown16;
26760 +extern syscall_handler_t sys_getcwd;
26761 +extern syscall_handler_t sys_capget;
26762 +extern syscall_handler_t sys_capset;
26763 +extern syscall_handler_t sys_sigaltstack;
26764 +extern syscall_handler_t sys_sendfile;
26765 +extern syscall_handler_t sys_ni_syscall;
26766 +extern syscall_handler_t sys_ni_syscall;
26767 +extern syscall_handler_t sys_vfork;
26768 +extern syscall_handler_t sys_getrlimit;
26769 +extern syscall_handler_t sys_mmap2;
26770 +extern syscall_handler_t sys_truncate64;
26771 +extern syscall_handler_t sys_ftruncate64;
26772 +extern syscall_handler_t sys_stat64;
26773 +extern syscall_handler_t sys_lstat64;
26774 +extern syscall_handler_t sys_fstat64;
26775 +extern syscall_handler_t sys_lchown;
26776 +extern syscall_handler_t sys_getuid;
26777 +extern syscall_handler_t sys_getgid;
26778 +extern syscall_handler_t sys_geteuid;
26779 +extern syscall_handler_t sys_getegid;
26780 +extern syscall_handler_t sys_setreuid;
26781 +extern syscall_handler_t sys_setregid;
26782 +extern syscall_handler_t sys_getgroups;
26783 +extern syscall_handler_t sys_setgroups;
26784 +extern syscall_handler_t sys_fchown;
26785 +extern syscall_handler_t sys_setresuid;
26786 +extern syscall_handler_t sys_getresuid;
26787 +extern syscall_handler_t sys_setresgid;
26788 +extern syscall_handler_t sys_getresgid;
26789 +extern syscall_handler_t sys_chown;
26790 +extern syscall_handler_t sys_setuid;
26791 +extern syscall_handler_t sys_setgid;
26792 +extern syscall_handler_t sys_setfsuid;
26793 +extern syscall_handler_t sys_setfsgid;
26794 +extern syscall_handler_t sys_pivot_root;
26795 +extern syscall_handler_t sys_mincore;
26796 +extern syscall_handler_t sys_madvise;
26797 +extern syscall_handler_t sys_fcntl64;
26798 +extern syscall_handler_t sys_getdents64;
26799 +extern syscall_handler_t sys_gettid;
26800 +extern syscall_handler_t sys_readahead;
26801 +extern syscall_handler_t sys_tkill;
26802 +extern syscall_handler_t sys_setxattr;
26803 +extern syscall_handler_t sys_lsetxattr;
26804 +extern syscall_handler_t sys_fsetxattr;
26805 +extern syscall_handler_t sys_getxattr;
26806 +extern syscall_handler_t sys_lgetxattr;
26807 +extern syscall_handler_t sys_fgetxattr;
26808 +extern syscall_handler_t sys_listxattr;
26809 +extern syscall_handler_t sys_llistxattr;
26810 +extern syscall_handler_t sys_flistxattr;
26811 +extern syscall_handler_t sys_removexattr;
26812 +extern syscall_handler_t sys_lremovexattr;
26813 +extern syscall_handler_t sys_fremovexattr;
26814 +extern syscall_handler_t sys_sendfile64;
26815 +
26816 +extern syscall_handler_t um_mount;
26817 +extern syscall_handler_t um_time;
26818 +extern syscall_handler_t um_stime;
26819 +
26820 +#define LAST_GENERIC_SYSCALL __NR_exit_group
26821 +
26822 +#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
26823 +#define LAST_SYSCALL LAST_GENERIC_SYSCALL
26824 +#else
26825 +#define LAST_SYSCALL LAST_ARCH_SYSCALL
26826 +#endif
26827 +
26828 +syscall_handler_t *sys_call_table[] = {
26829 +       [ 0 ] = sys_ni_syscall,
26830 +       [ __NR_exit ] = sys_exit,
26831 +       [ __NR_fork ] = sys_fork,
26832 +       [ __NR_read ] = (syscall_handler_t *) sys_read,
26833 +       [ __NR_write ] = (syscall_handler_t *) sys_write,
26834 +
26835 +       /* These three are declared differently in asm/unistd.h */
26836 +       [ __NR_open ] = (syscall_handler_t *) sys_open,
26837 +       [ __NR_close ] = (syscall_handler_t *) sys_close,
26838 +       [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
26839 +       [ __NR_creat ] = sys_creat,
26840 +       [ __NR_link ] = sys_link,
26841 +       [ __NR_unlink ] = sys_unlink,
26842 +
26843 +       /* declared differently in kern_util.h */
26844 +       [ __NR_execve ] = (syscall_handler_t *) sys_execve,
26845 +       [ __NR_chdir ] = sys_chdir,
26846 +       [ __NR_time ] = um_time,
26847 +       [ __NR_mknod ] = sys_mknod,
26848 +       [ __NR_chmod ] = sys_chmod,
26849 +       [ __NR_lchown ] = sys_lchown16,
26850 +       [ __NR_break ] = sys_ni_syscall,
26851 +       [ __NR_oldstat ] = sys_stat,
26852 +       [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
26853 +       [ __NR_getpid ] = sys_getpid,
26854 +       [ __NR_mount ] = um_mount,
26855 +       [ __NR_umount ] = sys_oldumount,
26856 +       [ __NR_setuid ] = sys_setuid16,
26857 +       [ __NR_getuid ] = sys_getuid16,
26858 +       [ __NR_stime ] = um_stime,
26859 +       [ __NR_ptrace ] = sys_ptrace,
26860 +       [ __NR_alarm ] = sys_alarm,
26861 +       [ __NR_oldfstat ] = sys_fstat,
26862 +       [ __NR_pause ] = sys_pause,
26863 +       [ __NR_utime ] = sys_utime,
26864 +       [ __NR_stty ] = sys_ni_syscall,
26865 +       [ __NR_gtty ] = sys_ni_syscall,
26866 +       [ __NR_access ] = sys_access,
26867 +       [ __NR_nice ] = sys_nice,
26868 +       [ __NR_ftime ] = sys_ni_syscall,
26869 +       [ __NR_sync ] = sys_sync,
26870 +       [ __NR_kill ] = sys_kill,
26871 +       [ __NR_rename ] = sys_rename,
26872 +       [ __NR_mkdir ] = sys_mkdir,
26873 +       [ __NR_rmdir ] = sys_rmdir,
26874 +
26875 +       /* Declared differently in asm/unistd.h */
26876 +       [ __NR_dup ] = (syscall_handler_t *) sys_dup,
26877 +       [ __NR_pipe ] = sys_pipe,
26878 +       [ __NR_times ] = sys_times,
26879 +       [ __NR_prof ] = sys_ni_syscall,
26880 +       [ __NR_brk ] = sys_brk,
26881 +       [ __NR_setgid ] = sys_setgid16,
26882 +       [ __NR_getgid ] = sys_getgid16,
26883 +       [ __NR_signal ] = sys_signal,
26884 +       [ __NR_geteuid ] = sys_geteuid16,
26885 +       [ __NR_getegid ] = sys_getegid16,
26886 +       [ __NR_acct ] = sys_acct,
26887 +       [ __NR_umount2 ] = sys_umount,
26888 +       [ __NR_lock ] = sys_ni_syscall,
26889 +       [ __NR_ioctl ] = sys_ioctl,
26890 +       [ __NR_fcntl ] = sys_fcntl,
26891 +       [ __NR_mpx ] = sys_ni_syscall,
26892 +       [ __NR_setpgid ] = sys_setpgid,
26893 +       [ __NR_ulimit ] = sys_ni_syscall,
26894 +       [ __NR_oldolduname ] = sys_olduname,
26895 +       [ __NR_umask ] = sys_umask,
26896 +       [ __NR_chroot ] = sys_chroot,
26897 +       [ __NR_ustat ] = sys_ustat,
26898 +       [ __NR_dup2 ] = sys_dup2,
26899 +       [ __NR_getppid ] = sys_getppid,
26900 +       [ __NR_getpgrp ] = sys_getpgrp,
26901 +       [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
26902 +       [ __NR_sigaction ] = sys_sigaction,
26903 +       [ __NR_sgetmask ] = sys_sgetmask,
26904 +       [ __NR_ssetmask ] = sys_ssetmask,
26905 +       [ __NR_setreuid ] = sys_setreuid16,
26906 +       [ __NR_setregid ] = sys_setregid16,
26907 +       [ __NR_sigsuspend ] = sys_sigsuspend,
26908 +       [ __NR_sigpending ] = sys_sigpending,
26909 +       [ __NR_sethostname ] = sys_sethostname,
26910 +       [ __NR_setrlimit ] = sys_setrlimit,
26911 +       [ __NR_getrlimit ] = sys_old_getrlimit,
26912 +       [ __NR_getrusage ] = sys_getrusage,
26913 +       [ __NR_gettimeofday ] = sys_gettimeofday,
26914 +       [ __NR_settimeofday ] = sys_settimeofday,
26915 +       [ __NR_getgroups ] = sys_getgroups16,
26916 +       [ __NR_setgroups ] = sys_setgroups16,
26917 +       [ __NR_symlink ] = sys_symlink,
26918 +       [ __NR_oldlstat ] = sys_lstat,
26919 +       [ __NR_readlink ] = sys_readlink,
26920 +       [ __NR_uselib ] = sys_uselib,
26921 +       [ __NR_swapon ] = sys_swapon,
26922 +       [ __NR_reboot ] = sys_reboot,
26923 +       [ __NR_readdir ] = old_readdir,
26924 +       [ __NR_munmap ] = sys_munmap,
26925 +       [ __NR_truncate ] = sys_truncate,
26926 +       [ __NR_ftruncate ] = sys_ftruncate,
26927 +       [ __NR_fchmod ] = sys_fchmod,
26928 +       [ __NR_fchown ] = sys_fchown16,
26929 +       [ __NR_getpriority ] = sys_getpriority,
26930 +       [ __NR_setpriority ] = sys_setpriority,
26931 +       [ __NR_profil ] = sys_ni_syscall,
26932 +       [ __NR_statfs ] = sys_statfs,
26933 +       [ __NR_fstatfs ] = sys_fstatfs,
26934 +       [ __NR_ioperm ] = sys_ni_syscall,
26935 +       [ __NR_socketcall ] = sys_socketcall,
26936 +       [ __NR_syslog ] = sys_syslog,
26937 +       [ __NR_setitimer ] = sys_setitimer,
26938 +       [ __NR_getitimer ] = sys_getitimer,
26939 +       [ __NR_stat ] = sys_newstat,
26940 +       [ __NR_lstat ] = sys_newlstat,
26941 +       [ __NR_fstat ] = sys_newfstat,
26942 +       [ __NR_olduname ] = sys_uname,
26943 +       [ __NR_iopl ] = sys_ni_syscall,
26944 +       [ __NR_vhangup ] = sys_vhangup,
26945 +       [ __NR_idle ] = sys_ni_syscall,
26946 +       [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
26947 +       [ __NR_swapoff ] = sys_swapoff,
26948 +       [ __NR_sysinfo ] = sys_sysinfo,
26949 +       [ __NR_ipc ] = sys_ipc,
26950 +       [ __NR_fsync ] = sys_fsync,
26951 +       [ __NR_sigreturn ] = sys_sigreturn,
26952 +       [ __NR_clone ] = sys_clone,
26953 +       [ __NR_setdomainname ] = sys_setdomainname,
26954 +       [ __NR_uname ] = sys_newuname,
26955 +       [ __NR_adjtimex ] = sys_adjtimex,
26956 +       [ __NR_mprotect ] = sys_mprotect,
26957 +       [ __NR_sigprocmask ] = sys_sigprocmask,
26958 +       [ __NR_create_module ] = sys_create_module,
26959 +       [ __NR_init_module ] = sys_init_module,
26960 +       [ __NR_delete_module ] = sys_delete_module,
26961 +       [ __NR_get_kernel_syms ] = sys_get_kernel_syms,
26962 +       [ __NR_quotactl ] = sys_quotactl,
26963 +       [ __NR_getpgid ] = sys_getpgid,
26964 +       [ __NR_fchdir ] = sys_fchdir,
26965 +       [ __NR_bdflush ] = sys_bdflush,
26966 +       [ __NR_sysfs ] = sys_sysfs,
26967 +       [ __NR_personality ] = sys_personality,
26968 +       [ __NR_afs_syscall ] = sys_ni_syscall,
26969 +       [ __NR_setfsuid ] = sys_setfsuid16,
26970 +       [ __NR_setfsgid ] = sys_setfsgid16,
26971 +       [ __NR__llseek ] = sys_llseek,
26972 +       [ __NR_getdents ] = sys_getdents,
26973 +       [ __NR__newselect ] = (syscall_handler_t *) sys_select,
26974 +       [ __NR_flock ] = sys_flock,
26975 +       [ __NR_msync ] = sys_msync,
26976 +       [ __NR_readv ] = sys_readv,
26977 +       [ __NR_writev ] = sys_writev,
26978 +       [ __NR_getsid ] = sys_getsid,
26979 +       [ __NR_fdatasync ] = sys_fdatasync,
26980 +       [ __NR__sysctl ] = sys_sysctl,
26981 +       [ __NR_mlock ] = sys_mlock,
26982 +       [ __NR_munlock ] = sys_munlock,
26983 +       [ __NR_mlockall ] = sys_mlockall,
26984 +       [ __NR_munlockall ] = sys_munlockall,
26985 +       [ __NR_sched_setparam ] = sys_sched_setparam,
26986 +       [ __NR_sched_getparam ] = sys_sched_getparam,
26987 +       [ __NR_sched_setscheduler ] = sys_sched_setscheduler,
26988 +       [ __NR_sched_getscheduler ] = sys_sched_getscheduler,
26989 +       [ __NR_sched_yield ] = (syscall_handler_t *) yield,
26990 +       [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max,
26991 +       [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min,
26992 +       [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval,
26993 +       [ __NR_nanosleep ] = sys_nanosleep,
26994 +       [ __NR_mremap ] = sys_mremap,
26995 +       [ __NR_setresuid ] = sys_setresuid16,
26996 +       [ __NR_getresuid ] = sys_getresuid16,
26997 +       [ __NR_vm86 ] = sys_ni_syscall,
26998 +       [ __NR_query_module ] = sys_query_module,
26999 +       [ __NR_poll ] = sys_poll,
27000 +       [ __NR_nfsservctl ] = sys_nfsservctl,
27001 +       [ __NR_setresgid ] = sys_setresgid16,
27002 +       [ __NR_getresgid ] = sys_getresgid16,
27003 +       [ __NR_prctl ] = sys_prctl,
27004 +       [ __NR_rt_sigreturn ] = sys_rt_sigreturn,
27005 +       [ __NR_rt_sigaction ] = sys_rt_sigaction,
27006 +       [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask,
27007 +       [ __NR_rt_sigpending ] = sys_rt_sigpending,
27008 +       [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait,
27009 +       [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo,
27010 +       [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend,
27011 +       [ __NR_pread ] = sys_pread,
27012 +       [ __NR_pwrite ] = sys_pwrite,
27013 +       [ __NR_chown ] = sys_chown16,
27014 +       [ __NR_getcwd ] = sys_getcwd,
27015 +       [ __NR_capget ] = sys_capget,
27016 +       [ __NR_capset ] = sys_capset,
27017 +       [ __NR_sigaltstack ] = sys_sigaltstack,
27018 +       [ __NR_sendfile ] = sys_sendfile,
27019 +       [ __NR_getpmsg ] = sys_ni_syscall,
27020 +       [ __NR_putpmsg ] = sys_ni_syscall,
27021 +       [ __NR_vfork ] = sys_vfork,
27022 +       [ __NR_ugetrlimit ] = sys_getrlimit,
27023 +       [ __NR_mmap2 ] = sys_mmap2,
27024 +       [ __NR_truncate64 ] = sys_truncate64,
27025 +       [ __NR_ftruncate64 ] = sys_ftruncate64,
27026 +       [ __NR_stat64 ] = sys_stat64,
27027 +       [ __NR_lstat64 ] = sys_lstat64,
27028 +       [ __NR_fstat64 ] = sys_fstat64,
27029 +       [ __NR_fcntl64 ] = sys_fcntl64,
27030 +       [ __NR_getdents64 ] = sys_getdents64,
27031 +        [ __NR_security ] = sys_ni_syscall,
27032 +       [ __NR_gettid ] = sys_gettid,
27033 +       [ __NR_readahead ] = sys_readahead,
27034 +       [ __NR_setxattr ] = sys_setxattr,
27035 +       [ __NR_lsetxattr ] = sys_lsetxattr,
27036 +       [ __NR_fsetxattr ] = sys_fsetxattr,
27037 +       [ __NR_getxattr ] = sys_getxattr,
27038 +       [ __NR_lgetxattr ] = sys_lgetxattr,
27039 +       [ __NR_fgetxattr ] = sys_fgetxattr,
27040 +       [ __NR_listxattr ] = sys_listxattr,
27041 +       [ __NR_llistxattr ] = sys_llistxattr,
27042 +       [ __NR_flistxattr ] = sys_flistxattr,
27043 +       [ __NR_removexattr ] = sys_removexattr,
27044 +       [ __NR_lremovexattr ] = sys_lremovexattr,
27045 +       [ __NR_fremovexattr ] = sys_fremovexattr,
27046 +       [ __NR_tkill ] = sys_tkill,
27047 +       [ __NR_sendfile64 ] = sys_sendfile64,
27048 +       [ __NR_futex ] = sys_ni_syscall,
27049 +       [ __NR_sched_setaffinity ] = sys_ni_syscall,
27050 +       [ __NR_sched_getaffinity ] = sys_ni_syscall,
27051 +       [ __NR_set_thread_area ] = sys_ni_syscall,
27052 +       [ __NR_get_thread_area ] = sys_ni_syscall,
27053 +       [ __NR_io_setup ] = sys_ni_syscall,
27054 +       [ __NR_io_destroy ] = sys_ni_syscall,
27055 +       [ __NR_io_getevents ] = sys_ni_syscall,
27056 +       [ __NR_io_submit ] = sys_ni_syscall,
27057 +       [ __NR_io_cancel ] = sys_ni_syscall,
27058 +       [ __NR_alloc_hugepages ] = sys_ni_syscall,
27059 +       [ __NR_free_hugepages ] = sys_ni_syscall,
27060 +       [ __NR_exit_group ] = sys_ni_syscall,
27061 +
27062 +       ARCH_SYSCALLS
27063 +       [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
27064 +               (syscall_handler_t *) sys_ni_syscall
27065 +};
27066 +
27067 +/*
27068 + * Overrides for Emacs so that we follow Linus's tabbing style.
27069 + * Emacs will notice this stuff at the end of the file and automatically
27070 + * adjust the settings for this buffer only.  This must remain at the end
27071 + * of the file.
27072 + * ---------------------------------------------------------------------------
27073 + * Local variables:
27074 + * c-file-style: "linux"
27075 + * End:
27076 + */
27077 diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_user.c um/arch/um/kernel/syscall_user.c
27078 --- orig/arch/um/kernel/syscall_user.c  1969-12-31 19:00:00.000000000 -0500
27079 +++ um/arch/um/kernel/syscall_user.c    2003-10-21 03:26:07.000000000 -0400
27080 @@ -0,0 +1,48 @@
27081 +/* 
27082 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27083 + * Licensed under the GPL
27084 + */
27085 +
27086 +#include <stdlib.h>
27087 +#include <sys/time.h>
27088 +#include "kern_util.h"
27089 +#include "syscall_user.h"
27090 +
27091 +struct {
27092 +       int syscall;
27093 +       int pid;
27094 +       int result;
27095 +       struct timeval start;
27096 +       struct timeval end;
27097 +} syscall_record[1024];
27098 +
27099 +int record_syscall_start(int syscall)
27100 +{
27101 +       int max, index;
27102 +       
27103 +       max = sizeof(syscall_record)/sizeof(syscall_record[0]);
27104 +       index = next_syscall_index(max);
27105 +
27106 +       syscall_record[index].syscall = syscall;
27107 +       syscall_record[index].pid = current_pid();
27108 +       syscall_record[index].result = 0xdeadbeef;
27109 +       gettimeofday(&syscall_record[index].start, NULL);
27110 +       return(index);
27111 +}
27112 +
27113 +void record_syscall_end(int index, int result)
27114 +{
27115 +       syscall_record[index].result = result;
27116 +       gettimeofday(&syscall_record[index].end, NULL);
27117 +}
27118 +
27119 +/*
27120 + * Overrides for Emacs so that we follow Linus's tabbing style.
27121 + * Emacs will notice this stuff at the end of the file and automatically
27122 + * adjust the settings for this buffer only.  This must remain at the end
27123 + * of the file.
27124 + * ---------------------------------------------------------------------------
27125 + * Local variables:
27126 + * c-file-style: "linux"
27127 + * End:
27128 + */
27129 diff -Naur -X ../exclude-files orig/arch/um/kernel/sysrq.c um/arch/um/kernel/sysrq.c
27130 --- orig/arch/um/kernel/sysrq.c 1969-12-31 19:00:00.000000000 -0500
27131 +++ um/arch/um/kernel/sysrq.c   2003-10-21 03:26:07.000000000 -0400
27132 @@ -0,0 +1,98 @@
27133 +/* 
27134 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
27135 + * Licensed under the GPL
27136 + */
27137 +
27138 +#include "linux/sched.h"
27139 +#include "linux/kernel.h"
27140 +#include "linux/module.h"
27141 +#include "asm/page.h"
27142 +#include "asm/processor.h"
27143 +#include "sysrq.h"
27144 +#include "user_util.h"
27145 +
27146 + /*
27147 +  * If the address is either in the .text section of the
27148 +  * kernel, or in the vmalloc'ed module regions, it *may* 
27149 +  * be the address of a calling routine
27150 +  */
27151
27152 +#ifdef CONFIG_MODULES
27153 +
27154 +extern struct module *module_list;
27155 +extern struct module kernel_module;
27156 +
27157 +static inline int kernel_text_address(unsigned long addr)
27158 +{
27159 +       int retval = 0;
27160 +       struct module *mod;
27161 +
27162 +       if (addr >= (unsigned long) &_stext &&
27163 +           addr <= (unsigned long) &_etext)
27164 +               return 1;
27165 +
27166 +       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
27167 +               /* mod_bound tests for addr being inside the vmalloc'ed
27168 +                * module area. Of course it'd be better to test only
27169 +                * for the .text subset... */
27170 +               if (mod_bound(addr, 0, mod)) {
27171 +                       retval = 1;
27172 +                       break;
27173 +               }
27174 +       }
27175 +
27176 +       return retval;
27177 +}
27178 +
27179 +#else
27180 +
27181 +static inline int kernel_text_address(unsigned long addr)
27182 +{
27183 +       return (addr >= (unsigned long) &_stext &&
27184 +               addr <= (unsigned long) &_etext);
27185 +}
27186 +
27187 +#endif
27188 +
27189 +void show_trace(unsigned long * stack)
27190 +{
27191 +        int i;
27192 +        unsigned long addr;
27193 +
27194 +        if (!stack)
27195 +                stack = (unsigned long*) &stack;
27196 +
27197 +        printk("Call Trace: ");
27198 +        i = 1;
27199 +        while (((long) stack & (THREAD_SIZE-1)) != 0) {
27200 +                addr = *stack++;
27201 +               if (kernel_text_address(addr)) {
27202 +                       if (i && ((i % 6) == 0))
27203 +                               printk("\n   ");
27204 +                       printk("[<%08lx>] ", addr);
27205 +                       i++;
27206 +                }
27207 +        }
27208 +        printk("\n");
27209 +}
27210 +
27211 +void show_trace_task(struct task_struct *tsk)
27212 +{
27213 +       unsigned long esp = PT_REGS_SP(&tsk->thread.regs);
27214 +
27215 +       /* User space on another CPU? */
27216 +       if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
27217 +               return;
27218 +       show_trace((unsigned long *)esp);
27219 +}
27220 +
27221 +/*
27222 + * Overrides for Emacs so that we follow Linus's tabbing style.
27223 + * Emacs will notice this stuff at the end of the file and automatically
27224 + * adjust the settings for this buffer only.  This must remain at the end
27225 + * of the file.
27226 + * ---------------------------------------------------------------------------
27227 + * Local variables:
27228 + * c-file-style: "linux"
27229 + * End:
27230 + */
27231 diff -Naur -X ../exclude-files orig/arch/um/kernel/tempfile.c um/arch/um/kernel/tempfile.c
27232 --- orig/arch/um/kernel/tempfile.c      1969-12-31 19:00:00.000000000 -0500
27233 +++ um/arch/um/kernel/tempfile.c        2003-10-21 03:26:07.000000000 -0400
27234 @@ -0,0 +1,82 @@
27235 +/* 
27236 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
27237 + * Licensed under the GPL
27238 + */
27239 +
27240 +#include <stdio.h>
27241 +#include <stdlib.h>
27242 +#include <unistd.h>
27243 +#include <string.h>
27244 +#include <errno.h>
27245 +#include <sys/param.h>
27246 +#include "init.h"
27247 +
27248 +/* Modified from create_mem_file and start_debugger */
27249 +static char *tempdir = NULL;
27250 +
27251 +static void __init find_tempdir(void)
27252 +{
27253 +       char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
27254 +       int i;
27255 +       char *dir = NULL;
27256 +
27257 +       if(tempdir != NULL) return;     /* We've already been called */
27258 +       for(i = 0; dirs[i]; i++){
27259 +               dir = getenv(dirs[i]);
27260 +               if((dir != NULL) && (*dir != '\0'))
27261 +                       break;
27262 +       }
27263 +       if((dir == NULL) || (*dir == '\0')) 
27264 +               dir = "/tmp";
27265 +
27266 +       tempdir = malloc(strlen(dir) + 2);
27267 +       if(tempdir == NULL){
27268 +               fprintf(stderr, "Failed to malloc tempdir, "
27269 +                       "errno = %d\n", errno);
27270 +               return;
27271 +       }
27272 +       strcpy(tempdir, dir);
27273 +       strcat(tempdir, "/");
27274 +}
27275 +
27276 +int make_tempfile(const char *template, char **out_tempname, int do_unlink)
27277 +{
27278 +       char tempname[MAXPATHLEN];
27279 +       int fd;
27280 +
27281 +       find_tempdir();
27282 +       if (*template != '/')
27283 +               strcpy(tempname, tempdir);
27284 +       else
27285 +               *tempname = 0;
27286 +       strcat(tempname, template);
27287 +       fd = mkstemp(tempname);
27288 +       if(fd < 0){
27289 +               fprintf(stderr, "open - cannot create %s: %s\n", tempname, 
27290 +                       strerror(errno));
27291 +               return -1;
27292 +       }
27293 +       if(do_unlink && (unlink(tempname) < 0)){
27294 +               perror("unlink");
27295 +               return -1;
27296 +       }
27297 +       if(out_tempname){
27298 +               *out_tempname = strdup(tempname);
27299 +               if(*out_tempname == NULL){
27300 +                       perror("strdup");
27301 +                       return -1;
27302 +               }
27303 +       }
27304 +       return(fd);
27305 +}
27306 +
27307 +/*
27308 + * Overrides for Emacs so that we follow Linus's tabbing style.
27309 + * Emacs will notice this stuff at the end of the file and automatically
27310 + * adjust the settings for this buffer only.  This must remain at the end
27311 + * of the file.
27312 + * ---------------------------------------------------------------------------
27313 + * Local variables:
27314 + * c-file-style: "linux"
27315 + * End:
27316 + */
27317 diff -Naur -X ../exclude-files orig/arch/um/kernel/time.c um/arch/um/kernel/time.c
27318 --- orig/arch/um/kernel/time.c  1969-12-31 19:00:00.000000000 -0500
27319 +++ um/arch/um/kernel/time.c    2003-12-17 01:08:27.000000000 -0500
27320 @@ -0,0 +1,164 @@
27321 +/* 
27322 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27323 + * Licensed under the GPL
27324 + */
27325 +
27326 +#include <stdio.h>
27327 +#include <stdlib.h>
27328 +#include <unistd.h>
27329 +#include <time.h>
27330 +#include <sys/time.h>
27331 +#include <signal.h>
27332 +#include <errno.h>
27333 +#include "user_util.h"
27334 +#include "kern_util.h"
27335 +#include "user.h"
27336 +#include "process.h"
27337 +#include "signal_user.h"
27338 +#include "time_user.h"
27339 +
27340 +extern struct timeval xtime;
27341 +
27342 +struct timeval local_offset = { 0, 0 };
27343 +
27344 +void timer(void)
27345 +{
27346 +       gettimeofday(&xtime, NULL);
27347 +       timeradd(&xtime, &local_offset, &xtime);
27348 +}
27349 +
27350 +void set_interval(int timer_type)
27351 +{
27352 +       int usec = 1000000/hz();
27353 +       struct itimerval interval = ((struct itimerval) { { 0, usec },
27354 +                                                         { 0, usec } });
27355 +
27356 +       if(setitimer(timer_type, &interval, NULL) == -1)
27357 +               panic("setitimer failed - errno = %d\n", errno);
27358 +}
27359 +
27360 +void enable_timer(void)
27361 +{
27362 +       int usec = 1000000/hz();
27363 +       struct itimerval enable = ((struct itimerval) { { 0, usec },
27364 +                                                       { 0, usec }});
27365 +       if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
27366 +               printk("enable_timer - setitimer failed, errno = %d\n",
27367 +                      errno);
27368 +}
27369 +
27370 +void switch_timers(int to_real)
27371 +{
27372 +       struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
27373 +       struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
27374 +                                                       { 0, 1000000/hz() }});
27375 +       int old, new;
27376 +
27377 +       if(to_real){
27378 +               old = ITIMER_VIRTUAL;
27379 +               new = ITIMER_REAL;
27380 +       }
27381 +       else {
27382 +               old = ITIMER_REAL;
27383 +               new = ITIMER_VIRTUAL;
27384 +       }
27385 +
27386 +       if((setitimer(old, &disable, NULL) < 0) ||
27387 +          (setitimer(new, &enable, NULL)))
27388 +               printk("switch_timers - setitimer failed, errno = %d\n",
27389 +                      errno);
27390 +}
27391 +
27392 +void idle_timer(void)
27393 +{
27394 +       if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
27395 +               panic("Couldn't unset SIGVTALRM handler");
27396 +       
27397 +       set_handler(SIGALRM, (__sighandler_t) alarm_handler, 
27398 +                   SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
27399 +       set_interval(ITIMER_REAL);
27400 +}
27401 +
27402 +static unsigned long long get_host_hz(void)
27403 +{
27404 +       char mhzline[16], *end;
27405 +       int ret, mult, mhz, rest, len;
27406 +
27407 +       ret = cpu_feature("cpu MHz", mhzline, 
27408 +                         sizeof(mhzline) / sizeof(mhzline[0]));
27409 +       if(!ret)
27410 +               panic ("Could not get host MHZ");
27411 +
27412 +       mhz = strtoul(mhzline, &end, 10);
27413 +
27414 +       /* This business is to parse a floating point number without using
27415 +        * floating types.
27416 +        */
27417 +
27418 +       rest = 0;
27419 +       mult = 0;
27420 +       if(*end == '.'){
27421 +               end++;
27422 +               len = strlen(end);
27423 +               if(len < 6)
27424 +                       mult = 6 - len;
27425 +               else if(len > 6)
27426 +                       end[6] = '\0';
27427 +               rest = strtoul(end, NULL, 10);
27428 +               while(mult-- > 0)
27429 +                       rest *= 10;
27430 +       }
27431 +
27432 +       return(1000000 * mhz + rest);
27433 +}
27434 +
27435 +unsigned long long host_hz = 0;
27436 +
27437 +void time_init(void)
27438 +{
27439 +       host_hz = get_host_hz();
27440 +       if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
27441 +               panic("Couldn't set SIGVTALRM handler");
27442 +       set_interval(ITIMER_VIRTUAL);
27443 +}
27444 +
27445 +void do_gettimeofday(struct timeval *tv)
27446 +{
27447 +       unsigned long flags;
27448 +
27449 +       flags = time_lock();
27450 +       gettimeofday(tv, NULL);
27451 +       timeradd(tv, &local_offset, tv);
27452 +       time_unlock(flags);
27453 +}
27454 +
27455 +void do_settimeofday(struct timeval *tv)
27456 +{
27457 +       struct timeval now;
27458 +       unsigned long flags;
27459 +
27460 +       flags = time_lock();
27461 +       gettimeofday(&now, NULL);
27462 +       timersub(tv, &now, &local_offset);
27463 +       time_unlock(flags);
27464 +}
27465 +
27466 +void idle_sleep(int secs)
27467 +{
27468 +       struct timespec ts;
27469 +
27470 +       ts.tv_sec = secs;
27471 +       ts.tv_nsec = 0;
27472 +       nanosleep(&ts, NULL);
27473 +}
27474 +
27475 +/*
27476 + * Overrides for Emacs so that we follow Linus's tabbing style.
27477 + * Emacs will notice this stuff at the end of the file and automatically
27478 + * adjust the settings for this buffer only.  This must remain at the end
27479 + * of the file.
27480 + * ---------------------------------------------------------------------------
27481 + * Local variables:
27482 + * c-file-style: "linux"
27483 + * End:
27484 + */
27485 diff -Naur -X ../exclude-files orig/arch/um/kernel/time_kern.c um/arch/um/kernel/time_kern.c
27486 --- orig/arch/um/kernel/time_kern.c     1969-12-31 19:00:00.000000000 -0500
27487 +++ um/arch/um/kernel/time_kern.c       2003-12-17 01:07:51.000000000 -0500
27488 @@ -0,0 +1,205 @@
27489 +/* 
27490 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
27491 + * Licensed under the GPL
27492 + */
27493 +
27494 +#include "linux/kernel.h"
27495 +#include "linux/unistd.h"
27496 +#include "linux/stddef.h"
27497 +#include "linux/spinlock.h"
27498 +#include "linux/sched.h"
27499 +#include "linux/interrupt.h"
27500 +#include "linux/init.h"
27501 +#include "linux/delay.h"
27502 +#include "asm/irq.h"
27503 +#include "asm/param.h"
27504 +#include "asm/current.h"
27505 +#include "kern_util.h"
27506 +#include "user_util.h"
27507 +#include "time_user.h"
27508 +#include "mode.h"
27509 +
27510 +extern rwlock_t xtime_lock;
27511 +
27512 +int hz(void)
27513 +{
27514 +       return(HZ);
27515 +}
27516 +
27517 +/* Changed at early boot */
27518 +int timer_irq_inited = 0;
27519 +
27520 +/* missed_ticks will be modified after kernel memory has been 
27521 + * write-protected, so this puts it in a section which will be left 
27522 + * write-enabled.
27523 + */
27524 +int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
27525 +
27526 +static int first_tick;
27527 +static unsigned long long prev_tsc;
27528 +static long long delta;                /* Deviation per interval */
27529 +
27530 +extern unsigned long long host_hz;
27531 +
27532 +void timer_irq(union uml_pt_regs *regs)
27533 +{
27534 +       unsigned long long ticks = 0;
27535 +
27536 +        if(!timer_irq_inited){
27537 +               /* This is to ensure that ticks don't pile up when
27538 +                * the timer handler is suspended */
27539 +               first_tick = 0;
27540 +               return;
27541 +       }
27542 +       
27543 +       if(first_tick){
27544 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
27545 +               unsigned long long tsc;
27546 +                /* We've had 1 tick */
27547 +               tsc = time_stamp();
27548 +
27549 +               delta += tsc - prev_tsc;
27550 +               prev_tsc = tsc;
27551 +
27552 +               ticks += (delta * HZ) / host_hz;
27553 +               delta -= (ticks * host_hz) / HZ;
27554 +#else
27555 +               ticks = 1;
27556 +#endif
27557 +       }
27558 +       else {
27559 +               prev_tsc = time_stamp();
27560 +               first_tick = 1;
27561 +       }
27562 +
27563 +       while(ticks > 0){
27564 +               do_IRQ(TIMER_IRQ, regs);
27565 +               ticks--;
27566 +       }
27567 +}
27568 +
27569 +void boot_timer_handler(int sig)
27570 +{
27571 +       struct pt_regs regs;
27572 +
27573 +       CHOOSE_MODE((void) 
27574 +                   (UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
27575 +                   (void) (regs.regs.skas.is_user = 0));
27576 +       do_timer(&regs);
27577 +}
27578 +
27579 +void um_timer(int irq, void *dev, struct pt_regs *regs)
27580 +{
27581 +       do_timer(regs);
27582 +       write_lock(&xtime_lock);
27583 +       vxtime_lock();
27584 +       timer();
27585 +       vxtime_unlock();
27586 +       write_unlock(&xtime_lock);
27587 +}
27588 +
27589 +long um_time(int * tloc)
27590 +{
27591 +       struct timeval now;
27592 +
27593 +       do_gettimeofday(&now);
27594 +       if (tloc) {
27595 +               if (put_user(now.tv_sec,tloc))
27596 +                       now.tv_sec = -EFAULT;
27597 +       }
27598 +       return now.tv_sec;
27599 +}
27600 +
27601 +long um_stime(int * tptr)
27602 +{
27603 +       int value;
27604 +       struct timeval new;
27605 +
27606 +       if (get_user(value, tptr))
27607 +                return -EFAULT;
27608 +       new.tv_sec = value;
27609 +       new.tv_usec = 0;
27610 +       do_settimeofday(&new);
27611 +       return 0;
27612 +}
27613 +
27614 +/* XXX Needs to be moved under sys-i386 */
27615 +void __delay(um_udelay_t time)
27616 +{
27617 +       /* Stolen from the i386 __loop_delay */
27618 +       int d0;
27619 +       __asm__ __volatile__(
27620 +               "\tjmp 1f\n"
27621 +               ".align 16\n"
27622 +               "1:\tjmp 2f\n"
27623 +               ".align 16\n"
27624 +               "2:\tdecl %0\n\tjns 2b"
27625 +               :"=&a" (d0)
27626 +               :"0" (time));
27627 +}
27628 +
27629 +void __udelay(um_udelay_t usecs)
27630 +{
27631 +       int i, n;
27632 +
27633 +       n = (loops_per_jiffy * HZ * usecs) / 1000000;
27634 +       for(i=0;i<n;i++) ;
27635 +}
27636 +
27637 +void __const_udelay(um_udelay_t usecs)
27638 +{
27639 +       int i, n;
27640 +
27641 +       n = (loops_per_jiffy * HZ * usecs) / 1000000;
27642 +       for(i=0;i<n;i++) ;
27643 +}
27644 +
27645 +void timer_handler(int sig, union uml_pt_regs *regs)
27646 +{
27647 +#ifdef CONFIG_SMP
27648 +       update_process_times(user_context(UPT_SP(regs)));
27649 +#endif
27650 +       if(current->processor == 0)
27651 +               timer_irq(regs);
27652 +}
27653 +
27654 +static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED;
27655 +
27656 +unsigned long time_lock(void)
27657 +{
27658 +       unsigned long flags;
27659 +
27660 +       spin_lock_irqsave(&timer_spinlock, flags);
27661 +       return(flags);
27662 +}
27663 +
27664 +void time_unlock(unsigned long flags)
27665 +{
27666 +       spin_unlock_irqrestore(&timer_spinlock, flags);
27667 +}
27668 +
27669 +int __init timer_init(void)
27670 +{
27671 +       int err;
27672 +
27673 +       CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
27674 +       err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
27675 +       if(err != 0)
27676 +               printk(KERN_ERR "timer_init : request_irq failed - "
27677 +                      "errno = %d\n", -err);
27678 +       timer_irq_inited = 1;
27679 +       return(0);
27680 +}
27681 +
27682 +__initcall(timer_init);
27683 +
27684 +/*
27685 + * Overrides for Emacs so that we follow Linus's tabbing style.
27686 + * Emacs will notice this stuff at the end of the file and automatically
27687 + * adjust the settings for this buffer only.  This must remain at the end
27688 + * of the file.
27689 + * ---------------------------------------------------------------------------
27690 + * Local variables:
27691 + * c-file-style: "linux"
27692 + * End:
27693 + */
27694 diff -Naur -X ../exclude-files orig/arch/um/kernel/tlb.c um/arch/um/kernel/tlb.c
27695 --- orig/arch/um/kernel/tlb.c   1969-12-31 19:00:00.000000000 -0500
27696 +++ um/arch/um/kernel/tlb.c     2003-10-21 03:26:07.000000000 -0400
27697 @@ -0,0 +1,80 @@
27698 +/* 
27699 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
27700 + * Licensed under the GPL
27701 + */
27702 +
27703 +#include "linux/mm.h"
27704 +#include "asm/page.h"
27705 +#include "asm/pgalloc.h"
27706 +#include "choose-mode.h"
27707 +#include "mode_kern.h"
27708 +
27709 +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
27710 +{
27711 +       address &= PAGE_MASK;
27712 +       flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE);
27713 +}
27714 +
27715 +void flush_tlb_all(void)
27716 +{
27717 +       flush_tlb_mm(current->mm);
27718 +}
27719 +
27720 +void flush_tlb_kernel_vm(void)
27721 +{
27722 +       CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas());
27723 +}
27724 +
27725 +void __flush_tlb_one(unsigned long addr)
27726 +{
27727 +       CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
27728 +}
27729 +
27730 +void flush_tlb_range(struct mm_struct *mm, unsigned long start, 
27731 +                    unsigned long end)
27732 +{
27733 +       CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start, 
27734 +                        end);
27735 +}
27736 +
27737 +void flush_tlb_mm(struct mm_struct *mm)
27738 +{
27739 +       CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
27740 +}
27741 +
27742 +void force_flush_all(void)
27743 +{
27744 +       CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
27745 +}
27746 +
27747 +
27748 +pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
27749 +{
27750 +       return(pgd_offset(mm, address));
27751 +}
27752 +
27753 +pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
27754 +{
27755 +       return(pmd_offset(pgd, address));
27756 +}
27757 +
27758 +pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
27759 +{
27760 +       return(pte_offset(pmd, address));
27761 +}
27762 +
27763 +pte_t *addr_pte(struct task_struct *task, unsigned long addr)
27764 +{
27765 +       return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr));
27766 +}
27767 +
27768 +/*
27769 + * Overrides for Emacs so that we follow Linus's tabbing style.
27770 + * Emacs will notice this stuff at the end of the file and automatically
27771 + * adjust the settings for this buffer only.  This must remain at the end
27772 + * of the file.
27773 + * ---------------------------------------------------------------------------
27774 + * Local variables:
27775 + * c-file-style: "linux"
27776 + * End:
27777 + */
27778 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_kern.c um/arch/um/kernel/trap_kern.c
27779 --- orig/arch/um/kernel/trap_kern.c     1969-12-31 19:00:00.000000000 -0500
27780 +++ um/arch/um/kernel/trap_kern.c       2003-12-14 11:18:05.000000000 -0500
27781 @@ -0,0 +1,220 @@
27782 +/* 
27783 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
27784 + * Licensed under the GPL
27785 + */
27786 +
27787 +#include "linux/kernel.h"
27788 +#include "linux/sched.h"
27789 +#include "linux/mm.h"
27790 +#include "linux/spinlock.h"
27791 +#include "linux/config.h"
27792 +#include "linux/init.h"
27793 +#include "asm/semaphore.h"
27794 +#include "asm/pgtable.h"
27795 +#include "asm/pgalloc.h"
27796 +#include "asm/a.out.h"
27797 +#include "asm/current.h"
27798 +#include "asm/irq.h"
27799 +#include "user_util.h"
27800 +#include "kern_util.h"
27801 +#include "kern.h"
27802 +#include "chan_kern.h"
27803 +#include "mconsole_kern.h"
27804 +#include "2_5compat.h"
27805 +#include "mem.h"
27806 +#include "mem_kern.h"
27807 +
27808 +unsigned long handle_page_fault(unsigned long address, unsigned long ip, 
27809 +                               int is_write, int is_user, int *code_out)
27810 +{
27811 +       struct mm_struct *mm = current->mm;
27812 +       struct vm_area_struct *vma;
27813 +       pgd_t *pgd;
27814 +       pmd_t *pmd;
27815 +       pte_t *pte;
27816 +       unsigned long page;
27817 +       int handled = 0;
27818 +
27819 +       *code_out = SEGV_MAPERR;
27820 +       down_read(&mm->mmap_sem);
27821 +       vma = find_vma(mm, address);
27822 +       if(!vma) 
27823 +               goto out;
27824 +       else if(vma->vm_start <= address) 
27825 +               goto good_area;
27826 +       else if(!(vma->vm_flags & VM_GROWSDOWN)) 
27827 +               goto out;
27828 +       else if(expand_stack(vma, address)) 
27829 +               goto out;
27830 +
27831 + good_area:
27832 +       *code_out = SEGV_ACCERR;
27833 +       if(is_write && !(vma->vm_flags & VM_WRITE)) 
27834 +               goto out;
27835 +       page = address & PAGE_MASK;
27836 +       if(page == (unsigned long) current + PAGE_SIZE)
27837 +               panic("Kernel stack overflow");
27838 +       pgd = pgd_offset(mm, page);
27839 +       pmd = pmd_offset(pgd, page);
27840 +       do {
27841 +       survive:
27842 +               switch (handle_mm_fault(mm, vma, address, is_write)) {
27843 +               case 1:
27844 +                       current->min_flt++;
27845 +                       break;
27846 +               case 2:
27847 +                       current->maj_flt++;
27848 +                       break;
27849 +               default:
27850 +                       if (current->pid == 1) {
27851 +                               up_read(&mm->mmap_sem);
27852 +                               yield();
27853 +                               down_read(&mm->mmap_sem);
27854 +                               goto survive;
27855 +                       }
27856 +                       /* Fall through to bad area case */
27857 +               case 0:
27858 +                       goto out;
27859 +               }
27860 +               pte = pte_offset(pmd, page);
27861 +       } while(!pte_present(*pte));
27862 +       handled = 1;
27863 +       *pte = pte_mkyoung(*pte);
27864 +       if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
27865 +       flush_tlb_page(vma, page);
27866 + out:
27867 +       up_read(&mm->mmap_sem);
27868 +       return(handled);
27869 +}
27870 +
27871 +LIST_HEAD(physmem_remappers);
27872 +
27873 +void register_remapper(struct remapper *info)
27874 +{
27875 +       list_add(&info->list, &physmem_remappers);
27876 +}
27877 +
27878 +static int check_remapped_addr(unsigned long address, int is_write)
27879 +{
27880 +       struct remapper *remapper;
27881 +       struct list_head *ele;
27882 +       __u64 offset;
27883 +       int fd;
27884 +
27885 +       fd = phys_mapping(__pa(address), &offset);
27886 +       if(fd == -1)
27887 +               return(0);
27888 +
27889 +       list_for_each(ele, &physmem_remappers){
27890 +               remapper = list_entry(ele, struct remapper, list);
27891 +               if((*remapper->proc)(fd, address, is_write, offset))
27892 +                       return(1);
27893 +       }
27894 +
27895 +       return(0);
27896 +}
27897 +
27898 +unsigned long segv(unsigned long address, unsigned long ip, int is_write, 
27899 +                  int is_user, void *sc)
27900 +{
27901 +       struct siginfo si;
27902 +       void *catcher;
27903 +       int handled;
27904 +
27905 +        if(!is_user && (address >= start_vm) && (address < end_vm)){
27906 +                flush_tlb_kernel_vm();
27907 +                return(0);
27908 +        }
27909 +       else if(check_remapped_addr(address & PAGE_MASK, is_write))
27910 +               return(0);
27911 +       else if(current->mm == NULL)
27912 +               panic("Segfault with no mm");
27913 +
27914 +       handled = handle_page_fault(address, ip, is_write, is_user, 
27915 +                                   &si.si_code);
27916 +
27917 +       catcher = current->thread.fault_catcher;
27918 +       if(handled)
27919 +               return(0);
27920 +       else if(catcher != NULL){
27921 +               current->thread.fault_addr = (void *) address;
27922 +               do_longjmp(catcher, 1);
27923 +       } 
27924 +       else if(current->thread.fault_addr != NULL)
27925 +               panic("fault_addr set but no fault catcher");
27926 +       else if(arch_fixup(ip, sc))
27927 +               return(0);
27928 +
27929 +       if(!is_user) 
27930 +               panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", 
27931 +                     address, ip);
27932 +       si.si_signo = SIGSEGV;
27933 +       si.si_addr = (void *) address;
27934 +       current->thread.cr2 = address;
27935 +       current->thread.err = is_write;
27936 +       force_sig_info(SIGSEGV, &si, current);
27937 +       return(0);
27938 +}
27939 +
27940 +void bad_segv(unsigned long address, unsigned long ip, int is_write)
27941 +{
27942 +       struct siginfo si;
27943 +
27944 +       si.si_signo = SIGSEGV;
27945 +       si.si_code = SEGV_ACCERR;
27946 +       si.si_addr = (void *) address;
27947 +       current->thread.cr2 = address;
27948 +       current->thread.err = is_write;
27949 +       force_sig_info(SIGSEGV, &si, current);
27950 +}
27951 +
27952 +void relay_signal(int sig, union uml_pt_regs *regs)
27953 +{
27954 +       if(arch_handle_signal(sig, regs)) return;
27955 +       if(!UPT_IS_USER(regs))
27956 +               panic("Kernel mode signal %d", sig);
27957 +       force_sig(sig, current);
27958 +}
27959 +
27960 +void bus_handler(int sig, union uml_pt_regs *regs)
27961 +{
27962 +       if(current->thread.fault_catcher != NULL)
27963 +               do_longjmp(current->thread.fault_catcher, 1);
27964 +       else relay_signal(sig, regs);
27965 +}
27966 +
27967 +void winch(int sig, union uml_pt_regs *regs)
27968 +{
27969 +       do_IRQ(WINCH_IRQ, regs);
27970 +}
27971 +
27972 +void trap_init(void)
27973 +{
27974 +}
27975 +
27976 +spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
27977 +
27978 +static int trap_index = 0;
27979 +
27980 +int next_trap_index(int limit)
27981 +{
27982 +       int ret;
27983 +
27984 +       spin_lock(&trap_lock);
27985 +       ret = trap_index;
27986 +       if(++trap_index == limit)
27987 +               trap_index = 0;
27988 +       spin_unlock(&trap_lock);
27989 +       return(ret);
27990 +}
27991 +
27992 +/*
27993 + * Overrides for Emacs so that we follow Linus's tabbing style.
27994 + * Emacs will notice this stuff at the end of the file and automatically
27995 + * adjust the settings for this buffer only.  This must remain at the end
27996 + * of the file.
27997 + * ---------------------------------------------------------------------------
27998 + * Local variables:
27999 + * c-file-style: "linux"
28000 + * End:
28001 + */
28002 diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_user.c um/arch/um/kernel/trap_user.c
28003 --- orig/arch/um/kernel/trap_user.c     1969-12-31 19:00:00.000000000 -0500
28004 +++ um/arch/um/kernel/trap_user.c       2003-10-21 03:26:07.000000000 -0400
28005 @@ -0,0 +1,138 @@
28006 +/* 
28007 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
28008 + * Licensed under the GPL
28009 + */
28010 +
28011 +#include <stdlib.h>
28012 +#include <errno.h>
28013 +#include <setjmp.h>
28014 +#include <signal.h>
28015 +#include <sys/time.h>
28016 +#include <sys/ptrace.h>
28017 +#include <sys/wait.h>
28018 +#include <asm/page.h>
28019 +#include <asm/unistd.h>
28020 +#include <asm/ptrace.h>
28021 +#include "init.h"
28022 +#include "sysdep/ptrace.h"
28023 +#include "sigcontext.h"
28024 +#include "sysdep/sigcontext.h"
28025 +#include "irq_user.h"
28026 +#include "frame_user.h"
28027 +#include "signal_user.h"
28028 +#include "time_user.h"
28029 +#include "task.h"
28030 +#include "mode.h"
28031 +#include "choose-mode.h"
28032 +#include "kern_util.h"
28033 +#include "user_util.h"
28034 +#include "os.h"
28035 +
28036 +void kill_child_dead(int pid)
28037 +{
28038 +       kill(pid, SIGKILL);
28039 +       kill(pid, SIGCONT);
28040 +       while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
28041 +}
28042 +
28043 +/* Unlocked - don't care if this is a bit off */
28044 +int nsegfaults = 0;
28045 +
28046 +struct {
28047 +       unsigned long address;
28048 +       int is_write;
28049 +       int pid;
28050 +       unsigned long sp;
28051 +       int is_user;
28052 +} segfault_record[1024];
28053 +
28054 +void segv_handler(int sig, union uml_pt_regs *regs)
28055 +{
28056 +       int index, max;
28057 +
28058 +       if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
28059 +               bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), 
28060 +                        UPT_FAULT_WRITE(regs));
28061 +               return;
28062 +       }
28063 +       max = sizeof(segfault_record)/sizeof(segfault_record[0]);
28064 +       index = next_trap_index(max);
28065 +
28066 +       nsegfaults++;
28067 +       segfault_record[index].address = UPT_FAULT_ADDR(regs);
28068 +       segfault_record[index].pid = os_getpid();
28069 +       segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
28070 +       segfault_record[index].sp = UPT_SP(regs);
28071 +       segfault_record[index].is_user = UPT_IS_USER(regs);
28072 +       segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
28073 +            UPT_IS_USER(regs), regs);
28074 +}
28075 +
28076 +void usr2_handler(int sig, union uml_pt_regs *regs)
28077 +{
28078 +       CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
28079 +}
28080 +
28081 +struct signal_info sig_info[] = {
28082 +       [ SIGTRAP ] { .handler          = relay_signal,
28083 +                     .is_irq           = 0 },
28084 +       [ SIGFPE ] { .handler           = relay_signal,
28085 +                    .is_irq            = 0 },
28086 +       [ SIGILL ] { .handler           = relay_signal,
28087 +                    .is_irq            = 0 },
28088 +       [ SIGWINCH ] { .handler         = winch,
28089 +                      .is_irq          = 1 },
28090 +       [ SIGBUS ] { .handler           = bus_handler,
28091 +                    .is_irq            = 0 },
28092 +       [ SIGSEGV] { .handler           = segv_handler,
28093 +                    .is_irq            = 0 },
28094 +       [ SIGIO ] { .handler            = sigio_handler,
28095 +                   .is_irq             = 1 },
28096 +       [ SIGVTALRM ] { .handler        = timer_handler,
28097 +                       .is_irq         = 1 },
28098 +        [ SIGALRM ] { .handler          = timer_handler,
28099 +                      .is_irq           = 1 },
28100 +       [ SIGUSR2 ] { .handler          = usr2_handler,
28101 +                     .is_irq           = 0 },
28102 +};
28103 +
28104 +void sig_handler(int sig, struct sigcontext sc)
28105 +{
28106 +       CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
28107 +                        sig, &sc);
28108 +}
28109 +
28110 +extern int timer_irq_inited, missed_ticks[];
28111 +
28112 +void alarm_handler(int sig, struct sigcontext sc)
28113 +{
28114 +       if(!timer_irq_inited) return;
28115 +       missed_ticks[cpu()]++;
28116 +
28117 +       if(sig == SIGALRM)
28118 +               switch_timers(0);
28119 +
28120 +       CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
28121 +                        sig, &sc);
28122 +
28123 +       if(sig == SIGALRM)
28124 +               switch_timers(1);
28125 +}
28126 +
28127 +void do_longjmp(void *b, int val)
28128 +{
28129 +       jmp_buf *buf = b;
28130 +
28131 +       siglongjmp(*buf, val);
28132 +}
28133 +
28134 +/*
28135 + * Overrides for Emacs so that we follow Linus's tabbing style.
28136 + * Emacs will notice this stuff at the end of the file and automatically
28137 + * adjust the settings for this buffer only.  This must remain at the end
28138 + * of the file.
28139 + * ---------------------------------------------------------------------------
28140 + * Local variables:
28141 + * c-file-style: "linux"
28142 + * End:
28143 + */
28144 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_kern.c um/arch/um/kernel/tt/exec_kern.c
28145 --- orig/arch/um/kernel/tt/exec_kern.c  1969-12-31 19:00:00.000000000 -0500
28146 +++ um/arch/um/kernel/tt/exec_kern.c    2003-11-07 02:23:10.000000000 -0500
28147 @@ -0,0 +1,84 @@
28148 +/* 
28149 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28150 + * Licensed under the GPL
28151 + */
28152 +
28153 +#include "linux/kernel.h"
28154 +#include "linux/mm.h"
28155 +#include "asm/signal.h"
28156 +#include "asm/ptrace.h"
28157 +#include "asm/uaccess.h"
28158 +#include "asm/pgalloc.h"
28159 +#include "user_util.h"
28160 +#include "kern_util.h"
28161 +#include "irq_user.h"
28162 +#include "time_user.h"
28163 +#include "mem_user.h"
28164 +#include "os.h"
28165 +#include "tlb.h"
28166 +#include "mode.h"
28167 +
28168 +static int exec_tramp(void *sig_stack)
28169 +{
28170 +       init_new_thread_stack(sig_stack, NULL);
28171 +       init_new_thread_signals(1);
28172 +       os_stop_process(os_getpid());
28173 +       return(0);
28174 +}
28175 +
28176 +void flush_thread_tt(void)
28177 +{
28178 +       unsigned long stack;
28179 +       int new_pid;
28180 +
28181 +       stack = alloc_stack(0, 0);
28182 +       if(stack == 0){
28183 +               printk(KERN_ERR 
28184 +                      "flush_thread : failed to allocate temporary stack\n");
28185 +               do_exit(SIGKILL);
28186 +       }
28187 +               
28188 +       new_pid = start_fork_tramp((void *) current->thread.kernel_stack,
28189 +                                  stack, 0, exec_tramp);
28190 +       if(new_pid < 0){
28191 +               printk(KERN_ERR 
28192 +                      "flush_thread : new thread failed, errno = %d\n",
28193 +                      -new_pid);
28194 +               do_exit(SIGKILL);
28195 +       }
28196 +
28197 +       if(current->processor == 0)
28198 +               forward_interrupts(new_pid);
28199 +       current->thread.request.op = OP_EXEC;
28200 +       current->thread.request.u.exec.pid = new_pid;
28201 +       unprotect_stack((unsigned long) current);
28202 +       os_usr1_process(os_getpid());
28203 +
28204 +       enable_timer();
28205 +       free_page(stack);
28206 +       protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
28207 +       task_protections((unsigned long) current);
28208 +       force_flush_all();
28209 +       unblock_signals();
28210 +}
28211 +
28212 +void start_thread_tt(struct pt_regs *regs, unsigned long eip, 
28213 +                    unsigned long esp)
28214 +{
28215 +       set_fs(USER_DS);
28216 +       flush_tlb_mm(current->mm);
28217 +       PT_REGS_IP(regs) = eip;
28218 +       PT_REGS_SP(regs) = esp;
28219 +       PT_FIX_EXEC_STACK(esp);
28220 +}
28221 +
28222 +/*
28223 + * Overrides for Emacs so that we follow Linus's tabbing style.
28224 + * Emacs will notice this stuff at the end of the file and automatically
28225 + * adjust the settings for this buffer only.  This must remain at the end
28226 + * of the file.
28227 + * ---------------------------------------------------------------------------
28228 + * Local variables:
28229 + * c-file-style: "linux"
28230 + * End:
28231 + */
28232 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_user.c um/arch/um/kernel/tt/exec_user.c
28233 --- orig/arch/um/kernel/tt/exec_user.c  1969-12-31 19:00:00.000000000 -0500
28234 +++ um/arch/um/kernel/tt/exec_user.c    2003-10-21 03:26:07.000000000 -0400
28235 @@ -0,0 +1,49 @@
28236 +/* 
28237 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
28238 + * Licensed under the GPL
28239 + */
28240 +
28241 +#include <stdio.h>
28242 +#include <unistd.h>
28243 +#include <stdlib.h>
28244 +#include <sched.h>
28245 +#include <errno.h>
28246 +#include <sys/wait.h>
28247 +#include <sys/ptrace.h>
28248 +#include <signal.h>
28249 +#include "user_util.h"
28250 +#include "kern_util.h"
28251 +#include "user.h"
28252 +#include "ptrace_user.h"
28253 +
28254 +void do_exec(int old_pid, int new_pid)
28255 +{
28256 +       unsigned long regs[FRAME_SIZE];
28257 +
28258 +       if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
28259 +          (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) ||
28260 +          (waitpid(new_pid, 0, WUNTRACED) < 0))
28261 +               tracer_panic("do_exec failed to attach proc - errno = %d",
28262 +                            errno);
28263 +
28264 +       if(ptrace_getregs(old_pid, regs) < 0)
28265 +               tracer_panic("do_exec failed to get registers - errno = %d",
28266 +                            errno);
28267 +
28268 +       kill(old_pid, SIGKILL);
28269 +
28270 +       if(ptrace_setregs(new_pid, regs) < 0)
28271 +               tracer_panic("do_exec failed to start new proc - errno = %d",
28272 +                            errno);
28273 +}
28274 +
28275 +/*
28276 + * Overrides for Emacs so that we follow Linus's tabbing style.
28277 + * Emacs will notice this stuff at the end of the file and automatically
28278 + * adjust the settings for this buffer only.  This must remain at the end
28279 + * of the file.
28280 + * ---------------------------------------------------------------------------
28281 + * Local variables:
28282 + * c-file-style: "linux"
28283 + * End:
28284 + */
28285 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb.c um/arch/um/kernel/tt/gdb.c
28286 --- orig/arch/um/kernel/tt/gdb.c        1969-12-31 19:00:00.000000000 -0500
28287 +++ um/arch/um/kernel/tt/gdb.c  2003-10-21 03:26:07.000000000 -0400
28288 @@ -0,0 +1,278 @@
28289 +/* 
28290 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28291 + * Licensed under the GPL
28292 + */
28293 +
28294 +#include <stdio.h>
28295 +#include <stdlib.h>
28296 +#include <errno.h>
28297 +#include <string.h>
28298 +#include <signal.h>
28299 +#include <sys/ptrace.h>
28300 +#include <sys/types.h>
28301 +#include "uml-config.h"
28302 +#include "kern_constants.h"
28303 +#include "chan_user.h"
28304 +#include "init.h"
28305 +#include "user.h"
28306 +#include "debug.h"
28307 +#include "kern_util.h"
28308 +#include "user_util.h"
28309 +#include "tt.h"
28310 +#include "sysdep/thread.h"
28311 +
28312 +extern int debugger_pid;
28313 +extern int debugger_fd;
28314 +extern int debugger_parent;
28315 +
28316 +int detach(int pid, int sig)
28317 +{
28318 +       return(ptrace(PTRACE_DETACH, pid, 0, sig));
28319 +}
28320 +
28321 +int attach(int pid)
28322 +{
28323 +       int err;
28324 +
28325 +       err = ptrace(PTRACE_ATTACH, pid, 0, 0);
28326 +       if(err < 0) return(-errno);
28327 +       else return(err);
28328 +}
28329 +
28330 +int cont(int pid)
28331 +{
28332 +       return(ptrace(PTRACE_CONT, pid, 0, 0));
28333 +}
28334 +
28335 +#ifdef UML_CONFIG_PT_PROXY
28336 +
28337 +int debugger_signal(int status, pid_t pid)
28338 +{
28339 +       return(debugger_proxy(status, pid));
28340 +}
28341 +
28342 +void child_signal(pid_t pid, int status)
28343 +{
28344 +       child_proxy(pid, status);
28345 +}
28346 +
28347 +static void gdb_announce(char *dev_name, int dev)
28348 +{
28349 +       printf("gdb assigned device '%s'\n", dev_name);
28350 +}
28351 +
28352 +static struct chan_opts opts = {
28353 +       .announce       = gdb_announce,
28354 +       .xterm_title    = "UML kernel debugger",
28355 +       .raw            = 0,
28356 +       .tramp_stack    = 0,
28357 +       .in_kernel      = 0,
28358 +};
28359 +
28360 +/* Accessed by the tracing thread, which automatically serializes access */
28361 +static void *xterm_data;
28362 +static int xterm_fd;
28363 +
28364 +extern void *xterm_init(char *, int, struct chan_opts *);
28365 +extern int xterm_open(int, int, int, void *, char **);
28366 +extern void xterm_close(int, void *);
28367 +
28368 +int open_gdb_chan(void)
28369 +{
28370 +       char stack[UM_KERN_PAGE_SIZE], *dummy;
28371 +
28372 +       opts.tramp_stack = (unsigned long) stack;
28373 +       xterm_data = xterm_init("", 0, &opts);
28374 +       xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
28375 +       return(xterm_fd);
28376 +}
28377 +
28378 +static void exit_debugger_cb(void *unused)
28379 +{
28380 +       if(debugger_pid != -1){
28381 +               if(gdb_pid != -1){
28382 +                       fake_child_exit();
28383 +                       gdb_pid = -1;
28384 +               }
28385 +               else kill_child_dead(debugger_pid);
28386 +               debugger_pid = -1;
28387 +               if(debugger_parent != -1)
28388 +                       detach(debugger_parent, SIGINT);
28389 +       }
28390 +       if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
28391 +}
28392 +
28393 +static void exit_debugger(void)
28394 +{
28395 +       initial_thread_cb(exit_debugger_cb, NULL);
28396 +}
28397 +
28398 +__uml_exitcall(exit_debugger);
28399 +
28400 +struct gdb_data {
28401 +       char *str;
28402 +       int err;
28403 +};
28404 +
28405 +static void config_gdb_cb(void *arg)
28406 +{
28407 +       struct gdb_data *data = arg;
28408 +       void *task;
28409 +       int pid;
28410 +
28411 +       data->err = -1;
28412 +       if(debugger_pid != -1) exit_debugger_cb(NULL);
28413 +       if(!strncmp(data->str, "pid,", strlen("pid,"))){
28414 +               data->str += strlen("pid,");
28415 +               pid = strtoul(data->str, NULL, 0);
28416 +               task = cpu_tasks[0].task;
28417 +               debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
28418 +               if(debugger_pid != -1){
28419 +                       data->err = 0;
28420 +                       gdb_pid = pid;
28421 +               }
28422 +               return;
28423 +       }
28424 +       data->err = 0;
28425 +       debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
28426 +       init_proxy(debugger_pid, 0, 0);
28427 +}
28428 +
28429 +int gdb_config(char *str)
28430 +{
28431 +       struct gdb_data data;
28432 +
28433 +       if(*str++ != '=') return(-1);
28434 +       data.str = str;
28435 +       initial_thread_cb(config_gdb_cb, &data);
28436 +       return(data.err);
28437 +}
28438 +
28439 +void remove_gdb_cb(void *unused)
28440 +{
28441 +       exit_debugger_cb(NULL);
28442 +}
28443 +
28444 +int gdb_remove(char *unused)
28445 +{
28446 +       initial_thread_cb(remove_gdb_cb, NULL);
28447 +       return(0);
28448 +}
28449 +
28450 +void signal_usr1(int sig)
28451 +{
28452 +       if(debugger_pid != -1){
28453 +               printk(UM_KERN_ERR "The debugger is already running\n");
28454 +               return;
28455 +       }
28456 +       debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
28457 +       init_proxy(debugger_pid, 0, 0);
28458 +}
28459 +
28460 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
28461 +{
28462 +       int pid, status;
28463 +
28464 +       pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
28465 +       status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
28466 +       if(pid < 0){
28467 +               cont(idle_pid);
28468 +               return(-1);
28469 +       }
28470 +       init_proxy(pid, 1, status);
28471 +       return(pid);
28472 +}
28473 +
28474 +int attach_debugger(int idle_pid, int pid, int stop)
28475 +{
28476 +       int status = 0, err;
28477 +
28478 +       err = attach(pid);
28479 +       if(err < 0){
28480 +               printf("Failed to attach pid %d, errno = %d\n", pid, -err);
28481 +               return(-1);
28482 +       }
28483 +       if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
28484 +       init_proxy(pid, 1, status);
28485 +       return(pid);
28486 +}
28487 +
28488 +#ifdef notdef /* Put this back in when it does something useful */
28489 +static int __init uml_gdb_init_setup(char *line, int *add)
28490 +{
28491 +       gdb_init = uml_strdup(line);
28492 +       return 0;
28493 +}
28494 +
28495 +__uml_setup("gdb=", uml_gdb_init_setup, 
28496 +"gdb=<channel description>\n\n"
28497 +);
28498 +#endif
28499 +
28500 +static int __init uml_gdb_pid_setup(char *line, int *add)
28501 +{
28502 +       gdb_pid = strtoul(line, NULL, 0);
28503 +       *add = 0;
28504 +       return 0;
28505 +}
28506 +
28507 +__uml_setup("gdb-pid=", uml_gdb_pid_setup, 
28508 +"gdb-pid=<pid>\n"
28509 +"    gdb-pid is used to attach an external debugger to UML.  This may be\n"
28510 +"    an already-running gdb or a debugger-like process like strace.\n\n"
28511 +);
28512 +
28513 +#else
28514 +
28515 +int debugger_signal(int status, pid_t pid){ return(0); }
28516 +void child_signal(pid_t pid, int status){ }
28517 +int init_ptrace_proxy(int idle_pid, int startup, int stop)
28518 +{
28519 +       printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
28520 +       kill_child_dead(idle_pid);
28521 +       exit(1);
28522 +}
28523 +
28524 +void signal_usr1(int sig)
28525 +{
28526 +       printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
28527 +}
28528 +
28529 +int attach_debugger(int idle_pid, int pid, int stop)
28530 +{
28531 +       printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
28532 +              "is off\n");
28533 +       return(-1);
28534 +}
28535 +
28536 +int config_gdb(char *str)
28537 +{
28538 +       return(-1);
28539 +}
28540 +
28541 +int remove_gdb(void)
28542 +{
28543 +       return(-1);
28544 +}
28545 +
28546 +int init_parent_proxy(int pid)
28547 +{
28548 +       return(-1);
28549 +}
28550 +
28551 +void debugger_parent_signal(int status, int pid)
28552 +{
28553 +}
28554 +
28555 +#endif
28556 +
28557 +/*
28558 + * Overrides for Emacs so that we follow Linus's tabbing style.
28559 + * Emacs will notice this stuff at the end of the file and automatically
28560 + * adjust the settings for this buffer only.  This must remain at the end
28561 + * of the file.
28562 + * ---------------------------------------------------------------------------
28563 + * Local variables:
28564 + * c-file-style: "linux"
28565 + * End:
28566 + */
28567 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb_kern.c um/arch/um/kernel/tt/gdb_kern.c
28568 --- orig/arch/um/kernel/tt/gdb_kern.c   1969-12-31 19:00:00.000000000 -0500
28569 +++ um/arch/um/kernel/tt/gdb_kern.c     2003-10-21 03:26:07.000000000 -0400
28570 @@ -0,0 +1,40 @@
28571 +/* 
28572 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28573 + * Licensed under the GPL
28574 + */
28575 +
28576 +#include "linux/init.h"
28577 +#include "linux/config.h"
28578 +#include "mconsole_kern.h"
28579 +
28580 +#ifdef CONFIG_MCONSOLE
28581 +
28582 +extern int gdb_config(char *str);
28583 +extern int gdb_remove(char *unused);
28584 +
28585 +static struct mc_device gdb_mc = {
28586 +       .name           = "gdb",
28587 +       .config         = gdb_config,
28588 +       .remove         = gdb_remove,
28589 +};
28590 +
28591 +int gdb_mc_init(void)
28592 +{
28593 +       mconsole_register_dev(&gdb_mc);
28594 +       return(0);
28595 +}
28596 +
28597 +__initcall(gdb_mc_init);
28598 +
28599 +#endif
28600 +
28601 +/*
28602 + * Overrides for Emacs so that we follow Linus's tabbing style.
28603 + * Emacs will notice this stuff at the end of the file and automatically
28604 + * adjust the settings for this buffer only.  This must remain at the end
28605 + * of the file.
28606 + * ---------------------------------------------------------------------------
28607 + * Local variables:
28608 + * c-file-style: "linux"
28609 + * End:
28610 + */
28611 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/debug.h um/arch/um/kernel/tt/include/debug.h
28612 --- orig/arch/um/kernel/tt/include/debug.h      1969-12-31 19:00:00.000000000 -0500
28613 +++ um/arch/um/kernel/tt/include/debug.h        2003-10-21 03:26:07.000000000 -0400
28614 @@ -0,0 +1,29 @@
28615 +/* 
28616 + * Copyright (C) 2000, 2001, 2002  Jeff Dike (jdike@karaya.com) and
28617 + * Lars Brinkhoff.
28618 + * Licensed under the GPL
28619 + */
28620 +
28621 +#ifndef __DEBUG_H
28622 +#define __DEBUG_H
28623 +
28624 +extern int debugger_proxy(int status, pid_t pid);
28625 +extern void child_proxy(pid_t pid, int status);
28626 +extern void init_proxy (pid_t pid, int waiting, int status);
28627 +extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
28628 +extern void fake_child_exit(void);
28629 +extern int gdb_config(char *str);
28630 +extern int gdb_remove(char *unused);
28631 +
28632 +#endif
28633 +
28634 +/*
28635 + * Overrides for Emacs so that we follow Linus's tabbing style.
28636 + * Emacs will notice this stuff at the end of the file and automatically
28637 + * adjust the settings for this buffer only.  This must remain at the end
28638 + * of the file.
28639 + * ---------------------------------------------------------------------------
28640 + * Local variables:
28641 + * c-file-style: "linux"
28642 + * End:
28643 + */
28644 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mmu.h um/arch/um/kernel/tt/include/mmu.h
28645 --- orig/arch/um/kernel/tt/include/mmu.h        1969-12-31 19:00:00.000000000 -0500
28646 +++ um/arch/um/kernel/tt/include/mmu.h  2003-10-21 03:26:07.000000000 -0400
28647 @@ -0,0 +1,23 @@
28648 +/* 
28649 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28650 + * Licensed under the GPL
28651 + */
28652 +
28653 +#ifndef __TT_MMU_H
28654 +#define __TT_MMU_H
28655 +
28656 +struct mmu_context_tt {
28657 +};
28658 +
28659 +#endif
28660 +
28661 +/*
28662 + * Overrides for Emacs so that we follow Linus's tabbing style.
28663 + * Emacs will notice this stuff at the end of the file and automatically
28664 + * adjust the settings for this buffer only.  This must remain at the end
28665 + * of the file.
28666 + * ---------------------------------------------------------------------------
28667 + * Local variables:
28668 + * c-file-style: "linux"
28669 + * End:
28670 + */
28671 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode.h um/arch/um/kernel/tt/include/mode.h
28672 --- orig/arch/um/kernel/tt/include/mode.h       1969-12-31 19:00:00.000000000 -0500
28673 +++ um/arch/um/kernel/tt/include/mode.h 2003-11-07 01:42:09.000000000 -0500
28674 @@ -0,0 +1,38 @@
28675 +/* 
28676 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28677 + * Licensed under the GPL
28678 + */
28679 +
28680 +#ifndef __MODE_TT_H__
28681 +#define __MODE_TT_H__
28682 +
28683 +#include "sysdep/ptrace.h"
28684 +
28685 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
28686 +
28687 +extern int tracing_pid;
28688 +
28689 +extern int tracer(int (*init_proc)(void *), void *sp);
28690 +extern void user_time_init_tt(void);
28691 +extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
28692 +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, 
28693 +                             void *data);
28694 +extern void sig_handler_common_tt(int sig, void *sc);
28695 +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
28696 +extern void reboot_tt(void);
28697 +extern void halt_tt(void);
28698 +extern int is_tracer_winch(int pid, int fd, void *data);
28699 +extern void kill_off_processes_tt(void);
28700 +
28701 +#endif
28702 +
28703 +/*
28704 + * Overrides for Emacs so that we follow Linus's tabbing style.
28705 + * Emacs will notice this stuff at the end of the file and automatically
28706 + * adjust the settings for this buffer only.  This must remain at the end
28707 + * of the file.
28708 + * ---------------------------------------------------------------------------
28709 + * Local variables:
28710 + * c-file-style: "linux"
28711 + * End:
28712 + */
28713 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode_kern.h um/arch/um/kernel/tt/include/mode_kern.h
28714 --- orig/arch/um/kernel/tt/include/mode_kern.h  1969-12-31 19:00:00.000000000 -0500
28715 +++ um/arch/um/kernel/tt/include/mode_kern.h    2003-10-21 03:26:07.000000000 -0400
28716 @@ -0,0 +1,52 @@
28717 +/* 
28718 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28719 + * Licensed under the GPL
28720 + */
28721 +
28722 +#ifndef __TT_MODE_KERN_H__
28723 +#define __TT_MODE_KERN_H__
28724 +
28725 +#include "linux/sched.h"
28726 +#include "asm/page.h"
28727 +#include "asm/ptrace.h"
28728 +#include "asm/uaccess.h"
28729 +
28730 +extern void *_switch_to_tt(void *prev, void *next);
28731 +extern void flush_thread_tt(void);
28732 +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, 
28733 +                          unsigned long esp);
28734 +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
28735 +                         unsigned long stack_top, struct task_struct *p, 
28736 +                         struct pt_regs *regs);
28737 +extern void release_thread_tt(struct task_struct *task);
28738 +extern void exit_thread_tt(void);
28739 +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
28740 +extern void init_idle_tt(void);
28741 +extern void flush_tlb_kernel_vm_tt(void);
28742 +extern void __flush_tlb_one_tt(unsigned long addr);
28743 +extern void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, 
28744 +                              unsigned long end);
28745 +extern void flush_tlb_mm_tt(struct mm_struct *mm);
28746 +extern void force_flush_all_tt(void);
28747 +extern long execute_syscall_tt(void *r);
28748 +extern void before_mem_tt(unsigned long brk_start);
28749 +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
28750 +                                      unsigned long *task_size_out);
28751 +extern int start_uml_tt(void);
28752 +extern int external_pid_tt(struct task_struct *task);
28753 +extern int thread_pid_tt(struct thread_struct *thread);
28754 +
28755 +#define kmem_end_tt (host_task_size - ABOVE_KMEM)
28756 +
28757 +#endif
28758 +
28759 +/*
28760 + * Overrides for Emacs so that we follow Linus's tabbing style.
28761 + * Emacs will notice this stuff at the end of the file and automatically
28762 + * adjust the settings for this buffer only.  This must remain at the end
28763 + * of the file.
28764 + * ---------------------------------------------------------------------------
28765 + * Local variables:
28766 + * c-file-style: "linux"
28767 + * End:
28768 + */
28769 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/ptrace-tt.h um/arch/um/kernel/tt/include/ptrace-tt.h
28770 --- orig/arch/um/kernel/tt/include/ptrace-tt.h  1969-12-31 19:00:00.000000000 -0500
28771 +++ um/arch/um/kernel/tt/include/ptrace-tt.h    2003-10-21 03:26:07.000000000 -0400
28772 @@ -0,0 +1,26 @@
28773 +/* 
28774 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
28775 + * Licensed under the GPL
28776 + */
28777 +
28778 +#ifndef __PTRACE_TT_H
28779 +#define __PTRACE_TT_H
28780 +
28781 +#include "uml-config.h"
28782 +
28783 +#ifdef UML_CONFIG_MODE_TT
28784 +#include "sysdep/sc.h"
28785 +#endif
28786 +
28787 +#endif
28788 +
28789 +/*
28790 + * Overrides for Emacs so that we follow Linus's tabbing style.
28791 + * Emacs will notice this stuff at the end of the file and automatically
28792 + * adjust the settings for this buffer only.  This must remain at the end
28793 + * of the file.
28794 + * ---------------------------------------------------------------------------
28795 + * Local variables:
28796 + * c-file-style: "linux"
28797 + * End:
28798 + */
28799 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/tt.h um/arch/um/kernel/tt/include/tt.h
28800 --- orig/arch/um/kernel/tt/include/tt.h 1969-12-31 19:00:00.000000000 -0500
28801 +++ um/arch/um/kernel/tt/include/tt.h   2003-10-21 03:26:07.000000000 -0400
28802 @@ -0,0 +1,46 @@
28803 +/* 
28804 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
28805 + * Licensed under the GPL
28806 + */
28807 +
28808 +#ifndef __TT_H__
28809 +#define __TT_H__
28810 +
28811 +#include "sysdep/ptrace.h"
28812 +
28813 +extern int gdb_pid;
28814 +extern int debug;
28815 +extern int debug_stop;
28816 +extern int debug_trace;
28817 +
28818 +extern int honeypot;
28819 +
28820 +extern int fork_tramp(void *sig_stack);
28821 +extern int do_proc_op(void *t, int proc_id);
28822 +extern int tracer(int (*init_proc)(void *), void *sp);
28823 +extern void attach_process(int pid);
28824 +extern void tracer_panic(char *format, ...);
28825 +extern void set_init_pid(int pid);
28826 +extern int set_user_mode(void *task);
28827 +extern void set_tracing(void *t, int tracing);
28828 +extern int is_tracing(void *task);
28829 +extern int singlestepping_tt(void *t);
28830 +extern void clear_singlestep(void *t);
28831 +extern void syscall_handler(int sig, union uml_pt_regs *regs);
28832 +extern void exit_kernel(int pid, void *task);
28833 +extern int do_syscall(void *task, int pid);
28834 +extern int is_valid_pid(int pid);
28835 +extern void remap_data(void *segment_start, void *segment_end, int w);
28836 +
28837 +#endif
28838 +
28839 +/*
28840 + * Overrides for Emacs so that we follow Linus's tabbing style.
28841 + * Emacs will notice this stuff at the end of the file and automatically
28842 + * adjust the settings for this buffer only.  This must remain at the end
28843 + * of the file.
28844 + * ---------------------------------------------------------------------------
28845 + * Local variables:
28846 + * c-file-style: "linux"
28847 + * End:
28848 + */
28849 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/uaccess.h um/arch/um/kernel/tt/include/uaccess.h
28850 --- orig/arch/um/kernel/tt/include/uaccess.h    1969-12-31 19:00:00.000000000 -0500
28851 +++ um/arch/um/kernel/tt/include/uaccess.h      2003-11-12 08:37:20.000000000 -0500
28852 @@ -0,0 +1,71 @@
28853 +/* 
28854 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
28855 + * Licensed under the GPL
28856 + */
28857 +
28858 +#ifndef __TT_UACCESS_H
28859 +#define __TT_UACCESS_H
28860 +
28861 +#include "linux/string.h"
28862 +#include "linux/sched.h"
28863 +#include "asm/processor.h"
28864 +#include "asm/errno.h"
28865 +#include "asm/current.h"
28866 +#include "asm/a.out.h"
28867 +#include "uml_uaccess.h"
28868 +
28869 +#define ABOVE_KMEM (16 * 1024 * 1024)
28870 +
28871 +extern unsigned long end_vm;
28872 +extern unsigned long uml_physmem;
28873 +
28874 +#define under_task_size(addr, size) \
28875 +       (((unsigned long) (addr) < TASK_SIZE) && \
28876 +         (((unsigned long) (addr) + (size)) < TASK_SIZE))
28877 +
28878 +#define is_stack(addr, size) \
28879 +       (((unsigned long) (addr) < STACK_TOP) && \
28880 +        ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
28881 +        (((unsigned long) (addr) + (size)) <= STACK_TOP))
28882 +
28883 +#define access_ok_tt(type, addr, size) \
28884 +       ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
28885 +         (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
28886 +          (under_task_size(addr, size) || is_stack(addr, size))))
28887 +
28888 +static inline int verify_area_tt(int type, const void * addr, 
28889 +                                unsigned long size)
28890 +{
28891 +       return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
28892 +}
28893 +
28894 +extern unsigned long get_fault_addr(void);
28895 +
28896 +extern int __do_copy_from_user(void *to, const void *from, int n,
28897 +                              void **fault_addr, void **fault_catcher);
28898 +extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
28899 +                                 void **fault_addr, void **fault_catcher);
28900 +extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
28901 +                          void **fault_catcher);
28902 +extern int __do_strnlen_user(const char *str, unsigned long n,
28903 +                            void **fault_addr, void **fault_catcher);
28904 +
28905 +extern int copy_from_user_tt(void *to, const void *from, int n);
28906 +extern int copy_to_user_tt(void *to, const void *from, int n);
28907 +extern int strncpy_from_user_tt(char *dst, const char *src, int count);
28908 +extern int __clear_user_tt(void *mem, int len);
28909 +extern int clear_user_tt(void *mem, int len);
28910 +extern int strnlen_user_tt(const void *str, int len);
28911 +
28912 +#endif
28913 +
28914 +/*
28915 + * Overrides for Emacs so that we follow Linus's tabbing style.
28916 + * Emacs will notice this stuff at the end of the file and automatically
28917 + * adjust the settings for this buffer only.  This must remain at the end
28918 + * of the file.
28919 + * ---------------------------------------------------------------------------
28920 + * Local variables:
28921 + * c-file-style: "linux"
28922 + * End:
28923 + */
28924 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ksyms.c um/arch/um/kernel/tt/ksyms.c
28925 --- orig/arch/um/kernel/tt/ksyms.c      1969-12-31 19:00:00.000000000 -0500
28926 +++ um/arch/um/kernel/tt/ksyms.c        2003-10-21 03:26:07.000000000 -0400
28927 @@ -0,0 +1,28 @@
28928 +/* 
28929 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
28930 + * Licensed under the GPL
28931 + */
28932 +
28933 +#include "linux/module.h"
28934 +#include "asm/uaccess.h"
28935 +#include "mode.h"
28936 +
28937 +EXPORT_SYMBOL(__do_copy_from_user);
28938 +EXPORT_SYMBOL(__do_copy_to_user);
28939 +EXPORT_SYMBOL(__do_strncpy_from_user);
28940 +EXPORT_SYMBOL(__do_strnlen_user); 
28941 +EXPORT_SYMBOL(__do_clear_user);
28942 +
28943 +EXPORT_SYMBOL(tracing_pid);
28944 +EXPORT_SYMBOL(honeypot);
28945 +
28946 +/*
28947 + * Overrides for Emacs so that we follow Linus's tabbing style.
28948 + * Emacs will notice this stuff at the end of the file and automatically
28949 + * adjust the settings for this buffer only.  This must remain at the end
28950 + * of the file.
28951 + * ---------------------------------------------------------------------------
28952 + * Local variables:
28953 + * c-file-style: "linux"
28954 + * End:
28955 + */
28956 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/Makefile um/arch/um/kernel/tt/Makefile
28957 --- orig/arch/um/kernel/tt/Makefile     1969-12-31 19:00:00.000000000 -0500
28958 +++ um/arch/um/kernel/tt/Makefile       2003-11-12 08:34:27.000000000 -0500
28959 @@ -0,0 +1,39 @@
28960 +# 
28961 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
28962 +# Licensed under the GPL
28963 +#
28964 +
28965 +O_TARGET = tt.o
28966 +
28967 +obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
28968 +       syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
28969 +       uaccess.o uaccess_user.o
28970 +
28971 +obj-$(CONFIG_PT_PROXY) += gdb_kern.o 
28972 +
28973 +subdir-y = sys-$(SUBARCH)
28974 +subdir-$(CONFIG_PT_PROXY) += ptproxy
28975 +
28976 +obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
28977 +
28978 +export-objs = ksyms.o
28979 +
28980 +USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
28981 +
28982 +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
28983 +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
28984 +
28985 +include $(TOPDIR)/Rules.make
28986 +
28987 +$(USER_OBJS) : %.o: %.c
28988 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
28989 +
28990 +$(O_TARGET) : unmap_fin.o
28991 +
28992 +unmap.o: unmap.c
28993 +       $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
28994 +
28995 +unmap_fin.o : unmap.o
28996 +       ld -r -o $@ $< -lc -L/usr/lib
28997 +
28998 +clean :
28999 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem.c um/arch/um/kernel/tt/mem.c
29000 --- orig/arch/um/kernel/tt/mem.c        1969-12-31 19:00:00.000000000 -0500
29001 +++ um/arch/um/kernel/tt/mem.c  2003-10-21 03:26:07.000000000 -0400
29002 @@ -0,0 +1,51 @@
29003 +/* 
29004 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29005 + * Licensed under the GPL
29006 + */
29007 +
29008 +#include "linux/stddef.h"
29009 +#include "linux/config.h"
29010 +#include "linux/mm.h"
29011 +#include "asm/uaccess.h"
29012 +#include "mem_user.h"
29013 +#include "kern_util.h"
29014 +#include "user_util.h"
29015 +#include "kern.h"
29016 +#include "tt.h"
29017 +
29018 +void before_mem_tt(unsigned long brk_start)
29019 +{
29020 +       if(!jail || debug)
29021 +               remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
29022 +       remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
29023 +       remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(brk_start), 1);
29024 +}
29025 +
29026 +#ifdef CONFIG_HOST_2G_2G
29027 +#define TOP 0x80000000
29028 +#else
29029 +#define TOP 0xc0000000
29030 +#endif
29031 +
29032 +#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
29033 +#define START (TOP - SIZE)
29034 +
29035 +unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, 
29036 +                               unsigned long *task_size_out)
29037 +{
29038 +       /* Round up to the nearest 4M */
29039 +       *host_size_out = ROUND_4M((unsigned long) &arg);
29040 +       *task_size_out = START;
29041 +       return(START);
29042 +}
29043 +
29044 +/*
29045 + * Overrides for Emacs so that we follow Linus's tabbing style.
29046 + * Emacs will notice this stuff at the end of the file and automatically
29047 + * adjust the settings for this buffer only.  This must remain at the end
29048 + * of the file.
29049 + * ---------------------------------------------------------------------------
29050 + * Local variables:
29051 + * c-file-style: "linux"
29052 + * End:
29053 + */
29054 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem_user.c um/arch/um/kernel/tt/mem_user.c
29055 --- orig/arch/um/kernel/tt/mem_user.c   1969-12-31 19:00:00.000000000 -0500
29056 +++ um/arch/um/kernel/tt/mem_user.c     2003-10-21 03:26:07.000000000 -0400
29057 @@ -0,0 +1,49 @@
29058 +/* 
29059 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29060 + * Licensed under the GPL
29061 + */
29062 +
29063 +#include <stdlib.h>
29064 +#include <stdio.h>
29065 +#include <unistd.h>
29066 +#include <string.h>
29067 +#include <errno.h>
29068 +#include <sys/mman.h>
29069 +#include "tt.h"
29070 +#include "mem_user.h"
29071 +#include "user_util.h"
29072 +
29073 +void remap_data(void *segment_start, void *segment_end, int w)
29074 +{
29075 +       void *addr;
29076 +       unsigned long size;
29077 +       int data, prot;
29078 +
29079 +       if(w) prot = PROT_WRITE;
29080 +       else prot = 0;
29081 +       prot |= PROT_READ | PROT_EXEC;
29082 +       size = (unsigned long) segment_end - 
29083 +               (unsigned long) segment_start;
29084 +       data = create_mem_file(size);
29085 +       addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
29086 +       if(addr == MAP_FAILED){
29087 +               perror("mapping new data segment");
29088 +               exit(1);
29089 +       }
29090 +       memcpy(addr, segment_start, size);
29091 +       if(switcheroo(data, prot, addr, segment_start, size) < 0){
29092 +               printf("switcheroo failed\n");
29093 +               exit(1);
29094 +       }
29095 +}
29096 +
29097 +/*
29098 + * Overrides for Emacs so that we follow Linus's tabbing style.
29099 + * Emacs will notice this stuff at the end of the file and automatically
29100 + * adjust the settings for this buffer only.  This must remain at the end
29101 + * of the file.
29102 + * ---------------------------------------------------------------------------
29103 + * Local variables:
29104 + * c-file-style: "linux"
29105 + * End:
29106 + */
29107 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/process_kern.c um/arch/um/kernel/tt/process_kern.c
29108 --- orig/arch/um/kernel/tt/process_kern.c       1969-12-31 19:00:00.000000000 -0500
29109 +++ um/arch/um/kernel/tt/process_kern.c 2003-10-21 03:26:07.000000000 -0400
29110 @@ -0,0 +1,537 @@
29111 +/* 
29112 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
29113 + * Licensed under the GPL
29114 + */
29115 +
29116 +#include "linux/sched.h"
29117 +#include "linux/signal.h"
29118 +#include "linux/kernel.h"
29119 +#include "asm/system.h"
29120 +#include "asm/pgalloc.h"
29121 +#include "asm/ptrace.h"
29122 +#include "irq_user.h"
29123 +#include "signal_user.h"
29124 +#include "kern_util.h"
29125 +#include "user_util.h"
29126 +#include "os.h"
29127 +#include "kern.h"
29128 +#include "sigcontext.h"
29129 +#include "time_user.h"
29130 +#include "mem_user.h"
29131 +#include "tlb.h"
29132 +#include "mode.h"
29133 +#include "init.h"
29134 +#include "tt.h"
29135 +
29136 +void *_switch_to_tt(void *prev, void *next)
29137 +{
29138 +       struct task_struct *from, *to;
29139 +       unsigned long flags;
29140 +       int err, vtalrm, alrm, prof, cpu;
29141 +       char c;
29142 +       /* jailing and SMP are incompatible, so this doesn't need to be 
29143 +        * made per-cpu 
29144 +        */
29145 +       static int reading;
29146 +
29147 +       from = prev;
29148 +       to = next;
29149 +
29150 +       to->thread.prev_sched = from;
29151 +
29152 +       cpu = from->processor;
29153 +       if(cpu == 0)
29154 +               forward_interrupts(to->thread.mode.tt.extern_pid);
29155 +#ifdef CONFIG_SMP
29156 +       forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
29157 +#endif
29158 +       local_irq_save(flags);
29159 +
29160 +       vtalrm = change_sig(SIGVTALRM, 0);
29161 +       alrm = change_sig(SIGALRM, 0);
29162 +       prof = change_sig(SIGPROF, 0);
29163 +
29164 +       c = 0;
29165 +       set_current(to);
29166 +
29167 +       reading = 0;
29168 +       err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
29169 +       if(err != sizeof(c))
29170 +               panic("write of switch_pipe failed, err = %d", -err);
29171 +
29172 +       reading = 1;
29173 +       if(from->state == TASK_ZOMBIE)
29174 +               os_kill_process(os_getpid(), 0);
29175 +
29176 +       err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
29177 +       if(err != sizeof(c))
29178 +               panic("read of switch_pipe failed, errno = %d", -err);
29179 +
29180 +       /* This works around a nasty race with 'jail'.  If we are switching
29181 +        * between two threads of a threaded app and the incoming process 
29182 +        * runs before the outgoing process reaches the read, and it makes
29183 +        * it all the way out to userspace, then it will have write-protected 
29184 +        * the outgoing process stack.  Then, when the outgoing process 
29185 +        * returns from the write, it will segfault because it can no longer
29186 +        * write its own stack.  So, in order to avoid that, the incoming 
29187 +        * thread sits in a loop yielding until 'reading' is set.  This 
29188 +        * isn't entirely safe, since there may be a reschedule from a timer
29189 +        * happening between setting 'reading' and sleeping in read.  But,
29190 +        * it should get a whole quantum in which to reach the read and sleep,
29191 +        * which should be enough.
29192 +        */
29193 +
29194 +       if(jail){
29195 +               while(!reading) sched_yield();
29196 +       }
29197 +
29198 +       change_sig(SIGVTALRM, vtalrm);
29199 +       change_sig(SIGALRM, alrm);
29200 +       change_sig(SIGPROF, prof);
29201 +
29202 +       arch_switch();
29203 +
29204 +       flush_tlb_all();
29205 +       local_irq_restore(flags);
29206 +
29207 +       return(current->thread.prev_sched);
29208 +}
29209 +
29210 +void release_thread_tt(struct task_struct *task)
29211 +{
29212 +       os_kill_process(task->thread.mode.tt.extern_pid, 0);
29213 +}
29214 +
29215 +void exit_thread_tt(void)
29216 +{
29217 +       os_close_file(current->thread.mode.tt.switch_pipe[0]);
29218 +       os_close_file(current->thread.mode.tt.switch_pipe[1]);
29219 +}
29220 +
29221 +extern void schedule_tail(struct task_struct *prev);
29222 +
29223 +static void new_thread_handler(int sig)
29224 +{
29225 +       unsigned long disable;
29226 +       int (*fn)(void *);
29227 +       void *arg;
29228 +
29229 +       fn = current->thread.request.u.thread.proc;
29230 +       arg = current->thread.request.u.thread.arg;
29231 +
29232 +       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
29233 +       disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
29234 +               (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
29235 +       SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
29236 +
29237 +       suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
29238 +
29239 +       init_new_thread_signals(1);
29240 +       enable_timer();
29241 +       free_page(current->thread.temp_stack);
29242 +       set_cmdline("(kernel thread)");
29243 +       force_flush_all();
29244 +
29245 +       if(current->thread.prev_sched != NULL)
29246 +               schedule_tail(current->thread.prev_sched);
29247 +       current->thread.prev_sched = NULL;
29248 +
29249 +       change_sig(SIGUSR1, 1);
29250 +       change_sig(SIGVTALRM, 1);
29251 +       change_sig(SIGPROF, 1);
29252 +       sti();
29253 +       if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
29254 +               do_exit(0);
29255 +}
29256 +
29257 +static int new_thread_proc(void *stack)
29258 +{
29259 +       /* cli is needed to block out signals until this thread is properly
29260 +        * scheduled.  Otherwise, the tracing thread will get mighty upset 
29261 +        * about any signals that arrive before that.  
29262 +        * This has the complication that it sets the saved signal mask in
29263 +        * the sigcontext to block signals.  This gets restored when this
29264 +        * thread (or a descendant, since they get a copy of this sigcontext)
29265 +        * returns to userspace.
29266 +        * So, this is compensated for elsewhere.
29267 +        * XXX There is still a small window until cli() actually finishes
29268 +        * where signals are possible - shouldn't be a problem in practice 
29269 +        * since SIGIO hasn't been forwarded here yet, and the cli should 
29270 +        * finish before a SIGVTALRM has time to be delivered.
29271 +        */
29272 +       cli();
29273 +       init_new_thread_stack(stack, new_thread_handler);
29274 +       os_usr1_process(os_getpid());
29275 +       return(0);
29276 +}
29277 +
29278 +/* Signal masking - signals are blocked at the start of fork_tramp.  They
29279 + * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
29280 + * itself with a SIGUSR1.  set_user_mode has to be run with SIGUSR1 off,
29281 + * so it is blocked before it's called.  They are re-enabled on sigreturn
29282 + * despite the fact that they were blocked when the SIGUSR1 was issued because
29283 + * copy_thread copies the parent's sigcontext, including the signal mask
29284 + * onto the signal frame.
29285 + */
29286 +
29287 +static void finish_fork_handler(int sig)
29288 +{
29289 +       UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
29290 +       suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
29291 +       
29292 +       init_new_thread_signals(1);
29293 +       enable_timer();
29294 +       sti();
29295 +       force_flush_all();
29296 +       if(current->mm != current->p_pptr->mm)
29297 +               protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
29298 +                              1, 0, 1);
29299 +       task_protections((unsigned long) current);
29300 +
29301 +       if(current->thread.prev_sched != NULL)
29302 +               schedule_tail(current->thread.prev_sched);
29303 +       current->thread.prev_sched = NULL;
29304 +
29305 +       free_page(current->thread.temp_stack);
29306 +       cli();
29307 +       change_sig(SIGUSR1, 0);
29308 +       set_user_mode(current);
29309 +}
29310 +
29311 +int fork_tramp(void *stack)
29312 +{
29313 +       cli();
29314 +       arch_init_thread();
29315 +       init_new_thread_stack(stack, finish_fork_handler);
29316 +       os_usr1_process(os_getpid());
29317 +       return(0);
29318 +}
29319 +
29320 +int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
29321 +                  unsigned long stack_top, struct task_struct * p, 
29322 +                  struct pt_regs *regs)
29323 +{
29324 +       int (*tramp)(void *);
29325 +       int new_pid, err;
29326 +       unsigned long stack;
29327 +       
29328 +       if(current->thread.forking)
29329 +               tramp = fork_tramp;
29330 +       else {
29331 +               tramp = new_thread_proc;
29332 +               p->thread.request.u.thread = current->thread.request.u.thread;
29333 +       }
29334 +
29335 +       err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
29336 +       if(err < 0){
29337 +               printk("copy_thread : pipe failed, err = %d\n", -err);
29338 +               return(err);
29339 +       }
29340 +
29341 +       stack = alloc_stack(0, 0);
29342 +       if(stack == 0){
29343 +               printk(KERN_ERR "copy_thread : failed to allocate "
29344 +                      "temporary stack\n");
29345 +               return(-ENOMEM);
29346 +       }
29347 +
29348 +       clone_flags &= CLONE_VM;
29349 +       p->thread.temp_stack = stack;
29350 +       new_pid = start_fork_tramp((void *) p->thread.kernel_stack, stack,
29351 +                                  clone_flags, tramp);
29352 +       if(new_pid < 0){
29353 +               printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", 
29354 +                      -new_pid);
29355 +               return(new_pid);
29356 +       }
29357 +
29358 +       if(current->thread.forking){
29359 +               sc_to_sc(UPT_SC(&p->thread.regs.regs), 
29360 +                        UPT_SC(&current->thread.regs.regs));
29361 +               SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
29362 +               if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
29363 +       }
29364 +       p->thread.mode.tt.extern_pid = new_pid;
29365 +
29366 +       current->thread.request.op = OP_FORK;
29367 +       current->thread.request.u.fork.pid = new_pid;
29368 +       os_usr1_process(os_getpid());
29369 +       return(0);
29370 +}
29371 +
29372 +void reboot_tt(void)
29373 +{
29374 +       current->thread.request.op = OP_REBOOT;
29375 +       os_usr1_process(os_getpid());
29376 +       os_kill_process(os_getpid(), 0);
29377 +}
29378 +
29379 +void halt_tt(void)
29380 +{
29381 +       current->thread.request.op = OP_HALT;
29382 +       os_usr1_process(os_getpid());
29383 +       os_kill_process(os_getpid(), 0);
29384 +}
29385 +
29386 +void kill_off_processes_tt(void)
29387 +{
29388 +       struct task_struct *p;
29389 +       int me;
29390 +
29391 +       me = os_getpid();
29392 +       for_each_task(p){
29393 +               int pid = p->thread.mode.tt.extern_pid;
29394 +               if((pid != me) && (pid != -1))
29395 +                       os_kill_process(p->thread.mode.tt.extern_pid, 0);
29396 +       }
29397 +       if((init_task.thread.mode.tt.extern_pid != me) &&
29398 +          (init_task.thread.mode.tt.extern_pid != -1))
29399 +               os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
29400 +}
29401 +
29402 +void initial_thread_cb_tt(void (*proc)(void *), void *arg)
29403 +{
29404 +       if(os_getpid() == tracing_pid){
29405 +               (*proc)(arg);
29406 +       }
29407 +       else {
29408 +               current->thread.request.op = OP_CB;
29409 +               current->thread.request.u.cb.proc = proc;
29410 +               current->thread.request.u.cb.arg = arg;
29411 +               os_usr1_process(os_getpid());
29412 +       }
29413 +}
29414 +
29415 +int do_proc_op(void *t, int proc_id)
29416 +{
29417 +       struct task_struct *task;
29418 +       struct thread_struct *thread;
29419 +       int op, pid;
29420 +
29421 +       task = t;
29422 +       thread = &task->thread;
29423 +       op = thread->request.op;
29424 +       switch(op){
29425 +       case OP_NONE:
29426 +       case OP_TRACE_ON:
29427 +               break;
29428 +       case OP_EXEC:
29429 +               pid = thread->request.u.exec.pid;
29430 +               do_exec(thread->mode.tt.extern_pid, pid);
29431 +               thread->mode.tt.extern_pid = pid;
29432 +               cpu_tasks[task->processor].pid = pid;
29433 +               break;
29434 +       case OP_FORK:
29435 +               attach_process(thread->request.u.fork.pid);
29436 +               break;
29437 +       case OP_CB:
29438 +               (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
29439 +               break;
29440 +       case OP_REBOOT:
29441 +       case OP_HALT:
29442 +               break;
29443 +       default:
29444 +               tracer_panic("Bad op in do_proc_op");
29445 +               break;
29446 +       }
29447 +       thread->request.op = OP_NONE;
29448 +       return(op);
29449 +}
29450 +
29451 +void init_idle_tt(void)
29452 +{
29453 +       idle_timer();
29454 +}
29455 +
29456 +/* Changed by jail_setup, which is a setup */
29457 +int jail = 0;
29458 +
29459 +int __init jail_setup(char *line, int *add)
29460 +{
29461 +       int ok = 1;
29462 +
29463 +       if(jail) return(0);
29464 +#ifdef CONFIG_SMP
29465 +       printf("'jail' may not used used in a kernel with CONFIG_SMP "
29466 +              "enabled\n");
29467 +       ok = 0;
29468 +#endif
29469 +#ifdef CONFIG_HOSTFS
29470 +       printf("'jail' may not used used in a kernel with CONFIG_HOSTFS "
29471 +              "enabled\n");
29472 +       ok = 0;
29473 +#endif
29474 +#ifdef CONFIG_MODULES
29475 +       printf("'jail' may not used used in a kernel with CONFIG_MODULES "
29476 +              "enabled\n");
29477 +       ok = 0;
29478 +#endif 
29479 +       if(!ok) exit(1);
29480 +
29481 +       /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem.
29482 +        * Removing it from the bounding set eliminates the ability of anything
29483 +        * to acquire it, and thus read or write kernel memory.
29484 +        */
29485 +       cap_lower(cap_bset, CAP_SYS_RAWIO);
29486 +       jail = 1;
29487 +       return(0);
29488 +}
29489 +
29490 +__uml_setup("jail", jail_setup,
29491 +"jail\n"
29492 +"    Enables the protection of kernel memory from processes.\n\n"
29493 +);
29494 +
29495 +static void mprotect_kernel_mem(int w)
29496 +{
29497 +       unsigned long start, end;
29498 +       int pages;
29499 +
29500 +       if(!jail || (current == &init_task)) return;
29501 +
29502 +       pages = (1 << CONFIG_KERNEL_STACK_ORDER);
29503 +
29504 +       start = (unsigned long) current + PAGE_SIZE;
29505 +       end = (unsigned long) current + PAGE_SIZE * pages;
29506 +       protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
29507 +       protect_memory(end, high_physmem - end, 1, w, 1, 1);
29508 +
29509 +       start = (unsigned long) UML_ROUND_DOWN(&_stext);
29510 +       end = (unsigned long) UML_ROUND_UP(&_etext);
29511 +       protect_memory(start, end - start, 1, w, 1, 1);
29512 +
29513 +       start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end);
29514 +       end = (unsigned long) UML_ROUND_UP(&_edata);
29515 +       protect_memory(start, end - start, 1, w, 1, 1);
29516 +
29517 +       start = (unsigned long) UML_ROUND_DOWN(&__bss_start);
29518 +       end = (unsigned long) UML_ROUND_UP(brk_start);
29519 +       protect_memory(start, end - start, 1, w, 1, 1);
29520 +
29521 +       mprotect_kernel_vm(w);
29522 +}
29523 +
29524 +void unprotect_kernel_mem(void)
29525 +{
29526 +       mprotect_kernel_mem(1);
29527 +}
29528 +
29529 +void protect_kernel_mem(void)
29530 +{
29531 +       mprotect_kernel_mem(0);
29532 +}
29533 +
29534 +extern void start_kernel(void);
29535 +
29536 +static int start_kernel_proc(void *unused)
29537 +{
29538 +       int pid;
29539 +
29540 +       block_signals();
29541 +       pid = os_getpid();
29542 +
29543 +       cpu_tasks[0].pid = pid;
29544 +       cpu_tasks[0].task = current;
29545 +#ifdef CONFIG_SMP
29546 +       cpu_online_map = 1;
29547 +#endif
29548 +       if(debug) os_stop_process(pid);
29549 +       start_kernel();
29550 +       return(0);
29551 +}
29552 +
29553 +void set_tracing(void *task, int tracing)
29554 +{
29555 +       ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
29556 +}
29557 +
29558 +int is_tracing(void *t)
29559 +{
29560 +       return (((struct task_struct *) t)->thread.mode.tt.tracing);
29561 +}
29562 +
29563 +int set_user_mode(void *t)
29564 +{
29565 +       struct task_struct *task;
29566 +
29567 +       task = t ? t : current;
29568 +       if(task->thread.mode.tt.tracing) 
29569 +               return(1);
29570 +       task->thread.request.op = OP_TRACE_ON;
29571 +       os_usr1_process(os_getpid());
29572 +       return(0);
29573 +}
29574 +
29575 +void set_init_pid(int pid)
29576 +{
29577 +       int err;
29578 +
29579 +       init_task.thread.mode.tt.extern_pid = pid;
29580 +       err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
29581 +       if(err) 
29582 +               panic("Can't create switch pipe for init_task, errno = %d", 
29583 +                     -err);
29584 +}
29585 +
29586 +int singlestepping_tt(void *t)
29587 +{
29588 +       struct task_struct *task = t;
29589 +
29590 +       if(task->thread.mode.tt.singlestep_syscall)
29591 +               return(0);
29592 +       return(task->ptrace & PT_DTRACE);
29593 +}
29594 +
29595 +void clear_singlestep(void *t)
29596 +{
29597 +       struct task_struct *task = t;
29598 +
29599 +       task->ptrace &= ~PT_DTRACE;
29600 +}
29601 +
29602 +int start_uml_tt(void)
29603 +{
29604 +       void *sp;
29605 +       int pages;
29606 +
29607 +       pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
29608 +       sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE - 
29609 +               sizeof(unsigned long);
29610 +       return(tracer(start_kernel_proc, sp));
29611 +}
29612 +
29613 +int external_pid_tt(struct task_struct *task)
29614 +{
29615 +       return(task->thread.mode.tt.extern_pid);
29616 +}
29617 +
29618 +int thread_pid_tt(struct thread_struct *thread)
29619 +{
29620 +       return(thread->mode.tt.extern_pid);
29621 +}
29622 +
29623 +int is_valid_pid(int pid)
29624 +{
29625 +       struct task_struct *task;
29626 +
29627 +        read_lock(&tasklist_lock);
29628 +        for_each_task(task){
29629 +                if(task->thread.mode.tt.extern_pid == pid){
29630 +                       read_unlock(&tasklist_lock);
29631 +                       return(1);
29632 +                }
29633 +        }
29634 +       read_unlock(&tasklist_lock);
29635 +       return(0);
29636 +}
29637 +
29638 +/*
29639 + * Overrides for Emacs so that we follow Linus's tabbing style.
29640 + * Emacs will notice this stuff at the end of the file and automatically
29641 + * adjust the settings for this buffer only.  This must remain at the end
29642 + * of the file.
29643 + * ---------------------------------------------------------------------------
29644 + * Local variables:
29645 + * c-file-style: "linux"
29646 + * End:
29647 + */
29648 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/Makefile um/arch/um/kernel/tt/ptproxy/Makefile
29649 --- orig/arch/um/kernel/tt/ptproxy/Makefile     1969-12-31 19:00:00.000000000 -0500
29650 +++ um/arch/um/kernel/tt/ptproxy/Makefile       2003-10-21 03:26:07.000000000 -0400
29651 @@ -0,0 +1,12 @@
29652 +O_TARGET = ptproxy.o
29653 +
29654 +obj-y = proxy.o ptrace.o sysdep.o wait.o
29655 +
29656 +USER_OBJS = $(obj-y)
29657 +
29658 +include $(TOPDIR)/Rules.make
29659 +
29660 +$(USER_OBJS) : %.o: %.c
29661 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
29662 +
29663 +clean:
29664 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/proxy.c um/arch/um/kernel/tt/ptproxy/proxy.c
29665 --- orig/arch/um/kernel/tt/ptproxy/proxy.c      1969-12-31 19:00:00.000000000 -0500
29666 +++ um/arch/um/kernel/tt/ptproxy/proxy.c        2003-10-21 03:26:07.000000000 -0400
29667 @@ -0,0 +1,371 @@
29668 +/**********************************************************************
29669 +proxy.c
29670 +
29671 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
29672 +terms and conditions.
29673 +
29674 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
29675 +**********************************************************************/
29676 +
29677 +/* XXX This file shouldn't refer to CONFIG_* */
29678 +
29679 +#include <errno.h>
29680 +#include <stdio.h>
29681 +#include <stdlib.h>
29682 +#include <unistd.h>
29683 +#include <signal.h>
29684 +#include <string.h>
29685 +#include <termios.h>
29686 +#include <sys/wait.h>
29687 +#include <sys/types.h>
29688 +#include <sys/ptrace.h>
29689 +#include <sys/ioctl.h>
29690 +#include <asm/unistd.h>
29691 +
29692 +#include "ptproxy.h"
29693 +#include "sysdep.h"
29694 +#include "wait.h"
29695 +
29696 +#include "user_util.h"
29697 +#include "user.h"
29698 +#include "os.h"
29699 +#include "tempfile.h"
29700 +
29701 +static int debugger_wait(debugger_state *debugger, int *status, int options,
29702 +                        int (*syscall)(debugger_state *debugger, pid_t child),
29703 +                        int (*normal_return)(debugger_state *debugger, 
29704 +                                             pid_t unused),
29705 +                        int (*wait_return)(debugger_state *debugger, 
29706 +                                           pid_t unused))
29707 +{
29708 +       if(debugger->real_wait){
29709 +               debugger->handle_trace = normal_return;
29710 +               syscall_continue(debugger->pid);
29711 +               debugger->real_wait = 0;
29712 +               return(1);
29713 +       }
29714 +       debugger->wait_status_ptr = status;
29715 +       debugger->wait_options = options;
29716 +       if((debugger->debugee != NULL) && debugger->debugee->event){
29717 +               syscall_continue(debugger->pid);
29718 +               wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
29719 +                             NULL);
29720 +               (*wait_return)(debugger, -1);
29721 +               return(0);
29722 +       }
29723 +       else if(debugger->wait_options & WNOHANG){
29724 +               syscall_cancel(debugger->pid, 0);
29725 +               debugger->handle_trace = syscall;
29726 +               return(0);
29727 +       }
29728 +       else {
29729 +               syscall_pause(debugger->pid);
29730 +               debugger->handle_trace = wait_return;
29731 +               debugger->waiting = 1;
29732 +       }
29733 +       return(1);
29734 +}
29735 +
29736 +/*
29737 + * Handle debugger trap, i.e. syscall.
29738 + */
29739 +
29740 +int debugger_syscall(debugger_state *debugger, pid_t child)
29741 +{
29742 +       long arg1, arg2, arg3, arg4, arg5, result;
29743 +       int syscall, ret = 0;
29744 +
29745 +       syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4, 
29746 +                             &arg5);
29747 +
29748 +       switch(syscall){
29749 +       case __NR_execve:
29750 +               /* execve never returns */
29751 +               debugger->handle_trace = debugger_syscall; 
29752 +               break;
29753 +
29754 +       case __NR_ptrace:
29755 +               if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
29756 +               if(!debugger->debugee->in_context) 
29757 +                       child = debugger->debugee->pid;
29758 +               result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
29759 +                                     &ret);
29760 +               syscall_cancel(debugger->pid, result);
29761 +               debugger->handle_trace = debugger_syscall;
29762 +               return(ret);
29763 +
29764 +       case __NR_waitpid:
29765 +       case __NR_wait4:
29766 +               if(!debugger_wait(debugger, (int *) arg2, arg3, 
29767 +                                 debugger_syscall, debugger_normal_return, 
29768 +                                 proxy_wait_return))
29769 +                       return(0);
29770 +               break;
29771 +
29772 +       case __NR_kill:
29773 +               if(!debugger->debugee->in_context) 
29774 +                       child = debugger->debugee->pid;
29775 +               if(arg1 == debugger->debugee->pid){
29776 +                       result = kill(child, arg2);
29777 +                       syscall_cancel(debugger->pid, result);
29778 +                       debugger->handle_trace = debugger_syscall;
29779 +                       return(0);
29780 +               }
29781 +               else debugger->handle_trace = debugger_normal_return;
29782 +               break;
29783 +
29784 +       default:
29785 +               debugger->handle_trace = debugger_normal_return;
29786 +       }
29787 +
29788 +       syscall_continue(debugger->pid);
29789 +       return(0);
29790 +}
29791 +
29792 +/* Used by the tracing thread */
29793 +static debugger_state parent;
29794 +static int parent_syscall(debugger_state *debugger, int pid);
29795 +
29796 +int init_parent_proxy(int pid)
29797 +{
29798 +       parent = ((debugger_state) { .pid               = pid,
29799 +                                    .wait_options      = 0,
29800 +                                    .wait_status_ptr   = NULL,
29801 +                                    .waiting           = 0,
29802 +                                    .real_wait         = 0,
29803 +                                    .expecting_child   = 0,
29804 +                                    .handle_trace      = parent_syscall,
29805 +                                    .debugee           = NULL } );
29806 +       return(0);
29807 +}
29808 +
29809 +int parent_normal_return(debugger_state *debugger, pid_t unused)
29810 +{
29811 +       debugger->handle_trace = parent_syscall;
29812 +       syscall_continue(debugger->pid);
29813 +       return(0);
29814 +}
29815 +
29816 +static int parent_syscall(debugger_state *debugger, int pid)
29817 +{
29818 +       long arg1, arg2, arg3, arg4, arg5;
29819 +       int syscall;
29820 +
29821 +       syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
29822 +               
29823 +       if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
29824 +               debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
29825 +                             parent_normal_return, parent_wait_return);
29826 +       }
29827 +       else ptrace(PTRACE_SYSCALL, pid, 0, 0);
29828 +       return(0);
29829 +}
29830 +
29831 +int debugger_normal_return(debugger_state *debugger, pid_t unused)
29832 +{
29833 +       debugger->handle_trace = debugger_syscall;
29834 +       syscall_continue(debugger->pid);
29835 +       return(0);
29836 +}
29837 +
29838 +void debugger_cancelled_return(debugger_state *debugger, int result)
29839 +{
29840 +       debugger->handle_trace = debugger_syscall;
29841 +       syscall_set_result(debugger->pid, result);
29842 +       syscall_continue(debugger->pid);
29843 +}
29844 +
29845 +/* Used by the tracing thread */
29846 +static debugger_state debugger;
29847 +static debugee_state debugee;
29848 +
29849 +void init_proxy (pid_t debugger_pid, int stopped, int status)
29850 +{
29851 +       debugger.pid = debugger_pid;
29852 +       debugger.handle_trace = debugger_syscall;
29853 +       debugger.debugee = &debugee;
29854 +       debugger.waiting = 0;
29855 +       debugger.real_wait = 0;
29856 +       debugger.expecting_child = 0;
29857 +
29858 +       debugee.pid = 0;
29859 +       debugee.traced = 0;
29860 +       debugee.stopped = stopped;
29861 +       debugee.event = 0;
29862 +       debugee.zombie = 0;
29863 +       debugee.died = 0;
29864 +       debugee.wait_status = status;
29865 +       debugee.in_context = 1;
29866 +}
29867 +
29868 +int debugger_proxy(int status, int pid)
29869 +{
29870 +       int ret = 0, sig;
29871 +
29872 +       if(WIFSTOPPED(status)){
29873 +               sig = WSTOPSIG(status);
29874 +               if (sig == SIGTRAP)
29875 +                       ret = (*debugger.handle_trace)(&debugger, pid);
29876 +                                                      
29877 +               else if(sig == SIGCHLD){
29878 +                       if(debugger.expecting_child){
29879 +                               ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29880 +                               debugger.expecting_child = 0;
29881 +                       }
29882 +                       else if(debugger.waiting)
29883 +                               real_wait_return(&debugger);
29884 +                       else {
29885 +                               ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29886 +                               debugger.real_wait = 1;
29887 +                       }
29888 +               }
29889 +               else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
29890 +       }
29891 +       else if(WIFEXITED(status)){
29892 +               tracer_panic("debugger (pid %d) exited with status %d", 
29893 +                            debugger.pid, WEXITSTATUS(status));
29894 +       }
29895 +       else if(WIFSIGNALED(status)){
29896 +               tracer_panic("debugger (pid %d) exited with signal %d", 
29897 +                            debugger.pid, WTERMSIG(status));
29898 +       }
29899 +       else {
29900 +               tracer_panic("proxy got unknown status (0x%x) on debugger "
29901 +                            "(pid %d)", status, debugger.pid);
29902 +       }
29903 +       return(ret);
29904 +}
29905 +
29906 +void child_proxy(pid_t pid, int status)
29907 +{
29908 +       debugee.event = 1;
29909 +       debugee.wait_status = status;
29910 +
29911 +       if(WIFSTOPPED(status)){
29912 +               debugee.stopped = 1;
29913 +               debugger.expecting_child = 1;
29914 +               kill(debugger.pid, SIGCHLD);
29915 +       }
29916 +       else if(WIFEXITED(status) || WIFSIGNALED(status)){
29917 +               debugee.zombie = 1;
29918 +               debugger.expecting_child = 1;
29919 +               kill(debugger.pid, SIGCHLD);
29920 +       }
29921 +       else panic("proxy got unknown status (0x%x) on child (pid %d)", 
29922 +                  status, pid);
29923 +}
29924 +
29925 +void debugger_parent_signal(int status, int pid)
29926 +{
29927 +       int sig;
29928 +
29929 +       if(WIFSTOPPED(status)){
29930 +               sig = WSTOPSIG(status);
29931 +               if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
29932 +               else ptrace(PTRACE_SYSCALL, pid, 0, sig);
29933 +       }
29934 +}
29935 +
29936 +void fake_child_exit(void)
29937 +{
29938 +       int status, pid;
29939 +
29940 +       child_proxy(1, W_EXITCODE(0, 0));
29941 +       while(debugger.waiting == 1){
29942 +               pid = waitpid(debugger.pid, &status, WUNTRACED);
29943 +               if(pid != debugger.pid){
29944 +                       printk("fake_child_exit - waitpid failed, "
29945 +                              "errno = %d\n", errno);
29946 +                       return;
29947 +               }
29948 +               debugger_proxy(status, debugger.pid);
29949 +       }
29950 +       pid = waitpid(debugger.pid, &status, WUNTRACED);
29951 +       if(pid != debugger.pid){
29952 +               printk("fake_child_exit - waitpid failed, "
29953 +                      "errno = %d\n", errno);
29954 +               return;
29955 +       }
29956 +       if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
29957 +               printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
29958 +                      errno);
29959 +}
29960 +
29961 +char gdb_init_string[] = 
29962 +"att 1 \n\
29963 +b panic \n\
29964 +b stop \n\
29965 +handle SIGWINCH nostop noprint pass \n\
29966 +";
29967 +
29968 +int start_debugger(char *prog, int startup, int stop, int *fd_out)
29969 +{
29970 +       int slave, child;
29971 +
29972 +       slave = open_gdb_chan();
29973 +       child = fork();
29974 +       if(child == 0){
29975 +               char *tempname = NULL;
29976 +               int fd;
29977 +
29978 +               if(setsid() < 0) perror("setsid");
29979 +               if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) || 
29980 +                  (dup2(slave, 2) < 0)){
29981 +                       printk("start_debugger : dup2 failed, errno = %d\n",
29982 +                              errno);
29983 +                       exit(1);
29984 +               }
29985 +               if(ioctl(0, TIOCSCTTY, 0) < 0){
29986 +                       printk("start_debugger : TIOCSCTTY failed, "
29987 +                              "errno = %d\n", errno);
29988 +                       exit(1);
29989 +               }
29990 +               if(tcsetpgrp (1, os_getpid()) < 0){
29991 +                       printk("start_debugger : tcsetpgrp failed, "
29992 +                              "errno = %d\n", errno);
29993 +#ifdef notdef
29994 +                       exit(1);
29995 +#endif
29996 +               }
29997 +               fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
29998 +               if(fd < 0){
29999 +                       printk("start_debugger : make_tempfile failed,"
30000 +                              "err = %d\n", -fd);
30001 +                       exit(1);
30002 +               }
30003 +               os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
30004 +               if(startup){
30005 +                       if(stop){
30006 +                               os_write_file(fd, "b start_kernel\n",
30007 +                                     strlen("b start_kernel\n"));
30008 +                       }
30009 +                       os_write_file(fd, "c\n", strlen("c\n"));
30010 +               }
30011 +               if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
30012 +                       printk("start_debugger :  PTRACE_TRACEME failed, "
30013 +                              "errno = %d\n", errno);
30014 +                       exit(1);
30015 +               }
30016 +               execlp("gdb", "gdb", "--command", tempname, prog, NULL);
30017 +               printk("start_debugger : exec of gdb failed, errno = %d\n",
30018 +                      errno);
30019 +       }
30020 +       if(child < 0){
30021 +               printk("start_debugger : fork for gdb failed, errno = %d\n",
30022 +                      errno);
30023 +               return(-1);
30024 +       }
30025 +       *fd_out = slave;
30026 +       return(child);
30027 +}
30028 +
30029 +/*
30030 + * Overrides for Emacs so that we follow Linus's tabbing style.
30031 + * Emacs will notice this stuff at the end of the file and automatically
30032 + * adjust the settings for this buffer only.  This must remain at the end
30033 + * of the file.
30034 + * ---------------------------------------------------------------------------
30035 + * Local variables:
30036 + * c-file-style: "linux"
30037 + * End:
30038 + */
30039 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptproxy.h um/arch/um/kernel/tt/ptproxy/ptproxy.h
30040 --- orig/arch/um/kernel/tt/ptproxy/ptproxy.h    1969-12-31 19:00:00.000000000 -0500
30041 +++ um/arch/um/kernel/tt/ptproxy/ptproxy.h      2003-10-21 03:26:07.000000000 -0400
30042 @@ -0,0 +1,61 @@
30043 +/**********************************************************************
30044 +ptproxy.h
30045 +
30046 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30047 +terms and conditions.
30048 +**********************************************************************/
30049 +
30050 +#ifndef __PTPROXY_H
30051 +#define __PTPROXY_H
30052 +
30053 +#include <sys/types.h>
30054 +
30055 +typedef struct debugger debugger_state;
30056 +typedef struct debugee debugee_state;
30057 +
30058 +struct debugger
30059 +{
30060 +       pid_t pid;
30061 +       int wait_options;
30062 +       int *wait_status_ptr;
30063 +       unsigned int waiting : 1;
30064 +       unsigned int real_wait : 1;
30065 +       unsigned int expecting_child : 1;
30066 +       int (*handle_trace) (debugger_state *, pid_t);
30067 +
30068 +       debugee_state *debugee;
30069 +};
30070 +
30071 +struct debugee
30072 +{
30073 +       pid_t pid;
30074 +       int wait_status;
30075 +       unsigned int died : 1;
30076 +       unsigned int event : 1;
30077 +       unsigned int stopped : 1;
30078 +       unsigned int trace_singlestep : 1;
30079 +       unsigned int trace_syscall : 1;
30080 +       unsigned int traced : 1;
30081 +       unsigned int zombie : 1;
30082 +       unsigned int in_context : 1;
30083 +};
30084 +
30085 +extern int debugger_syscall(debugger_state *debugger, pid_t pid);
30086 +extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
30087 +
30088 +extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
30089 +                         int *strace_out);
30090 +extern void debugger_cancelled_return(debugger_state *debugger, int result);
30091 +
30092 +#endif
30093 +
30094 +/*
30095 + * Overrides for Emacs so that we follow Linus's tabbing style.
30096 + * Emacs will notice this stuff at the end of the file and automatically
30097 + * adjust the settings for this buffer only.  This must remain at the end
30098 + * of the file.
30099 + * ---------------------------------------------------------------------------
30100 + * Local variables:
30101 + * c-file-style: "linux"
30102 + * End:
30103 + */
30104 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptrace.c um/arch/um/kernel/tt/ptproxy/ptrace.c
30105 --- orig/arch/um/kernel/tt/ptproxy/ptrace.c     1969-12-31 19:00:00.000000000 -0500
30106 +++ um/arch/um/kernel/tt/ptproxy/ptrace.c       2003-10-21 03:26:07.000000000 -0400
30107 @@ -0,0 +1,239 @@
30108 +/**********************************************************************
30109 +ptrace.c
30110 +
30111 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30112 +terms and conditions.
30113 +
30114 +Jeff Dike (jdike@karaya.com) : Modified for integration into uml
30115 +**********************************************************************/
30116 +
30117 +#include <errno.h>
30118 +#include <unistd.h>
30119 +#include <signal.h>
30120 +#include <sys/types.h>
30121 +#include <sys/time.h>
30122 +#include <sys/ptrace.h>
30123 +#include <sys/wait.h>
30124 +#include <asm/ptrace.h>
30125 +
30126 +#include "ptproxy.h"
30127 +#include "debug.h"
30128 +#include "user_util.h"
30129 +#include "kern_util.h"
30130 +#include "ptrace_user.h"
30131 +#include "tt.h"
30132 +
30133 +long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
30134 +                 long arg3, long arg4, pid_t child, int *ret)
30135 +{
30136 +       sigset_t relay;
30137 +       long result;
30138 +       int status;
30139 +
30140 +       *ret = 0;
30141 +       if(debugger->debugee->died) return(-ESRCH);
30142 +
30143 +       switch(arg1){
30144 +       case PTRACE_ATTACH:
30145 +               if(debugger->debugee->traced) return(-EPERM);
30146 +
30147 +               debugger->debugee->pid = arg2;
30148 +               debugger->debugee->traced = 1;
30149 +
30150 +               if(is_valid_pid(arg2) && (arg2 != child)){
30151 +                       debugger->debugee->in_context = 0;
30152 +                       kill(arg2, SIGSTOP);
30153 +                       debugger->debugee->event = 1;
30154 +                       debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
30155 +               }
30156 +               else {
30157 +                       debugger->debugee->in_context = 1;
30158 +                       if(debugger->debugee->stopped) 
30159 +                               child_proxy(child, W_STOPCODE(SIGSTOP));
30160 +                       else kill(child, SIGSTOP);
30161 +               }
30162 +
30163 +               return(0);
30164 +
30165 +       case PTRACE_DETACH:
30166 +               if(!debugger->debugee->traced) return(-EPERM);
30167 +               
30168 +               debugger->debugee->traced = 0;
30169 +               debugger->debugee->pid = 0;
30170 +               if(!debugger->debugee->in_context)
30171 +                       kill(child, SIGCONT);
30172 +
30173 +               return(0);
30174 +
30175 +       case PTRACE_CONT:
30176 +               if(!debugger->debugee->in_context) return(-EPERM);
30177 +               *ret = PTRACE_CONT;
30178 +               return(ptrace(PTRACE_CONT, child, arg3, arg4));
30179 +
30180 +#ifdef UM_HAVE_GETFPREGS
30181 +       case PTRACE_GETFPREGS:
30182 +       {
30183 +               long regs[FP_FRAME_SIZE];
30184 +               int i, result;
30185 +
30186 +               result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
30187 +               if(result == -1) return(-errno);
30188 +               
30189 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30190 +                       ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
30191 +                              regs[i]);
30192 +               return(result);
30193 +       }
30194 +#endif
30195 +
30196 +#ifdef UM_HAVE_GETFPXREGS
30197 +       case PTRACE_GETFPXREGS:
30198 +       {
30199 +               long regs[FPX_FRAME_SIZE];
30200 +               int i, result;
30201 +
30202 +               result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
30203 +               if(result == -1) return(-errno);
30204 +               
30205 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30206 +                       ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
30207 +                              regs[i]);
30208 +               return(result);
30209 +       }
30210 +#endif
30211 +
30212 +#ifdef UM_HAVE_GETREGS
30213 +       case PTRACE_GETREGS:
30214 +       {
30215 +               long regs[FRAME_SIZE];
30216 +               int i, result;
30217 +
30218 +               result = ptrace(PTRACE_GETREGS, child, 0, regs);
30219 +               if(result == -1) return(-errno);
30220 +
30221 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30222 +                       ptrace (PTRACE_POKEDATA, debugger->pid,
30223 +                               arg4 + 4 * i, regs[i]);
30224 +               return(result);
30225 +       }
30226 +       break;
30227 +#endif
30228 +
30229 +       case PTRACE_KILL:
30230 +               result = ptrace(PTRACE_KILL, child, arg3, arg4);
30231 +               if(result == -1) return(-errno);
30232 +
30233 +               return(result);
30234 +
30235 +       case PTRACE_PEEKDATA:
30236 +       case PTRACE_PEEKTEXT:
30237 +       case PTRACE_PEEKUSER:
30238 +               /* The value being read out could be -1, so we have to 
30239 +                * check errno to see if there's an error, and zero it
30240 +                * beforehand so we're not faked out by an old error
30241 +                */
30242 +
30243 +               errno = 0;
30244 +               result = ptrace(arg1, child, arg3, 0);
30245 +               if((result == -1) && (errno != 0)) return(-errno);
30246 +
30247 +               result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
30248 +               if(result == -1) return(-errno);
30249 +                       
30250 +               return(result);
30251 +
30252 +       case PTRACE_POKEDATA:
30253 +       case PTRACE_POKETEXT:
30254 +       case PTRACE_POKEUSER:
30255 +               result = ptrace(arg1, child, arg3, arg4);
30256 +               if(result == -1) return(-errno);
30257 +
30258 +               if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
30259 +               return(result);
30260 +
30261 +#ifdef UM_HAVE_SETFPREGS
30262 +       case PTRACE_SETFPREGS:
30263 +       {
30264 +               long regs[FP_FRAME_SIZE];
30265 +               int i;
30266 +
30267 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30268 +                       regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
30269 +                                         arg4 + 4 * i, 0);
30270 +               result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
30271 +               if(result == -1) return(-errno);
30272 +
30273 +               return(result);
30274 +       }
30275 +#endif
30276 +
30277 +#ifdef UM_HAVE_SETFPXREGS
30278 +       case PTRACE_SETFPXREGS:
30279 +       {
30280 +               long regs[FPX_FRAME_SIZE];
30281 +               int i;
30282 +
30283 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30284 +                       regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
30285 +                                         arg4 + 4 * i, 0);
30286 +               result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
30287 +               if(result == -1) return(-errno);
30288 +
30289 +               return(result);
30290 +       }
30291 +#endif
30292 +
30293 +#ifdef UM_HAVE_SETREGS
30294 +       case PTRACE_SETREGS:
30295 +       {
30296 +               long regs[FRAME_SIZE];
30297 +               int i;
30298 +
30299 +               for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
30300 +                       regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
30301 +                                        arg4 + 4 * i, 0);
30302 +               result = ptrace(PTRACE_SETREGS, child, 0, regs);
30303 +               if(result == -1) return(-errno);
30304 +
30305 +               return(result);
30306 +       }
30307 +#endif
30308 +
30309 +       case PTRACE_SINGLESTEP:
30310 +               if(!debugger->debugee->in_context) return(-EPERM);
30311 +               sigemptyset(&relay);
30312 +               sigaddset(&relay, SIGSEGV);
30313 +               sigaddset(&relay, SIGILL);
30314 +               sigaddset(&relay, SIGBUS);
30315 +               result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
30316 +               if(result == -1) return(-errno);
30317 +               
30318 +               status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
30319 +                                      &relay);
30320 +               child_proxy(child, status);
30321 +               return(result);
30322 +
30323 +       case PTRACE_SYSCALL:
30324 +               if(!debugger->debugee->in_context) return(-EPERM);
30325 +               result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
30326 +               if(result == -1) return(-errno);
30327 +
30328 +               *ret = PTRACE_SYSCALL;
30329 +               return(result);
30330 +
30331 +       case PTRACE_TRACEME:
30332 +       default:
30333 +               return(-EINVAL);
30334 +       }
30335 +}
30336 +
30337 +/*
30338 + * Overrides for Emacs so that we follow Linus's tabbing style.
30339 + * Emacs will notice this stuff at the end of the file and automatically
30340 + * adjust the settings for this buffer only.  This must remain at the end
30341 + * of the file.
30342 + * ---------------------------------------------------------------------------
30343 + * Local variables:
30344 + * c-file-style: "linux"
30345 + * End:
30346 + */
30347 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.c um/arch/um/kernel/tt/ptproxy/sysdep.c
30348 --- orig/arch/um/kernel/tt/ptproxy/sysdep.c     1969-12-31 19:00:00.000000000 -0500
30349 +++ um/arch/um/kernel/tt/ptproxy/sysdep.c       2003-10-21 03:26:07.000000000 -0400
30350 @@ -0,0 +1,72 @@
30351 +/**********************************************************************
30352 +sysdep.c
30353 +
30354 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30355 +terms and conditions.
30356 +**********************************************************************/
30357 +
30358 +#include <stdio.h>
30359 +#include <string.h>
30360 +#include <stdlib.h>
30361 +#include <signal.h>
30362 +#include <errno.h>
30363 +#include <sys/types.h>
30364 +#include <sys/ptrace.h>
30365 +#include <asm/ptrace.h>
30366 +#include <linux/unistd.h>
30367 +#include "ptrace_user.h"
30368 +#include "user_util.h"
30369 +#include "user.h"
30370 +
30371 +int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, 
30372 +               long *arg5)
30373 +{
30374 +       *arg1 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG1_OFFSET, 0);
30375 +       *arg2 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG2_OFFSET, 0);
30376 +       *arg3 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG3_OFFSET, 0);
30377 +       *arg4 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG4_OFFSET, 0);
30378 +       *arg5 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG5_OFFSET, 0);
30379 +       return(ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0));
30380 +}
30381 +
30382 +void syscall_cancel(pid_t pid, int result)
30383 +{
30384 +       if((ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
30385 +                  __NR_getpid) < 0) ||
30386 +          (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
30387 +          (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
30388 +          (ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
30389 +          (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
30390 +               printk("ptproxy: couldn't cancel syscall: errno = %d\n", 
30391 +                      errno);
30392 +}
30393 +
30394 +void syscall_set_result(pid_t pid, long result)
30395 +{
30396 +       ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result);
30397 +}
30398 +
30399 +void syscall_continue(pid_t pid)
30400 +{
30401 +       ptrace(PTRACE_SYSCALL, pid, 0, 0);
30402 +}
30403 +
30404 +int syscall_pause(pid_t pid) 
30405 +{
30406 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
30407 +               printk("syscall_change - ptrace failed, errno = %d\n", errno);
30408 +               return(-1);
30409 +       }
30410 +       return(0);
30411 +}
30412 +
30413 +/*
30414 + * Overrides for Emacs so that we follow Linus's tabbing style.
30415 + * Emacs will notice this stuff at the end of the file and automatically
30416 + * adjust the settings for this buffer only.  This must remain at the end
30417 + * of the file.
30418 + * ---------------------------------------------------------------------------
30419 + * Local variables:
30420 + * c-file-style: "linux"
30421 + * End:
30422 + */
30423 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.h um/arch/um/kernel/tt/ptproxy/sysdep.h
30424 --- orig/arch/um/kernel/tt/ptproxy/sysdep.h     1969-12-31 19:00:00.000000000 -0500
30425 +++ um/arch/um/kernel/tt/ptproxy/sysdep.h       2003-10-21 03:26:07.000000000 -0400
30426 @@ -0,0 +1,25 @@
30427 +/**********************************************************************
30428 +sysdep.h
30429 +
30430 +Copyright (C) 1999 Lars Brinkhoff.
30431 +Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
30432 +See the file COPYING for licensing terms and conditions.
30433 +**********************************************************************/
30434 +
30435 +extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, 
30436 +                      long *arg4, long *arg5);
30437 +extern void syscall_cancel (pid_t pid, long result);
30438 +extern void syscall_set_result (pid_t pid, long result);
30439 +extern void syscall_continue (pid_t pid);
30440 +extern int syscall_pause(pid_t pid);
30441 +
30442 +/*
30443 + * Overrides for Emacs so that we follow Linus's tabbing style.
30444 + * Emacs will notice this stuff at the end of the file and automatically
30445 + * adjust the settings for this buffer only.  This must remain at the end
30446 + * of the file.
30447 + * ---------------------------------------------------------------------------
30448 + * Local variables:
30449 + * c-file-style: "linux"
30450 + * End:
30451 + */
30452 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.c um/arch/um/kernel/tt/ptproxy/wait.c
30453 --- orig/arch/um/kernel/tt/ptproxy/wait.c       1969-12-31 19:00:00.000000000 -0500
30454 +++ um/arch/um/kernel/tt/ptproxy/wait.c 2003-10-21 03:26:07.000000000 -0400
30455 @@ -0,0 +1,88 @@
30456 +/**********************************************************************
30457 +wait.c
30458 +
30459 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30460 +terms and conditions.
30461 +
30462 +**********************************************************************/
30463 +
30464 +#include <errno.h>
30465 +#include <signal.h>
30466 +#include <sys/wait.h>
30467 +#include <sys/ptrace.h>
30468 +#include <asm/ptrace.h>
30469 +
30470 +#include "ptproxy.h"
30471 +#include "sysdep.h"
30472 +#include "wait.h"
30473 +#include "user_util.h"
30474 +#include "sysdep/ptrace.h"
30475 +#include "sysdep/ptrace_user.h"
30476 +#include "sysdep/sigcontext.h"
30477 +
30478 +int proxy_wait_return(struct debugger *debugger, pid_t unused)
30479 +{
30480 +       debugger->waiting = 0;
30481 +
30482 +       if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
30483 +               debugger_cancelled_return(debugger, -ECHILD);
30484 +               return(0);
30485 +       }
30486 +
30487 +       if(debugger->debugee->zombie && debugger->debugee->event)
30488 +               debugger->debugee->died = 1;
30489 +
30490 +       if(debugger->debugee->event){
30491 +               debugger->debugee->event = 0;
30492 +               ptrace(PTRACE_POKEDATA, debugger->pid,
30493 +                      debugger->wait_status_ptr, 
30494 +                      debugger->debugee->wait_status);
30495 +               /* if (wait4)
30496 +                  ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
30497 +               debugger_cancelled_return(debugger, debugger->debugee->pid);
30498 +               return(0);
30499 +       }
30500 +
30501 +       /* pause will return -EINTR, which happens to be right for wait */
30502 +       debugger_normal_return(debugger, -1);
30503 +       return(0);
30504 +}
30505 +
30506 +int parent_wait_return(struct debugger *debugger, pid_t unused)
30507 +{
30508 +       return(debugger_normal_return(debugger, -1));
30509 +}
30510 +
30511 +int real_wait_return(struct debugger *debugger)
30512 +{
30513 +       unsigned long ip;
30514 +       int pid;
30515 +
30516 +       pid = debugger->pid;
30517 +
30518 +       ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
30519 +       ip = IP_RESTART_SYSCALL(ip);
30520 +
30521 +       if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
30522 +               tracer_panic("real_wait_return : Failed to restart system "
30523 +                            "call, errno = %d\n", errno);
30524 +
30525 +       if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
30526 +          (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
30527 +          (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
30528 +          debugger_normal_return(debugger, -1))
30529 +               tracer_panic("real_wait_return : gdb failed to wait, "
30530 +                            "errno = %d\n", errno);
30531 +       return(0);
30532 +}
30533 +
30534 +/*
30535 + * Overrides for Emacs so that we follow Linus's tabbing style.
30536 + * Emacs will notice this stuff at the end of the file and automatically
30537 + * adjust the settings for this buffer only.  This must remain at the end
30538 + * of the file.
30539 + * ---------------------------------------------------------------------------
30540 + * Local variables:
30541 + * c-file-style: "linux"
30542 + * End:
30543 + */
30544 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.h um/arch/um/kernel/tt/ptproxy/wait.h
30545 --- orig/arch/um/kernel/tt/ptproxy/wait.h       1969-12-31 19:00:00.000000000 -0500
30546 +++ um/arch/um/kernel/tt/ptproxy/wait.h 2003-10-21 03:26:07.000000000 -0400
30547 @@ -0,0 +1,15 @@
30548 +/**********************************************************************
30549 +wait.h
30550 +
30551 +Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
30552 +terms and conditions.
30553 +**********************************************************************/
30554 +
30555 +#ifndef __PTPROXY_WAIT_H
30556 +#define __PTPROXY_WAIT_H
30557 +
30558 +extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
30559 +extern int real_wait_return(struct debugger *debugger);
30560 +extern int parent_wait_return(struct debugger *debugger, pid_t unused);
30561 +
30562 +#endif
30563 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_kern.c um/arch/um/kernel/tt/syscall_kern.c
30564 --- orig/arch/um/kernel/tt/syscall_kern.c       1969-12-31 19:00:00.000000000 -0500
30565 +++ um/arch/um/kernel/tt/syscall_kern.c 2003-10-21 03:26:07.000000000 -0400
30566 @@ -0,0 +1,142 @@
30567 +/* 
30568 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
30569 + * Licensed under the GPL
30570 + */
30571 +
30572 +#include "linux/types.h"
30573 +#include "linux/utime.h"
30574 +#include "linux/sys.h"
30575 +#include "asm/unistd.h"
30576 +#include "asm/ptrace.h"
30577 +#include "asm/uaccess.h"
30578 +#include "sysdep/syscalls.h"
30579 +#include "kern_util.h"
30580 +
30581 +static inline int check_area(void *ptr, int size)
30582 +{
30583 +       return(verify_area(VERIFY_WRITE, ptr, size));
30584 +}
30585 +
30586 +static int check_readlink(struct pt_regs *regs)
30587 +{
30588 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
30589 +                         UPT_SYSCALL_ARG2(&regs->regs)));
30590 +}
30591 +
30592 +static int check_utime(struct pt_regs *regs)
30593 +{
30594 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
30595 +                         sizeof(struct utimbuf)));
30596 +}
30597 +
30598 +static int check_oldstat(struct pt_regs *regs)
30599 +{
30600 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
30601 +                         sizeof(struct __old_kernel_stat)));
30602 +}
30603 +
30604 +static int check_stat(struct pt_regs *regs)
30605 +{
30606 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
30607 +                         sizeof(struct stat)));
30608 +}
30609 +
30610 +static int check_stat64(struct pt_regs *regs)
30611 +{
30612 +       return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs), 
30613 +                         sizeof(struct stat64)));
30614 +}
30615 +
30616 +struct bogus {
30617 +       int kernel_ds;
30618 +       int (*check_params)(struct pt_regs *);
30619 +};
30620 +
30621 +struct bogus this_is_bogus[256] = {
30622 +       [ __NR_mknod ] = { 1, NULL },
30623 +       [ __NR_mkdir ] = { 1, NULL },
30624 +       [ __NR_rmdir ] = { 1, NULL },
30625 +       [ __NR_unlink ] = { 1, NULL },
30626 +       [ __NR_symlink ] = { 1, NULL },
30627 +       [ __NR_link ] = { 1, NULL },
30628 +       [ __NR_rename ] = { 1, NULL },
30629 +       [ __NR_umount ] = { 1, NULL },
30630 +       [ __NR_mount ] = { 1, NULL },
30631 +       [ __NR_pivot_root ] = { 1, NULL },
30632 +       [ __NR_chdir ] = { 1, NULL },
30633 +       [ __NR_chroot ] = { 1, NULL },
30634 +       [ __NR_open ] = { 1, NULL },
30635 +       [ __NR_quotactl ] = { 1, NULL },
30636 +       [ __NR_sysfs ] = { 1, NULL },
30637 +       [ __NR_readlink ] = { 1, check_readlink },
30638 +       [ __NR_acct ] = { 1, NULL },
30639 +       [ __NR_execve ] = { 1, NULL },
30640 +       [ __NR_uselib ] = { 1, NULL },
30641 +       [ __NR_statfs ] = { 1, NULL },
30642 +       [ __NR_truncate ] = { 1, NULL },
30643 +       [ __NR_access ] = { 1, NULL },
30644 +       [ __NR_chmod ] = { 1, NULL },
30645 +       [ __NR_chown ] = { 1, NULL },
30646 +       [ __NR_lchown ] = { 1, NULL },
30647 +       [ __NR_utime ] = { 1, check_utime },
30648 +       [ __NR_oldlstat ] = { 1, check_oldstat },
30649 +       [ __NR_oldstat ] = { 1, check_oldstat },
30650 +       [ __NR_stat ] = { 1, check_stat },
30651 +       [ __NR_lstat ] = { 1, check_stat },
30652 +       [ __NR_stat64 ] = { 1, check_stat64 },
30653 +       [ __NR_lstat64 ] = { 1, check_stat64 },
30654 +       [ __NR_chown32 ] = { 1, NULL },
30655 +};
30656 +
30657 +/* sys_utimes */
30658 +
30659 +static int check_bogosity(struct pt_regs *regs)
30660 +{
30661 +       struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
30662 +
30663 +       if(!bogon->kernel_ds) return(0);
30664 +       if(bogon->check_params && (*bogon->check_params)(regs))
30665 +               return(-EFAULT);
30666 +       set_fs(KERNEL_DS);
30667 +       return(0);
30668 +}
30669 +
30670 +extern syscall_handler_t *sys_call_table[];
30671 +
30672 +long execute_syscall_tt(void *r)
30673 +{
30674 +       struct pt_regs *regs = r;
30675 +       long res;
30676 +       int syscall;
30677 +
30678 +       current->thread.nsyscalls++;
30679 +       nsyscalls++;
30680 +       syscall = UPT_SYSCALL_NR(&regs->regs);
30681 +
30682 +       if((syscall >= NR_syscalls) || (syscall < 0))
30683 +               res = -ENOSYS;
30684 +       else if(honeypot && check_bogosity(regs))
30685 +               res = -EFAULT;
30686 +       else res = EXECUTE_SYSCALL(syscall, regs);
30687 +
30688 +       set_fs(USER_DS);
30689 +
30690 +       if(current->thread.mode.tt.singlestep_syscall){
30691 +               current->thread.mode.tt.singlestep_syscall = 0;
30692 +               current->ptrace &= ~PT_DTRACE;
30693 +               force_sig(SIGTRAP, current);
30694 +       }
30695 +
30696 +       return(res);
30697 +}
30698 +
30699 +/*
30700 + * Overrides for Emacs so that we follow Linus's tabbing style.
30701 + * Emacs will notice this stuff at the end of the file and automatically
30702 + * adjust the settings for this buffer only.  This must remain at the end
30703 + * of the file.
30704 + * ---------------------------------------------------------------------------
30705 + * Local variables:
30706 + * c-file-style: "linux"
30707 + * End:
30708 + */
30709 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_user.c um/arch/um/kernel/tt/syscall_user.c
30710 --- orig/arch/um/kernel/tt/syscall_user.c       1969-12-31 19:00:00.000000000 -0500
30711 +++ um/arch/um/kernel/tt/syscall_user.c 2003-10-21 03:26:07.000000000 -0400
30712 @@ -0,0 +1,89 @@
30713 +/* 
30714 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
30715 + * Licensed under the GPL
30716 + */
30717 +
30718 +#include <unistd.h>
30719 +#include <signal.h>
30720 +#include <errno.h>
30721 +#include <sys/ptrace.h>
30722 +#include <asm/unistd.h>
30723 +#include "sysdep/ptrace.h"
30724 +#include "sigcontext.h"
30725 +#include "ptrace_user.h"
30726 +#include "task.h"
30727 +#include "user_util.h"
30728 +#include "kern_util.h"
30729 +#include "syscall_user.h"
30730 +#include "tt.h"
30731 +
30732 +/* XXX Bogus */
30733 +#define ERESTARTSYS    512
30734 +#define ERESTARTNOINTR 513
30735 +#define ERESTARTNOHAND 514
30736 +
30737 +void syscall_handler_tt(int sig, union uml_pt_regs *regs)
30738 +{
30739 +       void *sc;
30740 +       long result;
30741 +       int index, syscall;
30742 +
30743 +       syscall = UPT_SYSCALL_NR(regs);
30744 +       sc = UPT_SC(regs);
30745 +       SC_START_SYSCALL(sc);
30746 +
30747 +       index = record_syscall_start(syscall);
30748 +       syscall_trace();
30749 +       result = execute_syscall(regs);
30750 +
30751 +       /* regs->sc may have changed while the system call ran (there may
30752 +        * have been an interrupt or segfault), so it needs to be refreshed.
30753 +        */
30754 +       UPT_SC(regs) = sc;
30755 +
30756 +       SC_SET_SYSCALL_RETURN(sc, result);
30757 +       if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || 
30758 +          (result == -ERESTARTNOINTR))
30759 +               do_signal(result);
30760 +
30761 +       syscall_trace();
30762 +       record_syscall_end(index, result);
30763 +}
30764 +
30765 +int do_syscall(void *task, int pid)
30766 +{
30767 +       unsigned long proc_regs[FRAME_SIZE];
30768 +       union uml_pt_regs *regs;
30769 +       int syscall;
30770 +
30771 +       if(ptrace_getregs(pid, proc_regs) < 0)
30772 +               tracer_panic("Couldn't read registers");
30773 +       syscall = PT_SYSCALL_NR(proc_regs);
30774 +
30775 +       regs = TASK_REGS(task);
30776 +       UPT_SYSCALL_NR(regs) = syscall;
30777 +
30778 +       if(syscall < 1) return(0);
30779 +
30780 +       if((syscall != __NR_sigreturn) &&
30781 +          ((unsigned long *) PT_IP(proc_regs) >= &_stext) && 
30782 +          ((unsigned long *) PT_IP(proc_regs) <= &_etext))
30783 +               tracer_panic("I'm tracing myself and I can't get out");
30784 +
30785 +       if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, 
30786 +                 __NR_getpid) < 0)
30787 +               tracer_panic("do_syscall : Nullifying syscall failed, "
30788 +                            "errno = %d", errno);
30789 +       return(1);
30790 +}
30791 +
30792 +/*
30793 + * Overrides for Emacs so that we follow Linus's tabbing style.
30794 + * Emacs will notice this stuff at the end of the file and automatically
30795 + * adjust the settings for this buffer only.  This must remain at the end
30796 + * of the file.
30797 + * ---------------------------------------------------------------------------
30798 + * Local variables:
30799 + * c-file-style: "linux"
30800 + * End:
30801 + */
30802 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/Makefile um/arch/um/kernel/tt/sys-i386/Makefile
30803 --- orig/arch/um/kernel/tt/sys-i386/Makefile    1969-12-31 19:00:00.000000000 -0500
30804 +++ um/arch/um/kernel/tt/sys-i386/Makefile      2003-10-21 03:26:07.000000000 -0400
30805 @@ -0,0 +1,17 @@
30806 +# 
30807 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30808 +# Licensed under the GPL
30809 +#
30810 +
30811 +O_TARGET = sys-i386.o
30812 +
30813 +obj-y = sigcontext.o
30814 +
30815 +USER_OBJS = sigcontext.o
30816 +
30817 +include $(TOPDIR)/Rules.make
30818 +
30819 +$(USER_OBJS) : %.o: %.c
30820 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
30821 +
30822 +clean :
30823 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/sigcontext.c um/arch/um/kernel/tt/sys-i386/sigcontext.c
30824 --- orig/arch/um/kernel/tt/sys-i386/sigcontext.c        1969-12-31 19:00:00.000000000 -0500
30825 +++ um/arch/um/kernel/tt/sys-i386/sigcontext.c  2003-10-21 03:26:07.000000000 -0400
30826 @@ -0,0 +1,60 @@
30827 +/* 
30828 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30829 + * Licensed under the GPL
30830 + */
30831 +
30832 +#include <stdlib.h>
30833 +#include <asm/sigcontext.h>
30834 +#include "kern_util.h"
30835 +#include "sysdep/frame.h"
30836 +
30837 +int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
30838 +{
30839 +       struct arch_frame_data *arch = data;
30840 +       struct sigcontext *to = to_ptr, *from = from_ptr;
30841 +       struct _fpstate *to_fp, *from_fp;
30842 +       unsigned long sigs;
30843 +       int err;
30844 +
30845 +       to_fp = to->fpstate;
30846 +       from_fp = from->fpstate;
30847 +       sigs = to->oldmask;
30848 +       err = copy_from_user_proc(to, from, sizeof(*to));
30849 +       to->oldmask = sigs;
30850 +       if(to_fp != NULL){
30851 +               err |= copy_from_user_proc(&to->fpstate, &to_fp,
30852 +                                          sizeof(to->fpstate));
30853 +               err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
30854 +       }
30855 +       return(err);
30856 +}
30857 +
30858 +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
30859 +{
30860 +       struct arch_frame_data *arch = data;
30861 +       struct sigcontext *to = to_ptr, *from = from_ptr;
30862 +       struct _fpstate *to_fp, *from_fp;
30863 +       int err;
30864 +
30865 +       to_fp = (struct _fpstate *) 
30866 +               (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
30867 +       from_fp = from->fpstate;
30868 +       err = copy_to_user_proc(to, from, sizeof(*to));
30869 +       if(from_fp != NULL){
30870 +               err |= copy_to_user_proc(&to->fpstate, &to_fp,
30871 +                                        sizeof(to->fpstate));
30872 +               err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
30873 +       }
30874 +       return(err);
30875 +}
30876 +
30877 +/*
30878 + * Overrides for Emacs so that we follow Linus's tabbing style.
30879 + * Emacs will notice this stuff at the end of the file and automatically
30880 + * adjust the settings for this buffer only.  This must remain at the end
30881 + * of the file.
30882 + * ---------------------------------------------------------------------------
30883 + * Local variables:
30884 + * c-file-style: "linux"
30885 + * End:
30886 + */
30887 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/time.c um/arch/um/kernel/tt/time.c
30888 --- orig/arch/um/kernel/tt/time.c       1969-12-31 19:00:00.000000000 -0500
30889 +++ um/arch/um/kernel/tt/time.c 2003-10-21 03:26:07.000000000 -0400
30890 @@ -0,0 +1,28 @@
30891 +/* 
30892 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
30893 + * Licensed under the GPL
30894 + */
30895 +
30896 +#include <signal.h>
30897 +#include <sys/time.h>
30898 +#include <time_user.h>
30899 +#include "process.h"
30900 +#include "user.h"
30901 +
30902 +void user_time_init_tt(void)
30903 +{
30904 +       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
30905 +               panic("Couldn't set SIGVTALRM handler");
30906 +       set_interval(ITIMER_VIRTUAL);
30907 +}
30908 +
30909 +/*
30910 + * Overrides for Emacs so that we follow Linus's tabbing style.
30911 + * Emacs will notice this stuff at the end of the file and automatically
30912 + * adjust the settings for this buffer only.  This must remain at the end
30913 + * of the file.
30914 + * ---------------------------------------------------------------------------
30915 + * Local variables:
30916 + * c-file-style: "linux"
30917 + * End:
30918 + */
30919 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tlb.c um/arch/um/kernel/tt/tlb.c
30920 --- orig/arch/um/kernel/tt/tlb.c        1969-12-31 19:00:00.000000000 -0500
30921 +++ um/arch/um/kernel/tt/tlb.c  2003-11-13 00:40:57.000000000 -0500
30922 @@ -0,0 +1,220 @@
30923 +/* 
30924 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
30925 + * Licensed under the GPL
30926 + */
30927 +
30928 +#include "linux/stddef.h"
30929 +#include "linux/kernel.h"
30930 +#include "linux/sched.h"
30931 +#include "asm/page.h"
30932 +#include "asm/pgtable.h"
30933 +#include "asm/uaccess.h"
30934 +#include "user_util.h"
30935 +#include "mem_user.h"
30936 +#include "os.h"
30937 +
30938 +static void fix_range(struct mm_struct *mm, unsigned long start_addr, 
30939 +                     unsigned long end_addr, int force)
30940 +{
30941 +       pgd_t *npgd;
30942 +       pmd_t *npmd;
30943 +       pte_t *npte;
30944 +       unsigned long addr;
30945 +       int r, w, x, err;
30946 +
30947 +       if((current->thread.mode.tt.extern_pid != -1) && 
30948 +          (current->thread.mode.tt.extern_pid != os_getpid()))
30949 +               panic("fix_range fixing wrong address space, current = 0x%p",
30950 +                     current);
30951 +       if(mm == NULL) return;
30952 +       for(addr=start_addr;addr<end_addr;){
30953 +               if(addr == TASK_SIZE){
30954 +                       /* Skip over kernel text, kernel data, and physical
30955 +                        * memory, which don't have ptes, plus kernel virtual
30956 +                        * memory, which is flushed separately, and remap
30957 +                        * the process stack.  The only way to get here is
30958 +                        * if (end_addr == STACK_TOP) > TASK_SIZE, which is
30959 +                        * only true in the honeypot case.
30960 +                        */
30961 +                       addr = STACK_TOP - ABOVE_KMEM;
30962 +                       continue;
30963 +               }
30964 +               npgd = pgd_offset(mm, addr);
30965 +               npmd = pmd_offset(npgd, addr);
30966 +               if(pmd_present(*npmd)){
30967 +                       npte = pte_offset(npmd, addr);
30968 +                       r = pte_read(*npte);
30969 +                       w = pte_write(*npte);
30970 +                       x = pte_exec(*npte);
30971 +                       if(!pte_dirty(*npte)) w = 0;
30972 +                       if(!pte_young(*npte)){
30973 +                               r = 0;
30974 +                               w = 0;
30975 +                       }
30976 +                       if(force || pte_newpage(*npte)){
30977 +                               err = os_unmap_memory((void *) addr, 
30978 +                                                     PAGE_SIZE);
30979 +                               if(err < 0)
30980 +                                       panic("munmap failed, errno = %d\n",
30981 +                                             -err);
30982 +                               if(pte_present(*npte))
30983 +                                       map_memory(addr, 
30984 +                                                  pte_val(*npte) & PAGE_MASK,
30985 +                                                  PAGE_SIZE, r, w, x);
30986 +                       }
30987 +                       else if(pte_newprot(*npte)){
30988 +                               protect_memory(addr, PAGE_SIZE, r, w, x, 1);
30989 +                       }
30990 +                       *npte = pte_mkuptodate(*npte);
30991 +                       addr += PAGE_SIZE;
30992 +               }
30993 +               else {
30994 +                       if(force || pmd_newpage(*npmd)){
30995 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
30996 +                               if(err < 0)
30997 +                                       panic("munmap failed, errno = %d\n",
30998 +                                             -err);
30999 +                               pmd_mkuptodate(*npmd);
31000 +                       }
31001 +                       addr += PMD_SIZE;
31002 +               }
31003 +       }
31004 +}
31005 +
31006 +atomic_t vmchange_seq = ATOMIC_INIT(1);
31007 +
31008 +static void flush_kernel_vm_range(unsigned long start, unsigned long end,
31009 +                                 int update_seq)
31010 +{
31011 +       struct mm_struct *mm;
31012 +       pgd_t *pgd;
31013 +       pmd_t *pmd;
31014 +       pte_t *pte;
31015 +       unsigned long addr;
31016 +       int updated = 0, err;
31017 +
31018 +       mm = &init_mm;
31019 +       for(addr = start; addr < end;){
31020 +               pgd = pgd_offset(mm, addr);
31021 +               pmd = pmd_offset(pgd, addr);
31022 +               if(pmd_present(*pmd)){
31023 +                       pte = pte_offset(pmd, addr);
31024 +                       if(!pte_present(*pte) || pte_newpage(*pte)){
31025 +                               updated = 1;
31026 +                               err = os_unmap_memory((void *) addr, 
31027 +                                                     PAGE_SIZE);
31028 +                               if(err < 0)
31029 +                                       panic("munmap failed, errno = %d\n",
31030 +                                             -err);
31031 +                               if(pte_present(*pte))
31032 +                                       map_memory(addr, 
31033 +                                                  pte_val(*pte) & PAGE_MASK,
31034 +                                                  PAGE_SIZE, 1, 1, 1);
31035 +                       }
31036 +                       else if(pte_newprot(*pte)){
31037 +                               updated = 1;
31038 +                               protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
31039 +                       }
31040 +                       addr += PAGE_SIZE;
31041 +               }
31042 +               else {
31043 +                       if(pmd_newpage(*pmd)){
31044 +                               updated = 1;
31045 +                               err = os_unmap_memory((void *) addr, PMD_SIZE);
31046 +                               if(err < 0)
31047 +                                       panic("munmap failed, errno = %d\n",
31048 +                                             -err);
31049 +                       }
31050 +                       addr += PMD_SIZE;
31051 +               }
31052 +       }
31053 +       if(updated && update_seq) atomic_inc(&vmchange_seq);
31054 +}
31055 +
31056 +static void protect_vm_page(unsigned long addr, int w, int must_succeed)
31057 +{
31058 +       int err;
31059 +
31060 +       err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed);
31061 +       if(err == 0) return;
31062 +       else if((err == -EFAULT) || (err == -ENOMEM)){
31063 +               flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
31064 +               protect_vm_page(addr, w, 1);
31065 +       }
31066 +       else panic("protect_vm_page : protect failed, errno = %d\n", err);
31067 +}
31068 +
31069 +void mprotect_kernel_vm(int w)
31070 +{
31071 +       struct mm_struct *mm;
31072 +       pgd_t *pgd;
31073 +       pmd_t *pmd;
31074 +       pte_t *pte;
31075 +       unsigned long addr;
31076 +       
31077 +       mm = &init_mm;
31078 +       for(addr = start_vm; addr < end_vm;){
31079 +               pgd = pgd_offset(mm, addr);
31080 +               pmd = pmd_offset(pgd, addr);
31081 +               if(pmd_present(*pmd)){
31082 +                       pte = pte_offset(pmd, addr);
31083 +                       if(pte_present(*pte)) protect_vm_page(addr, w, 0);
31084 +                       addr += PAGE_SIZE;
31085 +               }
31086 +               else addr += PMD_SIZE;
31087 +       }
31088 +}
31089 +
31090 +void flush_tlb_kernel_vm_tt(void)
31091 +{
31092 +       flush_kernel_vm_range(start_vm, end_vm, 1);
31093 +}
31094 +
31095 +void __flush_tlb_one_tt(unsigned long addr)
31096 +{
31097 +       flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1);
31098 +}
31099 +
31100 +void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, 
31101 +                    unsigned long end)
31102 +{
31103 +       if(mm != current->mm) return;
31104 +
31105 +       /* Assumes that the range start ... end is entirely within
31106 +        * either process memory or kernel vm
31107 +        */
31108 +       if((start >= start_vm) && (start < end_vm)) 
31109 +               flush_kernel_vm_range(start, end, 1);
31110 +       else fix_range(mm, start, end, 0);
31111 +}
31112 +
31113 +void flush_tlb_mm_tt(struct mm_struct *mm)
31114 +{
31115 +       unsigned long seq;
31116 +
31117 +       if(mm != current->mm) return;
31118 +
31119 +       fix_range(mm, 0, STACK_TOP, 0);
31120 +
31121 +       seq = atomic_read(&vmchange_seq);
31122 +       if(current->thread.mode.tt.vm_seq == seq) return;
31123 +       current->thread.mode.tt.vm_seq = seq;
31124 +       flush_kernel_vm_range(start_vm, end_vm, 0);
31125 +}
31126 +
31127 +void force_flush_all_tt(void)
31128 +{
31129 +       fix_range(current->mm, 0, STACK_TOP, 1);
31130 +       flush_kernel_vm_range(start_vm, end_vm, 0);
31131 +}
31132 +
31133 +/*
31134 + * Overrides for Emacs so that we follow Linus's tabbing style.
31135 + * Emacs will notice this stuff at the end of the file and automatically
31136 + * adjust the settings for this buffer only.  This must remain at the end
31137 + * of the file.
31138 + * ---------------------------------------------------------------------------
31139 + * Local variables:
31140 + * c-file-style: "linux"
31141 + * End:
31142 + */
31143 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tracer.c um/arch/um/kernel/tt/tracer.c
31144 --- orig/arch/um/kernel/tt/tracer.c     1969-12-31 19:00:00.000000000 -0500
31145 +++ um/arch/um/kernel/tt/tracer.c       2003-10-21 03:26:07.000000000 -0400
31146 @@ -0,0 +1,454 @@
31147 +/* 
31148 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31149 + * Licensed under the GPL
31150 + */
31151 +
31152 +#include <stdio.h>
31153 +#include <stdlib.h>
31154 +#include <stdarg.h>
31155 +#include <unistd.h>
31156 +#include <signal.h>
31157 +#include <errno.h>
31158 +#include <sched.h>
31159 +#include <string.h>
31160 +#include <sys/mman.h>
31161 +#include <sys/ptrace.h>
31162 +#include <sys/time.h>
31163 +#include <sys/wait.h>
31164 +#include "user.h"
31165 +#include "sysdep/ptrace.h"
31166 +#include "sigcontext.h"
31167 +#include "sysdep/sigcontext.h"
31168 +#include "os.h"
31169 +#include "signal_user.h"
31170 +#include "user_util.h"
31171 +#include "mem_user.h"
31172 +#include "process.h"
31173 +#include "kern_util.h"
31174 +#include "frame.h"
31175 +#include "chan_user.h"
31176 +#include "ptrace_user.h"
31177 +#include "mode.h"
31178 +#include "tt.h"
31179 +
31180 +static int tracer_winch[2];
31181 +
31182 +int is_tracer_winch(int pid, int fd, void *data)
31183 +{
31184 +       if(pid != tracing_pid)
31185 +               return(0);
31186 +
31187 +       register_winch_irq(tracer_winch[0], fd, -1, data);
31188 +       return(1);
31189 +}
31190 +
31191 +static void tracer_winch_handler(int sig)
31192 +{
31193 +       int n;
31194 +       char c = 1;
31195 +
31196 +       n = os_write_file(tracer_winch[1], &c, sizeof(c));
31197 +       if(n != sizeof(c))
31198 +               printk("tracer_winch_handler - write failed, err = %d\n", -n);
31199 +}
31200 +
31201 +/* Called only by the tracing thread during initialization */
31202 +
31203 +static void setup_tracer_winch(void)
31204 +{
31205 +       int err;
31206 +
31207 +       err = os_pipe(tracer_winch, 1, 1);
31208 +       if(err < 0){
31209 +               printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
31210 +               return;
31211 +       }
31212 +       signal(SIGWINCH, tracer_winch_handler);
31213 +}
31214 +
31215 +void attach_process(int pid)
31216 +{
31217 +       if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
31218 +          (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
31219 +               tracer_panic("OP_FORK failed to attach pid");
31220 +       wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
31221 +       if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
31222 +               tracer_panic("OP_FORK failed to continue process");
31223 +}
31224 +
31225 +void tracer_panic(char *format, ...)
31226 +{
31227 +       va_list ap;
31228 +
31229 +       va_start(ap, format);
31230 +       vprintf(format, ap);
31231 +       printf("\n");
31232 +       while(1) pause();
31233 +}
31234 +
31235 +static void tracer_segv(int sig, struct sigcontext sc)
31236 +{
31237 +       printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
31238 +              SC_FAULT_ADDR(&sc), SC_IP(&sc));
31239 +       while(1)
31240 +               pause();
31241 +}
31242 +
31243 +/* Changed early in boot, and then only read */
31244 +int debug = 0;
31245 +int debug_stop = 1;
31246 +int debug_parent = 0;
31247 +int honeypot = 0;
31248 +
31249 +static int signal_tramp(void *arg)
31250 +{
31251 +       int (*proc)(void *);
31252 +
31253 +       if(honeypot && munmap((void *) (host_task_size - 0x10000000),
31254 +                             0x10000000)) 
31255 +               panic("Unmapping stack failed");
31256 +       if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
31257 +               panic("ptrace PTRACE_TRACEME failed");
31258 +       os_stop_process(os_getpid());
31259 +       change_sig(SIGWINCH, 0);
31260 +       signal(SIGUSR1, SIG_IGN);
31261 +       change_sig(SIGCHLD, 0);
31262 +       signal(SIGSEGV, (__sighandler_t) sig_handler);
31263 +       set_cmdline("(idle thread)");
31264 +       set_init_pid(os_getpid());
31265 +       proc = arg;
31266 +       return((*proc)(NULL));
31267 +}
31268 +
31269 +static void sleeping_process_signal(int pid, int sig)
31270 +{
31271 +       switch(sig){
31272 +       /* These two result from UML being ^Z-ed and bg-ed.  PTRACE_CONT is
31273 +        * right because the process must be in the kernel already.
31274 +        */
31275 +       case SIGCONT:
31276 +       case SIGTSTP:
31277 +               if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
31278 +                       tracer_panic("sleeping_process_signal : Failed to "
31279 +                                    "continue pid %d, signal = %d, "
31280 +                                    "errno = %d\n", pid, sig, errno);
31281 +               break;
31282 +
31283 +       /* This happens when the debugger (e.g. strace) is doing system call 
31284 +        * tracing on the kernel.  During a context switch, the current task
31285 +        * will be set to the incoming process and the outgoing process will
31286 +        * hop into write and then read.  Since it's not the current process
31287 +        * any more, the trace of those will land here.  So, we need to just 
31288 +        * PTRACE_SYSCALL it.
31289 +        */
31290 +       case SIGTRAP:
31291 +               if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
31292 +                       tracer_panic("sleeping_process_signal : Failed to "
31293 +                                    "PTRACE_SYSCALL pid %d, errno = %d\n",
31294 +                                    pid, errno);
31295 +               break;
31296 +       case SIGSTOP:
31297 +               break;
31298 +       default:
31299 +               tracer_panic("sleeping process %d got unexpected "
31300 +                            "signal : %d\n", pid, sig);
31301 +               break;
31302 +       }
31303 +}
31304 +
31305 +/* Accessed only by the tracing thread */
31306 +int debugger_pid = -1;
31307 +int debugger_parent = -1;
31308 +int debugger_fd = -1;
31309 +int gdb_pid = -1;
31310 +
31311 +struct {
31312 +       int pid;
31313 +       int signal;
31314 +       unsigned long addr;
31315 +       struct timeval time;
31316 +} signal_record[1024][32];
31317 +
31318 +int signal_index[32];
31319 +int nsignals = 0;
31320 +int debug_trace = 0;
31321 +extern int io_nsignals, io_count, intr_count;
31322 +
31323 +extern void signal_usr1(int sig);
31324 +
31325 +int tracing_pid = -1;
31326 +
31327 +int tracer(int (*init_proc)(void *), void *sp)
31328 +{
31329 +       void *task = NULL;
31330 +       unsigned long eip = 0;
31331 +       int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
31332 +       int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;
31333 +
31334 +       capture_signal_stack();
31335 +       signal(SIGPIPE, SIG_IGN);
31336 +       setup_tracer_winch();
31337 +       tracing_pid = os_getpid();
31338 +       printf("tracing thread pid = %d\n", tracing_pid);
31339 +
31340 +       pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
31341 +       n = waitpid(pid, &status, WUNTRACED);
31342 +       if(n < 0){
31343 +               printf("waitpid on idle thread failed, errno = %d\n", errno);
31344 +               exit(1);
31345 +       }
31346 +       if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
31347 +               printf("Failed to continue idle thread, errno = %d\n", errno);
31348 +               exit(1);
31349 +       }
31350 +
31351 +       signal(SIGSEGV, (sighandler_t) tracer_segv);
31352 +       signal(SIGUSR1, signal_usr1);
31353 +       if(debug_trace){
31354 +               printf("Tracing thread pausing to be attached\n");
31355 +               stop();
31356 +       }
31357 +       if(debug){
31358 +               if(gdb_pid != -1) 
31359 +                       debugger_pid = attach_debugger(pid, gdb_pid, 1);
31360 +               else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
31361 +               if(debug_parent){
31362 +                       debugger_parent = os_process_parent(debugger_pid);
31363 +                       init_parent_proxy(debugger_parent);
31364 +                       err = attach(debugger_parent);
31365 +                       if(err){
31366 +                               printf("Failed to attach debugger parent %d, "
31367 +                                      "errno = %d\n", debugger_parent, -err);
31368 +                               debugger_parent = -1;
31369 +                       }
31370 +                       else {
31371 +                               if(ptrace(PTRACE_SYSCALL, debugger_parent, 
31372 +                                         0, 0) < 0){
31373 +                                       printf("Failed to continue debugger "
31374 +                                              "parent, errno = %d\n", errno);
31375 +                                       debugger_parent = -1;
31376 +                               }
31377 +                       }
31378 +               }
31379 +       }
31380 +       set_cmdline("(tracing thread)");
31381 +       while(1){
31382 +               pid = waitpid(-1, &status, WUNTRACED);
31383 +               if(pid <= 0){
31384 +                       if(errno != ECHILD){
31385 +                               printf("wait failed - errno = %d\n", errno);
31386 +                       }
31387 +                       continue;
31388 +               }
31389 +               if(pid == debugger_pid){
31390 +                       int cont = 0;
31391 +
31392 +                       if(WIFEXITED(status) || WIFSIGNALED(status))
31393 +                               debugger_pid = -1;
31394 +                       /* XXX Figure out how to deal with gdb and SMP */
31395 +                       else cont = debugger_signal(status, cpu_tasks[0].pid);
31396 +                       if(cont == PTRACE_SYSCALL) strace = 1;
31397 +                       continue;
31398 +               }
31399 +               else if(pid == debugger_parent){
31400 +                       debugger_parent_signal(status, pid);
31401 +                       continue;
31402 +               }
31403 +               nsignals++;
31404 +               if(WIFEXITED(status)) ;
31405 +#ifdef notdef
31406 +               {
31407 +                       printf("Child %d exited with status %d\n", pid, 
31408 +                              WEXITSTATUS(status));
31409 +               }
31410 +#endif
31411 +               else if(WIFSIGNALED(status)){
31412 +                       sig = WTERMSIG(status);
31413 +                       if(sig != 9){
31414 +                               printf("Child %d exited with signal %d\n", pid,
31415 +                                      sig);
31416 +                       }
31417 +               }
31418 +               else if(WIFSTOPPED(status)){
31419 +                       proc_id = pid_to_processor_id(pid);
31420 +                       sig = WSTOPSIG(status);
31421 +                       if(signal_index[proc_id] == 1024){
31422 +                               signal_index[proc_id] = 0;
31423 +                               last_index = 1023;
31424 +                       }
31425 +                       else last_index = signal_index[proc_id] - 1;
31426 +                       if(((sig == SIGPROF) || (sig == SIGVTALRM) || 
31427 +                           (sig == SIGALRM)) &&
31428 +                          (signal_record[proc_id][last_index].signal == sig)&&
31429 +                          (signal_record[proc_id][last_index].pid == pid))
31430 +                               signal_index[proc_id] = last_index;
31431 +                       signal_record[proc_id][signal_index[proc_id]].pid = pid;
31432 +                       gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
31433 +                       eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
31434 +                       signal_record[proc_id][signal_index[proc_id]].addr = eip;
31435 +                       signal_record[proc_id][signal_index[proc_id]++].signal = sig;
31436 +                       
31437 +                       if(proc_id == -1){
31438 +                               sleeping_process_signal(pid, sig);
31439 +                               continue;
31440 +                       }
31441 +
31442 +                       task = cpu_tasks[proc_id].task;
31443 +                       tracing = is_tracing(task);
31444 +                       old_tracing = tracing;
31445 +
31446 +                       switch(sig){
31447 +                       case SIGUSR1:
31448 +                               sig = 0;
31449 +                               op = do_proc_op(task, proc_id);
31450 +                               switch(op){
31451 +                               case OP_TRACE_ON:
31452 +                                       arch_leave_kernel(task, pid);
31453 +                                       tracing = 1;
31454 +                                       break;
31455 +                               case OP_REBOOT:
31456 +                               case OP_HALT:
31457 +                                       unmap_physmem();
31458 +                                       kmalloc_ok = 0;
31459 +                                       ptrace(PTRACE_KILL, pid, 0, 0);
31460 +                                       return(op == OP_REBOOT);
31461 +                               case OP_NONE:
31462 +                                       printf("Detaching pid %d\n", pid);
31463 +                                       detach(pid, SIGSTOP);
31464 +                                       continue;
31465 +                               default:
31466 +                                       break;
31467 +                               }
31468 +                               /* OP_EXEC switches host processes on us,
31469 +                                * we want to continue the new one.
31470 +                                */
31471 +                               pid = cpu_tasks[proc_id].pid;
31472 +                               break;
31473 +                       case SIGTRAP:
31474 +                               if(!tracing && (debugger_pid != -1)){
31475 +                                       child_signal(pid, status);
31476 +                                       continue;
31477 +                               }
31478 +                               tracing = 0;
31479 +                               if(do_syscall(task, pid)) sig = SIGUSR2;
31480 +                               else clear_singlestep(task);
31481 +                               break;
31482 +                       case SIGPROF:
31483 +                               if(tracing) sig = 0;
31484 +                               break;
31485 +                       case SIGCHLD:
31486 +                       case SIGHUP:
31487 +                               sig = 0;
31488 +                               break;
31489 +                       case SIGSEGV:
31490 +                       case SIGIO:
31491 +                       case SIGALRM:
31492 +                       case SIGVTALRM:
31493 +                       case SIGFPE:
31494 +                       case SIGBUS:
31495 +                       case SIGILL:
31496 +                       case SIGWINCH:
31497 +                       default:
31498 +                               tracing = 0;
31499 +                               break;
31500 +                       }
31501 +                       set_tracing(task, tracing);
31502 +
31503 +                       if(!tracing && old_tracing)
31504 +                               arch_enter_kernel(task, pid);
31505 +
31506 +                       if(!tracing && (debugger_pid != -1) && (sig != 0) &&
31507 +                               (sig != SIGALRM) && (sig != SIGVTALRM) &&
31508 +                               (sig != SIGSEGV) && (sig != SIGTRAP) &&
31509 +                               (sig != SIGUSR2) && (sig != SIGIO) &&
31510 +                               (sig != SIGFPE)){
31511 +                               child_signal(pid, status);
31512 +                               continue;
31513 +                       }
31514 +
31515 +                       if(tracing){
31516 +                               if(singlestepping_tt(task))
31517 +                                       cont_type = PTRACE_SINGLESTEP;
31518 +                               else cont_type = PTRACE_SYSCALL;
31519 +                       }
31520 +                       else cont_type = PTRACE_CONT;
31521 +
31522 +                       if((cont_type == PTRACE_CONT) && 
31523 +                          (debugger_pid != -1) && strace)
31524 +                               cont_type = PTRACE_SYSCALL;
31525 +
31526 +                       if(ptrace(cont_type, pid, 0, sig) != 0){
31527 +                               tracer_panic("ptrace failed to continue "
31528 +                                            "process - errno = %d\n", 
31529 +                                            errno);
31530 +                       }
31531 +               }
31532 +       }
31533 +       return(0);
31534 +}
31535 +
31536 +static int __init uml_debug_setup(char *line, int *add)
31537 +{
31538 +       char *next;
31539 +
31540 +       debug = 1;
31541 +       *add = 0;
31542 +       if(*line != '=') return(0);
31543 +       line++;
31544 +
31545 +       while(line != NULL){
31546 +               next = strchr(line, ',');
31547 +               if(next) *next++ = '\0';
31548 +               
31549 +               if(!strcmp(line, "go")) debug_stop = 0;
31550 +               else if(!strcmp(line, "parent")) debug_parent = 1;
31551 +               else printf("Unknown debug option : '%s'\n", line);
31552 +
31553 +               line = next;
31554 +       }
31555 +       return(0);
31556 +}
31557 +
31558 +__uml_setup("debug", uml_debug_setup,
31559 +"debug\n"
31560 +"    Starts up the kernel under the control of gdb. See the \n"
31561 +"    kernel debugging tutorial and the debugging session pages\n"
31562 +"    at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
31563 +);
31564 +
31565 +static int __init uml_debugtrace_setup(char *line, int *add)
31566 +{
31567 +       debug_trace = 1;
31568 +       return 0;
31569 +}
31570 +__uml_setup("debugtrace", uml_debugtrace_setup,
31571 +"debugtrace\n"
31572 +"    Causes the tracing thread to pause until it is attached by a\n"
31573 +"    debugger and continued.  This is mostly for debugging crashes\n"
31574 +"    early during boot, and should be pretty much obsoleted by\n"
31575 +"    the debug switch.\n\n"
31576 +);
31577 +
31578 +static int __init uml_honeypot_setup(char *line, int *add)
31579 +{
31580 +       jail_setup("", add);
31581 +       honeypot = 1;
31582 +       return 0;
31583 +}
31584 +__uml_setup("honeypot", uml_honeypot_setup, 
31585 +"honeypot\n"
31586 +"    This makes UML put process stacks in the same location as they are\n"
31587 +"    on the host, allowing expoits such as stack smashes to work against\n"
31588 +"    UML.  This implies 'jail'.\n\n"
31589 +);
31590 +
31591 +/*
31592 + * Overrides for Emacs so that we follow Linus's tabbing style.
31593 + * Emacs will notice this stuff at the end of the file and automatically
31594 + * adjust the settings for this buffer only.  This must remain at the end
31595 + * of the file.
31596 + * ---------------------------------------------------------------------------
31597 + * Local variables:
31598 + * c-file-style: "linux"
31599 + * End:
31600 + */
31601 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/trap_user.c um/arch/um/kernel/tt/trap_user.c
31602 --- orig/arch/um/kernel/tt/trap_user.c  1969-12-31 19:00:00.000000000 -0500
31603 +++ um/arch/um/kernel/tt/trap_user.c    2003-10-21 03:26:07.000000000 -0400
31604 @@ -0,0 +1,59 @@
31605 +/* 
31606 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
31607 + * Licensed under the GPL
31608 + */
31609 +
31610 +#include <stdlib.h>
31611 +#include <errno.h>
31612 +#include <signal.h>
31613 +#include <asm/sigcontext.h>
31614 +#include "sysdep/ptrace.h"
31615 +#include "signal_user.h"
31616 +#include "user_util.h"
31617 +#include "kern_util.h"
31618 +#include "task.h"
31619 +#include "tt.h"
31620 +
31621 +void sig_handler_common_tt(int sig, void *sc_ptr)
31622 +{
31623 +       struct sigcontext *sc = sc_ptr;
31624 +       struct tt_regs save_regs, *r;
31625 +       struct signal_info *info;
31626 +       int save_errno = errno, is_user;
31627 +
31628 +       unprotect_kernel_mem();
31629 +
31630 +       r = &TASK_REGS(get_current())->tt;
31631 +       save_regs = *r;
31632 +       is_user = user_context(SC_SP(sc));
31633 +       r->sc = sc;
31634 +       if(sig != SIGUSR2) 
31635 +               r->syscall = -1;
31636 +
31637 +       change_sig(SIGUSR1, 1);
31638 +       info = &sig_info[sig];
31639 +       if(!info->is_irq) unblock_signals();
31640 +
31641 +       (*info->handler)(sig, (union uml_pt_regs *) r);
31642 +
31643 +       if(is_user){
31644 +               interrupt_end();
31645 +               block_signals();
31646 +               change_sig(SIGUSR1, 0);
31647 +               set_user_mode(NULL);
31648 +       }
31649 +       *r = save_regs;
31650 +       errno = save_errno;
31651 +       if(is_user) protect_kernel_mem();
31652 +}
31653 +
31654 +/*
31655 + * Overrides for Emacs so that we follow Linus's tabbing style.
31656 + * Emacs will notice this stuff at the end of the file and automatically
31657 + * adjust the settings for this buffer only.  This must remain at the end
31658 + * of the file.
31659 + * ---------------------------------------------------------------------------
31660 + * Local variables:
31661 + * c-file-style: "linux"
31662 + * End:
31663 + */
31664 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess.c um/arch/um/kernel/tt/uaccess.c
31665 --- orig/arch/um/kernel/tt/uaccess.c    1969-12-31 19:00:00.000000000 -0500
31666 +++ um/arch/um/kernel/tt/uaccess.c      2003-11-13 00:12:45.000000000 -0500
31667 @@ -0,0 +1,73 @@
31668 +/* 
31669 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
31670 + * Licensed under the GPL
31671 + */
31672 +
31673 +#include "linux/sched.h"
31674 +#include "asm/uaccess.h"
31675 +
31676 +int copy_from_user_tt(void *to, const void *from, int n)
31677 +{
31678 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
31679 +               return(n);
31680 +
31681 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
31682 +                                  &current->thread.fault_catcher));
31683 +}
31684 +
31685 +int copy_to_user_tt(void *to, const void *from, int n)
31686 +{
31687 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
31688 +               return(n);
31689 +               
31690 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
31691 +                                &current->thread.fault_catcher));
31692 +}
31693 +
31694 +int strncpy_from_user_tt(char *dst, const char *src, int count)
31695 +{
31696 +       int n;
31697 +
31698 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
31699 +               return(-EFAULT);
31700 +
31701 +       n = __do_strncpy_from_user(dst, src, count, 
31702 +                                  &current->thread.fault_addr,
31703 +                                  &current->thread.fault_catcher);
31704 +       if(n < 0) return(-EFAULT);
31705 +       return(n);
31706 +}
31707 +
31708 +int __clear_user_tt(void *mem, int len)
31709 +{
31710 +       return(__do_clear_user(mem, len,
31711 +                              &current->thread.fault_addr,
31712 +                              &current->thread.fault_catcher));
31713 +}
31714 +
31715 +int clear_user_tt(void *mem, int len)
31716 +{
31717 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
31718 +               return(len);
31719 +
31720 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
31721 +                              &current->thread.fault_catcher));
31722 +}
31723 +
31724 +int strnlen_user_tt(const void *str, int len)
31725 +{
31726 +       return(__do_strnlen_user(str, len,
31727 +                                &current->thread.fault_addr,
31728 +                                &current->thread.fault_catcher));
31729 +}
31730 +
31731 +/*
31732 + * Overrides for Emacs so that we follow Linus's tabbing style.
31733 + * Emacs will notice this stuff at the end of the file and automatically
31734 + * adjust the settings for this buffer only.  This must remain at the end
31735 + * of the file.
31736 + * ---------------------------------------------------------------------------
31737 + * Local variables:
31738 + * c-file-style: "linux"
31739 + * End:
31740 + */
31741 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess_user.c um/arch/um/kernel/tt/uaccess_user.c
31742 --- orig/arch/um/kernel/tt/uaccess_user.c       1969-12-31 19:00:00.000000000 -0500
31743 +++ um/arch/um/kernel/tt/uaccess_user.c 2003-11-12 08:51:13.000000000 -0500
31744 @@ -0,0 +1,98 @@
31745 +/* 
31746 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
31747 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
31748 + * Licensed under the GPL
31749 + */
31750 +
31751 +#include <setjmp.h>
31752 +#include <string.h>
31753 +#include "user_util.h"
31754 +#include "uml_uaccess.h"
31755 +#include "task.h"
31756 +#include "kern_util.h"
31757 +
31758 +int __do_copy_from_user(void *to, const void *from, int n,
31759 +                       void **fault_addr, void **fault_catcher)
31760 +{
31761 +       struct tt_regs save = TASK_REGS(get_current())->tt;
31762 +       unsigned long fault;
31763 +       int faulted;
31764 +
31765 +       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
31766 +                              __do_copy, &faulted);
31767 +       TASK_REGS(get_current())->tt = save;
31768 +
31769 +       if(!faulted) return(0);
31770 +       else return(n - (fault - (unsigned long) from));
31771 +}
31772 +
31773 +static void __do_strncpy(void *dst, const void *src, int count)
31774 +{
31775 +       strncpy(dst, src, count);
31776 +}      
31777 +
31778 +int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
31779 +                          void **fault_addr, void **fault_catcher)
31780 +{
31781 +       struct tt_regs save = TASK_REGS(get_current())->tt;
31782 +       unsigned long fault;
31783 +       int faulted;
31784 +
31785 +       fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
31786 +                              __do_strncpy, &faulted);
31787 +       TASK_REGS(get_current())->tt = save;
31788 +
31789 +       if(!faulted) return(strlen(dst));
31790 +       else return(-1);
31791 +}
31792 +
31793 +static void __do_clear(void *to, const void *from, int n)
31794 +{
31795 +       memset(to, 0, n);
31796 +}      
31797 +
31798 +int __do_clear_user(void *mem, unsigned long len,
31799 +                   void **fault_addr, void **fault_catcher)
31800 +{
31801 +       struct tt_regs save = TASK_REGS(get_current())->tt;
31802 +       unsigned long fault;
31803 +       int faulted;
31804 +
31805 +       fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
31806 +                              __do_clear, &faulted);
31807 +       TASK_REGS(get_current())->tt = save;
31808 +
31809 +       if(!faulted) return(0);
31810 +       else return(len - (fault - (unsigned long) mem));
31811 +}
31812 +
31813 +int __do_strnlen_user(const char *str, unsigned long n,
31814 +                     void **fault_addr, void **fault_catcher)
31815 +{
31816 +       struct tt_regs save = TASK_REGS(get_current())->tt;
31817 +       int ret;
31818 +       unsigned long *faddrp = (unsigned long *)fault_addr;
31819 +       jmp_buf jbuf;
31820 +
31821 +       *fault_catcher = &jbuf;
31822 +       if(sigsetjmp(jbuf, 1) == 0)
31823 +               ret = strlen(str) + 1;
31824 +       else ret = *faddrp - (unsigned long) str;
31825 +
31826 +       *fault_addr = NULL;
31827 +       *fault_catcher = NULL;
31828 +
31829 +       TASK_REGS(get_current())->tt = save;
31830 +       return ret;
31831 +}
31832 +
31833 +/*
31834 + * Overrides for Emacs so that we follow Linus's tabbing style.
31835 + * Emacs will notice this stuff at the end of the file and automatically
31836 + * adjust the settings for this buffer only.  This must remain at the end
31837 + * of the file.
31838 + * ---------------------------------------------------------------------------
31839 + * Local variables:
31840 + * c-file-style: "linux"
31841 + * End:
31842 + */
31843 diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/unmap.c um/arch/um/kernel/tt/unmap.c
31844 --- orig/arch/um/kernel/tt/unmap.c      1969-12-31 19:00:00.000000000 -0500
31845 +++ um/arch/um/kernel/tt/unmap.c        2003-10-21 03:26:07.000000000 -0400
31846 @@ -0,0 +1,31 @@
31847 +/* 
31848 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
31849 + * Licensed under the GPL
31850 + */
31851 +
31852 +#include <sys/mman.h>
31853 +
31854 +int switcheroo(int fd, int prot, void *from, void *to, int size)
31855 +{
31856 +       if(munmap(to, size) < 0){
31857 +               return(-1);
31858 +       }
31859 +       if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
31860 +               return(-1);
31861 +       }
31862 +       if(munmap(from, size) < 0){
31863 +               return(-1);
31864 +       }
31865 +       return(0);
31866 +}
31867 +
31868 +/*
31869 + * Overrides for Emacs so that we follow Linus's tabbing style.
31870 + * Emacs will notice this stuff at the end of the file and automatically
31871 + * adjust the settings for this buffer only.  This must remain at the end
31872 + * of the file.
31873 + * ---------------------------------------------------------------------------
31874 + * Local variables:
31875 + * c-file-style: "linux"
31876 + * End:
31877 + */
31878 diff -Naur -X ../exclude-files orig/arch/um/kernel/tty_log.c um/arch/um/kernel/tty_log.c
31879 --- orig/arch/um/kernel/tty_log.c       1969-12-31 19:00:00.000000000 -0500
31880 +++ um/arch/um/kernel/tty_log.c 2003-10-21 03:26:07.000000000 -0400
31881 @@ -0,0 +1,228 @@
31882 +/* 
31883 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and 
31884 + * geoffrey hing <ghing@net.ohio-state.edu>
31885 + * Licensed under the GPL
31886 + */
31887 +
31888 +#include <errno.h>
31889 +#include <string.h>
31890 +#include <stdio.h>
31891 +#include <stdlib.h>
31892 +#include <unistd.h>
31893 +#include <sys/time.h>
31894 +#include "init.h"
31895 +#include "user.h"
31896 +#include "kern_util.h"
31897 +#include "os.h"
31898 +
31899 +#define TTY_LOG_DIR "./"
31900 +
31901 +/* Set early in boot and then unchanged */
31902 +static char *tty_log_dir = TTY_LOG_DIR;
31903 +static int tty_log_fd = -1;
31904 +
31905 +#define TTY_LOG_OPEN 1
31906 +#define TTY_LOG_CLOSE 2
31907 +#define TTY_LOG_WRITE 3
31908 +#define TTY_LOG_EXEC 4
31909 +
31910 +#define TTY_READ 1
31911 +#define TTY_WRITE 2
31912 +
31913 +struct tty_log_buf {
31914 +       int what;
31915 +       unsigned long tty;
31916 +       int len;
31917 +       int direction;
31918 +       unsigned long sec;
31919 +       unsigned long usec;
31920 +};
31921 +
31922 +int open_tty_log(void *tty, void *current_tty)
31923 +{
31924 +       struct timeval tv;
31925 +       struct tty_log_buf data;
31926 +       char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
31927 +       int fd;
31928 +
31929 +       gettimeofday(&tv, NULL);
31930 +       if(tty_log_fd != -1){
31931 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
31932 +                                              .tty  = (unsigned long) tty,
31933 +                                              .len  = sizeof(current_tty),
31934 +                                              .direction = 0,
31935 +                                              .sec = tv.tv_sec,
31936 +                                              .usec = tv.tv_usec } );
31937 +               os_write_file(tty_log_fd, &data, sizeof(data));
31938 +               os_write_file(tty_log_fd, &current_tty, data.len);
31939 +               return(tty_log_fd);
31940 +       }
31941 +
31942 +       sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
31943 +               (unsigned int) tv.tv_usec);
31944 +
31945 +       fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
31946 +                         0644);
31947 +       if(fd < 0){
31948 +               printk("open_tty_log : couldn't open '%s', errno = %d\n",
31949 +                      buf, -fd);
31950 +       }
31951 +       return(fd);
31952 +}
31953 +
31954 +void close_tty_log(int fd, void *tty)
31955 +{
31956 +       struct tty_log_buf data;
31957 +       struct timeval tv;
31958 +
31959 +       if(tty_log_fd != -1){
31960 +               gettimeofday(&tv, NULL);
31961 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
31962 +                                              .tty  = (unsigned long) tty,
31963 +                                              .len  = 0,
31964 +                                              .direction = 0,
31965 +                                              .sec = tv.tv_sec,
31966 +                                              .usec = tv.tv_usec } );
31967 +               os_write_file(tty_log_fd, &data, sizeof(data));
31968 +               return;
31969 +       }
31970 +       os_close_file(fd);
31971 +}
31972 +
31973 +static int log_chunk(int fd, const char *buf, int len)
31974 +{
31975 +       int total = 0, try, missed, n;
31976 +       char chunk[64];
31977 +
31978 +       while(len > 0){
31979 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
31980 +               missed = copy_from_user_proc(chunk, (char *) buf, try);
31981 +               try -= missed;
31982 +               n = os_write_file(fd, chunk, try);
31983 +               if(n != try) {
31984 +                       if(n < 0) 
31985 +                               return(n);
31986 +                       return(-EIO);
31987 +               }
31988 +               if(missed != 0)
31989 +                       return(-EFAULT);
31990 +
31991 +               len -= try;
31992 +               total += try;
31993 +               buf += try;
31994 +       }
31995 +
31996 +       return(total);
31997 +}
31998 +
31999 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
32000 +{
32001 +       struct timeval tv;
32002 +       struct tty_log_buf data;
32003 +       int direction;
32004 +
32005 +       if(fd == tty_log_fd){
32006 +               gettimeofday(&tv, NULL);
32007 +               direction = is_read ? TTY_READ : TTY_WRITE;
32008 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
32009 +                                              .tty  = (unsigned long) tty,
32010 +                                              .len  = len,
32011 +                                              .direction = direction,
32012 +                                              .sec = tv.tv_sec,
32013 +                                              .usec = tv.tv_usec } );
32014 +               os_write_file(tty_log_fd, &data, sizeof(data));
32015 +       }
32016 +
32017 +       return(log_chunk(fd, buf, len));
32018 +}
32019 +
32020 +void log_exec(char **argv, void *tty)
32021 +{
32022 +       struct timeval tv;
32023 +       struct tty_log_buf data;
32024 +       char **ptr,*arg;
32025 +       int len;
32026 +       
32027 +       if(tty_log_fd == -1) return;
32028 +
32029 +       gettimeofday(&tv, NULL);
32030 +
32031 +       len = 0;
32032 +       for(ptr = argv; ; ptr++){
32033 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
32034 +                       return;
32035 +               if(arg == NULL) break;
32036 +               len += strlen_user_proc(arg);
32037 +       }
32038 +
32039 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
32040 +                                      .tty  = (unsigned long) tty,
32041 +                                      .len  = len,
32042 +                                      .direction = 0,
32043 +                                      .sec = tv.tv_sec,
32044 +                                      .usec = tv.tv_usec } );
32045 +       os_write_file(tty_log_fd, &data, sizeof(data));
32046 +
32047 +       for(ptr = argv; ; ptr++){
32048 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
32049 +                       return;
32050 +               if(arg == NULL) break;
32051 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
32052 +       }
32053 +}
32054 +
32055 +extern void register_tty_logger(int (*opener)(void *, void *),
32056 +                               int (*writer)(int, const char *, int, 
32057 +                                             void *, int),
32058 +                               void (*closer)(int, void *));
32059 +
32060 +static int register_logger(void)
32061 +{
32062 +       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
32063 +       return(0);
32064 +}
32065 +
32066 +__uml_initcall(register_logger);
32067 +
32068 +static int __init set_tty_log_dir(char *name, int *add)
32069 +{
32070 +       tty_log_dir = name;
32071 +       return 0;
32072 +}
32073 +
32074 +__uml_setup("tty_log_dir=", set_tty_log_dir,
32075 +"tty_log_dir=<directory>\n"
32076 +"    This is used to specify the directory where the logs of all pty\n"
32077 +"    data from this UML machine will be written.\n\n"
32078 +);
32079 +
32080 +static int __init set_tty_log_fd(char *name, int *add)
32081 +{
32082 +       char *end;
32083 +
32084 +       tty_log_fd = strtoul(name, &end, 0);
32085 +       if((*end != '\0') || (end == name)){
32086 +               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
32087 +               tty_log_fd = -1;
32088 +       }
32089 +       return 0;
32090 +}
32091 +
32092 +__uml_setup("tty_log_fd=", set_tty_log_fd,
32093 +"tty_log_fd=<fd>\n"
32094 +"    This is used to specify a preconfigured file descriptor to which all\n"
32095 +"    tty data will be written.  Preconfigure the descriptor with something\n"
32096 +"    like '10>tty_log tty_log_fd=10'.\n\n"
32097 +);
32098 +
32099 +
32100 +/*
32101 + * Overrides for Emacs so that we follow Linus's tabbing style.
32102 + * Emacs will notice this stuff at the end of the file and automatically
32103 + * adjust the settings for this buffer only.  This must remain at the end
32104 + * of the file.
32105 + * ---------------------------------------------------------------------------
32106 + * Local variables:
32107 + * c-file-style: "linux"
32108 + * End:
32109 + */
32110 diff -Naur -X ../exclude-files orig/arch/um/kernel/uaccess_user.c um/arch/um/kernel/uaccess_user.c
32111 --- orig/arch/um/kernel/uaccess_user.c  1969-12-31 19:00:00.000000000 -0500
32112 +++ um/arch/um/kernel/uaccess_user.c    2003-10-21 03:26:07.000000000 -0400
32113 @@ -0,0 +1,64 @@
32114 +/* 
32115 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
32116 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32117 + * Licensed under the GPL
32118 + */
32119 +
32120 +#include <setjmp.h>
32121 +#include <string.h>
32122 +
32123 +/* These are here rather than tt/uaccess.c because skas mode needs them in
32124 + * order to do SIGBUS recovery when a tmpfs mount runs out of room.
32125 + */
32126 +
32127 +unsigned long __do_user_copy(void *to, const void *from, int n,
32128 +                            void **fault_addr, void **fault_catcher,
32129 +                            void (*op)(void *to, const void *from,
32130 +                                       int n), int *faulted_out)
32131 +{
32132 +       unsigned long *faddrp = (unsigned long *) fault_addr, ret;
32133 +
32134 +       jmp_buf jbuf;
32135 +       *fault_catcher = &jbuf;
32136 +       if(sigsetjmp(jbuf, 1) == 0){
32137 +               (*op)(to, from, n);
32138 +               ret = 0;
32139 +               *faulted_out = 0;
32140 +       } 
32141 +       else {
32142 +               ret = *faddrp;
32143 +               *faulted_out = 1;
32144 +       }
32145 +       *fault_addr = NULL;
32146 +       *fault_catcher = NULL;
32147 +       return ret;
32148 +}
32149 +
32150 +void __do_copy(void *to, const void *from, int n)
32151 +{
32152 +       memcpy(to, from, n);
32153 +}      
32154 +
32155 +
32156 +int __do_copy_to_user(void *to, const void *from, int n,
32157 +                     void **fault_addr, void **fault_catcher)
32158 +{
32159 +       unsigned long fault;
32160 +       int faulted;
32161 +
32162 +       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
32163 +                              __do_copy, &faulted);
32164 +       if(!faulted) return(0);
32165 +       else return(n - (fault - (unsigned long) to));
32166 +}
32167 +
32168 +/*
32169 + * Overrides for Emacs so that we follow Linus's tabbing style.
32170 + * Emacs will notice this stuff at the end of the file and automatically
32171 + * adjust the settings for this buffer only.  This must remain at the end
32172 + * of the file.
32173 + * ---------------------------------------------------------------------------
32174 + * Local variables:
32175 + * c-file-style: "linux"
32176 + * End:
32177 + */
32178 diff -Naur -X ../exclude-files orig/arch/um/kernel/um_arch.c um/arch/um/kernel/um_arch.c
32179 --- orig/arch/um/kernel/um_arch.c       1969-12-31 19:00:00.000000000 -0500
32180 +++ um/arch/um/kernel/um_arch.c 2003-12-14 11:19:59.000000000 -0500
32181 @@ -0,0 +1,432 @@
32182 +/* 
32183 + * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
32184 + * Licensed under the GPL
32185 + */
32186 +
32187 +#include "linux/config.h"
32188 +#include "linux/kernel.h"
32189 +#include "linux/sched.h"
32190 +#include "linux/notifier.h"
32191 +#include "linux/mm.h"
32192 +#include "linux/types.h"
32193 +#include "linux/tty.h"
32194 +#include "linux/init.h"
32195 +#include "linux/bootmem.h"
32196 +#include "linux/spinlock.h"
32197 +#include "linux/utsname.h"
32198 +#include "linux/sysrq.h"
32199 +#include "linux/seq_file.h"
32200 +#include "linux/delay.h"
32201 +#include "asm/page.h"
32202 +#include "asm/pgtable.h"
32203 +#include "asm/ptrace.h"
32204 +#include "asm/elf.h"
32205 +#include "asm/user.h"
32206 +#include "ubd_user.h"
32207 +#include "asm/current.h"
32208 +#include "user_util.h"
32209 +#include "kern_util.h"
32210 +#include "kern.h"
32211 +#include "mprot.h"
32212 +#include "mem_user.h"
32213 +#include "mem.h"
32214 +#include "umid.h"
32215 +#include "initrd.h"
32216 +#include "init.h"
32217 +#include "os.h"
32218 +#include "choose-mode.h"
32219 +#include "mode_kern.h"
32220 +#include "mode.h"
32221 +
32222 +#define DEFAULT_COMMAND_LINE "root=/dev/ubd0"
32223 +
32224 +struct cpuinfo_um boot_cpu_data = { 
32225 +       .loops_per_jiffy        = 0,
32226 +       .pgd_quick              = NULL,
32227 +       .pmd_quick              = NULL,
32228 +       .pte_quick              = NULL,
32229 +       .pgtable_cache_sz       = 0,
32230 +       .ipi_pipe               = { -1, -1 }
32231 +};
32232 +
32233 +unsigned long thread_saved_pc(struct thread_struct *thread)
32234 +{
32235 +       return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
32236 +                                             thread)));
32237 +}
32238 +
32239 +static int show_cpuinfo(struct seq_file *m, void *v)
32240 +{
32241 +       int index = 0;
32242 +
32243 +#ifdef CONFIG_SMP
32244 +       index = (struct cpuinfo_um *)v - cpu_data;
32245 +       if (!(cpu_online_map & (1 << index)))
32246 +               return 0;
32247 +#endif
32248 +
32249 +       seq_printf(m, "processor\t: %d\n", index);
32250 +       seq_printf(m, "vendor_id\t: User Mode Linux\n");
32251 +       seq_printf(m, "model name\t: UML\n");
32252 +       seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
32253 +       seq_printf(m, "host\t\t: %s\n", host_info);
32254 +       seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
32255 +                  loops_per_jiffy/(500000/HZ),
32256 +                  (loops_per_jiffy/(5000/HZ)) % 100);
32257 +
32258 +       return(0);
32259 +}
32260 +
32261 +static void *c_start(struct seq_file *m, loff_t *pos)
32262 +{
32263 +       return *pos < NR_CPUS ? cpu_data + *pos : NULL;
32264 +}
32265 +
32266 +static void *c_next(struct seq_file *m, void *v, loff_t *pos)
32267 +{
32268 +       ++*pos;
32269 +       return c_start(m, pos);
32270 +}
32271 +
32272 +static void c_stop(struct seq_file *m, void *v)
32273 +{
32274 +}
32275 +
32276 +struct seq_operations cpuinfo_op = {
32277 +       .start  = c_start,
32278 +       .next   = c_next,
32279 +       .stop   = c_stop,
32280 +       .show   = show_cpuinfo,
32281 +};
32282 +
32283 +pte_t * __bad_pagetable(void)
32284 +{
32285 +       panic("Someone should implement __bad_pagetable");
32286 +       return(NULL);
32287 +}
32288 +
32289 +/* Set in linux_main */
32290 +unsigned long host_task_size;
32291 +unsigned long task_size;
32292 +unsigned long uml_start;
32293 +
32294 +/* Set in early boot */
32295 +unsigned long uml_physmem;
32296 +unsigned long uml_reserved;
32297 +unsigned long start_vm;
32298 +unsigned long end_vm;
32299 +int ncpus = 1;
32300 +
32301 +#ifdef CONFIG_MODE_TT
32302 +/* Pointer set in linux_main, the array itself is private to each thread,
32303 + * and changed at address space creation time so this poses no concurrency
32304 + * problems.
32305 + */
32306 +static char *argv1_begin = NULL;
32307 +static char *argv1_end = NULL;
32308 +#endif
32309 +
32310 +/* Set in early boot */
32311 +static int have_root __initdata = 0;
32312 +long physmem_size = 32 * 1024 * 1024;
32313 +
32314 +void set_cmdline(char *cmd)
32315 +{
32316 +#ifdef CONFIG_MODE_TT
32317 +       char *umid, *ptr;
32318 +
32319 +       if(CHOOSE_MODE(honeypot, 0)) return;
32320 +
32321 +       umid = get_umid(1);
32322 +       if(umid != NULL){
32323 +               snprintf(argv1_begin, 
32324 +                        (argv1_end - argv1_begin) * sizeof(*ptr), 
32325 +                        "(%s) ", umid);
32326 +               ptr = &argv1_begin[strlen(argv1_begin)];
32327 +       }
32328 +       else ptr = argv1_begin;
32329 +
32330 +       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
32331 +       memset(argv1_begin + strlen(argv1_begin), '\0', 
32332 +              argv1_end - argv1_begin - strlen(argv1_begin));
32333 +#endif
32334 +}
32335 +
32336 +static char *usage_string = 
32337 +"User Mode Linux v%s\n"
32338 +"      available at http://user-mode-linux.sourceforge.net/\n\n";
32339 +
32340 +static int __init uml_version_setup(char *line, int *add)
32341 +{
32342 +       printf("%s\n", system_utsname.release);
32343 +       exit(0);
32344 +}
32345 +
32346 +__uml_setup("--version", uml_version_setup,
32347 +"--version\n"
32348 +"    Prints the version number of the kernel.\n\n"
32349 +);
32350 +
32351 +static int __init uml_root_setup(char *line, int *add)
32352 +{
32353 +       have_root = 1;
32354 +       return 0;
32355 +}
32356 +
32357 +__uml_setup("root=", uml_root_setup,
32358 +"root=<file containing the root fs>\n"
32359 +"    This is actually used by the generic kernel in exactly the same\n"
32360 +"    way as in any other kernel. If you configure a number of block\n"
32361 +"    devices and want to boot off something other than ubd0, you \n"
32362 +"    would use something like:\n"
32363 +"        root=/dev/ubd5\n\n"
32364 +);
32365 +
32366 +#ifdef CONFIG_SMP
32367 +static int __init uml_ncpus_setup(char *line, int *add)
32368 +{
32369 +       if (!sscanf(line, "%d", &ncpus)) {
32370 +               printf("Couldn't parse [%s]\n", line);
32371 +               return -1;
32372 +       }
32373 +
32374 +       return 0;
32375 +}
32376 +
32377 +__uml_setup("ncpus=", uml_ncpus_setup,
32378 +"ncpus=<# of desired CPUs>\n"
32379 +"    This tells an SMP kernel how many virtual processors to start.\n\n" 
32380 +);
32381 +#endif
32382 +
32383 +int force_tt = 0;
32384 +
32385 +#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
32386 +#define DEFAULT_TT 0
32387 +
32388 +static int __init mode_tt_setup(char *line, int *add)
32389 +{
32390 +       force_tt = 1;
32391 +       return(0);
32392 +}
32393 +
32394 +#else
32395 +#ifdef CONFIG_MODE_SKAS
32396 +
32397 +#define DEFAULT_TT 0
32398 +
32399 +static int __init mode_tt_setup(char *line, int *add)
32400 +{
32401 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
32402 +       return(0);
32403 +}
32404 +
32405 +#else
32406 +#ifdef CONFIG_MODE_TT
32407 +
32408 +#define DEFAULT_TT 1
32409 +
32410 +static int __init mode_tt_setup(char *line, int *add)
32411 +{
32412 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
32413 +       return(0);
32414 +}
32415 +
32416 +#else
32417 +
32418 +#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled
32419 +
32420 +#endif
32421 +#endif
32422 +#endif
32423 +
32424 +__uml_setup("mode=tt", mode_tt_setup,
32425 +"mode=tt\n"
32426 +"    When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
32427 +"    forces UML to run in tt (tracing thread) mode.  It is not the default\n"
32428 +"    because it's slower and less secure than skas mode.\n\n"
32429 +);
32430 +
32431 +int mode_tt = DEFAULT_TT;
32432 +
32433 +static int __init Usage(char *line, int *add)
32434 +{
32435 +       const char **p;
32436 +
32437 +       printf(usage_string, system_utsname.release);
32438 +       p = &__uml_help_start;
32439 +       while (p < &__uml_help_end) {
32440 +               printf("%s", *p);
32441 +               p++;
32442 +       }
32443 +       exit(0);
32444 +}
32445 +
32446 +__uml_setup("--help", Usage,
32447 +"--help\n"
32448 +"    Prints this message.\n\n"
32449 +);
32450 +
32451 +static int __init uml_checksetup(char *line, int *add)
32452 +{
32453 +       struct uml_param *p;
32454 +
32455 +       p = &__uml_setup_start;
32456 +       while(p < &__uml_setup_end) {
32457 +               int n;
32458 +
32459 +               n = strlen(p->str);
32460 +               if(!strncmp(line, p->str, n)){
32461 +                       if (p->setup_func(line + n, add)) return 1;
32462 +               }
32463 +               p++;
32464 +       }
32465 +       return 0;
32466 +}
32467 +
32468 +static void __init uml_postsetup(void)
32469 +{
32470 +       initcall_t *p;
32471 +
32472 +       p = &__uml_postsetup_start;
32473 +       while(p < &__uml_postsetup_end){
32474 +               (*p)();
32475 +               p++;
32476 +       }
32477 +       return;
32478 +}
32479 +
32480 +/* Set during early boot */
32481 +unsigned long brk_start;
32482 +unsigned long end_iomem;
32483 +
32484 +#define MIN_VMALLOC (32 * 1024 * 1024)
32485 +
32486 +int linux_main(int argc, char **argv)
32487 +{
32488 +       unsigned long avail;
32489 +       unsigned long virtmem_size, max_physmem;
32490 +       unsigned int i, add;
32491 +
32492 +       for (i = 1; i < argc; i++){
32493 +               if((i == 1) && (argv[i][0] == ' ')) continue;
32494 +               add = 1;
32495 +               uml_checksetup(argv[i], &add);
32496 +               if(add) add_arg(saved_command_line, argv[i]);
32497 +       }
32498 +       if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
32499 +
32500 +       mode_tt = force_tt ? 1 : !can_do_skas();
32501 +       uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
32502 +                                    &host_task_size, &task_size);
32503 +
32504 +       brk_start = (unsigned long) sbrk(0);
32505 +       CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
32506 +
32507 +       uml_physmem = uml_start;
32508 +
32509 +       /* Reserve up to 4M after the current brk */
32510 +       uml_reserved = ROUND_4M(brk_start) + (1 << 22);
32511 +
32512 +       setup_machinename(system_utsname.machine);
32513 +
32514 +#ifdef CONFIG_MODE_TT
32515 +       argv1_begin = argv[1];
32516 +       argv1_end = &argv[1][strlen(argv[1])];
32517 +#endif
32518 +  
32519 +       highmem = 0;
32520 +       iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
32521 +       max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
32522 +
32523 +       /* Zones have to begin on a 1 << MAX_ORDER page boundary,
32524 +        * so this makes sure that's true for highmem
32525 +        */
32526 +       max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
32527 +       if(physmem_size + iomem_size > max_physmem){
32528 +               highmem = physmem_size + iomem_size - max_physmem;
32529 +               physmem_size -= highmem;
32530 +#ifndef CONFIG_HIGHMEM
32531 +               highmem = 0;
32532 +               printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
32533 +                      "to %ld bytes\n", physmem_size);
32534 +#endif
32535 +       }
32536 +
32537 +       high_physmem = uml_physmem + physmem_size;
32538 +       end_iomem = high_physmem + iomem_size;
32539 +       high_memory = (void *) end_iomem;
32540 +
32541 +       start_vm = VMALLOC_START;
32542 +
32543 +       setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
32544 +       if(init_maps(physmem_size, iomem_size, highmem)){
32545 +               printf("Failed to allocate mem_map for %ld bytes of physical "
32546 +                      "memory and %ld bytes of highmem\n", physmem_size,
32547 +                      highmem);
32548 +               exit(1);
32549 +       }
32550 +
32551 +       virtmem_size = physmem_size;
32552 +       avail = get_kmem_end() - start_vm;
32553 +       if(physmem_size > avail) virtmem_size = avail;
32554 +       end_vm = start_vm + virtmem_size;
32555 +
32556 +       if(virtmem_size < physmem_size)
32557 +               printf("Kernel virtual memory size shrunk to %ld bytes\n",
32558 +                      virtmem_size);
32559 +
32560 +       uml_postsetup();
32561 +
32562 +       init_task.thread.kernel_stack = (unsigned long) &init_task + 
32563 +               2 * PAGE_SIZE;
32564 +
32565 +       task_protections((unsigned long) &init_task);
32566 +       os_flush_stdout();
32567 +
32568 +       return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
32569 +}
32570 +
32571 +static int panic_exit(struct notifier_block *self, unsigned long unused1,
32572 +                     void *unused2)
32573 +{
32574 +#ifdef CONFIG_SYSRQ
32575 +       handle_sysrq('p', &current->thread.regs, NULL, NULL);
32576 +#endif
32577 +       machine_halt();
32578 +       return(0);
32579 +}
32580 +
32581 +static struct notifier_block panic_exit_notifier = {
32582 +       .notifier_call          = panic_exit,
32583 +       .next                   = NULL,
32584 +       .priority               = 0
32585 +};
32586 +
32587 +void __init setup_arch(char **cmdline_p)
32588 +{
32589 +       notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
32590 +       paging_init();
32591 +       strcpy(command_line, saved_command_line);
32592 +       *cmdline_p = command_line;
32593 +       setup_hostinfo();
32594 +}
32595 +
32596 +void __init check_bugs(void)
32597 +{
32598 +       arch_check_bugs();
32599 +       check_ptrace();
32600 +       check_sigio();
32601 +       check_devanon();
32602 +}
32603 +
32604 +/*
32605 + * Overrides for Emacs so that we follow Linus's tabbing style.
32606 + * Emacs will notice this stuff at the end of the file and automatically
32607 + * adjust the settings for this buffer only.  This must remain at the end
32608 + * of the file.
32609 + * ---------------------------------------------------------------------------
32610 + * Local variables:
32611 + * c-file-style: "linux"
32612 + * End:
32613 + */
32614 diff -Naur -X ../exclude-files orig/arch/um/kernel/umid.c um/arch/um/kernel/umid.c
32615 --- orig/arch/um/kernel/umid.c  1969-12-31 19:00:00.000000000 -0500
32616 +++ um/arch/um/kernel/umid.c    2003-10-21 03:26:07.000000000 -0400
32617 @@ -0,0 +1,324 @@
32618 +/* 
32619 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
32620 + * Licensed under the GPL
32621 + */
32622 +
32623 +#include <stdio.h>
32624 +#include <unistd.h>
32625 +#include <errno.h>
32626 +#include <string.h>
32627 +#include <stdlib.h>
32628 +#include <dirent.h>
32629 +#include <signal.h>
32630 +#include <sys/stat.h>
32631 +#include <sys/param.h>
32632 +#include "user.h"
32633 +#include "umid.h"
32634 +#include "init.h"
32635 +#include "os.h"
32636 +#include "user_util.h"
32637 +#include "choose-mode.h"
32638 +
32639 +#define UMID_LEN 64
32640 +#define UML_DIR "~/.uml/"
32641 +
32642 +/* Changed by set_umid and make_umid, which are run early in boot */
32643 +static char umid[UMID_LEN] = { 0 };
32644 +
32645 +/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
32646 +static char *uml_dir = UML_DIR;
32647 +
32648 +/* Changed by set_umid */
32649 +static int umid_is_random = 1;
32650 +static int umid_inited = 0;
32651 +
32652 +static int make_umid(int (*printer)(const char *fmt, ...));
32653 +
32654 +static int __init set_umid(char *name, int is_random, 
32655 +                          int (*printer)(const char *fmt, ...))
32656 +{
32657 +       if(umid_inited){
32658 +               (*printer)("Unique machine name can't be set twice\n");
32659 +               return(-1);
32660 +       }
32661 +
32662 +       if(strlen(name) > UMID_LEN - 1)
32663 +               (*printer)("Unique machine name is being truncated to %s "
32664 +                          "characters\n", UMID_LEN);
32665 +       strncpy(umid, name, UMID_LEN - 1);
32666 +       umid[UMID_LEN - 1] = '\0';
32667 +
32668 +       umid_is_random = is_random;
32669 +       umid_inited = 1;
32670 +       return 0;
32671 +}
32672 +
32673 +static int __init set_umid_arg(char *name, int *add)
32674 +{
32675 +       return(set_umid(name, 0, printf));
32676 +}
32677 +
32678 +__uml_setup("umid=", set_umid_arg,
32679 +"umid=<name>\n"
32680 +"    This is used to assign a unique identity to this UML machine and\n"
32681 +"    is used for naming the pid file and management console socket.\n\n"
32682 +);
32683 +
32684 +int __init umid_file_name(char *name, char *buf, int len)
32685 +{
32686 +       int n;
32687 +
32688 +       if(!umid_inited && make_umid(printk)) return(-1);
32689 +
32690 +       n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
32691 +       if(n > len){
32692 +               printk("umid_file_name : buffer too short\n");
32693 +               return(-1);
32694 +       }
32695 +
32696 +       sprintf(buf, "%s%s/%s", uml_dir, umid, name);
32697 +       return(0);
32698 +}
32699 +
32700 +extern int tracing_pid;
32701 +
32702 +static int __init create_pid_file(void)
32703 +{
32704 +       char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
32705 +       char pid[sizeof("nnnnn\0")];
32706 +       int fd, n;
32707 +
32708 +       if(umid_file_name("pid", file, sizeof(file))) return 0;
32709 +
32710 +       fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
32711 +                         0644);
32712 +       if(fd < 0){
32713 +               printf("Open of machine pid file \"%s\" failed - "
32714 +                      "err = %d\n", file, -fd);
32715 +               return 0;
32716 +       }
32717 +
32718 +       sprintf(pid, "%d\n", os_getpid());
32719 +       n = os_write_file(fd, pid, strlen(pid));
32720 +       if(n != strlen(pid))
32721 +               printf("Write of pid file failed - err = %d\n", -n);
32722 +       os_close_file(fd);
32723 +       return 0;
32724 +}
32725 +
32726 +static int actually_do_remove(char *dir)
32727 +{
32728 +       DIR *directory;
32729 +       struct dirent *ent;
32730 +       int len;
32731 +       char file[256];
32732 +
32733 +       directory = opendir(dir);
32734 +       if(directory == NULL){
32735 +               printk("actually_do_remove : couldn't open directory '%s', "
32736 +                      "errno = %d\n", dir, errno);
32737 +               return(1);
32738 +       }
32739 +       while((ent = readdir(directory)) != NULL){
32740 +               if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
32741 +                       continue;
32742 +               len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
32743 +               if(len > sizeof(file)){
32744 +                       printk("Not deleting '%s' from '%s' - name too long\n",
32745 +                              ent->d_name, dir);
32746 +                       continue;
32747 +               }
32748 +               sprintf(file, "%s/%s", dir, ent->d_name);
32749 +               if(unlink(file) < 0){
32750 +                       printk("actually_do_remove : couldn't remove '%s' "
32751 +                              "from '%s', errno = %d\n", ent->d_name, dir, 
32752 +                              errno);
32753 +                       return(1);
32754 +               }
32755 +       }
32756 +       if(rmdir(dir) < 0){
32757 +               printk("actually_do_remove : couldn't rmdir '%s', "
32758 +                      "errno = %d\n", dir, errno);
32759 +               return(1);
32760 +       }
32761 +       return(0);
32762 +}
32763 +
32764 +void remove_umid_dir(void)
32765 +{
32766 +       char dir[strlen(uml_dir) + UMID_LEN + 1];
32767 +       if(!umid_inited) return;
32768 +
32769 +       sprintf(dir, "%s%s", uml_dir, umid);
32770 +       actually_do_remove(dir);
32771 +}
32772 +
32773 +char *get_umid(int only_if_set)
32774 +{
32775 +       if(only_if_set && umid_is_random) return(NULL);
32776 +       return(umid);
32777 +}
32778 +
32779 +int not_dead_yet(char *dir)
32780 +{
32781 +       char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
32782 +       char pid[sizeof("nnnnn\0")], *end;
32783 +       int dead, fd, p, n;
32784 +
32785 +       sprintf(file, "%s/pid", dir);
32786 +       dead = 0;
32787 +       fd = os_open_file(file, of_read(OPENFLAGS()), 0);
32788 +       if(fd < 0){
32789 +               if(fd != -ENOENT){
32790 +                       printk("not_dead_yet : couldn't open pid file '%s', "
32791 +                              "err = %d\n", file, -fd);
32792 +                       return(1);
32793 +               }
32794 +               dead = 1;
32795 +       }
32796 +       if(fd > 0){
32797 +               n = os_read_file(fd, pid, sizeof(pid));
32798 +               if(n < 0){
32799 +                       printk("not_dead_yet : couldn't read pid file '%s', "
32800 +                              "err = %d\n", file, -n);
32801 +                       return(1);
32802 +               }
32803 +               p = strtoul(pid, &end, 0);
32804 +               if(end == pid){
32805 +                       printk("not_dead_yet : couldn't parse pid file '%s', "
32806 +                              "errno = %d\n", file, errno);
32807 +                       dead = 1;
32808 +               }
32809 +               if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
32810 +                  (p == CHOOSE_MODE(tracing_pid, os_getpid())))
32811 +                       dead = 1;
32812 +       }
32813 +       if(!dead) return(1);
32814 +       return(actually_do_remove(dir));
32815 +}
32816 +
32817 +static int __init set_uml_dir(char *name, int *add)
32818 +{
32819 +       if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
32820 +               uml_dir = malloc(strlen(name) + 1);
32821 +               if(uml_dir == NULL){
32822 +                       printf("Failed to malloc uml_dir - error = %d\n",
32823 +                              errno);
32824 +                       uml_dir = name;
32825 +                       return(0);
32826 +               }
32827 +               sprintf(uml_dir, "%s/", name);
32828 +       }
32829 +       else uml_dir = name;
32830 +       return 0;
32831 +}
32832 +
32833 +static int __init make_uml_dir(void)
32834 +{
32835 +       char dir[MAXPATHLEN + 1] = { '\0' };
32836 +       int len;
32837 +
32838 +       if(*uml_dir == '~'){
32839 +               char *home = getenv("HOME");
32840 +
32841 +               if(home == NULL){
32842 +                       printf("make_uml_dir : no value in environment for "
32843 +                              "$HOME\n");
32844 +                       exit(1);
32845 +               }
32846 +               strncpy(dir, home, sizeof(dir));
32847 +               uml_dir++;
32848 +       }
32849 +       len = strlen(dir);
32850 +       strncat(dir, uml_dir, sizeof(dir) - len);
32851 +       len = strlen(dir);
32852 +       if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){
32853 +               dir[len] = '/';
32854 +               dir[len + 1] = '\0';
32855 +       }
32856 +
32857 +       uml_dir = malloc(strlen(dir) + 1);
32858 +       if(uml_dir == NULL){
32859 +               printf("make_uml_dir : malloc failed, errno = %d\n", errno);
32860 +               exit(1);
32861 +       }
32862 +       strcpy(uml_dir, dir);
32863 +       
32864 +       if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
32865 +               printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
32866 +               return(-1);
32867 +       }
32868 +       return 0;
32869 +}
32870 +
32871 +static int __init make_umid(int (*printer)(const char *fmt, ...))
32872 +{
32873 +       int fd, err;
32874 +       char tmp[strlen(uml_dir) + UMID_LEN + 1];
32875 +
32876 +       strncpy(tmp, uml_dir, sizeof(tmp) - 1);
32877 +       tmp[sizeof(tmp) - 1] = '\0';
32878 +
32879 +       if(!umid_inited){
32880 +               strcat(tmp, "XXXXXX");
32881 +               fd = mkstemp(tmp);
32882 +               if(fd < 0){
32883 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
32884 +                                  errno);
32885 +                       return(1);
32886 +               }
32887 +
32888 +               os_close_file(fd);
32889 +               /* There's a nice tiny little race between this unlink and
32890 +                * the mkdir below.  It'd be nice if there were a mkstemp
32891 +                * for directories.
32892 +                */
32893 +               unlink(tmp);
32894 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
32895 +       }
32896 +       
32897 +       sprintf(tmp, "%s%s", uml_dir, umid);
32898 +
32899 +       err = mkdir(tmp, 0777);
32900 +       if(err < 0){
32901 +               if(errno == EEXIST){
32902 +                       if(not_dead_yet(tmp)){
32903 +                               (*printer)("umid '%s' is in use\n", umid);
32904 +                               return(-1);
32905 +                       }
32906 +                       err = mkdir(tmp, 0777);
32907 +               }
32908 +       }
32909 +       if(err < 0){
32910 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
32911 +               return(-1);
32912 +       }
32913 +
32914 +       return(0);
32915 +}
32916 +
32917 +__uml_setup("uml_dir=", set_uml_dir,
32918 +"uml_dir=<directory>\n"
32919 +"    The location to place the pid and umid files.\n\n"
32920 +);
32921 +
32922 +__uml_postsetup(make_uml_dir);
32923 +
32924 +static int __init make_umid_setup(void)
32925 +{
32926 +       return(make_umid(printf));
32927 +}
32928 +
32929 +__uml_postsetup(make_umid_setup);
32930 +__uml_postsetup(create_pid_file);
32931 +
32932 +/*
32933 + * Overrides for Emacs so that we follow Linus's tabbing style.
32934 + * Emacs will notice this stuff at the end of the file and automatically
32935 + * adjust the settings for this buffer only.  This must remain at the end
32936 + * of the file.
32937 + * ---------------------------------------------------------------------------
32938 + * Local variables:
32939 + * c-file-style: "linux"
32940 + * End:
32941 + */
32942 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_syms.c um/arch/um/kernel/user_syms.c
32943 --- orig/arch/um/kernel/user_syms.c     1969-12-31 19:00:00.000000000 -0500
32944 +++ um/arch/um/kernel/user_syms.c       2003-10-21 03:26:07.000000000 -0400
32945 @@ -0,0 +1,116 @@
32946 +#include <stdio.h>
32947 +#include <unistd.h>
32948 +#include <dirent.h>
32949 +#include <fcntl.h>
32950 +#include <errno.h>
32951 +#include <utime.h>
32952 +#include <string.h>
32953 +#include <sys/stat.h>
32954 +#include <sys/vfs.h>
32955 +#include <sys/ioctl.h>
32956 +#include "user_util.h"
32957 +#include "mem_user.h"
32958 +
32959 +/* XXX All the __CONFIG_* stuff is broken because this file can't include
32960 + * config.h
32961 + */
32962 +
32963 +/* Had to steal this from linux/module.h because that file can't be included
32964 + * since this includes various user-level headers.
32965 + */
32966 +
32967 +struct module_symbol
32968 +{
32969 +       unsigned long value;
32970 +       const char *name;
32971 +};
32972 +
32973 +/* Indirect stringification.  */
32974 +
32975 +#define __MODULE_STRING_1(x)   #x
32976 +#define __MODULE_STRING(x)     __MODULE_STRING_1(x)
32977 +
32978 +#if !defined(__AUTOCONF_INCLUDED__)
32979 +
32980 +#define __EXPORT_SYMBOL(sym,str)   error config_must_be_included_before_module
32981 +#define EXPORT_SYMBOL(var)        error config_must_be_included_before_module
32982 +#define EXPORT_SYMBOL_NOVERS(var)  error config_must_be_included_before_module
32983 +
32984 +#elif !defined(__CONFIG_MODULES__)
32985 +
32986 +#define __EXPORT_SYMBOL(sym,str)
32987 +#define EXPORT_SYMBOL(var)
32988 +#define EXPORT_SYMBOL_NOVERS(var)
32989 +
32990 +#else
32991 +
32992 +#define __EXPORT_SYMBOL(sym, str)                      \
32993 +const char __kstrtab_##sym[]                           \
32994 +__attribute__((section(".kstrtab"))) = str;            \
32995 +const struct module_symbol __ksymtab_##sym             \
32996 +__attribute__((section("__ksymtab"))) =                        \
32997 +{ (unsigned long)&sym, __kstrtab_##sym }
32998 +
32999 +#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__)
33000 +#define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
33001 +#else
33002 +#define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
33003 +#endif
33004 +
33005 +#define EXPORT_SYMBOL_NOVERS(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
33006 +
33007 +#endif
33008 +
33009 +EXPORT_SYMBOL(__errno_location);
33010 +
33011 +EXPORT_SYMBOL(access);
33012 +EXPORT_SYMBOL(open);
33013 +EXPORT_SYMBOL(open64);
33014 +EXPORT_SYMBOL(close);
33015 +EXPORT_SYMBOL(read);
33016 +EXPORT_SYMBOL(write);
33017 +EXPORT_SYMBOL(dup2);
33018 +EXPORT_SYMBOL(__xstat);
33019 +EXPORT_SYMBOL(__lxstat);
33020 +EXPORT_SYMBOL(__lxstat64);
33021 +EXPORT_SYMBOL(lseek);
33022 +EXPORT_SYMBOL(lseek64);
33023 +EXPORT_SYMBOL(chown);
33024 +EXPORT_SYMBOL(truncate);
33025 +EXPORT_SYMBOL(utime);
33026 +EXPORT_SYMBOL(chmod);
33027 +EXPORT_SYMBOL(rename);
33028 +EXPORT_SYMBOL(__xmknod);
33029 +
33030 +EXPORT_SYMBOL(symlink);
33031 +EXPORT_SYMBOL(link);
33032 +EXPORT_SYMBOL(unlink);
33033 +EXPORT_SYMBOL(readlink);
33034 +
33035 +EXPORT_SYMBOL(mkdir);
33036 +EXPORT_SYMBOL(rmdir);
33037 +EXPORT_SYMBOL(opendir);
33038 +EXPORT_SYMBOL(readdir);
33039 +EXPORT_SYMBOL(closedir);
33040 +EXPORT_SYMBOL(seekdir);
33041 +EXPORT_SYMBOL(telldir);
33042 +
33043 +EXPORT_SYMBOL(ioctl);
33044 +
33045 +extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
33046 +                       __off64_t __offset);
33047 +extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n,
33048 +                        __off64_t __offset);
33049 +EXPORT_SYMBOL(pread64);
33050 +EXPORT_SYMBOL(pwrite64);
33051 +
33052 +EXPORT_SYMBOL(statfs);
33053 +EXPORT_SYMBOL(statfs64);
33054 +
33055 +EXPORT_SYMBOL(memcpy);
33056 +EXPORT_SYMBOL(getuid);
33057 +
33058 +EXPORT_SYMBOL(memset);
33059 +EXPORT_SYMBOL(strstr);
33060 +
33061 +EXPORT_SYMBOL(find_iomem);
33062 diff -Naur -X ../exclude-files orig/arch/um/kernel/user_util.c um/arch/um/kernel/user_util.c
33063 --- orig/arch/um/kernel/user_util.c     1969-12-31 19:00:00.000000000 -0500
33064 +++ um/arch/um/kernel/user_util.c       2003-10-21 03:26:07.000000000 -0400
33065 @@ -0,0 +1,164 @@
33066 +/* 
33067 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
33068 + * Licensed under the GPL
33069 + */
33070 +
33071 +#include <stdio.h>
33072 +#include <stdlib.h>
33073 +#include <unistd.h>
33074 +#include <limits.h>
33075 +#include <sys/mman.h> 
33076 +#include <sys/stat.h>
33077 +#include <sys/ptrace.h>
33078 +#include <sys/utsname.h>
33079 +#include <sys/param.h>
33080 +#include <sys/time.h>
33081 +#include "asm/types.h"
33082 +#include <ctype.h>
33083 +#include <signal.h>
33084 +#include <wait.h>
33085 +#include <errno.h>
33086 +#include <stdarg.h>
33087 +#include <sched.h>
33088 +#include <termios.h>
33089 +#include <string.h>
33090 +#include "user_util.h"
33091 +#include "kern_util.h"
33092 +#include "user.h"
33093 +#include "mem_user.h"
33094 +#include "init.h"
33095 +#include "helper.h"
33096 +#include "uml-config.h"
33097 +
33098 +#define COMMAND_LINE_SIZE _POSIX_ARG_MAX
33099 +
33100 +/* Changed in linux_main and setup_arch, which run before SMP is started */
33101 +char saved_command_line[COMMAND_LINE_SIZE] = { 0 };
33102 +char command_line[COMMAND_LINE_SIZE] = { 0 };
33103 +
33104 +void add_arg(char *cmd_line, char *arg)
33105 +{
33106 +       if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) {
33107 +               printf("add_arg: Too much command line!\n");
33108 +               exit(1);
33109 +       }
33110 +       if(strlen(cmd_line) > 0) strcat(cmd_line, " ");
33111 +       strcat(cmd_line, arg);
33112 +}
33113 +
33114 +void stop(void)
33115 +{
33116 +       while(1) sleep(1000000);
33117 +}
33118 +
33119 +void stack_protections(unsigned long address)
33120 +{
33121 +       int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
33122 +
33123 +        if(mprotect((void *) address, page_size(), prot) < 0)
33124 +               panic("protecting stack failed, errno = %d", errno);
33125 +}
33126 +
33127 +void task_protections(unsigned long address)
33128 +{
33129 +       unsigned long guard = address + page_size();
33130 +       unsigned long stack = guard + page_size();
33131 +       int prot = 0, pages;
33132 +#ifdef notdef
33133 +       if(mprotect((void *) guard, page_size(), prot) < 0)
33134 +               panic("protecting guard page failed, errno = %d", errno);
33135 +#endif
33136 +       pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
33137 +       prot = PROT_READ | PROT_WRITE | PROT_EXEC;
33138 +       if(mprotect((void *) stack, pages * page_size(), prot) < 0)
33139 +               panic("protecting stack failed, errno = %d", errno);
33140 +}
33141 +
33142 +int wait_for_stop(int pid, int sig, int cont_type, void *relay)
33143 +{
33144 +       sigset_t *relay_signals = relay;
33145 +       int status, ret;
33146 +
33147 +       while(1){
33148 +               ret = waitpid(pid, &status, WUNTRACED);
33149 +               if((ret < 0) ||
33150 +                  !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
33151 +                       if(ret < 0){
33152 +                               if(errno == EINTR) continue;
33153 +                               printk("wait failed, errno = %d\n",
33154 +                                      errno);
33155 +                       }
33156 +                       else if(WIFEXITED(status)) 
33157 +                               printk("process exited with status %d\n", 
33158 +                                      WEXITSTATUS(status));
33159 +                       else if(WIFSIGNALED(status))
33160 +                               printk("process exited with signal %d\n", 
33161 +                                      WTERMSIG(status));
33162 +                       else if((WSTOPSIG(status) == SIGVTALRM) ||
33163 +                               (WSTOPSIG(status) == SIGALRM) ||
33164 +                               (WSTOPSIG(status) == SIGIO) ||
33165 +                               (WSTOPSIG(status) == SIGPROF) ||
33166 +                               (WSTOPSIG(status) == SIGCHLD) ||
33167 +                               (WSTOPSIG(status) == SIGWINCH) ||
33168 +                               (WSTOPSIG(status) == SIGINT)){
33169 +                               ptrace(cont_type, pid, 0, WSTOPSIG(status));
33170 +                               continue;
33171 +                       }
33172 +                       else if((relay_signals != NULL) &&
33173 +                               sigismember(relay_signals, WSTOPSIG(status))){
33174 +                               ptrace(cont_type, pid, 0, WSTOPSIG(status));
33175 +                               continue;
33176 +                       }
33177 +                       else printk("process stopped with signal %d\n", 
33178 +                                   WSTOPSIG(status));
33179 +                       panic("wait_for_stop failed to wait for %d to stop "
33180 +                             "with %d\n", pid, sig);
33181 +               }
33182 +               return(status);
33183 +       }
33184 +}
33185 +
33186 +int raw(int fd, int complain)
33187 +{
33188 +       struct termios tt;
33189 +       int err;
33190 +
33191 +       tcgetattr(fd, &tt);
33192 +       cfmakeraw(&tt);
33193 +       err = tcsetattr(fd, TCSANOW, &tt);
33194 +       if((err < 0) && complain){
33195 +               printk("tcsetattr failed, errno = %d\n", errno);
33196 +               return(-errno);
33197 +       }
33198 +       return(0);
33199 +}
33200 +
33201 +void setup_machinename(char *machine_out)
33202 +{
33203 +       struct utsname host;
33204 +
33205 +       uname(&host);
33206 +       strcpy(machine_out, host.machine);
33207 +}
33208 +
33209 +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
33210 +
33211 +void setup_hostinfo(void)
33212 +{
33213 +       struct utsname host;
33214 +
33215 +       uname(&host);
33216 +       sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
33217 +               host.release, host.version, host.machine);
33218 +}
33219 +
33220 +/*
33221 + * Overrides for Emacs so that we follow Linus's tabbing style.
33222 + * Emacs will notice this stuff at the end of the file and automatically
33223 + * adjust the settings for this buffer only.  This must remain at the end
33224 + * of the file.
33225 + * ---------------------------------------------------------------------------
33226 + * Local variables:
33227 + * c-file-style: "linux"
33228 + * End:
33229 + */
33230 diff -Naur -X ../exclude-files orig/arch/um/link.ld.in um/arch/um/link.ld.in
33231 --- orig/arch/um/link.ld.in     1969-12-31 19:00:00.000000000 -0500
33232 +++ um/arch/um/link.ld.in       2003-10-21 03:26:07.000000000 -0400
33233 @@ -0,0 +1,94 @@
33234 +OUTPUT_FORMAT("ELF_FORMAT")
33235 +OUTPUT_ARCH(ELF_ARCH)
33236 +ENTRY(_start)
33237 +
33238 +SECTIONS
33239 +{
33240 +  . = START() + SIZEOF_HEADERS;
33241 +
33242 +  __binary_start = .;
33243 +ifdef(`MODE_TT', `
33244 +  .thread_private : {
33245 +    __start_thread_private = .;
33246 +    errno = .;
33247 +    . += 4;
33248 +    arch/um/kernel/tt/unmap_fin.o (.data)
33249 +    __end_thread_private = .;
33250 +  }
33251 +  . = ALIGN(4096);
33252 +  .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
33253 +')
33254 +  . = ALIGN(4096);             /* Init code and data */
33255 +  _stext = .;
33256 +  __init_begin = .;
33257 +  .text.init : { *(.text.init) }
33258 +  . = ALIGN(4096);
33259 +  .text      :
33260 +  {
33261 +    *(.text)
33262 +    /* .gnu.warning sections are handled specially by elf32.em.  */
33263 +    *(.gnu.warning)
33264 +    *(.gnu.linkonce.t*)
33265 +  }
33266 +  .fini      : { *(.fini)    } =0x9090
33267 +  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
33268 +  .rodata1   : { *(.rodata1) }
33269 +  _etext = .;
33270 +  PROVIDE (etext = .);
33271 +
33272 +  . = ALIGN(4096);
33273 +  PROVIDE (_sdata = .);
33274 +
33275 +include(`arch/um/common.ld.in')
33276 +
33277 +  .data    :
33278 +  {
33279 +    . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
33280 +    *(.data.init_task)
33281 +    *(.data)
33282 +    *(.gnu.linkonce.d*)
33283 +    CONSTRUCTORS
33284 +  }
33285 +  .data1   : { *(.data1) }
33286 +  .ctors         :
33287 +  {
33288 +    *(.ctors)
33289 +  }
33290 +  .dtors         :
33291 +  {
33292 +    *(.dtors)
33293 +  }
33294 +
33295 +  .got           : { *(.got.plt) *(.got) }
33296 +  .dynamic       : { *(.dynamic) }
33297 +  /* We want the small data sections together, so single-instruction offsets
33298 +     can access them all, and initialized data all before uninitialized, so
33299 +     we can shorten the on-disk segment size.  */
33300 +  .sdata     : { *(.sdata) }
33301 +  _edata  =  .;
33302 +  PROVIDE (edata = .);
33303 +  . = ALIGN(0x1000);
33304 +  .sbss      : 
33305 +  {
33306 +   __bss_start = .;
33307 +   PROVIDE(_bss_start = .);
33308 +   *(.sbss) 
33309 +   *(.scommon) 
33310 +  }
33311 +  .bss       :
33312 +  {
33313 +   *(.dynbss)
33314 +   *(.bss)
33315 +   *(COMMON)
33316 +  }
33317 +  _end = . ;
33318 +  PROVIDE (end = .);
33319 +  /* Stabs debugging sections.  */
33320 +  .stab 0 : { *(.stab) }
33321 +  .stabstr 0 : { *(.stabstr) }
33322 +  .stab.excl 0 : { *(.stab.excl) }
33323 +  .stab.exclstr 0 : { *(.stab.exclstr) }
33324 +  .stab.index 0 : { *(.stab.index) }
33325 +  .stab.indexstr 0 : { *(.stab.indexstr) }
33326 +  .comment 0 : { *(.comment) }
33327 +}
33328 diff -Naur -X ../exclude-files orig/arch/um/main.c um/arch/um/main.c
33329 --- orig/arch/um/main.c 1969-12-31 19:00:00.000000000 -0500
33330 +++ um/arch/um/main.c   2003-10-21 03:26:07.000000000 -0400
33331 @@ -0,0 +1,198 @@
33332 +/* 
33333 + * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
33334 + * Licensed under the GPL
33335 + */
33336 +
33337 +#include <unistd.h>
33338 +#include <stdio.h> 
33339 +#include <stdlib.h>
33340 +#include <string.h>
33341 +#include <signal.h>
33342 +#include <errno.h>
33343 +#include <sys/resource.h>
33344 +#include <sys/mman.h>
33345 +#include <sys/user.h>
33346 +#include <asm/page.h>
33347 +#include "user_util.h"
33348 +#include "kern_util.h"
33349 +#include "mem_user.h"
33350 +#include "signal_user.h"
33351 +#include "user.h"
33352 +#include "init.h"
33353 +#include "mode.h"
33354 +#include "choose-mode.h"
33355 +#include "uml-config.h"
33356 +
33357 +/* Set in set_stklim, which is called from main and __wrap_malloc.  
33358 + * __wrap_malloc only calls it if main hasn't started.
33359 + */
33360 +unsigned long stacksizelim;
33361 +
33362 +/* Set in main */
33363 +char *linux_prog;
33364 +
33365 +#define PGD_BOUND (4 * 1024 * 1024)
33366 +#define STACKSIZE (8 * 1024 * 1024)
33367 +#define THREAD_NAME_LEN (256)
33368 +
33369 +static void set_stklim(void)
33370 +{
33371 +       struct rlimit lim;
33372 +
33373 +       if(getrlimit(RLIMIT_STACK, &lim) < 0){
33374 +               perror("getrlimit");
33375 +               exit(1);
33376 +       }
33377 +       if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
33378 +               lim.rlim_cur = STACKSIZE;
33379 +               if(setrlimit(RLIMIT_STACK, &lim) < 0){
33380 +                       perror("setrlimit");
33381 +                       exit(1);
33382 +               }
33383 +       }
33384 +       stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
33385 +}
33386 +
33387 +static __init void do_uml_initcalls(void)
33388 +{
33389 +       initcall_t *call;
33390 +
33391 +       call = &__uml_initcall_start;
33392 +       while (call < &__uml_initcall_end){;
33393 +               (*call)();
33394 +               call++;
33395 +       }
33396 +}
33397 +
33398 +static void last_ditch_exit(int sig)
33399 +{
33400 +       CHOOSE_MODE(kmalloc_ok = 0, (void) 0);
33401 +       signal(SIGINT, SIG_DFL);
33402 +       signal(SIGTERM, SIG_DFL);
33403 +       signal(SIGHUP, SIG_DFL);
33404 +       uml_cleanup();
33405 +       exit(1);
33406 +}
33407 +
33408 +extern int uml_exitcode;
33409 +
33410 +int main(int argc, char **argv, char **envp)
33411 +{
33412 +       char **new_argv;
33413 +       sigset_t mask;
33414 +       int ret, i;
33415 +
33416 +       /* Enable all signals except SIGIO - in some environments, we can 
33417 +        * enter with some signals blocked
33418 +        */
33419 +
33420 +       sigemptyset(&mask);
33421 +       sigaddset(&mask, SIGIO);
33422 +       if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){
33423 +               perror("sigprocmask");
33424 +               exit(1);
33425 +       }
33426 +
33427 +#ifdef UML_CONFIG_MODE_TT
33428 +       /* Allocate memory for thread command lines */
33429 +       if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
33430 +
33431 +               char padding[THREAD_NAME_LEN] = { 
33432 +                       [ 0 ...  THREAD_NAME_LEN - 2] = ' ', '\0' 
33433 +               };
33434 +
33435 +               new_argv = malloc((argc + 2) * sizeof(char*));
33436 +               if(!new_argv) {
33437 +                       perror("Allocating extended argv");
33438 +                       exit(1);
33439 +               }       
33440 +               
33441 +               new_argv[0] = argv[0];
33442 +               new_argv[1] = padding;
33443 +               
33444 +               for(i = 2; i <= argc; i++)
33445 +                       new_argv[i] = argv[i - 1];
33446 +               new_argv[argc + 1] = NULL;
33447 +               
33448 +               execvp(new_argv[0], new_argv);
33449 +               perror("execing with extended args");
33450 +               exit(1);
33451 +       }       
33452 +#endif
33453 +
33454 +       linux_prog = argv[0];
33455 +
33456 +       set_stklim();
33457 +
33458 +       new_argv = malloc((argc + 1) * sizeof(char *));
33459 +       if(new_argv == NULL){
33460 +               perror("Mallocing argv");
33461 +               exit(1);
33462 +       }
33463 +       for(i=0;i<argc;i++){
33464 +               new_argv[i] = strdup(argv[i]);
33465 +               if(new_argv[i] == NULL){
33466 +                       perror("Mallocing an arg");
33467 +                       exit(1);
33468 +               }
33469 +       }
33470 +       new_argv[argc] = NULL;
33471 +
33472 +       set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33473 +       set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33474 +       set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1);
33475 +
33476 +       do_uml_initcalls();
33477 +       ret = linux_main(argc, argv);
33478 +       
33479 +       /* Reboot */
33480 +       if(ret){
33481 +               printf("\n");
33482 +               execvp(new_argv[0], new_argv);
33483 +               perror("Failed to exec kernel");
33484 +               ret = 1;
33485 +       }
33486 +       printf("\n");
33487 +       return(uml_exitcode);
33488 +}
33489 +
33490 +#define CAN_KMALLOC() \
33491 +       (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
33492 +
33493 +extern void *__real_malloc(int);
33494 +
33495 +void *__wrap_malloc(int size)
33496 +{
33497 +       if(CAN_KMALLOC())
33498 +               return(um_kmalloc(size));
33499 +       else
33500 +               return(__real_malloc(size));
33501 +}
33502 +
33503 +void *__wrap_calloc(int n, int size)
33504 +{
33505 +       void *ptr = __wrap_malloc(n * size);
33506 +
33507 +       if(ptr == NULL) return(NULL);
33508 +       memset(ptr, 0, n * size);
33509 +       return(ptr);
33510 +}
33511 +
33512 +extern void __real_free(void *);
33513 +
33514 +void __wrap_free(void *ptr)
33515 +{
33516 +       if(CAN_KMALLOC()) kfree(ptr);
33517 +       else __real_free(ptr);
33518 +}
33519 +
33520 +/*
33521 + * Overrides for Emacs so that we follow Linus's tabbing style.
33522 + * Emacs will notice this stuff at the end of the file and automatically
33523 + * adjust the settings for this buffer only.  This must remain at the end
33524 + * of the file.
33525 + * ---------------------------------------------------------------------------
33526 + * Local variables:
33527 + * c-file-style: "linux"
33528 + * End:
33529 + */
33530 diff -Naur -X ../exclude-files orig/arch/um/Makefile um/arch/um/Makefile
33531 --- orig/arch/um/Makefile       1969-12-31 19:00:00.000000000 -0500
33532 +++ um/arch/um/Makefile 2003-12-17 03:02:28.000000000 -0500
33533 @@ -0,0 +1,174 @@
33534 +# 
33535 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33536 +# Licensed under the GPL
33537 +#
33538 +
33539 +OS := $(shell uname -s)
33540 +
33541 +ARCH_DIR = arch/um
33542 +
33543 +core-y := kernel sys-$(SUBARCH) os-$(OS)
33544 +drivers-y := fs drivers
33545 +subdir-y := $(core-y) $(drivers-y)
33546 +SUBDIRS += $(foreach dir,$(subdir-y),$(ARCH_DIR)/$(dir))
33547 +
33548 +CORE_FILES += $(foreach dir,$(core-y),$(ARCH_DIR)/$(dir)/built-in.o)
33549 +DRIVERS += $(foreach dir,$(drivers-y),$(ARCH_DIR)/$(dir)/built-in.o)
33550 +
33551 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
33552 +include $(ARCH_DIR)/Makefile-os-$(OS)
33553 +
33554 +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
33555 +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
33556 +
33557 +ifneq ($(MAKEFILE-y),)
33558 +  include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
33559 +endif
33560 +
33561 +EXTRAVERSION := $(EXTRAVERSION)-1um
33562 +
33563 +include/linux/version.h: arch/$(ARCH)/Makefile
33564 +
33565 +# Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE)
33566 +# The way the toplevel Makefile is written EXTRAVERSION is not supposed
33567 +# to be changed outside the toplevel Makefile, but recalculating MODLIB is
33568 +# a sufficient workaround until we no longer need architecture dependent
33569 +# EXTRAVERSION...
33570 +MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
33571 +
33572 +ifeq ($(CONFIG_DEBUGSYM),y)
33573 +CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS))
33574 +endif
33575 +
33576 +CFLAGS-$(CONFIG_DEBUGSYM) += -g
33577 +
33578 +ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include
33579 +
33580 +# -Derrno=kernel_errno - This turns all kernel references to errno into
33581 +# kernel_errno to separate them from the libc errno.  This allows -fno-common
33582 +# in CFLAGS.  Otherwise, it would cause ld to complain about the two different
33583 +# errnos.
33584 +
33585 +CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
33586 +       -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
33587 +       $(MODE_INCLUDE)
33588 +
33589 +LINKFLAGS += -r
33590 +
33591 +LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
33592 +
33593 +# These are needed for clean and mrproper, since in that case .config is not
33594 +# included; the values here are meaningless
33595 +
33596 +CONFIG_NEST_LEVEL ?= 0
33597 +CONFIG_KERNEL_HALF_GIGS ?=  0
33598 +
33599 +SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
33600 +
33601 +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
33602 +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
33603 +
33604 +LINK_TT = -static
33605 +LD_SCRIPT_TT := link.ld
33606 +
33607 +ifeq ($(CONFIG_STATIC_LINK),y)
33608 +  LINK-y += $(LINK_TT)
33609 +  LD_SCRIPT-y := $(LD_SCRIPT_TT)
33610 +else
33611 +ifeq ($(CONFIG_MODE_TT),y)
33612 +  LINK-y += $(LINK_TT)
33613 +  LD_SCRIPT-y := $(LD_SCRIPT_TT)
33614 +else
33615 +ifeq ($(CONFIG_MODE_SKAS),y)
33616 +  LINK-y += $(LINK_SKAS)
33617 +  LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
33618 +endif
33619 +endif
33620 +endif
33621 +
33622 +LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
33623 +M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
33624 +
33625 +$(LD_SCRIPT-y): $(LD_SCRIPT-y).in
33626 +       pages=$$(( 1 << $(CONFIG_KERNEL_STACK_ORDER) )) ; \
33627 +       m4 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
33628 +               -DELF_FORMAT=$(ELF_FORMAT) $(M4_MODE_TT) \
33629 +               -DKERNEL_STACK_SIZE=$$(( 4096 * $$pages )) $< > $@
33630 +
33631 +SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
33632 +       include/asm-um/sigcontext.h include/asm-um/processor.h \
33633 +       include/asm-um/ptrace.h include/asm-um/arch-signal.h
33634 +
33635 +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \
33636 +       $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
33637 +
33638 +ifeq ($(CONFIG_MODE_SKAS), y)
33639 +$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
33640 +endif
33641 +
33642 +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h 
33643 +
33644 +setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) 
33645 +
33646 +linux: setup $(ARCH_DIR)/main.o vmlinux $(LD_SCRIPT-y)
33647 +       mv vmlinux vmlinux.o
33648 +       $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
33649 +               -o linux $(ARCH_DIR)/main.o vmlinux.o -L/usr/lib -lutil
33650 +
33651 +USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
33652 +USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
33653 +USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
33654 +       $(MODE_INCLUDE)
33655 +
33656 +# To get a definition of F_SETSIG
33657 +USER_CFLAGS += -D_GNU_SOURCE
33658 +
33659 +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \
33660 +       $(GEN_HEADERS) $(ARCH_DIR)/include/uml-config.h
33661 +
33662 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
33663 +       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
33664 +
33665 +archmrproper:
33666 +       rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
33667 +               $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
33668 +
33669 +archclean: sysclean
33670 +       find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
33671 +               -o -name '*.gcov' \) -type f -print | xargs rm -f
33672 +       cd $(ARCH_DIR) ; \
33673 +       for dir in $(subdir-y) util ; do $(MAKE) -C $$dir clean; done
33674 +
33675 +archdep: 
33676 +
33677 +$(SYMLINK_HEADERS):
33678 +       cd $(TOPDIR)/$(dir $@) ; \
33679 +       ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
33680 +
33681 +include/asm-um/arch:
33682 +       cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
33683 +
33684 +arch/um/include/sysdep:
33685 +       cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep
33686 +
33687 +arch/um/os:
33688 +       cd $(ARCH_DIR) && ln -sf os-$(OS) os
33689 +
33690 +$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
33691 +       $< > $@
33692 +
33693 +$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
33694 +       $< > $@
33695 +
33696 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
33697 +       sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
33698 +
33699 +$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/util/mk_task_user.c \
33700 +       $(ARCH_DIR)/util/mk_task_kern.c $(SYS_HEADERS)
33701 +       $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_task
33702 +
33703 +$(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util/mk_constants_user.c \
33704 +       $(ARCH_DIR)/util/mk_constants_kern.c 
33705 +       $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_constants
33706 +
33707 +export SUBARCH USER_CFLAGS OS
33708 diff -Naur -X ../exclude-files orig/arch/um/Makefile-i386 um/arch/um/Makefile-i386
33709 --- orig/arch/um/Makefile-i386  1969-12-31 19:00:00.000000000 -0500
33710 +++ um/arch/um/Makefile-i386    2003-10-21 03:26:07.000000000 -0400
33711 @@ -0,0 +1,35 @@
33712 +ifeq ($(CONFIG_HOST_2G_2G), y)
33713 +TOP_ADDR = 0x80000000
33714 +else
33715 +TOP_ADDR = 0xc0000000
33716 +endif
33717 +
33718 +ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH) -DUM_FASTCALL
33719 +ELF_ARCH = $(SUBARCH)
33720 +ELF_FORMAT = elf32-$(SUBARCH)
33721 +
33722 +I386_H = $(ARCH_DIR)/include/sysdep-i386
33723 +SYS = $(ARCH_DIR)/sys-i386
33724 +UTIL = $(SYS)/util
33725 +SUBDIRS += $(UTIL)
33726 +
33727 +SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h
33728 +
33729 +$(I386_H)/sc.h : $(UTIL)/mk_sc
33730 +       $(UTIL)/mk_sc > $@
33731 +
33732 +$(I386_H)/thread.h : $(UTIL)/mk_thread
33733 +       $(UTIL)/mk_thread > $@
33734 +
33735 +$(UTIL)/mk_sc : $(UTIL)/mk_sc.c
33736 +       $(MAKE) -C $(UTIL) mk_sc
33737 +
33738 +$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \
33739 +       $(I386_H)/sc.h
33740 +       $(MAKE) -C $(UTIL) mk_thread
33741 +
33742 +sysclean :
33743 +       rm -f $(SYS_HEADERS)
33744 +       $(MAKE) -C $(UTIL) clean
33745 +       $(MAKE) -C $(SYS) clean
33746 +
33747 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ia64 um/arch/um/Makefile-ia64
33748 --- orig/arch/um/Makefile-ia64  1969-12-31 19:00:00.000000000 -0500
33749 +++ um/arch/um/Makefile-ia64    2003-10-21 03:26:07.000000000 -0400
33750 @@ -0,0 +1 @@
33751 +START_ADDR = 0x1000000000000000
33752 diff -Naur -X ../exclude-files orig/arch/um/Makefile-os-Linux um/arch/um/Makefile-os-Linux
33753 --- orig/arch/um/Makefile-os-Linux      1969-12-31 19:00:00.000000000 -0500
33754 +++ um/arch/um/Makefile-os-Linux        2003-10-21 03:26:07.000000000 -0400
33755 @@ -0,0 +1,7 @@
33756 +# 
33757 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
33758 +# Licensed under the GPL
33759 +#
33760 +
33761 +SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers
33762 +DRIVERS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o
33763 diff -Naur -X ../exclude-files orig/arch/um/Makefile-ppc um/arch/um/Makefile-ppc
33764 --- orig/arch/um/Makefile-ppc   1969-12-31 19:00:00.000000000 -0500
33765 +++ um/arch/um/Makefile-ppc     2003-10-21 03:26:07.000000000 -0400
33766 @@ -0,0 +1,9 @@
33767 +ifeq ($(CONFIG_HOST_2G_2G), y)
33768 +START_ADDR = 0x80000000
33769 +else
33770 +START_ADDR = 0xc0000000
33771 +endif
33772 +ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__
33773 +
33774 +# The arch is ppc, but the elf32 name is powerpc
33775 +ELF_SUBARCH = powerpc
33776 diff -Naur -X ../exclude-files orig/arch/um/Makefile-skas um/arch/um/Makefile-skas
33777 --- orig/arch/um/Makefile-skas  1969-12-31 19:00:00.000000000 -0500
33778 +++ um/arch/um/Makefile-skas    2003-10-21 03:26:07.000000000 -0400
33779 @@ -0,0 +1,20 @@
33780 +# 
33781 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33782 +# Licensed under the GPL
33783 +#
33784 +
33785 +PROFILE += -pg
33786 +
33787 +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage
33788 +CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
33789 +LINK-$(CONFIG_GPROF) += $(PROFILE)
33790 +
33791 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include
33792 +
33793 +LINK_SKAS = -Wl,-rpath,/lib 
33794 +LD_SCRIPT_SKAS = dyn_link.ld
33795 +
33796 +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
33797 +
33798 +$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
33799 +       $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
33800 diff -Naur -X ../exclude-files orig/arch/um/Makefile-tt um/arch/um/Makefile-tt
33801 --- orig/arch/um/Makefile-tt    1969-12-31 19:00:00.000000000 -0500
33802 +++ um/arch/um/Makefile-tt      2003-10-21 03:26:07.000000000 -0400
33803 @@ -0,0 +1,7 @@
33804 +# 
33805 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
33806 +# Licensed under the GPL
33807 +#
33808 +
33809 +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include
33810 +
33811 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/etap.h um/arch/um/os-Linux/drivers/etap.h
33812 --- orig/arch/um/os-Linux/drivers/etap.h        1969-12-31 19:00:00.000000000 -0500
33813 +++ um/arch/um/os-Linux/drivers/etap.h  2003-10-21 03:26:07.000000000 -0400
33814 @@ -0,0 +1,27 @@
33815 +/* 
33816 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
33817 + * Licensed under the GPL
33818 + */
33819 +
33820 +#include "net_user.h"
33821 +
33822 +struct ethertap_data {
33823 +       char *dev_name;
33824 +       char *gate_addr;
33825 +       int data_fd;
33826 +       int control_fd;
33827 +       void *dev;
33828 +};
33829 +
33830 +extern struct net_user_info ethertap_user_info;
33831 +
33832 +/*
33833 + * Overrides for Emacs so that we follow Linus's tabbing style.
33834 + * Emacs will notice this stuff at the end of the file and automatically
33835 + * adjust the settings for this buffer only.  This must remain at the end
33836 + * of the file.
33837 + * ---------------------------------------------------------------------------
33838 + * Local variables:
33839 + * c-file-style: "linux"
33840 + * End:
33841 + */
33842 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_kern.c um/arch/um/os-Linux/drivers/ethertap_kern.c
33843 --- orig/arch/um/os-Linux/drivers/ethertap_kern.c       1969-12-31 19:00:00.000000000 -0500
33844 +++ um/arch/um/os-Linux/drivers/ethertap_kern.c 2003-10-21 03:26:07.000000000 -0400
33845 @@ -0,0 +1,122 @@
33846 +/*
33847 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
33848 + * James Leu (jleu@mindspring.net).
33849 + * Copyright (C) 2001 by various other people who didn't put their name here.
33850 + * Licensed under the GPL.
33851 + */
33852 +
33853 +#include "linux/init.h"
33854 +#include "linux/netdevice.h"
33855 +#include "linux/etherdevice.h"
33856 +#include "linux/init.h"
33857 +#include "net_kern.h"
33858 +#include "net_user.h"
33859 +#include "etap.h"
33860 +
33861 +struct ethertap_init {
33862 +       char *dev_name;
33863 +       char *gate_addr;
33864 +};
33865 +
33866 +static void etap_init(struct net_device *dev, void *data)
33867 +{
33868 +       struct uml_net_private *pri;
33869 +       struct ethertap_data *epri;
33870 +       struct ethertap_init *init = data;
33871 +
33872 +       init_etherdev(dev, 0);
33873 +       pri = dev->priv;
33874 +       epri = (struct ethertap_data *) pri->user;
33875 +       *epri = ((struct ethertap_data)
33876 +               { .dev_name             = init->dev_name,
33877 +                 .gate_addr            = init->gate_addr,
33878 +                 .data_fd              = -1,
33879 +                 .control_fd           = -1,
33880 +                 .dev                  = dev });
33881 +
33882 +       printk("ethertap backend - %s", epri->dev_name);
33883 +       if(epri->gate_addr != NULL) 
33884 +               printk(", IP = %s", epri->gate_addr);
33885 +       printk("\n");
33886 +}
33887 +
33888 +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
33889 +{
33890 +       int len;
33891 +
33892 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
33893 +       if(*skb == NULL) return(-ENOMEM);
33894 +       len = net_recvfrom(fd, (*skb)->mac.raw, 
33895 +                          (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
33896 +       if(len <= 0) return(len);
33897 +       skb_pull(*skb, 2);
33898 +       len -= 2;
33899 +       return(len);
33900 +}
33901 +
33902 +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
33903 +{
33904 +       if(skb_headroom(*skb) < 2){
33905 +               struct sk_buff *skb2;
33906 +
33907 +               skb2 = skb_realloc_headroom(*skb, 2);
33908 +               dev_kfree_skb(*skb);
33909 +               if (skb2 == NULL) return(-ENOMEM);
33910 +               *skb = skb2;
33911 +       }
33912 +       skb_push(*skb, 2);
33913 +       return(net_send(fd, (*skb)->data, (*skb)->len));
33914 +}
33915 +
33916 +struct net_kern_info ethertap_kern_info = {
33917 +       .init                   = etap_init,
33918 +       .protocol               = eth_protocol,
33919 +       .read                   = etap_read,
33920 +       .write                  = etap_write,
33921 +};
33922 +
33923 +int ethertap_setup(char *str, char **mac_out, void *data)
33924 +{
33925 +       struct ethertap_init *init = data;
33926 +
33927 +       *init = ((struct ethertap_init)
33928 +               { .dev_name     = NULL,
33929 +                 .gate_addr    = NULL });
33930 +       if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
33931 +                           &init->gate_addr))
33932 +               return(0);
33933 +       if(init->dev_name == NULL){
33934 +               printk("ethertap_setup : Missing tap device name\n");
33935 +               return(0);
33936 +       }
33937 +
33938 +       return(1);
33939 +}
33940 +
33941 +static struct transport ethertap_transport = {
33942 +       .list           = LIST_HEAD_INIT(ethertap_transport.list),
33943 +       .name           = "ethertap",
33944 +       .setup          = ethertap_setup,
33945 +       .user           = &ethertap_user_info,
33946 +       .kern           = &ethertap_kern_info,
33947 +       .private_size   = sizeof(struct ethertap_data),
33948 +};
33949 +
33950 +static int register_ethertap(void)
33951 +{
33952 +       register_transport(&ethertap_transport);
33953 +       return(1);
33954 +}
33955 +
33956 +__initcall(register_ethertap);
33957 +
33958 +/*
33959 + * Overrides for Emacs so that we follow Linus's tabbing style.
33960 + * Emacs will notice this stuff at the end of the file and automatically
33961 + * adjust the settings for this buffer only.  This must remain at the end
33962 + * of the file.
33963 + * ---------------------------------------------------------------------------
33964 + * Local variables:
33965 + * c-file-style: "linux"
33966 + * End:
33967 + */
33968 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_user.c um/arch/um/os-Linux/drivers/ethertap_user.c
33969 --- orig/arch/um/os-Linux/drivers/ethertap_user.c       1969-12-31 19:00:00.000000000 -0500
33970 +++ um/arch/um/os-Linux/drivers/ethertap_user.c 2003-10-21 03:26:07.000000000 -0400
33971 @@ -0,0 +1,238 @@
33972 +/*
33973 + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 
33974 + * James Leu (jleu@mindspring.net).
33975 + * Copyright (C) 2001 by various other people who didn't put their name here.
33976 + * Licensed under the GPL.
33977 + */
33978 +
33979 +#include <stdio.h>
33980 +#include <unistd.h>
33981 +#include <stddef.h>
33982 +#include <stdlib.h>
33983 +#include <sys/errno.h>
33984 +#include <sys/socket.h>
33985 +#include <sys/wait.h>
33986 +#include <sys/un.h>
33987 +#include <net/if.h>
33988 +#include "user.h"
33989 +#include "kern_util.h"
33990 +#include "net_user.h"
33991 +#include "etap.h"
33992 +#include "helper.h"
33993 +#include "os.h"
33994 +
33995 +#define MAX_PACKET ETH_MAX_PACKET
33996 +
33997 +void etap_user_init(void *data, void *dev)
33998 +{
33999 +       struct ethertap_data *pri = data;
34000 +
34001 +       pri->dev = dev;
34002 +}
34003 +
34004 +struct addr_change {
34005 +       enum { ADD_ADDR, DEL_ADDR } what;
34006 +       unsigned char addr[4];
34007 +       unsigned char netmask[4];
34008 +};
34009 +
34010 +static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
34011 +                       int fd)
34012 +{
34013 +       struct addr_change change;
34014 +       void *output;
34015 +       int n;
34016 +
34017 +       change.what = op;
34018 +       memcpy(change.addr, addr, sizeof(change.addr));
34019 +       memcpy(change.netmask, netmask, sizeof(change.netmask));
34020 +       n = os_write_file(fd, &change, sizeof(change));
34021 +       if(n != sizeof(change))
34022 +               printk("etap_change - request failed, err = %d\n", -n);
34023 +       output = um_kmalloc(page_size());
34024 +       if(output == NULL)
34025 +               printk("etap_change : Failed to allocate output buffer\n");
34026 +       read_output(fd, output, page_size());
34027 +       if(output != NULL){
34028 +               printk("%s", output);
34029 +               kfree(output);
34030 +       }
34031 +}
34032 +
34033 +static void etap_open_addr(unsigned char *addr, unsigned char *netmask,
34034 +                          void *arg)
34035 +{
34036 +       etap_change(ADD_ADDR, addr, netmask, *((int *) arg));
34037 +}
34038 +
34039 +static void etap_close_addr(unsigned char *addr, unsigned char *netmask,
34040 +                           void *arg)
34041 +{
34042 +       etap_change(DEL_ADDR, addr, netmask, *((int *) arg));
34043 +}
34044 +
34045 +struct etap_pre_exec_data {
34046 +       int control_remote;
34047 +       int control_me;
34048 +       int data_me;
34049 +};
34050 +
34051 +static void etap_pre_exec(void *arg)
34052 +{
34053 +       struct etap_pre_exec_data *data = arg;
34054 +
34055 +       dup2(data->control_remote, 1);
34056 +       os_close_file(data->data_me);
34057 +       os_close_file(data->control_me);
34058 +}
34059 +
34060 +static int etap_tramp(char *dev, char *gate, int control_me, 
34061 +                     int control_remote, int data_me, int data_remote)
34062 +{
34063 +       struct etap_pre_exec_data pe_data;
34064 +       int pid, status, err, n;
34065 +       char version_buf[sizeof("nnnnn\0")];
34066 +       char data_fd_buf[sizeof("nnnnnn\0")];
34067 +       char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
34068 +       char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
34069 +                              data_fd_buf, gate_buf, NULL };
34070 +       char *nosetup_args[] = { "uml_net", version_buf, "ethertap", 
34071 +                                dev, data_fd_buf, NULL };
34072 +       char **args, c;
34073 +
34074 +       sprintf(data_fd_buf, "%d", data_remote);
34075 +       sprintf(version_buf, "%d", UML_NET_VERSION);
34076 +       if(gate != NULL){
34077 +               strcpy(gate_buf, gate);
34078 +               args = setup_args;
34079 +       }
34080 +       else args = nosetup_args;
34081 +
34082 +       err = 0;
34083 +       pe_data.control_remote = control_remote;
34084 +       pe_data.control_me = control_me;
34085 +       pe_data.data_me = data_me;
34086 +       pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
34087 +
34088 +       if(pid < 0) err = pid;
34089 +       os_close_file(data_remote);
34090 +       os_close_file(control_remote);
34091 +       n = os_read_file(control_me, &c, sizeof(c));
34092 +       if(n != sizeof(c)){
34093 +               printk("etap_tramp : read of status failed, err = %d\n", -n);
34094 +               return(-EINVAL);
34095 +       }
34096 +       if(c != 1){
34097 +               printk("etap_tramp : uml_net failed\n");
34098 +               err = -EINVAL;
34099 +               if(waitpid(pid, &status, 0) < 0)
34100 +                       err = -errno;
34101 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
34102 +                       printk("uml_net didn't exit with status 1\n");
34103 +       }
34104 +       return(err);
34105 +}
34106 +
34107 +static int etap_open(void *data)
34108 +{
34109 +       struct ethertap_data *pri = data;
34110 +       char *output;
34111 +       int data_fds[2], control_fds[2], err, output_len;
34112 +
34113 +       err = tap_open_common(pri->dev, pri->gate_addr);
34114 +       if(err) return(err);
34115 +
34116 +       err = os_pipe(data_fds, 0, 0);
34117 +       if(err < 0){
34118 +               printk("data os_pipe failed - err = %d\n", -err);
34119 +               return(err);
34120 +       }
34121 +
34122 +       err = os_pipe(control_fds, 1, 0);
34123 +       if(err < 0){
34124 +               printk("control os_pipe failed - err = %d\n", -err);
34125 +               return(err);
34126 +       }
34127 +       
34128 +       err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], 
34129 +                        control_fds[1], data_fds[0], data_fds[1]);
34130 +       output_len = page_size();
34131 +       output = um_kmalloc(output_len);
34132 +       read_output(control_fds[0], output, output_len);
34133 +
34134 +       if(output == NULL)
34135 +               printk("etap_open : failed to allocate output buffer\n");
34136 +       else {
34137 +               printk("%s", output);
34138 +               kfree(output);
34139 +       }
34140 +
34141 +       if(err < 0){
34142 +               printk("etap_tramp failed - err = %d\n", -err);
34143 +               return(err);
34144 +       }
34145 +
34146 +       pri->data_fd = data_fds[0];
34147 +       pri->control_fd = control_fds[0];
34148 +       iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
34149 +       return(data_fds[0]);
34150 +}
34151 +
34152 +static void etap_close(int fd, void *data)
34153 +{
34154 +       struct ethertap_data *pri = data;
34155 +
34156 +       iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
34157 +       os_close_file(fd);
34158 +       os_shutdown_socket(pri->data_fd, 1, 1);
34159 +       os_close_file(pri->data_fd);
34160 +       pri->data_fd = -1;
34161 +       os_close_file(pri->control_fd);
34162 +       pri->control_fd = -1;
34163 +}
34164 +
34165 +static int etap_set_mtu(int mtu, void *data)
34166 +{
34167 +       return(mtu);
34168 +}
34169 +
34170 +static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
34171 +                         void *data)
34172 +{
34173 +       struct ethertap_data *pri = data;
34174 +
34175 +       tap_check_ips(pri->gate_addr, addr);
34176 +       if(pri->control_fd == -1) return;
34177 +       etap_open_addr(addr, netmask, &pri->control_fd);
34178 +}
34179 +
34180 +static void etap_del_addr(unsigned char *addr, unsigned char *netmask, 
34181 +                         void *data)
34182 +{
34183 +       struct ethertap_data *pri = data;
34184 +
34185 +       if(pri->control_fd == -1) return;
34186 +       etap_close_addr(addr, netmask, &pri->control_fd);
34187 +}
34188 +
34189 +struct net_user_info ethertap_user_info = {
34190 +       .init           = etap_user_init,
34191 +       .open           = etap_open,
34192 +       .close          = etap_close,
34193 +       .remove         = NULL,
34194 +       .set_mtu        = etap_set_mtu,
34195 +       .add_address    = etap_add_addr,
34196 +       .delete_address = etap_del_addr,
34197 +       .max_packet     = MAX_PACKET - ETH_HEADER_ETHERTAP
34198 +};
34199 +
34200 +/*
34201 + * Overrides for Emacs so that we follow Linus's tabbing style.
34202 + * Emacs will notice this stuff at the end of the file and automatically
34203 + * adjust the settings for this buffer only.  This must remain at the end
34204 + * of the file.
34205 + * ---------------------------------------------------------------------------
34206 + * Local variables:
34207 + * c-file-style: "linux"
34208 + * End:
34209 + */
34210 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/Makefile um/arch/um/os-Linux/drivers/Makefile
34211 --- orig/arch/um/os-Linux/drivers/Makefile      1969-12-31 19:00:00.000000000 -0500
34212 +++ um/arch/um/os-Linux/drivers/Makefile        2003-10-21 03:26:07.000000000 -0400
34213 @@ -0,0 +1,31 @@
34214 +# 
34215 +# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
34216 +# Licensed under the GPL
34217 +#
34218 +
34219 +O_TARGET := drivers.o
34220 +
34221 +list-multi := tuntap.o ethertap.o
34222 +
34223 +ethertap-objs := ethertap_kern.o ethertap_user.o
34224 +tuntap-objs := tuntap_kern.o tuntap_user.o
34225 +
34226 +obj-y = 
34227 +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o
34228 +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o
34229 +
34230 +USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs))
34231 +
34232 +USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS))
34233 +
34234 +include $(TOPDIR)/Rules.make
34235 +
34236 +$(USER_OBJS) : %.o: %.c
34237 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
34238 +
34239 +ethertap.o : $(ethertap-objs)
34240 +
34241 +tuntap.o : $(tuntap-objs)
34242 +
34243 +$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)'
34244 +       $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs)
34245 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap.h um/arch/um/os-Linux/drivers/tuntap.h
34246 --- orig/arch/um/os-Linux/drivers/tuntap.h      1969-12-31 19:00:00.000000000 -0500
34247 +++ um/arch/um/os-Linux/drivers/tuntap.h        2003-10-21 03:26:07.000000000 -0400
34248 @@ -0,0 +1,32 @@
34249 +/* 
34250 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34251 + * Licensed under the GPL
34252 + */
34253 +
34254 +#ifndef __UM_TUNTAP_H
34255 +#define __UM_TUNTAP_H
34256 +
34257 +#include "net_user.h"
34258 +
34259 +struct tuntap_data {
34260 +       char *dev_name;
34261 +       int fixed_config;
34262 +       char *gate_addr;
34263 +       int fd;
34264 +       void *dev;
34265 +};
34266 +
34267 +extern struct net_user_info tuntap_user_info;
34268 +
34269 +#endif
34270 +
34271 +/*
34272 + * Overrides for Emacs so that we follow Linus's tabbing style.
34273 + * Emacs will notice this stuff at the end of the file and automatically
34274 + * adjust the settings for this buffer only.  This must remain at the end
34275 + * of the file.
34276 + * ---------------------------------------------------------------------------
34277 + * Local variables:
34278 + * c-file-style: "linux"
34279 + * End:
34280 + */
34281 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_kern.c um/arch/um/os-Linux/drivers/tuntap_kern.c
34282 --- orig/arch/um/os-Linux/drivers/tuntap_kern.c 1969-12-31 19:00:00.000000000 -0500
34283 +++ um/arch/um/os-Linux/drivers/tuntap_kern.c   2003-10-21 03:26:07.000000000 -0400
34284 @@ -0,0 +1,105 @@
34285 +/* 
34286 + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
34287 + * Licensed under the GPL
34288 + */
34289 +
34290 +#include "linux/stddef.h"
34291 +#include "linux/netdevice.h"
34292 +#include "linux/etherdevice.h"
34293 +#include "linux/skbuff.h"
34294 +#include "linux/init.h"
34295 +#include "asm/errno.h"
34296 +#include "net_kern.h"
34297 +#include "net_user.h"
34298 +#include "tuntap.h"
34299 +
34300 +struct tuntap_init {
34301 +       char *dev_name;
34302 +       char *gate_addr;
34303 +};
34304 +
34305 +static void tuntap_init(struct net_device *dev, void *data)
34306 +{
34307 +       struct uml_net_private *pri;
34308 +       struct tuntap_data *tpri;
34309 +       struct tuntap_init *init = data;
34310 +
34311 +       init_etherdev(dev, 0);
34312 +       pri = dev->priv;
34313 +       tpri = (struct tuntap_data *) pri->user;
34314 +       *tpri = ((struct tuntap_data)
34315 +               { .dev_name             = init->dev_name,
34316 +                 .fixed_config         = (init->dev_name != NULL),
34317 +                 .gate_addr            = init->gate_addr,
34318 +                 .fd                   = -1,
34319 +                 .dev                  = dev });
34320 +       printk("TUN/TAP backend - ");
34321 +       if(tpri->gate_addr != NULL) 
34322 +               printk("IP = %s", tpri->gate_addr);
34323 +       printk("\n");
34324 +}
34325 +
34326 +static int tuntap_read(int fd, struct sk_buff **skb, 
34327 +                      struct uml_net_private *lp)
34328 +{
34329 +       *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
34330 +       if(*skb == NULL) return(-ENOMEM);
34331 +       return(net_read(fd, (*skb)->mac.raw, 
34332 +                       (*skb)->dev->mtu + ETH_HEADER_OTHER));
34333 +}
34334 +
34335 +static int tuntap_write(int fd, struct sk_buff **skb, 
34336 +                       struct uml_net_private *lp)
34337 +{
34338 +       return(net_write(fd, (*skb)->data, (*skb)->len));
34339 +}
34340 +
34341 +struct net_kern_info tuntap_kern_info = {
34342 +       .init                   = tuntap_init,
34343 +       .protocol               = eth_protocol,
34344 +       .read                   = tuntap_read,
34345 +       .write                  = tuntap_write,
34346 +};
34347 +
34348 +int tuntap_setup(char *str, char **mac_out, void *data)
34349 +{
34350 +       struct tuntap_init *init = data;
34351 +
34352 +       *init = ((struct tuntap_init)
34353 +               { .dev_name     = NULL,
34354 +                 .gate_addr    = NULL });
34355 +       if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
34356 +                           &init->gate_addr))
34357 +               return(0);
34358 +
34359 +       return(1);
34360 +}
34361 +
34362 +static struct transport tuntap_transport = {
34363 +       .list           = LIST_HEAD_INIT(tuntap_transport.list),
34364 +       .name           = "tuntap",
34365 +       .setup          = tuntap_setup,
34366 +       .user           = &tuntap_user_info,
34367 +       .kern           = &tuntap_kern_info,
34368 +       .private_size   = sizeof(struct tuntap_data),
34369 +       .setup_size     = sizeof(struct tuntap_init),
34370 +};
34371 +
34372 +static int register_tuntap(void)
34373 +{
34374 +       register_transport(&tuntap_transport);
34375 +       return(1);
34376 +}
34377 +
34378 +__initcall(register_tuntap);
34379 +
34380 +/*
34381 + * Overrides for Emacs so that we follow Linus's tabbing style.
34382 + * Emacs will notice this stuff at the end of the file and automatically
34383 + * adjust the settings for this buffer only.  This must remain at the end
34384 + * of the file.
34385 + * ---------------------------------------------------------------------------
34386 + * Local variables:
34387 + * c-file-style: "linux"
34388 + * End:
34389 + */
34390 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_user.c um/arch/um/os-Linux/drivers/tuntap_user.c
34391 --- orig/arch/um/os-Linux/drivers/tuntap_user.c 1969-12-31 19:00:00.000000000 -0500
34392 +++ um/arch/um/os-Linux/drivers/tuntap_user.c   2003-11-12 00:02:30.000000000 -0500
34393 @@ -0,0 +1,224 @@
34394 +/* 
34395 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
34396 + * Licensed under the GPL
34397 + */
34398 +
34399 +#include <stdio.h>
34400 +#include <stddef.h>
34401 +#include <stdlib.h>
34402 +#include <unistd.h>
34403 +#include <errno.h>
34404 +#include <sys/wait.h>
34405 +#include <sys/socket.h>
34406 +#include <sys/un.h>
34407 +#include <sys/uio.h>
34408 +#include <sys/ioctl.h>
34409 +#include <net/if.h>
34410 +#include <linux/if_tun.h>
34411 +#include "net_user.h"
34412 +#include "tuntap.h"
34413 +#include "kern_util.h"
34414 +#include "user.h"
34415 +#include "helper.h"
34416 +#include "os.h"
34417 +
34418 +#define MAX_PACKET ETH_MAX_PACKET
34419 +
34420 +void tuntap_user_init(void *data, void *dev)
34421 +{
34422 +       struct tuntap_data *pri = data;
34423 +
34424 +       pri->dev = dev;
34425 +}
34426 +
34427 +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
34428 +                           void *data)
34429 +{
34430 +       struct tuntap_data *pri = data;
34431 +
34432 +       tap_check_ips(pri->gate_addr, addr);
34433 +       if((pri->fd == -1) || pri->fixed_config) return;
34434 +       open_addr(addr, netmask, pri->dev_name);
34435 +}
34436 +
34437 +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
34438 +                           void *data)
34439 +{
34440 +       struct tuntap_data *pri = data;
34441 +
34442 +       if((pri->fd == -1) || pri->fixed_config) return;
34443 +       close_addr(addr, netmask, pri->dev_name);
34444 +}
34445 +
34446 +struct tuntap_pre_exec_data {
34447 +       int stdout;
34448 +       int close_me;
34449 +};
34450 +
34451 +static void tuntap_pre_exec(void *arg)
34452 +{
34453 +       struct tuntap_pre_exec_data *data = arg;
34454 +       
34455 +       dup2(data->stdout, 1);
34456 +       os_close_file(data->close_me);
34457 +}
34458 +
34459 +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
34460 +                            char *buffer, int buffer_len, int *used_out)
34461 +{
34462 +       struct tuntap_pre_exec_data data;
34463 +       char version_buf[sizeof("nnnnn\0")];
34464 +       char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate,
34465 +                        NULL };
34466 +       char buf[CMSG_SPACE(sizeof(*fd_out))];
34467 +       struct msghdr msg;
34468 +       struct cmsghdr *cmsg;
34469 +       struct iovec iov;
34470 +       int pid, n;
34471 +
34472 +       sprintf(version_buf, "%d", UML_NET_VERSION);
34473 +
34474 +       data.stdout = remote;
34475 +       data.close_me = me;
34476 +
34477 +       pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
34478 +
34479 +       if(pid < 0) return(-pid);
34480 +
34481 +       os_close_file(remote);
34482 +
34483 +       msg.msg_name = NULL;
34484 +       msg.msg_namelen = 0;
34485 +       if(buffer != NULL){
34486 +               iov = ((struct iovec) { buffer, buffer_len });
34487 +               msg.msg_iov = &iov;
34488 +               msg.msg_iovlen = 1;
34489 +       }
34490 +       else {
34491 +               msg.msg_iov = NULL;
34492 +               msg.msg_iovlen = 0;
34493 +       }
34494 +       msg.msg_control = buf;
34495 +       msg.msg_controllen = sizeof(buf);
34496 +       msg.msg_flags = 0;
34497 +       n = recvmsg(me, &msg, 0);
34498 +       *used_out = n;
34499 +       if(n < 0){
34500 +               printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", 
34501 +                      errno);
34502 +               return(-errno);
34503 +       }
34504 +       waitpid(pid, NULL, 0);
34505 +
34506 +       cmsg = CMSG_FIRSTHDR(&msg);
34507 +       if(cmsg == NULL){
34508 +               printk("tuntap_open_tramp : didn't receive a message\n");
34509 +               return(-EINVAL);
34510 +       }
34511 +       if((cmsg->cmsg_level != SOL_SOCKET) || 
34512 +          (cmsg->cmsg_type != SCM_RIGHTS)){
34513 +               printk("tuntap_open_tramp : didn't receive a descriptor\n");
34514 +               return(-EINVAL);
34515 +       }
34516 +       *fd_out = ((int *) CMSG_DATA(cmsg))[0];
34517 +       return(0);
34518 +}
34519 +
34520 +static int tuntap_open(void *data)
34521 +{
34522 +       struct ifreq ifr;
34523 +       struct tuntap_data *pri = data;
34524 +       char *output, *buffer;
34525 +       int err, fds[2], len, used;
34526 +
34527 +       err = tap_open_common(pri->dev, pri->gate_addr);
34528 +       if(err < 0) 
34529 +               return(err);
34530 +
34531 +       if(pri->fixed_config){
34532 +               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
34533 +               if(pri->fd < 0){
34534 +                       printk("Failed to open /dev/net/tun, err = %d\n",
34535 +                              -pri->fd);
34536 +                       return(pri->fd);
34537 +               }
34538 +               memset(&ifr, 0, sizeof(ifr));
34539 +               ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
34540 +               strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1);
34541 +               if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
34542 +                       printk("TUNSETIFF failed, errno = %d\n", errno);
34543 +                       os_close_file(pri->fd);
34544 +                       return(-errno);
34545 +               }
34546 +       }
34547 +       else {
34548 +               err = os_pipe(fds, 0, 0);
34549 +               if(err < 0){
34550 +                       printk("tuntap_open : os_pipe failed - err = %d\n",
34551 +                              -err);
34552 +                       return(err);
34553 +               }
34554 +
34555 +               buffer = get_output_buffer(&len);
34556 +               if(buffer != NULL) len--;
34557 +               used = 0;
34558 +
34559 +               err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
34560 +                                       fds[1], buffer, len, &used);
34561 +
34562 +               output = buffer;
34563 +               if(err < 0) {
34564 +                       printk("%s", output);
34565 +                       free_output_buffer(buffer);
34566 +                       printk("tuntap_open_tramp failed - err = %d\n", -err);
34567 +                       return(err);
34568 +               }
34569 +
34570 +               pri->dev_name = uml_strdup(buffer);
34571 +               output += IFNAMSIZ;
34572 +               printk("%s", output);
34573 +               free_output_buffer(buffer);
34574 +
34575 +               os_close_file(fds[0]);
34576 +               iter_addresses(pri->dev, open_addr, pri->dev_name);
34577 +       }
34578 +
34579 +       return(pri->fd);
34580 +}
34581 +
34582 +static void tuntap_close(int fd, void *data)
34583 +{
34584 +       struct tuntap_data *pri = data;
34585 +
34586 +       if(!pri->fixed_config) 
34587 +               iter_addresses(pri->dev, close_addr, pri->dev_name);
34588 +       os_close_file(fd);
34589 +       pri->fd = -1;
34590 +}
34591 +
34592 +static int tuntap_set_mtu(int mtu, void *data)
34593 +{
34594 +       return(mtu);
34595 +}
34596 +
34597 +struct net_user_info tuntap_user_info = {
34598 +       .init           = tuntap_user_init,
34599 +       .open           = tuntap_open,
34600 +       .close          = tuntap_close,
34601 +       .remove         = NULL,
34602 +       .set_mtu        = tuntap_set_mtu,
34603 +       .add_address    = tuntap_add_addr,
34604 +       .delete_address = tuntap_del_addr,
34605 +       .max_packet     = MAX_PACKET
34606 +};
34607 +
34608 +/*
34609 + * Overrides for Emacs so that we follow Linus's tabbing style.
34610 + * Emacs will notice this stuff at the end of the file and automatically
34611 + * adjust the settings for this buffer only.  This must remain at the end
34612 + * of the file.
34613 + * ---------------------------------------------------------------------------
34614 + * Local variables:
34615 + * c-file-style: "linux"
34616 + * End:
34617 + */
34618 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/file.c um/arch/um/os-Linux/file.c
34619 --- orig/arch/um/os-Linux/file.c        1969-12-31 19:00:00.000000000 -0500
34620 +++ um/arch/um/os-Linux/file.c  2003-11-30 20:18:39.000000000 -0500
34621 @@ -0,0 +1,669 @@
34622 +/* 
34623 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
34624 + * Licensed under the GPL
34625 + */
34626 +
34627 +#include <stdio.h>
34628 +#include <unistd.h>
34629 +#include <errno.h>
34630 +#include <fcntl.h>
34631 +#include <signal.h>
34632 +#include <sys/types.h>
34633 +#include <sys/stat.h>
34634 +#include <sys/socket.h>
34635 +#include <sys/un.h>
34636 +#include <sys/ioctl.h>
34637 +#include <sys/mount.h>
34638 +#include <sys/uio.h>
34639 +#include "os.h"
34640 +#include "user.h"
34641 +#include "kern_util.h"
34642 +
34643 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
34644 +{
34645 +       *dst = ((struct uml_stat) {
34646 +               .ust_dev     = src->st_dev,     /* device */
34647 +               .ust_ino     = src->st_ino,     /* inode */
34648 +               .ust_mode    = src->st_mode,    /* protection */
34649 +               .ust_nlink   = src->st_nlink,   /* number of hard links */
34650 +               .ust_uid     = src->st_uid,     /* user ID of owner */
34651 +               .ust_gid     = src->st_gid,     /* group ID of owner */
34652 +               .ust_size    = src->st_size,    /* total size, in bytes */
34653 +               .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
34654 +               .ust_blocks  = src->st_blocks,  /* number of blocks allocated */
34655 +               .ust_atime   = src->st_atime,   /* time of last access */
34656 +               .ust_mtime   = src->st_mtime,   /* time of last modification */
34657 +               .ust_ctime   = src->st_ctime,   /* time of last change */
34658 +       });
34659 +}
34660 +
34661 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
34662 +{
34663 +       struct stat64 sbuf;
34664 +       int err;
34665 +
34666 +       do {
34667 +               err = fstat64(fd, &sbuf);
34668 +       } while((err < 0) && (errno == EINTR)) ;
34669 +
34670 +       if(err < 0) 
34671 +               return(-errno);
34672 +
34673 +       if(ubuf != NULL)
34674 +               copy_stat(ubuf, &sbuf);
34675 +       return(err);
34676 +}
34677 +
34678 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
34679 +{
34680 +       struct stat64 sbuf;
34681 +       int err;
34682 +
34683 +       do {
34684 +               err = stat64(file_name, &sbuf);
34685 +       } while((err < 0) && (errno == EINTR)) ;
34686 +
34687 +       if(err < 0) 
34688 +               return(-errno);
34689 +
34690 +       if(ubuf != NULL)
34691 +               copy_stat(ubuf, &sbuf);
34692 +       return(err);
34693 +}
34694 +
34695 +int os_access(const char* file, int mode)
34696 +{
34697 +       int amode, err;
34698 +
34699 +       amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
34700 +             (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
34701 +
34702 +       err = access(file, amode);
34703 +       if(err < 0)
34704 +               return(-errno);
34705 +
34706 +       return(0);
34707 +}
34708 +
34709 +void os_print_error(int error, const char* str)
34710 +{
34711 +       errno = error < 0 ? -error : error;
34712 +
34713 +       perror(str);
34714 +}
34715 +
34716 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
34717 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
34718 +{
34719 +       int err;
34720 +
34721 +       err = ioctl(fd, cmd, arg);
34722 +       if(err < 0)
34723 +               return(-errno);
34724 +
34725 +       return(err);
34726 +}
34727 +
34728 +int os_window_size(int fd, int *rows, int *cols)
34729 +{
34730 +       struct winsize size;
34731 +
34732 +       if(ioctl(fd, TIOCGWINSZ, &size) < 0)
34733 +               return(-errno);
34734 +
34735 +       *rows = size.ws_row;
34736 +       *cols = size.ws_col;
34737 +
34738 +       return(0);
34739 +}
34740 +
34741 +int os_new_tty_pgrp(int fd, int pid)
34742 +{
34743 +       if(ioctl(fd, TIOCSCTTY, 0) < 0){
34744 +               printk("TIOCSCTTY failed, errno = %d\n", errno);
34745 +               return(-errno);
34746 +       }
34747 +
34748 +       if(tcsetpgrp(fd, pid) < 0){
34749 +               printk("tcsetpgrp failed, errno = %d\n", errno);
34750 +               return(-errno);
34751 +       }
34752 +
34753 +       return(0);
34754 +}
34755 +
34756 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
34757 +int os_get_ifname(int fd, char* namebuf)
34758 +{
34759 +       if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
34760 +               return(-errno);
34761 +
34762 +       return(0);
34763 +}
34764 +
34765 +int os_set_slip(int fd)
34766 +{
34767 +       int disc, sencap;
34768 +
34769 +       disc = N_SLIP;
34770 +       if(ioctl(fd, TIOCSETD, &disc) < 0){
34771 +               printk("Failed to set slip line discipline - "
34772 +                      "errno = %d\n", errno);
34773 +               return(-errno);
34774 +       }
34775 +
34776 +       sencap = 0;
34777 +       if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
34778 +               printk("Failed to set slip encapsulation - "
34779 +                      "errno = %d\n", errno);
34780 +               return(-errno);
34781 +       }
34782 +
34783 +       return(0);
34784 +}
34785 +
34786 +int os_set_owner(int fd, int pid)
34787 +{
34788 +       if(fcntl(fd, F_SETOWN, pid) < 0){
34789 +               int save_errno = errno;
34790 +
34791 +               if(fcntl(fd, F_GETOWN, 0) != pid){
34792 +                       return(-save_errno);
34793 +                }
34794 +        }
34795 +
34796 +       return(0);
34797 +}
34798 +
34799 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ 
34800 +int os_sigio_async(int master, int slave)
34801 +{
34802 +       int flags;
34803 +
34804 +       flags = fcntl(master, F_GETFL);
34805 +       if(flags < 0) {
34806 +               printk("fcntl F_GETFL failed, errno = %d\n", errno);
34807 +               return(-errno);
34808 +       }
34809 +
34810 +        if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
34811 +           (fcntl(master, F_SETOWN, os_getpid()) < 0)){
34812 +                printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
34813 +               return(-errno);
34814 +       }
34815 +
34816 +        if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
34817 +                printk("fcntl F_SETFL failed, errno = %d\n", errno);
34818 +               return(-errno);
34819 +       }
34820 +
34821 +       return(0);
34822 +}
34823 +
34824 +int os_mode_fd(int fd, int mode)
34825 +{
34826 +       int err;
34827 +
34828 +       do {
34829 +               err = fchmod(fd, mode);
34830 +       } while((err < 0) && (errno==EINTR)) ;
34831 +
34832 +       if(err < 0)
34833 +               return(-errno);
34834 +
34835 +       return(0);
34836 +}
34837 +
34838 +int os_file_type(char *file)
34839 +{
34840 +       struct uml_stat buf;
34841 +       int err;
34842 +
34843 +       err = os_stat_file(file, &buf);
34844 +       if(err < 0)
34845 +               return(err);
34846 +
34847 +       if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
34848 +       else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
34849 +       else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
34850 +       else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
34851 +       else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
34852 +       else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
34853 +       else return(OS_TYPE_FILE);
34854 +}
34855 +
34856 +int os_file_mode(char *file, struct openflags *mode_out)
34857 +{
34858 +       int err;
34859 +
34860 +       *mode_out = OPENFLAGS();
34861 +
34862 +       err = os_access(file, OS_ACC_W_OK);
34863 +       if((err < 0) && (err != -EACCES))
34864 +               return(err);
34865 +
34866 +       *mode_out = of_write(*mode_out);
34867 +
34868 +       err = os_access(file, OS_ACC_R_OK);
34869 +       if((err < 0) && (err != -EACCES))
34870 +               return(err);
34871 +
34872 +       *mode_out = of_read(*mode_out);
34873 +
34874 +       return(0);
34875 +}
34876 +
34877 +int os_open_file(char *file, struct openflags flags, int mode)
34878 +{
34879 +       int fd, f = 0;
34880 +
34881 +       if(flags.r && flags.w) f = O_RDWR;
34882 +       else if(flags.r) f = O_RDONLY;
34883 +       else if(flags.w) f = O_WRONLY;
34884 +       else f = 0;
34885 +
34886 +       if(flags.s) f |= O_SYNC;
34887 +       if(flags.c) f |= O_CREAT;
34888 +       if(flags.t) f |= O_TRUNC;
34889 +       if(flags.e) f |= O_EXCL;
34890 +
34891 +       fd = open64(file, f, mode);
34892 +       if(fd < 0)
34893 +               return(-errno);
34894 +
34895 +       if(flags.cl && fcntl(fd, F_SETFD, 1)){
34896 +               os_close_file(fd);
34897 +               return(-errno);
34898 +       }
34899 +
34900 +       return(fd);
34901 +}
34902 +
34903 +int os_connect_socket(char *name)
34904 +{
34905 +       struct sockaddr_un sock;
34906 +       int fd, err;
34907 +
34908 +       sock.sun_family = AF_UNIX;
34909 +       snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
34910 +
34911 +       fd = socket(AF_UNIX, SOCK_STREAM, 0);
34912 +       if(fd < 0)
34913 +               return(fd);
34914 +
34915 +       err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
34916 +       if(err)
34917 +               return(-errno);
34918 +
34919 +       return(fd);
34920 +}
34921 +
34922 +void os_close_file(int fd)
34923 +{
34924 +       close(fd);
34925 +}
34926 +
34927 +int os_seek_file(int fd, __u64 offset)
34928 +{
34929 +       __u64 actual;
34930 +
34931 +       actual = lseek64(fd, offset, SEEK_SET);
34932 +       if(actual != offset) return(-errno);
34933 +       return(0);
34934 +}
34935 +
34936 +static int fault_buffer(void *start, int len, 
34937 +                       int (*copy_proc)(void *addr, void *buf, int len))
34938 +{
34939 +       int page = getpagesize(), i;
34940 +       char c;
34941 +
34942 +       for(i = 0; i < len; i += page){
34943 +               if((*copy_proc)(start + i, &c, sizeof(c)))
34944 +                       return(-EFAULT);
34945 +       }
34946 +       if((len % page) != 0){
34947 +               if((*copy_proc)(start + len - 1, &c, sizeof(c)))
34948 +                       return(-EFAULT);
34949 +       }
34950 +       return(0);
34951 +}
34952 +
34953 +static int file_io(int fd, void *buf, int len,
34954 +                  int (*io_proc)(int fd, void *buf, int len),
34955 +                  int (*copy_user_proc)(void *addr, void *buf, int len))
34956 +{
34957 +       int n, err;
34958 +
34959 +       do {
34960 +               n = (*io_proc)(fd, buf, len);
34961 +               if((n < 0) && (errno == EFAULT)){
34962 +                       err = fault_buffer(buf, len, copy_user_proc);
34963 +                       if(err)
34964 +                               return(err);
34965 +                       n = (*io_proc)(fd, buf, len);
34966 +               }
34967 +       } while((n < 0) && (errno == EINTR));
34968 +
34969 +       if(n < 0)
34970 +               return(-errno);
34971 +       return(n);
34972 +}
34973 +
34974 +int os_read_file(int fd, void *buf, int len)
34975 +{
34976 +       return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, 
34977 +                      copy_from_user_proc));
34978 +}
34979 +
34980 +int os_write_file(int fd, const void *buf, int len)
34981 +{
34982 +       return(file_io(fd, (void *) buf, len, 
34983 +                      (int (*)(int, void *, int)) write, copy_to_user_proc));
34984 +}
34985 +
34986 +int os_file_size(char *file, long long *size_out)
34987 +{
34988 +       struct uml_stat buf;
34989 +       int err;
34990 +
34991 +       err = os_stat_file(file, &buf);
34992 +       if(err < 0){
34993 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
34994 +               return(err);
34995 +       }
34996 +
34997 +       if(S_ISBLK(buf.ust_mode)){
34998 +               int fd, blocks;
34999 +
35000 +               fd = os_open_file(file, of_read(OPENFLAGS()), 0);
35001 +               if(fd < 0){
35002 +                       printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
35003 +                       return(fd);
35004 +               }
35005 +               if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
35006 +                       printk("Couldn't get the block size of \"%s\", "
35007 +                              "errno = %d\n", file, errno);
35008 +                       err = -errno;
35009 +                       os_close_file(fd);
35010 +                       return(err);
35011 +               }
35012 +               *size_out = ((long long) blocks) * 512;
35013 +               os_close_file(fd);
35014 +               return(0);
35015 +       }
35016 +       *size_out = buf.ust_size;
35017 +       return(0);
35018 +}
35019 +
35020 +int os_file_modtime(char *file, unsigned long *modtime)
35021 +{
35022 +       struct uml_stat buf;
35023 +       int err;
35024 +
35025 +       err = os_stat_file(file, &buf);
35026 +       if(err < 0){
35027 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
35028 +               return(err);
35029 +       }
35030 +
35031 +       *modtime = buf.ust_mtime;
35032 +       return(0);
35033 +}
35034
35035 +int os_get_exec_close(int fd, int* close_on_exec)
35036 +{
35037 +       int ret;
35038 +
35039 +       do {
35040 +               ret = fcntl(fd, F_GETFD);
35041 +       } while((ret < 0) && (errno == EINTR)) ;
35042 +
35043 +       if(ret < 0)
35044 +               return(-errno);
35045 +
35046 +       *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
35047 +       return(ret);
35048 +}
35049 +
35050 +int os_set_exec_close(int fd, int close_on_exec)
35051 +{
35052 +       int flag, err;
35053 +
35054 +       if(close_on_exec) flag = FD_CLOEXEC;
35055 +       else flag = 0;
35056 +
35057 +       do {
35058 +               err = fcntl(fd, F_SETFD, flag);
35059 +       } while((err < 0) && (errno == EINTR)) ;
35060 +
35061 +       if(err < 0)
35062 +               return(-errno);
35063 +       return(err);
35064 +}
35065 +
35066 +int os_pipe(int *fds, int stream, int close_on_exec)
35067 +{
35068 +       int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
35069 +
35070 +       err = socketpair(AF_UNIX, type, 0, fds);
35071 +       if(err < 0) 
35072 +               return(-errno);
35073 +
35074 +       if(!close_on_exec)
35075 +               return(0);
35076 +
35077 +       err = os_set_exec_close(fds[0], 1);
35078 +       if(err < 0)
35079 +               goto error;
35080 +
35081 +       err = os_set_exec_close(fds[1], 1);
35082 +       if(err < 0)
35083 +               goto error;
35084 +
35085 +       return(0);
35086 +
35087 + error:
35088 +       printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
35089 +       os_close_file(fds[1]);
35090 +       os_close_file(fds[0]);
35091 +       return(err);
35092 +}
35093 +
35094 +int os_set_fd_async(int fd, int owner)
35095 +{
35096 +       /* XXX This should do F_GETFL first */
35097 +       if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){
35098 +               printk("os_set_fd_async : failed to set O_ASYNC and "
35099 +                      "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
35100 +               return(-errno);
35101 +       }
35102 +#ifdef notdef
35103 +       if(fcntl(fd, F_SETFD, 1) < 0){
35104 +               printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
35105 +                      "errno = %d\n", errno);
35106 +       }
35107 +#endif
35108 +
35109 +       if((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
35110 +          (fcntl(fd, F_SETOWN, owner) < 0)){
35111 +               printk("os_set_fd_async : Failed to fcntl F_SETOWN "
35112 +                      "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, 
35113 +                      owner, errno);
35114 +               return(-errno);
35115 +       }
35116 +
35117 +       return(0);
35118 +}
35119 +
35120 +int os_set_fd_block(int fd, int blocking)
35121 +{
35122 +       int flags;
35123 +
35124 +       flags = fcntl(fd, F_GETFL);
35125 +
35126 +       if(blocking) flags &= ~O_NONBLOCK;
35127 +       else flags |= O_NONBLOCK;
35128 +
35129 +       if(fcntl(fd, F_SETFL, flags) < 0){
35130 +               printk("Failed to change blocking on fd # %d, errno = %d\n",
35131 +                      fd, errno);
35132 +               return(-errno);
35133 +       }
35134 +       return(0);
35135 +}
35136 +
35137 +int os_accept_connection(int fd)
35138 +{
35139 +       int new;
35140 +
35141 +       new = accept(fd, NULL, 0);
35142 +       if(new < 0) 
35143 +               return(-errno);
35144 +       return(new);
35145 +}
35146 +
35147 +#ifndef SHUT_RD
35148 +#define SHUT_RD 0
35149 +#endif
35150 +
35151 +#ifndef SHUT_WR
35152 +#define SHUT_WR 1
35153 +#endif
35154 +
35155 +#ifndef SHUT_RDWR
35156 +#define SHUT_RDWR 2
35157 +#endif
35158 +
35159 +int os_shutdown_socket(int fd, int r, int w)
35160 +{
35161 +       int what, err;
35162 +
35163 +       if(r && w) what = SHUT_RDWR;
35164 +       else if(r) what = SHUT_RD;
35165 +       else if(w) what = SHUT_WR;
35166 +       else {
35167 +               printk("os_shutdown_socket : neither r or w was set\n");
35168 +               return(-EINVAL);
35169 +       }
35170 +       err = shutdown(fd, what);
35171 +       if(err < 0)
35172 +               return(-errno);
35173 +       return(0);
35174 +}
35175 +
35176 +int os_rcv_fd(int fd, int *helper_pid_out)
35177 +{
35178 +       int new, n;
35179 +       char buf[CMSG_SPACE(sizeof(new))];
35180 +       struct msghdr msg;
35181 +       struct cmsghdr *cmsg;
35182 +       struct iovec iov;
35183 +
35184 +       msg.msg_name = NULL;
35185 +       msg.msg_namelen = 0;
35186 +       iov = ((struct iovec) { .iov_base  = helper_pid_out,
35187 +                               .iov_len   = sizeof(*helper_pid_out) });
35188 +       msg.msg_iov = &iov;
35189 +       msg.msg_iovlen = 1;
35190 +       msg.msg_control = buf;
35191 +       msg.msg_controllen = sizeof(buf);
35192 +       msg.msg_flags = 0;
35193 +
35194 +       n = recvmsg(fd, &msg, 0);
35195 +       if(n < 0)
35196 +               return(-errno);
35197 +
35198 +       else if(n != sizeof(iov.iov_len))
35199 +               *helper_pid_out = -1;
35200 +
35201 +       cmsg = CMSG_FIRSTHDR(&msg);
35202 +       if(cmsg == NULL){
35203 +               printk("rcv_fd didn't receive anything, error = %d\n", errno);
35204 +               return(-1);
35205 +       }
35206 +       if((cmsg->cmsg_level != SOL_SOCKET) || 
35207 +          (cmsg->cmsg_type != SCM_RIGHTS)){
35208 +               printk("rcv_fd didn't receive a descriptor\n");
35209 +               return(-1);
35210 +       }
35211 +
35212 +       new = ((int *) CMSG_DATA(cmsg))[0];
35213 +       return(new);
35214 +}
35215 +
35216 +int os_create_unix_socket(char *file, int len, int close_on_exec)
35217 +{
35218 +       struct sockaddr_un addr;
35219 +       int sock, err;
35220 +
35221 +       sock = socket(PF_UNIX, SOCK_DGRAM, 0);
35222 +       if (sock < 0){
35223 +               printk("create_unix_socket - socket failed, errno = %d\n",
35224 +                      errno);
35225 +               return(-errno);
35226 +       }
35227 +
35228 +       if(close_on_exec) {
35229 +               err = os_set_exec_close(sock, 1);
35230 +               if(err < 0)
35231 +                       printk("create_unix_socket : close_on_exec failed, "
35232 +                      "err = %d", -err);
35233 +       }
35234 +
35235 +       addr.sun_family = AF_UNIX;
35236 +
35237 +       /* XXX Be more careful about overflow */
35238 +       snprintf(addr.sun_path, len, "%s", file);
35239 +
35240 +       err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
35241 +       if (err < 0){
35242 +               printk("create_listening_socket at '%s' - bind failed, "
35243 +                      "errno = %d\n", file, errno);
35244 +               return(-errno);
35245 +       }
35246 +
35247 +       return(sock);
35248 +}
35249 +
35250 +void os_flush_stdout(void)
35251 +{
35252 +       fflush(stdout);
35253 +}
35254 +
35255 +int os_lock_file(int fd, int excl)
35256 +{
35257 +       int type = excl ? F_WRLCK : F_RDLCK;
35258 +       struct flock lock = ((struct flock) { .l_type   = type,
35259 +                                             .l_whence = SEEK_SET,
35260 +                                             .l_start  = 0,
35261 +                                             .l_len    = 0 } );
35262 +       int err, save;
35263 +
35264 +       err = fcntl(fd, F_SETLK, &lock);
35265 +       if(!err)
35266 +               goto out;
35267 +
35268 +       save = -errno;
35269 +       err = fcntl(fd, F_GETLK, &lock);
35270 +       if(err){
35271 +               err = -errno;
35272 +               goto out;
35273 +       }
35274 +               
35275 +       printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
35276 +       err = save;
35277 + out:
35278 +       return(err);
35279 +}
35280 +
35281 +/*
35282 + * Overrides for Emacs so that we follow Linus's tabbing style.
35283 + * Emacs will notice this stuff at the end of the file and automatically
35284 + * adjust the settings for this buffer only.  This must remain at the end
35285 + * of the file.
35286 + * ---------------------------------------------------------------------------
35287 + * Local variables:
35288 + * c-file-style: "linux"
35289 + * End:
35290 + */
35291 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/include/file.h um/arch/um/os-Linux/include/file.h
35292 --- orig/arch/um/os-Linux/include/file.h        1969-12-31 19:00:00.000000000 -0500
35293 +++ um/arch/um/os-Linux/include/file.h  2003-10-21 03:26:07.000000000 -0400
35294 @@ -0,0 +1,22 @@
35295 +/* 
35296 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35297 + * Licensed under the GPL
35298 + */
35299 +
35300 +#ifndef __OS_FILE_H__
35301 +#define __OS_FILE_H__
35302 +
35303 +#define DEV_NULL "/dev/null"
35304 +
35305 +#endif
35306 +
35307 +/*
35308 + * Overrides for Emacs so that we follow Linus's tabbing style.
35309 + * Emacs will notice this stuff at the end of the file and automatically
35310 + * adjust the settings for this buffer only.  This must remain at the end
35311 + * of the file.
35312 + * ---------------------------------------------------------------------------
35313 + * Local variables:
35314 + * c-file-style: "linux"
35315 + * End:
35316 + */
35317 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/Makefile um/arch/um/os-Linux/Makefile
35318 --- orig/arch/um/os-Linux/Makefile      1969-12-31 19:00:00.000000000 -0500
35319 +++ um/arch/um/os-Linux/Makefile        2003-10-21 03:26:07.000000000 -0400
35320 @@ -0,0 +1,17 @@
35321 +# 
35322 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
35323 +# Licensed under the GPL
35324 +#
35325 +
35326 +O_TARGET = built-in.o
35327 +
35328 +obj-y = file.o process.o tty.o
35329 +
35330 +include $(TOPDIR)/Rules.make
35331 +
35332 +$(obj-y) : %.o: %.c
35333 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
35334 +
35335 +clean :
35336 +
35337 +archmrproper:
35338 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/process.c um/arch/um/os-Linux/process.c
35339 --- orig/arch/um/os-Linux/process.c     1969-12-31 19:00:00.000000000 -0500
35340 +++ um/arch/um/os-Linux/process.c       2003-12-18 03:08:34.000000000 -0500
35341 @@ -0,0 +1,148 @@
35342 +/* 
35343 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
35344 + * Licensed under the GPL
35345 + */
35346 +
35347 +#include <unistd.h>
35348 +#include <stdio.h>
35349 +#include <errno.h>
35350 +#include <signal.h>
35351 +#include <sys/mman.h>
35352 +#include <sys/wait.h>
35353 +#include "os.h"
35354 +#include "user.h"
35355 +
35356 +#define ARBITRARY_ADDR -1
35357 +#define FAILURE_PID    -1
35358 +
35359 +unsigned long os_process_pc(int pid)
35360 +{
35361 +       char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
35362 +       unsigned long pc;
35363 +       int fd, err;
35364 +
35365 +       sprintf(proc_stat, "/proc/%d/stat", pid);
35366 +       fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
35367 +       if(fd < 0){
35368 +               printk("os_process_pc - couldn't open '%s', err = %d\n", 
35369 +                      proc_stat, -fd);
35370 +               return(ARBITRARY_ADDR);
35371 +       }
35372 +       err = os_read_file(fd, buf, sizeof(buf));
35373 +       if(err < 0){
35374 +               printk("os_process_pc - couldn't read '%s', err = %d\n", 
35375 +                      proc_stat, -err);
35376 +               os_close_file(fd);
35377 +               return(ARBITRARY_ADDR);
35378 +       }
35379 +       os_close_file(fd);
35380 +       pc = ARBITRARY_ADDR;
35381 +       if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
35382 +                 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
35383 +                 "%*d %*d %*d %*d %ld", &pc) != 1){
35384 +               printk("os_process_pc - couldn't find pc in '%s'\n", buf);
35385 +       }
35386 +       return(pc);
35387 +}
35388 +
35389 +int os_process_parent(int pid)
35390 +{
35391 +       char stat[sizeof("/proc/nnnnn/stat\0")];
35392 +       char data[256];
35393 +       int parent, n, fd;
35394 +
35395 +       if(pid == -1) return(-1);
35396 +
35397 +       snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
35398 +       fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
35399 +       if(fd < 0){
35400 +               printk("Couldn't open '%s', err = %d\n", stat, -fd);
35401 +               return(FAILURE_PID);
35402 +       }
35403 +
35404 +       n = os_read_file(fd, data, sizeof(data));
35405 +       os_close_file(fd);
35406 +
35407 +       if(n < 0){
35408 +               printk("Couldn't read '%s', err = %d\n", stat, -n);
35409 +               return(FAILURE_PID);
35410 +       }
35411 +
35412 +       parent = FAILURE_PID;
35413 +       /* XXX This will break if there is a space in the command */
35414 +       n = sscanf(data, "%*d %*s %*c %d", &parent);
35415 +       if(n != 1) 
35416 +               printk("Failed to scan '%s'\n", data);
35417 +
35418 +       return(parent);
35419 +}
35420 +
35421 +void os_stop_process(int pid)
35422 +{
35423 +       kill(pid, SIGSTOP);
35424 +}
35425 +
35426 +void os_kill_process(int pid, int reap_child)
35427 +{
35428 +       kill(pid, SIGKILL);
35429 +       if(reap_child)
35430 +               waitpid(pid, NULL, 0);
35431 +               
35432 +}
35433 +
35434 +void os_usr1_process(int pid)
35435 +{
35436 +       kill(pid, SIGUSR1);
35437 +}
35438 +
35439 +int os_getpid(void)
35440 +{
35441 +       return(getpid());
35442 +}
35443 +
35444 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
35445 +                 int r, int w, int x)
35446 +{
35447 +       void *loc;
35448 +       int prot;
35449 +
35450 +       prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
35451 +               (x ? PROT_EXEC : 0);
35452 +
35453 +       loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
35454 +                    fd, off);
35455 +       if(loc == MAP_FAILED)
35456 +               return(-errno);
35457 +       return(0);
35458 +}
35459 +
35460 +int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
35461 +{
35462 +        int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
35463 +                   (x ? PROT_EXEC : 0));
35464 +
35465 +        if(mprotect(addr, len, prot) < 0)
35466 +               return(-errno);
35467 +        return(0);
35468 +}
35469 +
35470 +int os_unmap_memory(void *addr, int len)
35471 +{
35472 +        int err;
35473 +
35474 +        err = munmap(addr, len);
35475 +        if(err < 0) 
35476 +               return(-errno);
35477 +        return(0);
35478 +}
35479 +
35480 +/*
35481 + * Overrides for Emacs so that we follow Linus's tabbing style.
35482 + * Emacs will notice this stuff at the end of the file and automatically
35483 + * adjust the settings for this buffer only.  This must remain at the end
35484 + * of the file.
35485 + * ---------------------------------------------------------------------------
35486 + * Local variables:
35487 + * c-file-style: "linux"
35488 + * End:
35489 + */
35490 diff -Naur -X ../exclude-files orig/arch/um/os-Linux/tty.c um/arch/um/os-Linux/tty.c
35491 --- orig/arch/um/os-Linux/tty.c 1969-12-31 19:00:00.000000000 -0500
35492 +++ um/arch/um/os-Linux/tty.c   2003-10-21 03:26:07.000000000 -0400
35493 @@ -0,0 +1,61 @@
35494 +/* 
35495 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35496 + * Licensed under the GPL
35497 + */
35498 +
35499 +#include <stdlib.h>
35500 +#include <errno.h>
35501 +#include "os.h"
35502 +#include "user.h"
35503 +#include "kern_util.h"
35504 +
35505 +struct grantpt_info {
35506 +       int fd;
35507 +       int res;
35508 +       int err;
35509 +};
35510 +
35511 +static void grantpt_cb(void *arg)
35512 +{
35513 +       struct grantpt_info *info = arg;
35514 +
35515 +       info->res = grantpt(info->fd);
35516 +       info->err = errno;
35517 +}
35518 +
35519 +int get_pty(void)
35520 +{
35521 +       struct grantpt_info info;
35522 +       int fd;
35523 +
35524 +       fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
35525 +       if(fd < 0){
35526 +               printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
35527 +               return(fd);
35528 +       }
35529 +
35530 +       info.fd = fd;
35531 +       initial_thread_cb(grantpt_cb, &info);
35532 +
35533 +       if(info.res < 0){
35534 +               printk("get_pty : Couldn't grant pty - errno = %d\n", 
35535 +                      -info.err);
35536 +               return(-1);
35537 +       }
35538 +       if(unlockpt(fd) < 0){
35539 +               printk("get_pty : Couldn't unlock pty - errno = %d\n", errno);
35540 +               return(-1);
35541 +       }
35542 +       return(fd);
35543 +}
35544 +
35545 +/*
35546 + * Overrides for Emacs so that we follow Linus's tabbing style.
35547 + * Emacs will notice this stuff at the end of the file and automatically
35548 + * adjust the settings for this buffer only.  This must remain at the end
35549 + * of the file.
35550 + * ---------------------------------------------------------------------------
35551 + * Local variables:
35552 + * c-file-style: "linux"
35553 + * End:
35554 + */
35555 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/bugs.c um/arch/um/sys-i386/bugs.c
35556 --- orig/arch/um/sys-i386/bugs.c        1969-12-31 19:00:00.000000000 -0500
35557 +++ um/arch/um/sys-i386/bugs.c  2003-11-15 02:54:48.000000000 -0500
35558 @@ -0,0 +1,221 @@
35559 +/* 
35560 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
35561 + * Licensed under the GPL
35562 + */
35563 +
35564 +#include <unistd.h>
35565 +#include <errno.h>
35566 +#include <string.h>
35567 +#include <sys/signal.h>
35568 +#include <asm/ldt.h>
35569 +#include "kern_util.h"
35570 +#include "user.h"
35571 +#include "sysdep/ptrace.h"
35572 +#include "task.h"
35573 +#include "os.h"
35574 +
35575 +#define MAXTOKEN 64
35576 +
35577 +/* Set during early boot */
35578 +int cpu_has_cmov = 1;
35579 +int cpu_has_xmm = 0;
35580 +
35581 +static char token(int fd, char *buf, int len, char stop)
35582 +{
35583 +       int n;
35584 +       char *ptr, *end, c;
35585 +
35586 +       ptr = buf;
35587 +       end = &buf[len];
35588 +       do {
35589 +               n = os_read_file(fd, ptr, sizeof(*ptr));
35590 +               c = *ptr++;
35591 +               if(n != sizeof(*ptr)){
35592 +                       if(n == 0) return(0);
35593 +                       printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
35594 +                       if(n < 0) 
35595 +                               return(n);
35596 +                       else 
35597 +                               return(-EIO);
35598 +               }
35599 +       } while((c != '\n') && (c != stop) && (ptr < end));
35600 +
35601 +       if(ptr == end){
35602 +               printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
35603 +               return(-1);
35604 +       }
35605 +       *(ptr - 1) = '\0';
35606 +       return(c);
35607 +}
35608 +
35609 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
35610 +{
35611 +       int n;
35612 +       char c;
35613 +
35614 +       scratch[len - 1] = '\0';
35615 +       while(1){
35616 +               c = token(fd, scratch, len - 1, ':');
35617 +               if(c <= 0)
35618 +                       return(0);
35619 +               else if(c != ':'){
35620 +                       printk("Failed to find ':' in /proc/cpuinfo\n");
35621 +                       return(0);
35622 +               }
35623 +
35624 +               if(!strncmp(scratch, key, strlen(key))) 
35625 +                       return(1);
35626 +
35627 +               do {
35628 +                       n = os_read_file(fd, &c, sizeof(c));
35629 +                       if(n != sizeof(c)){
35630 +                               printk("Failed to find newline in "
35631 +                                      "/proc/cpuinfo, err = %d\n", -n);
35632 +                               return(0);
35633 +                       }
35634 +               } while(c != '\n');
35635 +       }
35636 +       return(0);
35637 +}
35638 +
35639 +int cpu_feature(char *what, char *buf, int len)
35640 +{
35641 +       int fd, ret = 0;
35642 +
35643 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
35644 +       if(fd < 0){
35645 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
35646 +               return(0);
35647 +       }
35648 +
35649 +       if(!find_cpuinfo_line(fd, what, buf, len)){
35650 +               printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
35651 +               goto out_close;
35652 +       }
35653 +
35654 +       token(fd, buf, len, '\n');
35655 +       ret = 1;
35656 +
35657 + out_close:
35658 +       os_close_file(fd);
35659 +       return(ret);
35660 +}
35661 +
35662 +static int check_cpu_flag(char *feature, int *have_it)
35663 +{
35664 +       char buf[MAXTOKEN], c;
35665 +       int fd, len = sizeof(buf)/sizeof(buf[0]);
35666 +
35667 +       printk("Checking for host processor %s support...", feature);
35668 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
35669 +       if(fd < 0){
35670 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
35671 +               return(0);
35672 +       }
35673 +
35674 +       *have_it = 0;
35675 +       if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
35676 +               goto out;
35677 +
35678 +       c = token(fd, buf, len - 1, ' ');
35679 +       if(c < 0) goto out;
35680 +       else if(c != ' '){
35681 +               printk("Failed to find ' ' in /proc/cpuinfo\n");
35682 +               goto out;
35683 +       }
35684 +
35685 +       while(1){
35686 +               c = token(fd, buf, len - 1, ' ');
35687 +               if(c < 0) goto out;
35688 +               else if(c == '\n') break;
35689 +
35690 +               if(!strcmp(buf, feature)){
35691 +                       *have_it = 1;
35692 +                       goto out;
35693 +               }
35694 +       }
35695 + out:
35696 +       if(*have_it == 0) printk("No\n");
35697 +       else if(*have_it == 1) printk("Yes\n");
35698 +       os_close_file(fd);
35699 +       return(1);
35700 +}
35701 +
35702 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
35703 +       * for some people.
35704 +       */
35705 +static void disable_lcall(void)
35706 +{
35707 +       struct modify_ldt_ldt_s ldt;
35708 +       int err;
35709 +
35710 +       bzero(&ldt, sizeof(ldt));
35711 +       ldt.entry_number = 7;
35712 +       ldt.base_addr = 0;
35713 +       ldt.limit = 0;
35714 +       err = modify_ldt(1, &ldt, sizeof(ldt));
35715 +       if(err)
35716 +               printk("Failed to disable lcall7 - errno = %d\n", errno);
35717 +}
35718 +#endif
35719 +
35720 +void arch_init_thread(void)
35721 +{
35722 +#if 0
35723 +       disable_lcall();
35724 +#endif
35725 +}
35726 +
35727 +void arch_check_bugs(void)
35728 +{
35729 +       int have_it;
35730 +
35731 +       if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
35732 +               printk("/proc/cpuinfo not available - skipping CPU capability "
35733 +                      "checks\n");
35734 +               return;
35735 +       }
35736 +       if(check_cpu_flag("cmov", &have_it)) 
35737 +               cpu_has_cmov = have_it;
35738 +       if(check_cpu_flag("xmm", &have_it)) 
35739 +               cpu_has_xmm = have_it;
35740 +}
35741 +
35742 +int arch_handle_signal(int sig, union uml_pt_regs *regs)
35743 +{
35744 +       unsigned long ip;
35745 +
35746 +       /* This is testing for a cmov (0x0f 0x4x) instruction causing a
35747 +        * SIGILL in init.
35748 +        */
35749 +       if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
35750 +
35751 +       ip = UPT_IP(regs);
35752 +       if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
35753 +               return(0);
35754 +
35755 +       if(cpu_has_cmov == 0)
35756 +               panic("SIGILL caused by cmov, which this processor doesn't "
35757 +                     "implement, boot a filesystem compiled for older "
35758 +                     "processors");
35759 +       else if(cpu_has_cmov == 1)
35760 +               panic("SIGILL caused by cmov, which this processor claims to "
35761 +                     "implement");
35762 +       else if(cpu_has_cmov == -1)
35763 +               panic("SIGILL caused by cmov, couldn't tell if this processor "
35764 +                     "implements it, boot a filesystem compiled for older "
35765 +                     "processors");
35766 +       else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
35767 +       return(0);
35768 +}
35769 +
35770 +/*
35771 + * Overrides for Emacs so that we follow Linus's tabbing style.
35772 + * Emacs will notice this stuff at the end of the file and automatically
35773 + * adjust the settings for this buffer only.  This must remain at the end
35774 + * of the file.
35775 + * ---------------------------------------------------------------------------
35776 + * Local variables:
35777 + * c-file-style: "linux"
35778 + * End:
35779 + */
35780 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/checksum.S um/arch/um/sys-i386/checksum.S
35781 --- orig/arch/um/sys-i386/checksum.S    1969-12-31 19:00:00.000000000 -0500
35782 +++ um/arch/um/sys-i386/checksum.S      2003-10-21 03:26:07.000000000 -0400
35783 @@ -0,0 +1,460 @@
35784 +/*
35785 + * INET                An implementation of the TCP/IP protocol suite for the LINUX
35786 + *             operating system.  INET is implemented using the  BSD Socket
35787 + *             interface as the means of communication with the user level.
35788 + *
35789 + *             IP/TCP/UDP checksumming routines
35790 + *
35791 + * Authors:    Jorge Cwik, <jorge@laser.satlink.net>
35792 + *             Arnt Gulbrandsen, <agulbra@nvg.unit.no>
35793 + *             Tom May, <ftom@netcom.com>
35794 + *              Pentium Pro/II routines:
35795 + *              Alexander Kjeldaas <astor@guardian.no>
35796 + *              Finn Arne Gangstad <finnag@guardian.no>
35797 + *             Lots of code moved from tcp.c and ip.c; see those files
35798 + *             for more names.
35799 + *
35800 + * Changes:     Ingo Molnar, converted csum_partial_copy() to 2.1 exception
35801 + *                          handling.
35802 + *             Andi Kleen,  add zeroing on error
35803 + *                   converted to pure assembler
35804 + *
35805 + *             This program is free software; you can redistribute it and/or
35806 + *             modify it under the terms of the GNU General Public License
35807 + *             as published by the Free Software Foundation; either version
35808 + *             2 of the License, or (at your option) any later version.
35809 + */
35810 +
35811 +#include <linux/config.h>
35812 +#include <asm/errno.h>
35813 +                               
35814 +/*
35815 + * computes a partial checksum, e.g. for TCP/UDP fragments
35816 + */
35817 +
35818 +/*     
35819 +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
35820 + */
35821 +               
35822 +.text
35823 +.align 4
35824 +.globl arch_csum_partial                                                               
35825 +               
35826 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
35827 +
35828 +         /*            
35829 +          * Experiments with Ethernet and SLIP connections show that buff
35830 +          * is aligned on either a 2-byte or 4-byte boundary.  We get at
35831 +          * least a twofold speedup on 486 and Pentium if it is 4-byte aligned.
35832 +          * Fortunately, it is easy to convert 2-byte alignment to 4-byte
35833 +          * alignment for the unrolled loop.
35834 +          */           
35835 +arch_csum_partial:     
35836 +       pushl %esi
35837 +       pushl %ebx
35838 +       movl 20(%esp),%eax      # Function arg: unsigned int sum
35839 +       movl 16(%esp),%ecx      # Function arg: int len
35840 +       movl 12(%esp),%esi      # Function arg: unsigned char *buff
35841 +       testl $2, %esi          # Check alignment.
35842 +       jz 2f                   # Jump if alignment is ok.
35843 +       subl $2, %ecx           # Alignment uses up two bytes.
35844 +       jae 1f                  # Jump if we had at least two bytes.
35845 +       addl $2, %ecx           # ecx was < 2.  Deal with it.
35846 +       jmp 4f
35847 +1:     movw (%esi), %bx
35848 +       addl $2, %esi
35849 +       addw %bx, %ax
35850 +       adcl $0, %eax
35851 +2:
35852 +       movl %ecx, %edx
35853 +       shrl $5, %ecx
35854 +       jz 2f
35855 +       testl %esi, %esi
35856 +1:     movl (%esi), %ebx
35857 +       adcl %ebx, %eax
35858 +       movl 4(%esi), %ebx
35859 +       adcl %ebx, %eax
35860 +       movl 8(%esi), %ebx
35861 +       adcl %ebx, %eax
35862 +       movl 12(%esi), %ebx
35863 +       adcl %ebx, %eax
35864 +       movl 16(%esi), %ebx
35865 +       adcl %ebx, %eax
35866 +       movl 20(%esi), %ebx
35867 +       adcl %ebx, %eax
35868 +       movl 24(%esi), %ebx
35869 +       adcl %ebx, %eax
35870 +       movl 28(%esi), %ebx
35871 +       adcl %ebx, %eax
35872 +       lea 32(%esi), %esi
35873 +       dec %ecx
35874 +       jne 1b
35875 +       adcl $0, %eax
35876 +2:     movl %edx, %ecx
35877 +       andl $0x1c, %edx
35878 +       je 4f
35879 +       shrl $2, %edx           # This clears CF
35880 +3:     adcl (%esi), %eax
35881 +       lea 4(%esi), %esi
35882 +       dec %edx
35883 +       jne 3b
35884 +       adcl $0, %eax
35885 +4:     andl $3, %ecx
35886 +       jz 7f
35887 +       cmpl $2, %ecx
35888 +       jb 5f
35889 +       movw (%esi),%cx
35890 +       leal 2(%esi),%esi
35891 +       je 6f
35892 +       shll $16,%ecx
35893 +5:     movb (%esi),%cl
35894 +6:     addl %ecx,%eax
35895 +       adcl $0, %eax 
35896 +7:     
35897 +       popl %ebx
35898 +       popl %esi
35899 +       ret
35900 +
35901 +#else
35902 +
35903 +/* Version for PentiumII/PPro */
35904 +
35905 +arch_csum_partial:
35906 +       pushl %esi
35907 +       pushl %ebx
35908 +       movl 20(%esp),%eax      # Function arg: unsigned int sum
35909 +       movl 16(%esp),%ecx      # Function arg: int len
35910 +       movl 12(%esp),%esi      # Function arg: const unsigned char *buf
35911 +
35912 +       testl $2, %esi         
35913 +       jnz 30f                 
35914 +10:
35915 +       movl %ecx, %edx
35916 +       movl %ecx, %ebx
35917 +       andl $0x7c, %ebx
35918 +       shrl $7, %ecx
35919 +       addl %ebx,%esi
35920 +       shrl $2, %ebx  
35921 +       negl %ebx
35922 +       lea 45f(%ebx,%ebx,2), %ebx
35923 +       testl %esi, %esi
35924 +       jmp *%ebx
35925 +
35926 +       # Handle 2-byte-aligned regions
35927 +20:    addw (%esi), %ax
35928 +       lea 2(%esi), %esi
35929 +       adcl $0, %eax
35930 +       jmp 10b
35931 +
35932 +30:    subl $2, %ecx          
35933 +       ja 20b                 
35934 +       je 32f
35935 +       movzbl (%esi),%ebx      # csumming 1 byte, 2-aligned
35936 +       addl %ebx, %eax
35937 +       adcl $0, %eax
35938 +       jmp 80f
35939 +32:
35940 +       addw (%esi), %ax        # csumming 2 bytes, 2-aligned
35941 +       adcl $0, %eax
35942 +       jmp 80f
35943 +
35944 +40: 
35945 +       addl -128(%esi), %eax
35946 +       adcl -124(%esi), %eax
35947 +       adcl -120(%esi), %eax
35948 +       adcl -116(%esi), %eax   
35949 +       adcl -112(%esi), %eax   
35950 +       adcl -108(%esi), %eax
35951 +       adcl -104(%esi), %eax
35952 +       adcl -100(%esi), %eax
35953 +       adcl -96(%esi), %eax
35954 +       adcl -92(%esi), %eax
35955 +       adcl -88(%esi), %eax
35956 +       adcl -84(%esi), %eax
35957 +       adcl -80(%esi), %eax
35958 +       adcl -76(%esi), %eax
35959 +       adcl -72(%esi), %eax
35960 +       adcl -68(%esi), %eax
35961 +       adcl -64(%esi), %eax     
35962 +       adcl -60(%esi), %eax     
35963 +       adcl -56(%esi), %eax     
35964 +       adcl -52(%esi), %eax   
35965 +       adcl -48(%esi), %eax   
35966 +       adcl -44(%esi), %eax
35967 +       adcl -40(%esi), %eax
35968 +       adcl -36(%esi), %eax
35969 +       adcl -32(%esi), %eax
35970 +       adcl -28(%esi), %eax
35971 +       adcl -24(%esi), %eax
35972 +       adcl -20(%esi), %eax
35973 +       adcl -16(%esi), %eax
35974 +       adcl -12(%esi), %eax
35975 +       adcl -8(%esi), %eax
35976 +       adcl -4(%esi), %eax
35977 +45:
35978 +       lea 128(%esi), %esi
35979 +       adcl $0, %eax
35980 +       dec %ecx
35981 +       jge 40b
35982 +       movl %edx, %ecx
35983 +50:    andl $3, %ecx
35984 +       jz 80f
35985 +
35986 +       # Handle the last 1-3 bytes without jumping
35987 +       notl %ecx               # 1->2, 2->1, 3->0, higher bits are masked
35988 +       movl $0xffffff,%ebx     # by the shll and shrl instructions
35989 +       shll $3,%ecx
35990 +       shrl %cl,%ebx
35991 +       andl -128(%esi),%ebx    # esi is 4-aligned so should be ok
35992 +       addl %ebx,%eax
35993 +       adcl $0,%eax
35994 +80: 
35995 +       popl %ebx
35996 +       popl %esi
35997 +       ret
35998 +                               
35999 +#endif
36000 +
36001 +/*
36002 +unsigned int csum_partial_copy_generic (const char *src, char *dst,
36003 +                                 int len, int sum, int *src_err_ptr, int *dst_err_ptr)
36004 + */ 
36005 +
36006 +/*
36007 + * Copy from ds while checksumming, otherwise like csum_partial
36008 + *
36009 + * The macros SRC and DST specify the type of access for the instruction.
36010 + * thus we can call a custom exception handler for all access types.
36011 + *
36012 + * FIXME: could someone double-check whether I haven't mixed up some SRC and
36013 + *       DST definitions? It's damn hard to trigger all cases.  I hope I got
36014 + *       them all but there's no guarantee.
36015 + */
36016 +
36017 +#define SRC(y...)                      \
36018 +       9999: y;                        \
36019 +       .section __ex_table, "a";       \
36020 +       .long 9999b, 6001f      ;       \
36021 +       .previous
36022 +
36023 +#define DST(y...)                      \
36024 +       9999: y;                        \
36025 +       .section __ex_table, "a";       \
36026 +       .long 9999b, 6002f      ;       \
36027 +       .previous
36028 +
36029 +.align 4
36030 +.globl csum_partial_copy_generic_i386
36031 +                               
36032 +#ifndef CONFIG_X86_USE_PPRO_CHECKSUM
36033 +
36034 +#define ARGBASE 16             
36035 +#define FP             12
36036 +               
36037 +csum_partial_copy_generic_i386:
36038 +       subl  $4,%esp   
36039 +       pushl %edi
36040 +       pushl %esi
36041 +       pushl %ebx
36042 +       movl ARGBASE+16(%esp),%eax      # sum
36043 +       movl ARGBASE+12(%esp),%ecx      # len
36044 +       movl ARGBASE+4(%esp),%esi       # src
36045 +       movl ARGBASE+8(%esp),%edi       # dst
36046 +
36047 +       testl $2, %edi                  # Check alignment. 
36048 +       jz 2f                           # Jump if alignment is ok.
36049 +       subl $2, %ecx                   # Alignment uses up two bytes.
36050 +       jae 1f                          # Jump if we had at least two bytes.
36051 +       addl $2, %ecx                   # ecx was < 2.  Deal with it.
36052 +       jmp 4f
36053 +SRC(1: movw (%esi), %bx        )
36054 +       addl $2, %esi
36055 +DST(   movw %bx, (%edi)        )
36056 +       addl $2, %edi
36057 +       addw %bx, %ax   
36058 +       adcl $0, %eax
36059 +2:
36060 +       movl %ecx, FP(%esp)
36061 +       shrl $5, %ecx
36062 +       jz 2f
36063 +       testl %esi, %esi
36064 +SRC(1: movl (%esi), %ebx       )
36065 +SRC(   movl 4(%esi), %edx      )
36066 +       adcl %ebx, %eax
36067 +DST(   movl %ebx, (%edi)       )
36068 +       adcl %edx, %eax
36069 +DST(   movl %edx, 4(%edi)      )
36070 +
36071 +SRC(   movl 8(%esi), %ebx      )
36072 +SRC(   movl 12(%esi), %edx     )
36073 +       adcl %ebx, %eax
36074 +DST(   movl %ebx, 8(%edi)      )
36075 +       adcl %edx, %eax
36076 +DST(   movl %edx, 12(%edi)     )
36077 +
36078 +SRC(   movl 16(%esi), %ebx     )
36079 +SRC(   movl 20(%esi), %edx     )
36080 +       adcl %ebx, %eax
36081 +DST(   movl %ebx, 16(%edi)     )
36082 +       adcl %edx, %eax
36083 +DST(   movl %edx, 20(%edi)     )
36084 +
36085 +SRC(   movl 24(%esi), %ebx     )
36086 +SRC(   movl 28(%esi), %edx     )
36087 +       adcl %ebx, %eax
36088 +DST(   movl %ebx, 24(%edi)     )
36089 +       adcl %edx, %eax
36090 +DST(   movl %edx, 28(%edi)     )
36091 +
36092 +       lea 32(%esi), %esi
36093 +       lea 32(%edi), %edi
36094 +       dec %ecx
36095 +       jne 1b
36096 +       adcl $0, %eax
36097 +2:     movl FP(%esp), %edx
36098 +       movl %edx, %ecx
36099 +       andl $0x1c, %edx
36100 +       je 4f
36101 +       shrl $2, %edx                   # This clears CF
36102 +SRC(3: movl (%esi), %ebx       )
36103 +       adcl %ebx, %eax
36104 +DST(   movl %ebx, (%edi)       )
36105 +       lea 4(%esi), %esi
36106 +       lea 4(%edi), %edi
36107 +       dec %edx
36108 +       jne 3b
36109 +       adcl $0, %eax
36110 +4:     andl $3, %ecx
36111 +       jz 7f
36112 +       cmpl $2, %ecx
36113 +       jb 5f
36114 +SRC(   movw (%esi), %cx        )
36115 +       leal 2(%esi), %esi
36116 +DST(   movw %cx, (%edi)        )
36117 +       leal 2(%edi), %edi
36118 +       je 6f
36119 +       shll $16,%ecx
36120 +SRC(5: movb (%esi), %cl        )
36121 +DST(   movb %cl, (%edi)        )
36122 +6:     addl %ecx, %eax
36123 +       adcl $0, %eax
36124 +7:
36125 +5000:
36126 +
36127 +# Exception handler:
36128 +.section .fixup, "ax"                                                  
36129 +
36130 +6001:
36131 +       movl ARGBASE+20(%esp), %ebx     # src_err_ptr
36132 +       movl $-EFAULT, (%ebx)
36133 +
36134 +       # zero the complete destination - computing the rest
36135 +       # is too much work 
36136 +       movl ARGBASE+8(%esp), %edi      # dst
36137 +       movl ARGBASE+12(%esp), %ecx     # len
36138 +       xorl %eax,%eax
36139 +       rep ; stosb
36140 +
36141 +       jmp 5000b
36142 +
36143 +6002:
36144 +       movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
36145 +       movl $-EFAULT,(%ebx)
36146 +       jmp 5000b
36147 +
36148 +.previous
36149 +
36150 +       popl %ebx
36151 +       popl %esi
36152 +       popl %edi
36153 +       popl %ecx                       # equivalent to addl $4,%esp
36154 +       ret     
36155 +
36156 +#else
36157 +
36158 +/* Version for PentiumII/PPro */
36159 +
36160 +#define ROUND1(x) \
36161 +       SRC(movl x(%esi), %ebx  )       ;       \
36162 +       addl %ebx, %eax                 ;       \
36163 +       DST(movl %ebx, x(%edi)  )       ; 
36164 +
36165 +#define ROUND(x) \
36166 +       SRC(movl x(%esi), %ebx  )       ;       \
36167 +       adcl %ebx, %eax                 ;       \
36168 +       DST(movl %ebx, x(%edi)  )       ;
36169 +
36170 +#define ARGBASE 12
36171 +               
36172 +csum_partial_copy_generic_i386:
36173 +       pushl %ebx
36174 +       pushl %edi
36175 +       pushl %esi
36176 +       movl ARGBASE+4(%esp),%esi       #src
36177 +       movl ARGBASE+8(%esp),%edi       #dst    
36178 +       movl ARGBASE+12(%esp),%ecx      #len
36179 +       movl ARGBASE+16(%esp),%eax      #sum
36180 +#      movl %ecx, %edx  
36181 +       movl %ecx, %ebx  
36182 +       movl %esi, %edx
36183 +       shrl $6, %ecx     
36184 +       andl $0x3c, %ebx  
36185 +       negl %ebx
36186 +       subl %ebx, %esi  
36187 +       subl %ebx, %edi  
36188 +       lea  -1(%esi),%edx
36189 +       andl $-32,%edx
36190 +       lea 3f(%ebx,%ebx), %ebx
36191 +       testl %esi, %esi 
36192 +       jmp *%ebx
36193 +1:     addl $64,%esi
36194 +       addl $64,%edi 
36195 +       SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
36196 +       ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)    
36197 +       ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)    
36198 +       ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)    
36199 +       ROUND (-16) ROUND(-12) ROUND(-8)  ROUND(-4)     
36200 +3:     adcl $0,%eax
36201 +       addl $64, %edx
36202 +       dec %ecx
36203 +       jge 1b
36204 +4:     movl ARGBASE+12(%esp),%edx      #len
36205 +       andl $3, %edx
36206 +       jz 7f
36207 +       cmpl $2, %edx
36208 +       jb 5f
36209 +SRC(   movw (%esi), %dx         )
36210 +       leal 2(%esi), %esi
36211 +DST(   movw %dx, (%edi)         )
36212 +       leal 2(%edi), %edi
36213 +       je 6f
36214 +       shll $16,%edx
36215 +5:
36216 +SRC(   movb (%esi), %dl         )
36217 +DST(   movb %dl, (%edi)         )
36218 +6:     addl %edx, %eax
36219 +       adcl $0, %eax
36220 +7:
36221 +.section .fixup, "ax"
36222 +6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
36223 +       movl $-EFAULT, (%ebx)
36224 +       # zero the complete destination (computing the rest is too much work)
36225 +       movl ARGBASE+8(%esp),%edi       # dst
36226 +       movl ARGBASE+12(%esp),%ecx      # len
36227 +       xorl %eax,%eax
36228 +       rep; stosb
36229 +       jmp 7b
36230 +6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
36231 +       movl $-EFAULT, (%ebx)
36232 +       jmp  7b                 
36233 +.previous                              
36234 +
36235 +       popl %esi
36236 +       popl %edi
36237 +       popl %ebx
36238 +       ret
36239 +                               
36240 +#undef ROUND
36241 +#undef ROUND1          
36242 +               
36243 +#endif
36244 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/fault.c um/arch/um/sys-i386/fault.c
36245 --- orig/arch/um/sys-i386/fault.c       1969-12-31 19:00:00.000000000 -0500
36246 +++ um/arch/um/sys-i386/fault.c 2003-10-21 03:26:07.000000000 -0400
36247 @@ -0,0 +1,34 @@
36248 +/* 
36249 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36250 + * Licensed under the GPL
36251 + */
36252 +
36253 +#include <signal.h>
36254 +#include "sysdep/ptrace.h"
36255 +#include "sysdep/sigcontext.h"
36256 +
36257 +extern unsigned long search_exception_table(unsigned long addr);
36258 +
36259 +int arch_fixup(unsigned long address, void *sc_ptr)
36260 +{
36261 +       struct sigcontext *sc = sc_ptr;
36262 +       unsigned long fixup;
36263 +
36264 +       fixup = search_exception_table(address);
36265 +       if(fixup != 0){
36266 +               sc->eip = fixup;
36267 +               return(1);
36268 +       }
36269 +       return(0);
36270 +}
36271 +
36272 +/*
36273 + * Overrides for Emacs so that we follow Linus's tabbing style.
36274 + * Emacs will notice this stuff at the end of the file and automatically
36275 + * adjust the settings for this buffer only.  This must remain at the end
36276 + * of the file.
36277 + * ---------------------------------------------------------------------------
36278 + * Local variables:
36279 + * c-file-style: "linux"
36280 + * End:
36281 + */
36282 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ksyms.c um/arch/um/sys-i386/ksyms.c
36283 --- orig/arch/um/sys-i386/ksyms.c       1969-12-31 19:00:00.000000000 -0500
36284 +++ um/arch/um/sys-i386/ksyms.c 2003-10-21 03:26:07.000000000 -0400
36285 @@ -0,0 +1,17 @@
36286 +#include "linux/module.h"
36287 +#include "linux/in6.h"
36288 +#include "linux/rwsem.h"
36289 +#include "asm/byteorder.h"
36290 +#include "asm/semaphore.h"
36291 +#include "asm/uaccess.h"
36292 +#include "asm/checksum.h"
36293 +#include "asm/errno.h"
36294 +
36295 +EXPORT_SYMBOL(__down_failed);
36296 +EXPORT_SYMBOL(__down_failed_interruptible);
36297 +EXPORT_SYMBOL(__down_failed_trylock);
36298 +EXPORT_SYMBOL(__up_wakeup);
36299 +
36300 +/* Networking helper routines. */
36301 +EXPORT_SYMBOL(csum_partial_copy_from);
36302 +EXPORT_SYMBOL(csum_partial_copy_to);
36303 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ldt.c um/arch/um/sys-i386/ldt.c
36304 --- orig/arch/um/sys-i386/ldt.c 1969-12-31 19:00:00.000000000 -0500
36305 +++ um/arch/um/sys-i386/ldt.c   2003-10-21 03:26:07.000000000 -0400
36306 @@ -0,0 +1,92 @@
36307 +/*
36308 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
36309 + * Licensed under the GPL
36310 + */
36311 +
36312 +#include "linux/config.h"
36313 +#include "linux/slab.h"
36314 +#include "asm/uaccess.h"
36315 +#include "asm/ptrace.h"
36316 +#include "choose-mode.h"
36317 +#include "kern.h"
36318 +
36319 +#ifdef CONFIG_MODE_TT
36320 +extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
36321 +
36322 +int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
36323 +{
36324 +       if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
36325 +       return(modify_ldt(func, ptr, bytecount));
36326 +}
36327 +#endif
36328 +
36329 +#ifdef CONFIG_MODE_SKAS
36330 +extern int userspace_pid;
36331 +
36332 +int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
36333 +{
36334 +       struct ptrace_ldt ldt;
36335 +       void *buf;
36336 +       int res, n;
36337 +
36338 +       buf = kmalloc(bytecount, GFP_KERNEL);
36339 +       if(buf == NULL)
36340 +               return(-ENOMEM);
36341 +
36342 +       res = 0;
36343 +
36344 +       switch(func){
36345 +       case 1:
36346 +       case 0x11:
36347 +               res = copy_from_user(buf, ptr, bytecount);
36348 +               break;
36349 +       }
36350 +
36351 +       if(res != 0){
36352 +               res = -EFAULT;
36353 +               goto out;
36354 +       }
36355 +
36356 +       ldt = ((struct ptrace_ldt) { .func      = func,
36357 +                                    .ptr       = buf,
36358 +                                    .bytecount = bytecount });
36359 +       res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
36360 +       if(res < 0)
36361 +               goto out;
36362 +
36363 +       switch(func){
36364 +       case 0:
36365 +       case 2:
36366 +               n = res;
36367 +               res = copy_to_user(ptr, buf, n);
36368 +               if(res != 0)
36369 +                       res = -EFAULT;
36370 +               else 
36371 +                       res = n;
36372 +               break;
36373 +       }
36374 +
36375 + out:
36376 +       kfree(buf);
36377 +       return(res);
36378 +}
36379 +#endif
36380 +
36381 +int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
36382 +{
36383 +       return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, 
36384 +                               ptr, bytecount));
36385 +}
36386 +
36387 +
36388 +
36389 +/*
36390 + * Overrides for Emacs so that we follow Linus's tabbing style.
36391 + * Emacs will notice this stuff at the end of the file and automatically
36392 + * adjust the settings for this buffer only.  This must remain at the end
36393 + * of the file.
36394 + * ---------------------------------------------------------------------------
36395 + * Local variables:
36396 + * c-file-style: "linux"
36397 + * End:
36398 + */
36399 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/Makefile um/arch/um/sys-i386/Makefile
36400 --- orig/arch/um/sys-i386/Makefile      1969-12-31 19:00:00.000000000 -0500
36401 +++ um/arch/um/sys-i386/Makefile        2003-11-09 11:55:24.000000000 -0500
36402 @@ -0,0 +1,46 @@
36403 +# 
36404 +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36405 +# Licensed under the GPL
36406 +#
36407 +
36408 +O_TARGET = built-in.o
36409 +
36410 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
36411 +       ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o time.o
36412 +export-objs = ksyms.o
36413 +
36414 +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o
36415 +
36416 +SYMLINKS = semaphore.c extable.c
36417 +
36418 +semaphore.c-dir = kernel
36419 +extable.c-dir = mm
36420 +
36421 +include $(TOPDIR)/Rules.make
36422 +
36423 +$(USER_OBJS) : %.o: %.c
36424 +       $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
36425 +
36426 +define make_link
36427 +       -rm -f $1
36428 +       ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1
36429 +endef
36430 +
36431 +$(SYMLINKS): 
36432 +       $(call make_link,$@)
36433 +
36434 +clean:
36435 +       $(MAKE) -C util clean
36436 +       rm -f $(SYMLINKS)
36437 +
36438 +fastdep:
36439 +
36440 +dep:
36441 +
36442 +archmrproper:
36443 +
36444 +archclean:
36445 +
36446 +archdep:
36447 +
36448 +modules:
36449 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace.c um/arch/um/sys-i386/ptrace.c
36450 --- orig/arch/um/sys-i386/ptrace.c      1969-12-31 19:00:00.000000000 -0500
36451 +++ um/arch/um/sys-i386/ptrace.c        2003-10-21 03:26:07.000000000 -0400
36452 @@ -0,0 +1,365 @@
36453 +/* 
36454 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
36455 + * Licensed under the GPL
36456 + */
36457 +
36458 +#include "linux/sched.h"
36459 +#include "asm/elf.h"
36460 +#include "asm/ptrace.h"
36461 +#include "asm/uaccess.h"
36462 +#include "ptrace_user.h"
36463 +#include "sysdep/sigcontext.h"
36464 +#include "sysdep/sc.h"
36465 +
36466 +void arch_switch(void)
36467 +{
36468 +       update_debugregs(current->thread.arch.debugregs_seq);
36469 +}
36470 +
36471 +int is_syscall(unsigned long addr)
36472 +{
36473 +       unsigned short instr;
36474 +       int n;
36475 +
36476 +       n = copy_from_user(&instr, (void *) addr, sizeof(instr));
36477 +       if(n){
36478 +               printk("is_syscall : failed to read instruction from 0x%lu\n", 
36479 +                      addr);
36480 +               return(0);
36481 +       }
36482 +       return(instr == 0x80cd);
36483 +}
36484 +
36485 +/* determines which flags the user has access to. */
36486 +/* 1 = access 0 = no access */
36487 +#define FLAG_MASK 0x00044dd5
36488 +
36489 +int putreg(struct task_struct *child, int regno, unsigned long value)
36490 +{
36491 +       regno >>= 2;
36492 +       switch (regno) {
36493 +       case FS:
36494 +               if (value && (value & 3) != 3)
36495 +                       return -EIO;
36496 +               PT_REGS_FS(&child->thread.regs) = value;
36497 +               return 0;
36498 +       case GS:
36499 +               if (value && (value & 3) != 3)
36500 +                       return -EIO;
36501 +               PT_REGS_GS(&child->thread.regs) = value;
36502 +               return 0;
36503 +       case DS:
36504 +       case ES:
36505 +               if (value && (value & 3) != 3)
36506 +                       return -EIO;
36507 +               value &= 0xffff;
36508 +               break;
36509 +       case SS:
36510 +       case CS:
36511 +               if ((value & 3) != 3)
36512 +                       return -EIO;
36513 +               value &= 0xffff;
36514 +               break;
36515 +       case EFL:
36516 +               value &= FLAG_MASK;
36517 +               value |= PT_REGS_EFLAGS(&child->thread.regs);
36518 +               break;
36519 +       }
36520 +       PT_REGS_SET(&child->thread.regs, regno, value);
36521 +       return 0;
36522 +}
36523 +
36524 +unsigned long getreg(struct task_struct *child, int regno)
36525 +{
36526 +       unsigned long retval = ~0UL;
36527 +
36528 +       regno >>= 2;
36529 +       switch (regno) {
36530 +       case FS:
36531 +       case GS:
36532 +       case DS:
36533 +       case ES:
36534 +       case SS:
36535 +       case CS:
36536 +               retval = 0xffff;
36537 +               /* fall through */
36538 +       default:
36539 +               retval &= PT_REG(&child->thread.regs, regno);
36540 +       }
36541 +       return retval;
36542 +}
36543 +
36544 +struct i387_fxsave_struct {
36545 +       unsigned short  cwd;
36546 +       unsigned short  swd;
36547 +       unsigned short  twd;
36548 +       unsigned short  fop;
36549 +       long    fip;
36550 +       long    fcs;
36551 +       long    foo;
36552 +       long    fos;
36553 +       long    mxcsr;
36554 +       long    reserved;
36555 +       long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
36556 +       long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
36557 +       long    padding[56];
36558 +};
36559 +
36560 +/*
36561 + * FPU tag word conversions.
36562 + */
36563 +
36564 +static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
36565 +{
36566 +       unsigned int tmp; /* to avoid 16 bit prefixes in the code */
36567
36568 +       /* Transform each pair of bits into 01 (valid) or 00 (empty) */
36569 +        tmp = ~twd;
36570 +        tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
36571 +        /* and move the valid bits to the lower byte. */
36572 +        tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
36573 +        tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
36574 +        tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
36575 +        return tmp;
36576 +}
36577 +
36578 +static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
36579 +{
36580 +       struct _fpxreg *st = NULL;
36581 +       unsigned long twd = (unsigned long) fxsave->twd;
36582 +       unsigned long tag;
36583 +       unsigned long ret = 0xffff0000;
36584 +       int i;
36585 +
36586 +#define FPREG_ADDR(f, n)       ((char *)&(f)->st_space + (n) * 16);
36587 +
36588 +       for ( i = 0 ; i < 8 ; i++ ) {
36589 +               if ( twd & 0x1 ) {
36590 +                       st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
36591 +
36592 +                       switch ( st->exponent & 0x7fff ) {
36593 +                       case 0x7fff:
36594 +                               tag = 2;                /* Special */
36595 +                               break;
36596 +                       case 0x0000:
36597 +                               if ( !st->significand[0] &&
36598 +                                    !st->significand[1] &&
36599 +                                    !st->significand[2] &&
36600 +                                    !st->significand[3] ) {
36601 +                                       tag = 1;        /* Zero */
36602 +                               } else {
36603 +                                       tag = 2;        /* Special */
36604 +                               }
36605 +                               break;
36606 +                       default:
36607 +                               if ( st->significand[3] & 0x8000 ) {
36608 +                                       tag = 0;        /* Valid */
36609 +                               } else {
36610 +                                       tag = 2;        /* Special */
36611 +                               }
36612 +                               break;
36613 +                       }
36614 +               } else {
36615 +                       tag = 3;                        /* Empty */
36616 +               }
36617 +               ret |= (tag << (2 * i));
36618 +               twd = twd >> 1;
36619 +       }
36620 +       return ret;
36621 +}
36622 +
36623 +/*
36624 + * FXSR floating point environment conversions.
36625 + */
36626 +
36627 +#ifdef CONFIG_MODE_TT
36628 +static inline int convert_fxsr_to_user_tt(struct _fpstate *buf, 
36629 +                                         struct pt_regs *regs)
36630 +{
36631 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36632 +       unsigned long env[7];
36633 +       struct _fpreg *to;
36634 +       struct _fpxreg *from;
36635 +       int i;
36636 +
36637 +       env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
36638 +       env[1] = (unsigned long)fxsave->swd | 0xffff0000;
36639 +       env[2] = twd_fxsr_to_i387(fxsave);
36640 +       env[3] = fxsave->fip;
36641 +       env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
36642 +       env[5] = fxsave->foo;
36643 +       env[6] = fxsave->fos;
36644 +
36645 +       if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
36646 +               return 1;
36647 +
36648 +       to = &buf->_st[0];
36649 +       from = (struct _fpxreg *) &fxsave->st_space[0];
36650 +       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
36651 +               if ( __copy_to_user( to, from, sizeof(*to) ) )
36652 +                       return 1;
36653 +       }
36654 +       return 0;
36655 +}
36656 +#endif
36657 +
36658 +static inline int convert_fxsr_to_user(struct _fpstate *buf, 
36659 +                                      struct pt_regs *regs)
36660 +{
36661 +       return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
36662 +}
36663 +
36664 +#ifdef CONFIG_MODE_TT
36665 +static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
36666 +                                           struct _fpstate *buf)
36667 +{
36668 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36669 +       unsigned long env[7];
36670 +       struct _fpxreg *to;
36671 +       struct _fpreg *from;
36672 +       int i;
36673 +
36674 +       if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
36675 +               return 1;
36676 +
36677 +       fxsave->cwd = (unsigned short)(env[0] & 0xffff);
36678 +       fxsave->swd = (unsigned short)(env[1] & 0xffff);
36679 +       fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
36680 +       fxsave->fip = env[3];
36681 +       fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
36682 +       fxsave->fcs = (env[4] & 0xffff);
36683 +       fxsave->foo = env[5];
36684 +       fxsave->fos = env[6];
36685 +
36686 +       to = (struct _fpxreg *) &fxsave->st_space[0];
36687 +       from = &buf->_st[0];
36688 +       for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
36689 +               if ( __copy_from_user( to, from, sizeof(*from) ) )
36690 +                       return 1;
36691 +       }
36692 +       return 0;
36693 +}
36694 +#endif
36695 +
36696 +static inline int convert_fxsr_from_user(struct pt_regs *regs, 
36697 +                                        struct _fpstate *buf)
36698 +{
36699 +       return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
36700 +}
36701 +
36702 +int get_fpregs(unsigned long buf, struct task_struct *child)
36703 +{
36704 +       int err;
36705 +
36706 +       err = convert_fxsr_to_user((struct _fpstate *) buf, 
36707 +                                  &child->thread.regs);
36708 +       if(err) return(-EFAULT);
36709 +       else return(0);
36710 +}
36711 +
36712 +int set_fpregs(unsigned long buf, struct task_struct *child)
36713 +{
36714 +       int err;
36715 +
36716 +       err = convert_fxsr_from_user(&child->thread.regs, 
36717 +                                    (struct _fpstate *) buf);
36718 +       if(err) return(-EFAULT);
36719 +       else return(0);
36720 +}
36721 +
36722 +#ifdef CONFIG_MODE_TT
36723 +int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
36724 +{
36725 +       struct pt_regs *regs = &tsk->thread.regs;
36726 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36727 +       int err;
36728 +
36729 +       err = __copy_to_user((void *) buf, fxsave,
36730 +                            sizeof(struct user_fxsr_struct));
36731 +       if(err) return -EFAULT;
36732 +       else return 0;
36733 +}
36734 +#endif
36735 +
36736 +int get_fpxregs(unsigned long buf, struct task_struct *tsk)
36737 +{
36738 +       return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
36739 +}
36740 +
36741 +#ifdef CONFIG_MODE_TT
36742 +int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
36743 +{
36744 +       struct pt_regs *regs = &tsk->thread.regs;
36745 +       struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
36746 +       int err;
36747 +
36748 +       err = __copy_from_user(fxsave, (void *) buf,
36749 +                              sizeof(struct user_fxsr_struct) );
36750 +       if(err) return -EFAULT;
36751 +       else return 0;
36752 +}
36753 +#endif
36754 +
36755 +int set_fpxregs(unsigned long buf, struct task_struct *tsk)
36756 +{
36757 +       return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
36758 +}
36759 +
36760 +#ifdef notdef
36761 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
36762 +{
36763 +       fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
36764 +                   (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
36765 +       fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
36766 +       fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
36767 +       fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
36768 +       fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
36769 +       fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
36770 +       fpu->fos = 0;
36771 +       memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
36772 +              sizeof(fpu->st_space));
36773 +       return(1);
36774 +}
36775 +#endif
36776 +
36777 +#ifdef CONFIG_MODE_TT
36778 +static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
36779 +                                     struct user_i387_struct *buf)
36780 +{
36781 +       struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
36782 +       unsigned short *to;
36783 +       unsigned short *from;
36784 +       int i;
36785 +
36786 +       memcpy( buf, fpu, 7 * sizeof(long) );
36787 +
36788 +       to = (unsigned short *) &buf->st_space[0];
36789 +       from = (unsigned short *) &fpu->st_space[0];
36790 +       for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
36791 +               memcpy( to, from, 5 * sizeof(unsigned short) );
36792 +       }
36793 +}
36794 +#endif
36795 +
36796 +static inline void copy_fpu_fxsave(struct pt_regs *regs,
36797 +                                  struct user_i387_struct *buf)
36798 +{
36799 +       (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
36800 +}
36801 +
36802 +int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
36803 +{
36804 +       copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
36805 +       return(1);
36806 +}
36807 +
36808 +/*
36809 + * Overrides for Emacs so that we follow Linus's tabbing style.
36810 + * Emacs will notice this stuff at the end of the file and automatically
36811 + * adjust the settings for this buffer only.  This must remain at the end
36812 + * of the file.
36813 + * ---------------------------------------------------------------------------
36814 + * Local variables:
36815 + * c-file-style: "linux"
36816 + * End:
36817 + */
36818 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace_user.c um/arch/um/sys-i386/ptrace_user.c
36819 --- orig/arch/um/sys-i386/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500
36820 +++ um/arch/um/sys-i386/ptrace_user.c   2003-12-17 01:33:17.000000000 -0500
36821 @@ -0,0 +1,117 @@
36822 +/* 
36823 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
36824 + * Licensed under the GPL
36825 + */
36826 +
36827 +#include <stdio.h>
36828 +#include <errno.h>
36829 +#include <unistd.h>
36830 +#include <linux/stddef.h>
36831 +#include <sys/ptrace.h>
36832 +#include <asm/ptrace.h>
36833 +#include <asm/user.h>
36834 +#include "kern_util.h"
36835 +#include "sysdep/thread.h"
36836 +#include "user.h"
36837 +#include "os.h"
36838 +
36839 +int ptrace_getregs(long pid, unsigned long *regs_out)
36840 +{
36841 +       return(ptrace(PTRACE_GETREGS, pid, 0, regs_out));
36842 +}
36843 +
36844 +int ptrace_setregs(long pid, unsigned long *regs)
36845 +{
36846 +       return(ptrace(PTRACE_SETREGS, pid, 0, regs));
36847 +}
36848 +
36849 +int ptrace_getfpregs(long pid, unsigned long *regs)
36850 +{
36851 +       return(ptrace(PTRACE_GETFPREGS, pid, 0, regs));
36852 +}
36853 +
36854 +static void write_debugregs(int pid, unsigned long *regs)
36855 +{
36856 +       struct user *dummy;
36857 +       int nregs, i;
36858 +
36859 +       dummy = NULL;
36860 +       nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
36861 +       for(i = 0; i < nregs; i++){
36862 +               if((i == 4) || (i == 5)) continue;
36863 +               if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
36864 +                         regs[i]) < 0)
36865 +                       printk("write_debugregs - ptrace failed on "
36866 +                              "register %d, errno = %d\n", errno);
36867 +       }
36868 +}
36869 +
36870 +static void read_debugregs(int pid, unsigned long *regs)
36871 +{
36872 +       struct user *dummy;
36873 +       int nregs, i;
36874 +
36875 +       dummy = NULL;
36876 +       nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
36877 +       for(i = 0; i < nregs; i++){
36878 +               regs[i] = ptrace(PTRACE_PEEKUSER, pid, 
36879 +                                &dummy->u_debugreg[i], 0);
36880 +       }
36881 +}
36882 +
36883 +/* Accessed only by the tracing thread */
36884 +static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
36885 +static int debugregs_seq = 0;
36886 +
36887 +void arch_enter_kernel(void *task, int pid)
36888 +{
36889 +       read_debugregs(pid, TASK_DEBUGREGS(task));
36890 +       write_debugregs(pid, kernel_debugregs);
36891 +}
36892 +
36893 +void arch_leave_kernel(void *task, int pid)
36894 +{
36895 +       read_debugregs(pid, kernel_debugregs);
36896 +       write_debugregs(pid, TASK_DEBUGREGS(task));
36897 +}
36898 +
36899 +void ptrace_pokeuser(unsigned long addr, unsigned long data)
36900 +{
36901 +       if((addr < offsetof(struct user, u_debugreg[0])) ||
36902 +          (addr > offsetof(struct user, u_debugreg[7])))
36903 +               return;
36904 +       addr -= offsetof(struct user, u_debugreg[0]);
36905 +       addr = addr >> 2;
36906 +       if(kernel_debugregs[addr] == data) return;
36907 +
36908 +       kernel_debugregs[addr] = data;
36909 +       debugregs_seq++;
36910 +}
36911 +
36912 +static void update_debugregs_cb(void *arg)
36913 +{
36914 +       int pid = *((int *) arg);
36915 +
36916 +       write_debugregs(pid, kernel_debugregs);
36917 +}
36918 +
36919 +void update_debugregs(int seq)
36920 +{
36921 +       int me;
36922 +
36923 +       if(seq == debugregs_seq) return;
36924 +
36925 +       me = os_getpid();
36926 +       initial_thread_cb(update_debugregs_cb, &me);
36927 +}
36928 +
36929 +/*
36930 + * Overrides for Emacs so that we follow Linus's tabbing style.
36931 + * Emacs will notice this stuff at the end of the file and automatically
36932 + * adjust the settings for this buffer only.  This must remain at the end
36933 + * of the file.
36934 + * ---------------------------------------------------------------------------
36935 + * Local variables:
36936 + * c-file-style: "linux"
36937 + * End:
36938 + */
36939 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sigcontext.c um/arch/um/sys-i386/sigcontext.c
36940 --- orig/arch/um/sys-i386/sigcontext.c  1969-12-31 19:00:00.000000000 -0500
36941 +++ um/arch/um/sys-i386/sigcontext.c    2003-10-21 03:26:07.000000000 -0400
36942 @@ -0,0 +1,80 @@
36943 +/* 
36944 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
36945 + * Licensed under the GPL
36946 + */
36947 +
36948 +#include <stddef.h>
36949 +#include <string.h>
36950 +#include <asm/ptrace.h>
36951 +#include <asm/sigcontext.h>
36952 +#include "sysdep/ptrace.h"
36953 +#include "kern_util.h"
36954 +#include "frame_user.h"
36955 +
36956 +int sc_size(void *data)
36957 +{
36958 +       struct arch_frame_data *arch = data;
36959 +
36960 +       return(sizeof(struct sigcontext) + arch->fpstate_size);
36961 +}
36962 +
36963 +void sc_to_sc(void *to_ptr, void *from_ptr)
36964 +{
36965 +       struct sigcontext *to = to_ptr, *from = from_ptr;
36966 +       int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
36967 +
36968 +       memcpy(to, from, size);
36969 +       if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
36970 +}
36971 +
36972 +unsigned long *sc_sigmask(void *sc_ptr)
36973 +{
36974 +       struct sigcontext *sc = sc_ptr;
36975 +
36976 +       return(&sc->oldmask);
36977 +}
36978 +
36979 +int sc_get_fpregs(unsigned long buf, void *sc_ptr)
36980 +{
36981 +       struct sigcontext *sc = sc_ptr;
36982 +       struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
36983 +       int err = 0;
36984 +
36985 +       if(from == NULL){
36986 +               err |= clear_user_proc(&to->cw, sizeof(to->cw));
36987 +               err |= clear_user_proc(&to->sw, sizeof(to->sw));
36988 +               err |= clear_user_proc(&to->tag, sizeof(to->tag));
36989 +               err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
36990 +               err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
36991 +               err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
36992 +               err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
36993 +               err |= clear_user_proc(&to->_st, sizeof(to->_st));
36994 +       }
36995 +       else {
36996 +               err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
36997 +               err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
36998 +               err |= copy_to_user_proc(&to->tag, &from->tag, 
36999 +                                        sizeof(to->tag));
37000 +               err |= copy_to_user_proc(&to->ipoff, &from->ipoff, 
37001 +                                        sizeof(to->ipoff));
37002 +               err |= copy_to_user_proc(&to->cssel,& from->cssel, 
37003 +                                        sizeof(to->cssel));
37004 +               err |= copy_to_user_proc(&to->dataoff, &from->dataoff, 
37005 +                                   sizeof(to->dataoff));
37006 +               err |= copy_to_user_proc(&to->datasel, &from->datasel, 
37007 +                                   sizeof(to->datasel));
37008 +               err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
37009 +       }
37010 +       return(err);
37011 +}
37012 +
37013 +/*
37014 + * Overrides for Emacs so that we follow Linus's tabbing style.
37015 + * Emacs will notice this stuff at the end of the file and automatically
37016 + * adjust the settings for this buffer only.  This must remain at the end
37017 + * of the file.
37018 + * ---------------------------------------------------------------------------
37019 + * Local variables:
37020 + * c-file-style: "linux"
37021 + * End:
37022 + */
37023 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/syscalls.c um/arch/um/sys-i386/syscalls.c
37024 --- orig/arch/um/sys-i386/syscalls.c    1969-12-31 19:00:00.000000000 -0500
37025 +++ um/arch/um/sys-i386/syscalls.c      2003-10-21 03:26:07.000000000 -0400
37026 @@ -0,0 +1,68 @@
37027 +/* 
37028 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
37029 + * Licensed under the GPL
37030 + */
37031 +
37032 +#include "asm/mman.h"
37033 +#include "asm/uaccess.h"
37034 +#include "asm/unistd.h"
37035 +
37036 +/*
37037 + * Perform the select(nd, in, out, ex, tv) and mmap() system
37038 + * calls. Linux/i386 didn't use to be able to handle more than
37039 + * 4 system call parameters, so these system calls used a memory
37040 + * block for parameter passing..
37041 + */
37042 +
37043 +struct mmap_arg_struct {
37044 +       unsigned long addr;
37045 +       unsigned long len;
37046 +       unsigned long prot;
37047 +       unsigned long flags;
37048 +       unsigned long fd;
37049 +       unsigned long offset;
37050 +};
37051 +
37052 +extern int old_mmap(unsigned long addr, unsigned long len,
37053 +                   unsigned long prot, unsigned long flags,
37054 +                   unsigned long fd, unsigned long offset);
37055 +
37056 +int old_mmap_i386(struct mmap_arg_struct *arg)
37057 +{
37058 +       struct mmap_arg_struct a;
37059 +       int err = -EFAULT;
37060 +
37061 +       if (copy_from_user(&a, arg, sizeof(a)))
37062 +               goto out;
37063 +
37064 +       err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
37065 + out:
37066 +       return err;
37067 +}
37068 +
37069 +struct sel_arg_struct {
37070 +       unsigned long n;
37071 +       fd_set *inp, *outp, *exp;
37072 +       struct timeval *tvp;
37073 +};
37074 +
37075 +int old_select(struct sel_arg_struct *arg)
37076 +{
37077 +       struct sel_arg_struct a;
37078 +
37079 +       if (copy_from_user(&a, arg, sizeof(a)))
37080 +               return -EFAULT;
37081 +       /* sys_select() does the appropriate kernel locking */
37082 +       return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
37083 +}
37084 +
37085 +/*
37086 + * Overrides for Emacs so that we follow Linus's tabbing style.
37087 + * Emacs will notice this stuff at the end of the file and automatically
37088 + * adjust the settings for this buffer only.  This must remain at the end
37089 + * of the file.
37090 + * ---------------------------------------------------------------------------
37091 + * Local variables:
37092 + * c-file-style: "linux"
37093 + * End:
37094 + */
37095 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sysrq.c um/arch/um/sys-i386/sysrq.c
37096 --- orig/arch/um/sys-i386/sysrq.c       1969-12-31 19:00:00.000000000 -0500
37097 +++ um/arch/um/sys-i386/sysrq.c 2003-10-21 03:26:07.000000000 -0400
37098 @@ -0,0 +1,30 @@
37099 +#include "linux/kernel.h"
37100 +#include "linux/smp.h"
37101 +#include "linux/sched.h"
37102 +#include "asm/ptrace.h"
37103 +#include "sysrq.h"
37104 +
37105 +void show_regs(struct pt_regs *regs)
37106 +{
37107 +        printk("\n");
37108 +        printk("EIP: %04lx:[<%08lx>] CPU: %d %s", 
37109 +              0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs),
37110 +              smp_processor_id(), print_tainted());
37111 +        if (PT_REGS_CS(regs) & 3)
37112 +                printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs),
37113 +                      PT_REGS_SP(regs));
37114 +        printk(" EFLAGS: %08lx\n    %s\n", PT_REGS_EFLAGS(regs),
37115 +              print_tainted());
37116 +        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
37117 +                PT_REGS_EAX(regs), PT_REGS_EBX(regs), 
37118 +              PT_REGS_ECX(regs), 
37119 +              PT_REGS_EDX(regs));
37120 +        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
37121 +              PT_REGS_ESI(regs), PT_REGS_EDI(regs), 
37122 +              PT_REGS_EBP(regs));
37123 +        printk(" DS: %04lx ES: %04lx\n",
37124 +              0xffff & PT_REGS_DS(regs), 
37125 +              0xffff & PT_REGS_ES(regs));
37126 +
37127 +        show_trace((unsigned long *) &regs);
37128 +}
37129 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/time.c um/arch/um/sys-i386/time.c
37130 --- orig/arch/um/sys-i386/time.c        1969-12-31 19:00:00.000000000 -0500
37131 +++ um/arch/um/sys-i386/time.c  2003-11-10 01:46:49.000000000 -0500
37132 @@ -0,0 +1,24 @@
37133 +/*
37134 + * sys-i386/time.c 
37135 + * Created             25.9.2002       Sapan Bhatia
37136 + *
37137 + */
37138 +
37139 +unsigned long long time_stamp(void)
37140 +{
37141 +       unsigned long low, high;
37142 +
37143 +       asm("rdtsc" : "=a" (low), "=d" (high));
37144 +       return((((unsigned long long) high) << 32) + low);
37145 +}
37146 +
37147 +/*
37148 + * Overrides for Emacs so that we follow Linus's tabbing style.
37149 + * Emacs will notice this stuff at the end of the file and automatically
37150 + * adjust the settings for this buffer only.  This must remain at the end
37151 + * of the file.
37152 + * ---------------------------------------------------------------------------
37153 + * Local variables:
37154 + * c-file-style: "linux"
37155 + * End:
37156 + */
37157 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/Makefile um/arch/um/sys-i386/util/Makefile
37158 --- orig/arch/um/sys-i386/util/Makefile 1969-12-31 19:00:00.000000000 -0500
37159 +++ um/arch/um/sys-i386/util/Makefile   2003-11-08 08:26:40.000000000 -0500
37160 @@ -0,0 +1,28 @@
37161 +EXE = mk_sc mk_thread
37162 +
37163 +include $(TOPDIR)/Rules.make
37164 +
37165 +all : $(EXE)
37166 +
37167 +mk_sc : mk_sc.o
37168 +       $(HOSTCC) -o mk_sc mk_sc.o
37169 +
37170 +mk_sc.o : mk_sc.c
37171 +       $(HOSTCC) -c $< 
37172 +
37173 +mk_thread : mk_thread_user.o mk_thread_kern.o
37174 +       $(HOSTCC) -o mk_thread mk_thread_user.o mk_thread_kern.o
37175 +
37176 +mk_thread_user.o : mk_thread_user.c
37177 +       $(HOSTCC) -c $< 
37178 +
37179 +mk_thread_kern.o : mk_thread_kern.c
37180 +       $(HOSTCC) $(CFLAGS) -c $< 
37181 +
37182 +clean :
37183 +       $(RM) $(EXE) *.o
37184 +
37185 +archmrproper : clean
37186 +
37187 +fastdep :
37188 +
37189 diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_sc.c um/arch/um/sys-i386/util/mk_sc.c
37190 --- orig/arch/um/sys-i386/util/mk_sc.c  1969-12-31 19:00:00.000000000 -0500
37191 +++ um/arch/um/sys-i386/util/mk_sc.c    2003-10-21 03:26:07.000000000 -0400
37192 @@ -0,0 +1,52 @@
37193 +#include <stdio.h>
37194 +#include <signal.h>
37195 +#include <linux/stddef.h>
37196 +
37197 +#define SC_OFFSET(name, field) \
37198 +  printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\
37199 +        offsetof(struct sigcontext, field))
37200 +
37201 +#define SC_FP_OFFSET(name, field) \
37202 +  printf("#define " name \
37203 +        "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
37204 +        offsetof(struct _fpstate, field))
37205 +
37206 +#define SC_FP_OFFSET_PTR(name, field, type) \
37207 +  printf("#define " name \
37208 +        "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
37209 +        offsetof(struct _fpstate, field))
37210 +
37211 +int main(int argc, char **argv)
37212 +{
37213 +  SC_OFFSET("SC_IP", eip);
37214 +  SC_OFFSET("SC_SP", esp);
37215 +  SC_OFFSET("SC_FS", fs);
37216 +  SC_OFFSET("SC_GS", gs);
37217 +  SC_OFFSET("SC_DS", ds);
37218 +  SC_OFFSET("SC_ES", es);
37219 +  SC_OFFSET("SC_SS", ss);
37220 +  SC_OFFSET("SC_CS", cs);
37221 +  SC_OFFSET("SC_EFLAGS", eflags);
37222 +  SC_OFFSET("SC_EAX", eax);
37223 +  SC_OFFSET("SC_EBX", ebx);
37224 +  SC_OFFSET("SC_ECX", ecx);
37225 +  SC_OFFSET("SC_EDX", edx);
37226 +  SC_OFFSET("SC_EDI", edi);
37227 +  SC_OFFSET("SC_ESI", esi);
37228 +  SC_OFFSET("SC_EBP", ebp);
37229 +  SC_OFFSET("SC_TRAPNO", trapno);
37230 +  SC_OFFSET("SC_ERR", err);
37231 +  SC_OFFSET("SC_CR2", cr2);
37232 +  SC_OFFSET("SC_FPSTATE", fpstate);
37233 +  SC_OFFSET("SC_SIGMASK", oldmask);
37234 +  SC_FP_OFFSET("SC_FP_CW", cw);
37235 +  SC_FP_OFFSET("SC_FP_SW", sw);
37236 +  SC_FP_OFFSET("SC_FP_TAG", tag);
37237 +  SC_FP_OFFSET("SC_FP_IPOFF", ipoff);
37238 +  SC_FP_OFFSET("SC_FP_CSSEL", cssel);
37239 +  SC_FP_OFFSET("SC_FP_DATAOFF", dataoff);
37240 +  SC_FP_OFFSET("SC_FP_DATASEL", datasel);
37241 +  SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate");
37242 +  SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void");
37243 +  return(0);
37244 +}
37245 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
37246 --- orig/arch/um/sys-i386/util/mk_thread_kern.c 1969-12-31 19:00:00.000000000 -0500
37247 +++ um/arch/um/sys-i386/util/mk_thread_kern.c   2003-10-21 03:26:07.000000000 -0400
37248 @@ -0,0 +1,22 @@
37249 +#include "linux/config.h"
37250 +#include "linux/stddef.h"
37251 +#include "linux/sched.h"
37252 +
37253 +extern void print_head(void);
37254 +extern void print_constant_ptr(char *name, int value);
37255 +extern void print_constant(char *name, char *type, int value);
37256 +extern void print_tail(void);
37257 +
37258 +#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
37259 +
37260 +int main(int argc, char **argv)
37261 +{
37262 +  print_head();
37263 +  print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs));
37264 +#ifdef CONFIG_MODE_TT
37265 +  print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
37266 +#endif
37267 +  print_tail();
37268 +  return(0);
37269 +}
37270 +
37271 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
37272 --- orig/arch/um/sys-i386/util/mk_thread_user.c 1969-12-31 19:00:00.000000000 -0500
37273 +++ um/arch/um/sys-i386/util/mk_thread_user.c   2003-10-21 03:26:07.000000000 -0400
37274 @@ -0,0 +1,30 @@
37275 +#include <stdio.h>
37276 +
37277 +void print_head(void)
37278 +{
37279 +  printf("/*\n");
37280 +  printf(" * Generated by mk_thread\n");
37281 +  printf(" */\n");
37282 +  printf("\n");
37283 +  printf("#ifndef __UM_THREAD_H\n");
37284 +  printf("#define __UM_THREAD_H\n");
37285 +  printf("\n");
37286 +}
37287 +
37288 +void print_constant_ptr(char *name, int value)
37289 +{
37290 +  printf("#define %s(task) ((unsigned long *) "
37291 +        "&(((char *) (task))[%d]))\n", name, value);
37292 +}
37293 +
37294 +void print_constant(char *name, char *type, int value)
37295 +{
37296 +  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, 
37297 +        value);
37298 +}
37299 +
37300 +void print_tail(void)
37301 +{
37302 +  printf("\n");
37303 +  printf("#endif\n");
37304 +}
37305 diff -Naur -X ../exclude-files orig/arch/um/sys-ia64/Makefile um/arch/um/sys-ia64/Makefile
37306 --- orig/arch/um/sys-ia64/Makefile      1969-12-31 19:00:00.000000000 -0500
37307 +++ um/arch/um/sys-ia64/Makefile        2003-10-21 03:26:07.000000000 -0400
37308 @@ -0,0 +1,26 @@
37309 +OBJ = sys.o
37310 +
37311 +OBJS =
37312 +
37313 +all: $(OBJ)
37314 +
37315 +$(OBJ): $(OBJS)
37316 +       rm -f $@
37317 +       $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
37318 +clean:
37319 +       rm -f $(OBJS)
37320 +
37321 +fastdep:
37322 +
37323 +archmrproper:
37324 +
37325 +archclean:
37326 +       rm -f link.ld
37327 +       @$(MAKEBOOT) clean
37328 +
37329 +archdep:
37330 +       @$(MAKEBOOT) dep
37331 +
37332 +modules:
37333 +
37334 +include $(TOPDIR)/Rules.make
37335 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/Makefile um/arch/um/sys-ppc/Makefile
37336 --- orig/arch/um/sys-ppc/Makefile       1969-12-31 19:00:00.000000000 -0500
37337 +++ um/arch/um/sys-ppc/Makefile 2003-10-21 03:26:07.000000000 -0400
37338 @@ -0,0 +1,80 @@
37339 +OBJ = sys.o
37340 +
37341 +.S.o:
37342 +       $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37343 +
37344 +OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
37345 +       ptrace_user.o sysrq.o
37346 +
37347 +EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
37348 +
37349 +all: $(OBJ)
37350 +
37351 +$(OBJ): $(OBJS)
37352 +       rm -f $@
37353 +       $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
37354 +
37355 +ptrace_user.o: ptrace_user.c
37356 +       $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
37357 +
37358 +sigcontext.o: sigcontext.c
37359 +       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
37360 +
37361 +semaphore.c:
37362 +       rm -f $@
37363 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37364 +
37365 +checksum.S:
37366 +       rm -f $@
37367 +       ln -s $(TOPDIR)/arch/ppc/lib/$@ $@
37368 +
37369 +mk_defs.c:
37370 +       rm -f $@
37371 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37372 +
37373 +ppc_defs.head:
37374 +       rm -f $@
37375 +       ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@
37376 +
37377 +ppc_defs.h: mk_defs.c ppc_defs.head \
37378 +               $(TOPDIR)/include/asm-ppc/mmu.h \
37379 +               $(TOPDIR)/include/asm-ppc/processor.h \
37380 +               $(TOPDIR)/include/asm-ppc/pgtable.h \
37381 +               $(TOPDIR)/include/asm-ppc/ptrace.h
37382 +#      $(CC) $(CFLAGS) -S mk_defs.c
37383 +       cp ppc_defs.head ppc_defs.h
37384 +# for bk, this way we can write to the file even if it's not checked out
37385 +       echo '#define THREAD 608' >> ppc_defs.h
37386 +       echo '#define PT_REGS 8' >> ppc_defs.h
37387 +       echo '#define CLONE_VM 256' >> ppc_defs.h
37388 +#      chmod u+w ppc_defs.h
37389 +#      grep '^#define' mk_defs.s >> ppc_defs.h
37390 +#      rm mk_defs.s
37391 +
37392 +# the asm link is horrible, and breaks the other targets.  This is also
37393 +# not going to work with parallel makes.
37394 +
37395 +checksum.o: checksum.S
37396 +       rm -f asm
37397 +       ln -s $(TOPDIR)/include/asm-ppc asm
37398 +       $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37399 +       rm -f asm
37400 +
37401 +misc.o: misc.S ppc_defs.h
37402 +       rm -f asm
37403 +       ln -s $(TOPDIR)/include/asm-ppc asm
37404 +       $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
37405 +       rm -f asm
37406 +
37407 +clean:
37408 +       rm -f $(OBJS)
37409 +       rm -f ppc_defs.h
37410 +       rm -f checksum.S semaphore.c mk_defs.c
37411 +
37412 +fastdep:
37413 +
37414 +dep:
37415 +
37416 +modules:
37417 +
37418 +include $(TOPDIR)/Rules.make
37419 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/misc.S um/arch/um/sys-ppc/misc.S
37420 --- orig/arch/um/sys-ppc/misc.S 1969-12-31 19:00:00.000000000 -0500
37421 +++ um/arch/um/sys-ppc/misc.S   2003-10-21 03:26:07.000000000 -0400
37422 @@ -0,0 +1,116 @@
37423 +/*
37424 + * This file contains miscellaneous low-level functions.
37425 + *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
37426 + *
37427 + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
37428 + * and Paul Mackerras.
37429 + *
37430 + * A couple of functions stolen from arch/ppc/kernel/misc.S for UML
37431 + * by Chris Emerson.
37432 + *
37433 + * This program is free software; you can redistribute it and/or
37434 + * modify it under the terms of the GNU General Public License
37435 + * as published by the Free Software Foundation; either version
37436 + * 2 of the License, or (at your option) any later version.
37437 + *
37438 + */
37439 +
37440 +#include <linux/config.h>
37441 +#include <asm/processor.h>
37442 +#include "ppc_asm.h"
37443 +
37444 +#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
37445 +#define CACHE_LINE_SIZE                16
37446 +#define LG_CACHE_LINE_SIZE     4
37447 +#define MAX_COPY_PREFETCH      1
37448 +#elif !defined(CONFIG_PPC64BRIDGE)
37449 +#define CACHE_LINE_SIZE                32
37450 +#define LG_CACHE_LINE_SIZE     5
37451 +#define MAX_COPY_PREFETCH      4
37452 +#else
37453 +#define CACHE_LINE_SIZE                128
37454 +#define LG_CACHE_LINE_SIZE     7
37455 +#define MAX_COPY_PREFETCH      1
37456 +#endif /* CONFIG_4xx || CONFIG_8xx */
37457 +
37458 +       .text
37459 +
37460 +/*
37461 + * Clear a page using the dcbz instruction, which doesn't cause any
37462 + * memory traffic (except to write out any cache lines which get
37463 + * displaced).  This only works on cacheable memory.
37464 + */
37465 +_GLOBAL(clear_page)
37466 +       li      r0,4096/CACHE_LINE_SIZE
37467 +       mtctr   r0
37468 +#ifdef CONFIG_8xx
37469 +       li      r4, 0
37470 +1:     stw     r4, 0(r3)
37471 +       stw     r4, 4(r3)
37472 +       stw     r4, 8(r3)
37473 +       stw     r4, 12(r3)
37474 +#else
37475 +1:     dcbz    0,r3
37476 +#endif
37477 +       addi    r3,r3,CACHE_LINE_SIZE
37478 +       bdnz    1b
37479 +       blr
37480 +
37481 +/*
37482 + * Copy a whole page.  We use the dcbz instruction on the destination
37483 + * to reduce memory traffic (it eliminates the unnecessary reads of
37484 + * the destination into cache).  This requires that the destination
37485 + * is cacheable.
37486 + */
37487 +#define COPY_16_BYTES          \
37488 +       lwz     r6,4(r4);       \
37489 +       lwz     r7,8(r4);       \
37490 +       lwz     r8,12(r4);      \
37491 +       lwzu    r9,16(r4);      \
37492 +       stw     r6,4(r3);       \
37493 +       stw     r7,8(r3);       \
37494 +       stw     r8,12(r3);      \
37495 +       stwu    r9,16(r3)
37496 +
37497 +_GLOBAL(copy_page)
37498 +       addi    r3,r3,-4
37499 +       addi    r4,r4,-4
37500 +       li      r5,4
37501 +
37502 +#ifndef CONFIG_8xx
37503 +#if MAX_COPY_PREFETCH > 1
37504 +       li      r0,MAX_COPY_PREFETCH
37505 +       li      r11,4
37506 +       mtctr   r0
37507 +11:    dcbt    r11,r4
37508 +       addi    r11,r11,CACHE_LINE_SIZE
37509 +       bdnz    11b
37510 +#else /* MAX_COPY_PREFETCH == 1 */
37511 +       dcbt    r5,r4
37512 +       li      r11,CACHE_LINE_SIZE+4
37513 +#endif /* MAX_COPY_PREFETCH */
37514 +#endif /* CONFIG_8xx */
37515 +
37516 +       li      r0,4096/CACHE_LINE_SIZE
37517 +       mtctr   r0
37518 +1:
37519 +#ifndef CONFIG_8xx
37520 +       dcbt    r11,r4
37521 +       dcbz    r5,r3
37522 +#endif
37523 +       COPY_16_BYTES
37524 +#if CACHE_LINE_SIZE >= 32
37525 +       COPY_16_BYTES
37526 +#if CACHE_LINE_SIZE >= 64
37527 +       COPY_16_BYTES
37528 +       COPY_16_BYTES
37529 +#if CACHE_LINE_SIZE >= 128
37530 +       COPY_16_BYTES
37531 +       COPY_16_BYTES
37532 +       COPY_16_BYTES
37533 +       COPY_16_BYTES
37534 +#endif
37535 +#endif
37536 +#endif
37537 +       bdnz    1b
37538 +       blr
37539 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/miscthings.c um/arch/um/sys-ppc/miscthings.c
37540 --- orig/arch/um/sys-ppc/miscthings.c   1969-12-31 19:00:00.000000000 -0500
37541 +++ um/arch/um/sys-ppc/miscthings.c     2003-10-21 03:26:07.000000000 -0400
37542 @@ -0,0 +1,53 @@
37543 +#include "linux/threads.h"
37544 +#include "linux/stddef.h"  // for NULL
37545 +#include "linux/elf.h"  // for AT_NULL
37546 +
37547 +/* The following function nicked from arch/ppc/kernel/process.c and
37548 + * adapted slightly */
37549 +/*
37550 + * XXX ld.so expects the auxiliary table to start on
37551 + * a 16-byte boundary, so we have to find it and
37552 + * move it up. :-(
37553 + */
37554 +void shove_aux_table(unsigned long sp)
37555 +{
37556 +       int argc;
37557 +       char *p;
37558 +       unsigned long e;
37559 +       unsigned long aux_start, offset;
37560 +
37561 +       argc = *(int *)sp;
37562 +       sp += sizeof(int) + (argc + 1) * sizeof(char *);
37563 +       /* skip over the environment pointers */
37564 +       do {
37565 +               p = *(char **)sp;
37566 +               sp += sizeof(char *);
37567 +       } while (p != NULL);
37568 +       aux_start = sp;
37569 +       /* skip to the end of the auxiliary table */
37570 +       do {
37571 +               e = *(unsigned long *)sp;
37572 +               sp += 2 * sizeof(unsigned long);
37573 +       } while (e != AT_NULL);
37574 +       offset = ((aux_start + 15) & ~15) - aux_start;
37575 +       if (offset != 0) {
37576 +               do {
37577 +                       sp -= sizeof(unsigned long);
37578 +                       e = *(unsigned long *)sp;
37579 +                       *(unsigned long *)(sp + offset) = e;
37580 +               } while (sp > aux_start);
37581 +       }
37582 +}
37583 +/* END stuff taken from arch/ppc/kernel/process.c */
37584 +
37585 +
37586 +/*
37587 + * Overrides for Emacs so that we follow Linus's tabbing style.
37588 + * Emacs will notice this stuff at the end of the file and automatically
37589 + * adjust the settings for this buffer only.  This must remain at the end
37590 + * of the file.
37591 + * ---------------------------------------------------------------------------
37592 + * Local variables:
37593 + * c-file-style: "linux"
37594 + * End:
37595 + */
37596 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace.c um/arch/um/sys-ppc/ptrace.c
37597 --- orig/arch/um/sys-ppc/ptrace.c       1969-12-31 19:00:00.000000000 -0500
37598 +++ um/arch/um/sys-ppc/ptrace.c 2003-10-21 03:26:07.000000000 -0400
37599 @@ -0,0 +1,28 @@
37600 +#include "linux/sched.h"
37601 +#include "asm/ptrace.h"
37602 +
37603 +int putreg(struct task_struct *child, unsigned long regno, 
37604 +                 unsigned long value)
37605 +{
37606 +       child->thread.process_regs.regs[regno >> 2] = value;
37607 +       return 0;
37608 +}
37609 +
37610 +unsigned long getreg(struct task_struct *child, unsigned long regno)
37611 +{
37612 +       unsigned long retval = ~0UL;
37613 +
37614 +       retval &= child->thread.process_regs.regs[regno >> 2];
37615 +       return retval;
37616 +}
37617 +
37618 +/*
37619 + * Overrides for Emacs so that we follow Linus's tabbing style.
37620 + * Emacs will notice this stuff at the end of the file and automatically
37621 + * adjust the settings for this buffer only.  This must remain at the end
37622 + * of the file.
37623 + * ---------------------------------------------------------------------------
37624 + * Local variables:
37625 + * c-file-style: "linux"
37626 + * End:
37627 + */
37628 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace_user.c um/arch/um/sys-ppc/ptrace_user.c
37629 --- orig/arch/um/sys-ppc/ptrace_user.c  1969-12-31 19:00:00.000000000 -0500
37630 +++ um/arch/um/sys-ppc/ptrace_user.c    2003-10-21 03:26:07.000000000 -0400
37631 @@ -0,0 +1,40 @@
37632 +#include <sys/ptrace.h>
37633 +#include <errno.h>
37634 +#include <asm/ptrace.h>
37635 +#include "sysdep/ptrace.h"
37636 +
37637 +int ptrace_getregs(long pid, unsigned long *regs_out)
37638 +{
37639 +    int i;
37640 +    for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
37641 +       errno = 0;
37642 +       regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0);
37643 +       if (errno) {
37644 +           return -errno;
37645 +       }
37646 +    }
37647 +    return 0;
37648 +}
37649 +
37650 +int ptrace_setregs(long pid, unsigned long *regs_in)
37651 +{
37652 +    int i;
37653 +    for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) {
37654 +       if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) {
37655 +           if (ptrace(PTRACE_POKEUSER, pid, i*4, regs_in->regs[i]) < 0) {
37656 +               return -errno;
37657 +           }
37658 +       }
37659 +    }
37660 +    return 0;
37661 +}
37662 +/*
37663 + * Overrides for Emacs so that we follow Linus's tabbing style.
37664 + * Emacs will notice this stuff at the end of the file and automatically
37665 + * adjust the settings for this buffer only.  This must remain at the end
37666 + * of the file.
37667 + * ---------------------------------------------------------------------------
37668 + * Local variables:
37669 + * c-file-style: "linux"
37670 + * End:
37671 + */
37672 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sigcontext.c um/arch/um/sys-ppc/sigcontext.c
37673 --- orig/arch/um/sys-ppc/sigcontext.c   1969-12-31 19:00:00.000000000 -0500
37674 +++ um/arch/um/sys-ppc/sigcontext.c     2003-10-21 03:26:07.000000000 -0400
37675 @@ -0,0 +1,15 @@
37676 +#include "asm/ptrace.h"
37677 +#include "asm/sigcontext.h"
37678 +#include "sysdep/ptrace.h"
37679 +#include "user_util.h"
37680 +
37681 +/*
37682 + * Overrides for Emacs so that we follow Linus's tabbing style.
37683 + * Emacs will notice this stuff at the end of the file and automatically
37684 + * adjust the settings for this buffer only.  This must remain at the end
37685 + * of the file.
37686 + * ---------------------------------------------------------------------------
37687 + * Local variables:
37688 + * c-file-style: "linux"
37689 + * End:
37690 + */
37691 diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sysrq.c um/arch/um/sys-ppc/sysrq.c
37692 --- orig/arch/um/sys-ppc/sysrq.c        1969-12-31 19:00:00.000000000 -0500
37693 +++ um/arch/um/sys-ppc/sysrq.c  2003-10-21 03:26:07.000000000 -0400
37694 @@ -0,0 +1,43 @@
37695 +/* 
37696 + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
37697 + * Licensed under the GPL
37698 + */
37699 +
37700 +#include "linux/kernel.h"
37701 +#include "linux/smp.h"
37702 +#include "asm/ptrace.h"
37703 +#include "sysrq.h"
37704 +
37705 +void show_regs(struct pt_regs_subarch *regs)
37706 +{
37707 +       printk("\n");
37708 +       printk("show_regs(): insert regs here.\n");
37709 +#if 0
37710 +        printk("\n");
37711 +        printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip,
37712 +              smp_processor_id());
37713 +        if (regs->xcs & 3)
37714 +                printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp);
37715 +        printk(" EFLAGS: %08lx\n", regs->eflags);
37716 +        printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
37717 +                regs->eax, regs->ebx, regs->ecx, regs->edx);
37718 +        printk("ESI: %08lx EDI: %08lx EBP: %08lx",
37719 +                regs->esi, regs->edi, regs->ebp);
37720 +        printk(" DS: %04x ES: %04x\n",
37721 +                0xffff & regs->xds, 0xffff & regs->xes);
37722 +#endif
37723 +
37724 +        show_trace(&regs->gpr[1]);
37725 +}
37726 +
37727 +
37728 +/*
37729 + * Overrides for Emacs so that we follow Linus's tabbing style.
37730 + * Emacs will notice this stuff at the end of the file and automatically
37731 + * adjust the settings for this buffer only.  This must remain at the end
37732 + * of the file.
37733 + * ---------------------------------------------------------------------------
37734 + * Local variables:
37735 + * c-file-style: "linux"
37736 + * End:
37737 + */
37738 diff -Naur -X ../exclude-files orig/arch/um/util/Makefile um/arch/um/util/Makefile
37739 --- orig/arch/um/util/Makefile  1969-12-31 19:00:00.000000000 -0500
37740 +++ um/arch/um/util/Makefile    2003-11-08 02:51:30.000000000 -0500
37741 @@ -0,0 +1,26 @@
37742 +ALL = mk_task mk_constants
37743 +
37744 +all : $(ALL)
37745 +
37746 +mk_task : mk_task_user.o mk_task_kern.o
37747 +       $(HOSTCC) -o mk_task mk_task_user.o mk_task_kern.o
37748 +
37749 +mk_task_user.o : mk_task_user.c
37750 +       $(HOSTCC) -c $< 
37751 +
37752 +mk_task_kern.o : mk_task_kern.c
37753 +       $(HOSTCC) $(CFLAGS) -c $< 
37754 +
37755 +mk_constants : mk_constants_user.o mk_constants_kern.o
37756 +       $(HOSTCC) -o mk_constants mk_constants_user.o mk_constants_kern.o
37757 +
37758 +mk_constants_user.o : mk_constants_user.c
37759 +       $(HOSTCC) -c $< 
37760 +
37761 +mk_constants_kern.o : mk_constants_kern.c
37762 +       $(HOSTCC) $(CFLAGS) -c $< 
37763 +
37764 +clean :
37765 +       $(RM) $(ALL) *.o *~
37766 +
37767 +archmrproper : clean
37768 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_kern.c um/arch/um/util/mk_constants_kern.c
37769 --- orig/arch/um/util/mk_constants_kern.c       1969-12-31 19:00:00.000000000 -0500
37770 +++ um/arch/um/util/mk_constants_kern.c 2003-10-21 03:26:07.000000000 -0400
37771 @@ -0,0 +1,24 @@
37772 +#include "linux/kernel.h"
37773 +#include "linux/stringify.h"
37774 +#include "asm/page.h"
37775 +
37776 +extern void print_head(void);
37777 +extern void print_constant_str(char *name, char *value);
37778 +extern void print_constant_int(char *name, int value);
37779 +extern void print_tail(void);
37780 +
37781 +int main(int argc, char **argv)
37782 +{
37783 +  print_head();
37784 +  print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
37785 +  print_constant_str("UM_KERN_EMERG", KERN_EMERG);
37786 +  print_constant_str("UM_KERN_ALERT", KERN_ALERT);
37787 +  print_constant_str("UM_KERN_CRIT", KERN_CRIT);
37788 +  print_constant_str("UM_KERN_ERR", KERN_ERR);
37789 +  print_constant_str("UM_KERN_WARNING", KERN_WARNING);
37790 +  print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
37791 +  print_constant_str("UM_KERN_INFO", KERN_INFO);
37792 +  print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
37793 +  print_tail();
37794 +  return(0);
37795 +}
37796 diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_user.c um/arch/um/util/mk_constants_user.c
37797 --- orig/arch/um/util/mk_constants_user.c       1969-12-31 19:00:00.000000000 -0500
37798 +++ um/arch/um/util/mk_constants_user.c 2003-10-21 03:26:07.000000000 -0400
37799 @@ -0,0 +1,28 @@
37800 +#include <stdio.h>
37801 +
37802 +void print_head(void)
37803 +{
37804 +  printf("/*\n");
37805 +  printf(" * Generated by mk_constants\n");
37806 +  printf(" */\n");
37807 +  printf("\n");
37808 +  printf("#ifndef __UM_CONSTANTS_H\n");
37809 +  printf("#define __UM_CONSTANTS_H\n");
37810 +  printf("\n");
37811 +}
37812 +
37813 +void print_constant_str(char *name, char *value)
37814 +{
37815 +  printf("#define %s \"%s\"\n", name, value);
37816 +}
37817 +
37818 +void print_constant_int(char *name, int value)
37819 +{
37820 +  printf("#define %s %d\n", name, value);
37821 +}
37822 +
37823 +void print_tail(void)
37824 +{
37825 +  printf("\n");
37826 +  printf("#endif\n");
37827 +}
37828 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_kern.c um/arch/um/util/mk_task_kern.c
37829 --- orig/arch/um/util/mk_task_kern.c    1969-12-31 19:00:00.000000000 -0500
37830 +++ um/arch/um/util/mk_task_kern.c      2003-10-21 03:26:07.000000000 -0400
37831 @@ -0,0 +1,17 @@
37832 +#include "linux/sched.h"
37833 +#include "linux/stddef.h"
37834 +
37835 +extern void print(char *name, char *type, int offset);
37836 +extern void print_ptr(char *name, char *type, int offset);
37837 +extern void print_head(void);
37838 +extern void print_tail(void);
37839 +
37840 +int main(int argc, char **argv)
37841 +{
37842 +  print_head();
37843 +  print_ptr("TASK_REGS", "union uml_pt_regs", 
37844 +           offsetof(struct task_struct, thread.regs));
37845 +  print("TASK_PID", "int", offsetof(struct task_struct, pid));
37846 +  print_tail();
37847 +  return(0);
37848 +}
37849 diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_user.c um/arch/um/util/mk_task_user.c
37850 --- orig/arch/um/util/mk_task_user.c    1969-12-31 19:00:00.000000000 -0500
37851 +++ um/arch/um/util/mk_task_user.c      2003-10-21 03:26:07.000000000 -0400
37852 @@ -0,0 +1,30 @@
37853 +#include <stdio.h>
37854 +
37855 +void print(char *name, char *type, int offset)
37856 +{
37857 +  printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
37858 +        offset);
37859 +}
37860 +
37861 +void print_ptr(char *name, char *type, int offset)
37862 +{
37863 +  printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type,
37864 +        offset);
37865 +}
37866 +
37867 +void print_head(void)
37868 +{
37869 +  printf("/*\n");
37870 +  printf(" * Generated by mk_task\n");
37871 +  printf(" */\n");
37872 +  printf("\n");
37873 +  printf("#ifndef __TASK_H\n");
37874 +  printf("#define __TASK_H\n");
37875 +  printf("\n");
37876 +}
37877 +
37878 +void print_tail(void)
37879 +{
37880 +  printf("\n");
37881 +  printf("#endif\n");
37882 +}
37883 diff -Naur -X ../exclude-files orig/CREDITS um/CREDITS
37884 --- orig/CREDITS        2003-12-16 22:16:23.000000000 -0500
37885 +++ um/CREDITS  2003-12-16 22:17:22.000000000 -0500
37886 @@ -434,6 +434,7 @@
37887  E: lars@nocrew.org
37888  W: http://lars.nocrew.org/
37889  D: dsp56k device driver
37890 +D: ptrace proxy in user mode kernel port
37891  S: Kopmansg 2
37892  S: 411 13  Goteborg
37893  S: Sweden
37894 @@ -719,7 +720,7 @@
37895  E: jdike@karaya.com
37896  W: http://user-mode-linux.sourceforge.net
37897  D: User mode kernel port
37898 -S: RR1 Box 67C
37899 +S: 375 Tubbs Hill Rd
37900  S: Deering NH 03244
37901  S: USA
37902  
37903 diff -Naur -X ../exclude-files orig/Documentation/Configure.help um/Documentation/Configure.help
37904 --- orig/Documentation/Configure.help   2003-12-16 22:16:23.000000000 -0500
37905 +++ um/Documentation/Configure.help     2003-12-16 22:17:22.000000000 -0500
37906 @@ -15821,6 +15821,63 @@
37907    The module will be called speedtch.o. If you want to compile it as
37908    a module, say M here and read <file:Documentation/modules.txt>.
37909  
37910 +Support for /proc/mm
37911 +CONFIG_PROC_MM
37912 +  Enables support for address space separation through /proc/mm.
37913 +  A host kernel needs to have this enabled in order for UML to
37914 +  run in skas mode.  UML kernels do not need to have this option
37915 +  unless they will host sub-UMLs.
37916 +
37917 +  If you don't know what this does just say Y.
37918 +
37919 +Separate Kernel Address Space support
37920 +CONFIG_MODE_SKAS
37921 +  This option controls whether skas (separate kernel address space)
37922 +  support is compiled in.  If you have applied the skas patch to the
37923 +  host and enabled support for /proc/mm in the host kernel, then you
37924 +  certainly want to say Y here (and consider saying N to
37925 +  CONFIG_MODE_TT).  Otherwise, it is safe to say Y.  Disabling this
37926 +  option will shrink the UML binary slightly.
37927 +
37928 +Tracing thread support
37929 +CONFIG_MODE_TT
37930 +  This option controls whether tracing thread support is compiled
37931 +  into UML.  Normally, this should be set to Y.  If you intend to
37932 +  use only skas mode (and the host has the skas patch applied to it),
37933 +  then it is OK to say N here.
37934 +
37935 +Force a static link
37936 +CONFIG_STATIC_LINK
37937 +  If CONFIG_MODE_TT is disabled, then this option gives you the ability
37938 +  to force a static link of UML.  Normally, if only skas mode is built
37939 +  in to UML, it will be linked as a shared binary.  This is inconvenient
37940 +  for use in a chroot jail.  So, if you intend to run UML inside a
37941 +  chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
37942 +  here.
37943 +
37944 +2G/2G host address space split
37945 +CONFIG_HOST_2G_2G
37946 +  Most Linux machines are configured so that the kernel occupies the
37947 +  upper 1G of the 4G address space and processes use the lower 3G.
37948 +  However, some machine are configured with a 2G/2G split, with the
37949 +  kernel occupying the upper 2G and processes using the lower 2G.
37950 +
37951 +  To allow UML to run on a such host you have to say Y here. N should be
37952 +  a safe choice most of the time.
37953 +
37954 +Kernel stack size order
37955 +CONFIG_KERNEL_STACK_ORDER
37956 +  This option determines the size of UML kernel stacks.  They will
37957 +  be 1 << order pages.  The default is OK unless you're running Valgrind
37958 +  on UML, in which case, set this to 3.
37959 +
37960 +UML ubd block driver
37961 +CONFIG_BLK_DEV_UBD
37962 +  The User-Mode Linux port includes a driver called UBD which will let
37963 +  you access arbitrary files on the host computer as block devices.
37964 +  Unless you know that you do not need such virtual block devices say
37965 +  Y here.
37966 +
37967  CONFIG_USB_GADGET
37968    USB is a master/slave protocol, organized with one master
37969    host (such as a PC) controlling up to 127 peripheral devices.
37970 @@ -15905,17 +15962,15 @@
37971  
37972  Always do synchronous disk IO for UBD
37973  CONFIG_BLK_DEV_UBD_SYNC
37974 -  The User-Mode Linux port includes a driver called UBD which will let
37975 -  you access arbitrary files on the host computer as block devices.
37976 -  Writes to such a block device are not immediately written to the
37977 -  host's disk; this may cause problems if, for example, the User-Mode
37978 -  Linux 'Virtual Machine' uses a journalling file system and the host
37979 -  computer crashes.
37980 +  Writes to the virtual block device are not immediately written to the host's
37981 +  disk; this may cause problems if, for example, the User-Mode Linux
37982 +  'Virtual Machine' uses a journalling filesystem and the host computer
37983 +  crashes.
37984  
37985    Synchronous operation (i.e. always writing data to the host's disk
37986    immediately) is configurable on a per-UBD basis by using a special
37987    kernel command line option.  Alternatively, you can say Y here to
37988 -  turn on synchronous operation by default for all block.
37989 +  turn on synchronous operation by default for all block devices.
37990  
37991    If you're running a journalling file system (like reiserfs, for
37992    example) in your virtual machine, you will want to say Y here.  If
37993 @@ -15927,6 +15982,7 @@
37994  CONFIG_PT_PROXY
37995    This option enables a debugging interface which allows gdb to debug
37996    the kernel without needing to actually attach to kernel threads.
37997 +  CONFIG_XTERM_CHAN must be enabled in order to enable CONFIG_PT_PROXY.
37998    If you want to do kernel debugging, say Y here; otherwise say N.
37999  
38000  Management console
38001 @@ -15959,7 +16015,7 @@
38002    This option allows developers to retrieve coverage data from a UML
38003    session.
38004  
38005 -  See <http://user-mode-linux.sourceforge.net/gcov.html> for more
38006 +  See <http://user-mode-linux.sourceforge.net/gprof.html> for more
38007    details.
38008  
38009    If you're involved in UML kernel development and want to use gcov,
38010 @@ -15996,6 +16052,19 @@
38011    If you'd like to be able to work with files stored on the host, 
38012    say Y or M here; otherwise say N.
38013  
38014 +HoneyPot ProcFS
38015 +CONFIG_HPPFS
38016 +  hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
38017 +  entries to be overridden, removed, or fabricated from the host.
38018 +  Its purpose is to allow a UML to appear to be a physical machine
38019 +  by removing or changing anything in /proc which gives away the
38020 +  identity of a UML.
38021 +
38022 +  See <http://user-mode-linux.sf.net/hppfs.html> for more information.
38023 +
38024 +  You only need this if you are setting up a UML honeypot.  Otherwise,
38025 +  it is safe to say 'N' here.
38026 +
38027  Example IO Memory driver
38028  CONFIG_MMAPPER
38029    The User-Mode Linux port can provide support for IO Memory
38030 @@ -16011,6 +16080,21 @@
38031    If you'd like to be able to provide a simulated IO port space for
38032    User-Mode Linux processes, say Y.  If unsure, say N.
38033  
38034 +Anonymous Memory support
38035 +CONFIG_DEV_ANON
38036 +  Don't ask. Just say Y.
38037 +
38038 +Support for software watchdog inside UML
38039 +CONFIG_UML_WATCHDOG
38040 +  Support for a virtual hardware watchdog. It's safe to say N here.
38041 +
38042 +COW block device
38043 +CONFIG_COW
38044 +  This is a layered driver which sits above two other block devices.
38045 +  One is read-only, and the other is a read-write layer which stores
38046 +  all changes.  This provides the illusion that the read-only layer
38047 +  can be mounted read-write and changed.
38048 +
38049  Virtual Serial Line
38050  CONFIG_SSL
38051    The User-Mode Linux environment allows you to create virtual serial
38052 @@ -16121,26 +16205,197 @@
38053  
38054  SLIP transport
38055  CONFIG_UML_NET_SLIP
38056 -  The Slip User-Mode Linux network transport allows a running UML to
38057 +  The slip User-Mode Linux network transport allows a running UML to
38058    network with its host over a point-to-point link.  Unlike Ethertap,
38059    which can carry any Ethernet frame (and hence even non-IP packets),
38060 -  the Slip transport can only carry IP packets.
38061 +  the slip transport can only carry IP packets.
38062  
38063 -  To use this, your host must support Slip devices.
38064 +  To use this, your host must support slip devices.
38065  
38066    For more information, see
38067    <http://user-mode-linux.sourceforge.net/networking.html>.  That site
38068 -  has examples of the UML command line to use to enable Slip
38069 +  has examples of the UML command line to use to enable slip
38070    networking, and details of a few quirks with it.
38071  
38072 -  The Ethertap Transport is preferred over Slip because of its
38073 -  limitation.  If you prefer Slip, however, say Y here.  Otherwise
38074 +  The Ethertap Transport is preferred over slip because of its
38075 +  limitations.  If you prefer slip, however, say Y here.  Otherwise
38076    choose the Multicast transport (to network multiple UMLs on 
38077    multiple hosts), Ethertap (to network with the host and the
38078    outside world), and/or the Daemon transport (to network multiple
38079    UMLs on a single host).  You may choose more than one without
38080    conflict.  If you don't need UML networking, say N.
38081  
38082 +SLiRP transport
38083 +CONFIG_UML_NET_SLIRP
38084 +  The SLiRP User-Mode Linux network transport allows a running UML
38085 +  to network by invoking a program that can handle SLIP encapsulated
38086 +  packets.  This is commonly (but not limited to) the application
38087 +  known as SLiRP, a program that can re-socket IP packets back onto
38088 +  the host on which it is run.  Only IP packets are supported,
38089 +  unlike other network transports that can handle all Ethernet
38090 +  frames.  In general, slirp allows the UML the same IP connectivity
38091 +  to the outside world that the host user is permitted, and unlike
38092 +  other transports, SLiRP works without the need of root level
38093 +  privleges, setuid binaries, or SLIP devices on the host.  This
38094 +  also means not every type of connection is possible, but most
38095 +  situations can be accomodated with carefully crafted slirp
38096 +  commands that can be passed along as part of the network device's
38097 +  setup string.  The effect of this transport on the UML is similar
38098 +  that of a host behind a firewall that masquerades all network
38099 +  connections passing through it (but is less secure).
38100 +
38101 +  To use this you should first have slirp compiled somewhere
38102 +  accessible on the host, and have read its documentation.  If you
38103 +  don't need UML networking, say N.
38104 +
38105 +  Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
38106 +
38107 +pcap transport
38108 +CONFIG_UML_NET_PCAP
38109 + The pcap transport makes a pcap packet stream on the host look
38110 +  like an ethernet device inside UML.  This is useful for making
38111 +  UML act as a network monitor for the host.  You must have libcap
38112 +  installed in order to build the pcap transport into UML.
38113 +
38114 +  For more information, see
38115 +  <http://user-mode-linux.sourceforge.net/networking.html>  That site
38116 +  has examples of the UML command line to use to enable this option.
38117 +
38118 +  If you intend to use UML as a network monitor for the host, say
38119 +  Y here.  Otherwise, say N.
38120 +
38121 +Default main console channel initialization
38122 +CONFIG_CON_ZERO_CHAN
38123 +  This is the string describing the channel to which the main console
38124 +  will be attached by default.  This value can be overridden from the
38125 +  command line.  The default value is "fd:0,fd:1", which attaches the
38126 +  main console to stdin and stdout.
38127 +  It is safe to leave this unchanged.
38128 +
38129 +Default console channel initialization
38130 +CONFIG_CON_CHAN
38131 +  This is the string describing the channel to which all consoles
38132 +  except the main console will be attached by default.  This value can
38133 +  be overridden from the command line.  The default value is "xterm",
38134 +  which brings them up in xterms.
38135 +  It is safe to leave this unchanged, although you may wish to change
38136 +  this if you expect the UML that you build to be run in environments
38137 +  which don't have X or xterm available.
38138 +
38139 +Default serial line channel initialization
38140 +CONFIG_SSL_CHAN
38141 +  This is the string describing the channel to which the serial lines
38142 +  will be attached by default.  This value can be overridden from the
38143 +  command line.  The default value is "pty", which attaches them to
38144 +  traditional pseudo-terminals.
38145 +  It is safe to leave this unchanged, although you may wish to change
38146 +  this if you expect the UML that you build to be run in environments
38147 +  which don't have a set of /dev/pty* devices.
38148 +
38149 +Nesting level
38150 +CONFIG_NEST_LEVEL
38151 +  This is set to the number of layers of UMLs that this UML will be run
38152 +  in.  Normally, this is zero, meaning that it will run directly on the
38153 +  host.  Setting it to one will build a UML that can run inside a UML
38154 +  that is running on the host.  Generally, if you intend this UML to run
38155 +  inside another UML, set CONFIG_NEST_LEVEL to one more than the host UML.
38156 +  Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to 
38157 +  greater than one, then the guest UML should have its CONFIG_NEST_LEVEL 
38158 +  set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
38159 +  Only change this if you are running nested UMLs.
38160 +
38161 +Kernel address space size (in .5G units)
38162 +CONFIG_KERNEL_HALF_GIGS
38163 +  This determines the amount of address space that UML will allocate for
38164 +  its own, measured in half Gigabyte units.  The default is 1.
38165 +  Change this only if you need to boot UML with an unusually large amount
38166 +  of physical memory.
38167 +
38168 +UML sound support
38169 +CONFIG_UML_SOUND
38170 +  This option enables UML sound support.  If enabled, it will pull in
38171 +  soundcore and the UML hostaudio relay, which acts as a intermediary
38172 +  between the host's dsp and mixer devices and the UML sound system.
38173 +  It is safe to say 'Y' here.
38174 +
38175 +UML SMP support
38176 +CONFIG_UML_SMP
38177 +  This option enables UML SMP support.  UML implements virtual SMP by
38178 +  allowing as many processes to run simultaneously on the host as
38179 +  there are virtual processors configured.  Obviously, if the host is
38180 +  a uniprocessor, those processes will timeshare, but, inside UML,
38181 +  will appear to be running simultaneously.  If the host is a
38182 +  multiprocessor, then UML processes may run simultaneously, depending
38183 +  on the host scheduler.
38184 +  CONFIG_SMP will be set to whatever this option is set to.
38185 +  It is safe to leave this unchanged.
38186 +
38187 +file descriptor channel support
38188 +CONFIG_FD_CHAN
38189 +  This option enables support for attaching UML consoles and serial
38190 +  lines to already set up file descriptors.  Generally, the main
38191 +  console is attached to file descriptors 0 and 1 (stdin and stdout),
38192 +  so it would be wise to leave this enabled unless you intend to
38193 +  attach it to some other host device.
38194 +
38195 +null device channel support
38196 +CONFIG_NULL_CHAN
38197 +  This option enables support for attaching UML consoles and serial
38198 +  lines to a device similar to /dev/null.  Data written to it disappears
38199 +  and there is never any data to be read.
38200 +
38201 +port channel support
38202 +CONFIG_PORT_CHAN
38203 +  This option enables support for attaching UML consoles and serial
38204 +  lines to host portals.  They may be accessed with 'telnet <host>
38205 +  <port number>'.  Any number of consoles and serial lines may be
38206 +  attached to a single portal, although what UML device you get when
38207 +  you telnet to that portal will be unpredictable.
38208 +  It is safe to say 'Y' here.
38209 +
38210 +pty channel support
38211 +CONFIG_PTY_CHAN
38212 +  This option enables support for attaching UML consoles and serial
38213 +  lines to host pseudo-terminals.  Access to both traditional
38214 +  pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
38215 +  with this option.  The assignment of UML devices to host devices
38216 +  will be announced in the kernel message log.
38217 +  It is safe to say 'Y' here.
38218 +
38219 +tty channel support
38220 +CONFIG_TTY_CHAN
38221 +  This option enables support for attaching UML consoles and serial
38222 +  lines to host terminals.  Access to both virtual consoles
38223 +  (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
38224 +  /dev/pts/*) are controlled by this option.
38225 +  It is safe to say 'Y' here.
38226 +
38227 +xterm channel support
38228 +CONFIG_XTERM_CHAN
38229 +  This option enables support for attaching UML consoles and serial
38230 +  lines to xterms.  Each UML device so assigned will be brought up in
38231 +  its own xterm.
38232 +  If you disable this option, then CONFIG_PT_PROXY will be disabled as
38233 +  well, since UML's gdb currently requires an xterm.
38234 +  It is safe to say 'Y' here.
38235 +
38236 +tty logging
38237 +CONFIG_TTY_LOG
38238 +  This option enables logging of all data going through pseudo-terminals
38239 +  to the host.  This is primarily useful for honeypots, where you want
38240 +  secure keystroke logging that can't be detected or disabled by root.
38241 +  Say 'N' unless you are setting up a UML honeypot or otherwise know that
38242 +  you want this option.
38243 +
38244 +UML real-time clock support
38245 +CONFIG_UML_REAL_TIME_CLOCK
38246 +  This option ties the UML clock to the host clock, so that time passes at
38247 +  the same rate as on the host, regardless of how much CPU time the UML is
38248 +  getting.  This should normally be enabled.  The exception would be if you're
38249 +  debugging UML.  In this case, time spent staring at the debugger with UML
38250 +  stopped will cause lots of timer ticks to be backed up, and UML will spent
38251 +  lots of time calling the timer when it is finally continued.
38252 +
38253  Microtek USB scanner support
38254  CONFIG_USB_MICROTEK
38255    Say Y here if you want support for the Microtek X6USB and
38256 diff -Naur -X ../exclude-files orig/drivers/char/Makefile um/drivers/char/Makefile
38257 --- orig/drivers/char/Makefile  2003-12-16 22:16:26.000000000 -0500
38258 +++ um/drivers/char/Makefile    2003-12-16 22:17:25.000000000 -0500
38259 @@ -109,6 +109,12 @@
38260    endif
38261  endif
38262  
38263 +ifeq ($(ARCH),um)
38264 +  KEYMAP   =
38265 +  KEYBD    =
38266 +  CONSOLE  =
38267 +endif
38268 +
38269  ifeq ($(ARCH),sh)
38270    KEYMAP   =
38271    KEYBD    =
38272 diff -Naur -X ../exclude-files orig/drivers/char/mem.c um/drivers/char/mem.c
38273 --- orig/drivers/char/mem.c     2003-12-16 22:16:27.000000000 -0500
38274 +++ um/drivers/char/mem.c       2003-12-16 22:17:25.000000000 -0500
38275 @@ -220,7 +220,8 @@
38276         ssize_t read = 0;
38277         ssize_t virtr = 0;
38278         char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
38279 -               
38280 +
38281 +       p = (unsigned long) __va(p);
38282         if (p < (unsigned long) high_memory) {
38283                 read = count;
38284                 if (count > (unsigned long) high_memory - p)
38285 @@ -269,7 +270,7 @@
38286                 }
38287                 free_page((unsigned long)kbuf);
38288         }
38289 -       *ppos = p;
38290 +       *ppos = __pa((void *) p);
38291         return virtr + read;
38292  }
38293  
38294 @@ -664,6 +665,8 @@
38295         write:          write_full,
38296  };
38297  
38298 +extern struct file_operations anon_file_operations;
38299 +
38300  static int memory_open(struct inode * inode, struct file * filp)
38301  {
38302         switch (MINOR(inode->i_rdev)) {
38303 @@ -693,6 +696,9 @@
38304                 case 9:
38305                         filp->f_op = &urandom_fops;
38306                         break;
38307 +               case 10:
38308 +                       filp->f_op = &anon_file_operations;
38309 +                       break;
38310                 default:
38311                         return -ENXIO;
38312         }
38313 @@ -719,7 +725,8 @@
38314         {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
38315         {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
38316         {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
38317 -       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
38318 +       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
38319 +       {10, "anon", S_IRUGO | S_IWUSR,             &anon_file_operations},
38320      };
38321      int i;
38322  
38323 diff -Naur -X ../exclude-files orig/drivers/char/tty_io.c um/drivers/char/tty_io.c
38324 --- orig/drivers/char/tty_io.c  2003-12-16 22:16:27.000000000 -0500
38325 +++ um/drivers/char/tty_io.c    2003-12-16 22:17:25.000000000 -0500
38326 @@ -649,6 +649,23 @@
38327         wake_up_interruptible(&tty->write_wait);
38328  }
38329  
38330 +#ifdef CONFIG_TTY_LOG
38331 +
38332 +int (*open_log)(void *, void *) = NULL;
38333 +int (*write_log)(int, const char *, int, void *, int) = NULL;
38334 +void (*close_log)(int, void *) = NULL;
38335 +
38336 +void register_tty_logger(int (*opener)(void *, void *),
38337 +                        int (*writer)(int, const char *, int, void *, int),
38338 +                        void (*closer)(int, void *))
38339 +{
38340 +        open_log = opener;
38341 +       write_log = writer;
38342 +       close_log = closer;
38343 +}
38344 +
38345 +#endif
38346 +
38347  static ssize_t tty_read(struct file * file, char * buf, size_t count, 
38348                         loff_t *ppos)
38349  {
38350 @@ -689,8 +706,13 @@
38351         else
38352                 i = -EIO;
38353         unlock_kernel();
38354 -       if (i > 0)
38355 +       if (i > 0){
38356                 inode->i_atime = CURRENT_TIME;
38357 +#ifdef CONFIG_TTY_LOG
38358 +               if((tty->log_fd >= 0) && (write_log != NULL))
38359 +                       (*write_log)(tty->log_fd, buf, i, tty, 1);
38360 +#endif
38361 +       }
38362         return i;
38363  }
38364  
38365 @@ -744,6 +766,10 @@
38366         if (written) {
38367                 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
38368                 ret = written;
38369 +#ifdef CONFIG_TTY_LOG
38370 +               if((tty->log_fd >= 0) && (write_log != NULL))
38371 +                       (*write_log)(tty->log_fd, buf - ret, ret, tty, 0);
38372 +#endif
38373         }
38374         up(&tty->atomic_write);
38375         return ret;
38376 @@ -971,6 +997,7 @@
38377                         goto release_mem_out;
38378                 }
38379         }
38380 +
38381         goto success;
38382  
38383         /*
38384 @@ -1290,6 +1317,11 @@
38385         run_task_queue(&tq_timer);
38386         flush_scheduled_tasks();
38387  
38388 +#ifdef CONFIG_TTY_LOG
38389 +       if((tty->log_fd >= 0) && (close_log != NULL))
38390 +               (*close_log)(tty->log_fd, tty);
38391 +#endif
38392 +
38393         /* 
38394          * The release_mem function takes care of the details of clearing
38395          * the slots and preserving the termios structure.
38396 @@ -1448,6 +1480,11 @@
38397                         nr_warns++;
38398                 }
38399         }
38400 +
38401 +#ifdef CONFIG_TTY_LOG
38402 +       if((tty->log_fd < 0) && (open_log != NULL))
38403 +              tty->log_fd = (*open_log)(tty, current->tty);
38404 +#endif
38405         return 0;
38406  }
38407  
38408 @@ -2047,6 +2084,9 @@
38409         spin_lock_init(&tty->read_lock);
38410         INIT_LIST_HEAD(&tty->tty_files);
38411         INIT_TQUEUE(&tty->SAK_tq, 0, 0);
38412 +#ifdef CONFIG_TTY_LOG
38413 +       tty->log_fd = -1;
38414 +#endif
38415  }
38416  
38417  /*
38418 diff -Naur -X ../exclude-files orig/drivers/net/setup.c um/drivers/net/setup.c
38419 --- orig/drivers/net/setup.c    2002-09-15 12:13:19.000000000 -0400
38420 +++ um/drivers/net/setup.c      2003-10-21 03:26:07.000000000 -0400
38421 @@ -28,7 +28,6 @@
38422  extern int lmc_setup(void);
38423  
38424  extern int madgemc_probe(void);
38425 -extern int uml_net_probe(void);
38426  
38427  /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
38428  #define __PAD6 "\0\0\0\0\0\0\0\0\0"
38429 @@ -103,9 +102,6 @@
38430  #ifdef CONFIG_MADGEMC
38431         {madgemc_probe, 0},
38432  #endif
38433 -#ifdef CONFIG_UML_NET
38434 -       {uml_net_probe, 0},
38435 -#endif
38436   
38437         {NULL, 0},
38438  };
38439 diff -Naur -X ../exclude-files orig/fs/bad_inode.c um/fs/bad_inode.c
38440 --- orig/fs/bad_inode.c 2002-08-21 11:47:27.000000000 -0400
38441 +++ um/fs/bad_inode.c   2003-10-21 03:26:07.000000000 -0400
38442 @@ -83,6 +83,7 @@
38443   
38444  void make_bad_inode(struct inode * inode) 
38445  {
38446 +       inode->i_state = 0;
38447         inode->i_mode = S_IFREG;
38448         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
38449         inode->i_op = &bad_inode_ops;   
38450 diff -Naur -X ../exclude-files orig/include/asm-i386/hardirq.h um/include/asm-i386/hardirq.h
38451 --- orig/include/asm-i386/hardirq.h     2003-12-16 22:16:35.000000000 -0500
38452 +++ um/include/asm-i386/hardirq.h       2003-12-17 02:16:13.000000000 -0500
38453 @@ -4,6 +4,7 @@
38454  #include <linux/config.h>
38455  #include <linux/threads.h>
38456  #include <linux/irq.h>
38457 +#include <asm/processor.h>             /* for cpu_relax */
38458  
38459  /* assembly code in softirq.h is sensitive to the offsets of these fields */
38460  typedef struct {
38461 diff -Naur -X ../exclude-files orig/include/asm-um/a.out.h um/include/asm-um/a.out.h
38462 --- orig/include/asm-um/a.out.h 1969-12-31 19:00:00.000000000 -0500
38463 +++ um/include/asm-um/a.out.h   2003-10-21 03:26:07.000000000 -0400
38464 @@ -0,0 +1,20 @@
38465 +#ifndef __UM_A_OUT_H
38466 +#define __UM_A_OUT_H
38467 +
38468 +#include "linux/config.h"
38469 +#include "asm/arch/a.out.h"
38470 +#include "choose-mode.h"
38471 +
38472 +#undef STACK_TOP
38473 +
38474 +extern unsigned long stacksizelim;
38475 +
38476 +extern unsigned long host_task_size;
38477 +
38478 +#define STACK_ROOM (stacksizelim)
38479 +
38480 +extern int honeypot;
38481 +#define STACK_TOP \
38482 +       CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
38483 +
38484 +#endif
38485 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-i386.h um/include/asm-um/archparam-i386.h
38486 --- orig/include/asm-um/archparam-i386.h        1969-12-31 19:00:00.000000000 -0500
38487 +++ um/include/asm-um/archparam-i386.h  2003-12-16 08:50:39.000000000 -0500
38488 @@ -0,0 +1,80 @@
38489 +/* 
38490 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
38491 + * Licensed under the GPL
38492 + */
38493 +
38494 +#ifndef __UM_ARCHPARAM_I386_H
38495 +#define __UM_ARCHPARAM_I386_H
38496 +
38497 +/********* Bits for asm-um/elf.h ************/
38498 +
38499 +#include "user.h"
38500 +
38501 +#define ELF_PLATFORM "i586"
38502 +
38503 +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
38504 +
38505 +typedef struct user_i387_struct elf_fpregset_t;
38506 +typedef unsigned long elf_greg_t;
38507 +
38508 +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
38509 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38510 +
38511 +#define ELF_DATA        ELFDATA2LSB
38512 +#define ELF_ARCH        EM_386
38513 +
38514 +#define ELF_PLAT_INIT(regs, load_addr) do { \
38515 +       PT_REGS_EBX(regs) = 0; \
38516 +       PT_REGS_ECX(regs) = 0; \
38517 +       PT_REGS_EDX(regs) = 0; \
38518 +       PT_REGS_ESI(regs) = 0; \
38519 +       PT_REGS_EDI(regs) = 0; \
38520 +       PT_REGS_EBP(regs) = 0; \
38521 +       PT_REGS_EAX(regs) = 0; \
38522 +} while(0)
38523 +
38524 +/* Shamelessly stolen from include/asm-i386/elf.h */
38525 +
38526 +#define ELF_CORE_COPY_REGS(pr_reg, regs) do {  \
38527 +       pr_reg[0] = PT_REGS_EBX(regs);          \
38528 +       pr_reg[1] = PT_REGS_ECX(regs);          \
38529 +       pr_reg[2] = PT_REGS_EDX(regs);          \
38530 +       pr_reg[3] = PT_REGS_ESI(regs);          \
38531 +       pr_reg[4] = PT_REGS_EDI(regs);          \
38532 +       pr_reg[5] = PT_REGS_EBP(regs);          \
38533 +       pr_reg[6] = PT_REGS_EAX(regs);          \
38534 +       pr_reg[7] = PT_REGS_DS(regs);           \
38535 +       pr_reg[8] = PT_REGS_ES(regs);           \
38536 +       /* fake once used fs and gs selectors? */       \
38537 +       pr_reg[9] = PT_REGS_DS(regs);           \
38538 +       pr_reg[10] = PT_REGS_DS(regs);          \
38539 +       pr_reg[11] = PT_REGS_SYSCALL_NR(regs);  \
38540 +       pr_reg[12] = PT_REGS_IP(regs);          \
38541 +       pr_reg[13] = PT_REGS_CS(regs);          \
38542 +       pr_reg[14] = PT_REGS_EFLAGS(regs);      \
38543 +       pr_reg[15] = PT_REGS_SP(regs);          \
38544 +       pr_reg[16] = PT_REGS_SS(regs);          \
38545 +} while(0);
38546 +
38547 +/********* Bits for asm-um/delay.h **********/
38548 +
38549 +typedef unsigned long um_udelay_t;
38550 +
38551 +/********* Nothing for asm-um/hardirq.h **********/
38552 +
38553 +/********* Nothing for asm-um/hw_irq.h **********/
38554 +
38555 +/********* Nothing for asm-um/string.h **********/
38556 +
38557 +#endif
38558 +
38559 +/*
38560 + * Overrides for Emacs so that we follow Linus's tabbing style.
38561 + * Emacs will notice this stuff at the end of the file and automatically
38562 + * adjust the settings for this buffer only.  This must remain at the end
38563 + * of the file.
38564 + * ---------------------------------------------------------------------------
38565 + * Local variables:
38566 + * c-file-style: "linux"
38567 + * End:
38568 + */
38569 diff -Naur -X ../exclude-files orig/include/asm-um/archparam-ppc.h um/include/asm-um/archparam-ppc.h
38570 --- orig/include/asm-um/archparam-ppc.h 1969-12-31 19:00:00.000000000 -0500
38571 +++ um/include/asm-um/archparam-ppc.h   2003-10-21 03:26:07.000000000 -0400
38572 @@ -0,0 +1,41 @@
38573 +#ifndef __UM_ARCHPARAM_PPC_H
38574 +#define __UM_ARCHPARAM_PPC_H
38575 +
38576 +/********* Bits for asm-um/elf.h ************/
38577 +
38578 +#define ELF_PLATFORM (0)
38579 +
38580 +#define ELF_ET_DYN_BASE (0x08000000)
38581 +
38582 +/* the following stolen from asm-ppc/elf.h */
38583 +#define ELF_NGREG      48      /* includes nip, msr, lr, etc. */
38584 +#define ELF_NFPREG     33      /* includes fpscr */
38585 +/* General registers */
38586 +typedef unsigned long elf_greg_t;
38587 +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38588 +
38589 +/* Floating point registers */
38590 +typedef double elf_fpreg_t;
38591 +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
38592 +
38593 +#define ELF_DATA        ELFDATA2MSB
38594 +#define ELF_ARCH       EM_PPC
38595 +
38596 +/********* Bits for asm-um/delay.h **********/
38597 +
38598 +typedef unsigned int um_udelay_t;
38599 +
38600 +/********* Bits for asm-um/hw_irq.h **********/
38601 +
38602 +struct hw_interrupt_type;
38603 +
38604 +/********* Bits for asm-um/hardirq.h **********/
38605 +
38606 +#define irq_enter(cpu, irq) hardirq_enter(cpu)
38607 +#define irq_exit(cpu, irq) hardirq_exit(cpu)
38608 +
38609 +/********* Bits for asm-um/string.h **********/
38610 +
38611 +#define __HAVE_ARCH_STRRCHR
38612 +
38613 +#endif
38614 diff -Naur -X ../exclude-files orig/include/asm-um/arch-signal-i386.h um/include/asm-um/arch-signal-i386.h
38615 --- orig/include/asm-um/arch-signal-i386.h      1969-12-31 19:00:00.000000000 -0500
38616 +++ um/include/asm-um/arch-signal-i386.h        2003-10-21 03:26:07.000000000 -0400
38617 @@ -0,0 +1,24 @@
38618 +/* 
38619 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
38620 + * Licensed under the GPL
38621 + */
38622 +
38623 +#ifndef __UM_ARCH_SIGNAL_I386_H
38624 +#define __UM_ARCH_SIGNAL_I386_H
38625 +
38626 +struct arch_signal_context {
38627 +       unsigned long extrasigs[_NSIG_WORDS];
38628 +};
38629 +
38630 +#endif
38631 +
38632 +/*
38633 + * Overrides for Emacs so that we follow Linus's tabbing style.
38634 + * Emacs will notice this stuff at the end of the file and automatically
38635 + * adjust the settings for this buffer only.  This must remain at the end
38636 + * of the file.
38637 + * ---------------------------------------------------------------------------
38638 + * Local variables:
38639 + * c-file-style: "linux"
38640 + * End:
38641 + */
38642 diff -Naur -X ../exclude-files orig/include/asm-um/atomic.h um/include/asm-um/atomic.h
38643 --- orig/include/asm-um/atomic.h        1969-12-31 19:00:00.000000000 -0500
38644 +++ um/include/asm-um/atomic.h  2003-12-17 02:16:13.000000000 -0500
38645 @@ -0,0 +1,6 @@
38646 +#ifndef __UM_ATOMIC_H
38647 +#define __UM_ATOMIC_H
38648 +
38649 +#include "asm/arch/atomic.h"
38650 +
38651 +#endif
38652 diff -Naur -X ../exclude-files orig/include/asm-um/bitops.h um/include/asm-um/bitops.h
38653 --- orig/include/asm-um/bitops.h        1969-12-31 19:00:00.000000000 -0500
38654 +++ um/include/asm-um/bitops.h  2003-12-17 02:16:13.000000000 -0500
38655 @@ -0,0 +1,6 @@
38656 +#ifndef __UM_BITOPS_H
38657 +#define __UM_BITOPS_H
38658 +
38659 +#include "asm/arch/bitops.h"
38660 +
38661 +#endif
38662 diff -Naur -X ../exclude-files orig/include/asm-um/boot.h um/include/asm-um/boot.h
38663 --- orig/include/asm-um/boot.h  1969-12-31 19:00:00.000000000 -0500
38664 +++ um/include/asm-um/boot.h    2003-10-21 03:26:07.000000000 -0400
38665 @@ -0,0 +1,6 @@
38666 +#ifndef __UM_BOOT_H
38667 +#define __UM_BOOT_H
38668 +
38669 +#include "asm/arch/boot.h"
38670 +
38671 +#endif
38672 diff -Naur -X ../exclude-files orig/include/asm-um/bugs.h um/include/asm-um/bugs.h
38673 --- orig/include/asm-um/bugs.h  1969-12-31 19:00:00.000000000 -0500
38674 +++ um/include/asm-um/bugs.h    2003-10-21 03:26:07.000000000 -0400
38675 @@ -0,0 +1,6 @@
38676 +#ifndef __UM_BUGS_H
38677 +#define __UM_BUGS_H
38678 +
38679 +void check_bugs(void);
38680 +
38681 +#endif
38682 diff -Naur -X ../exclude-files orig/include/asm-um/byteorder.h um/include/asm-um/byteorder.h
38683 --- orig/include/asm-um/byteorder.h     1969-12-31 19:00:00.000000000 -0500
38684 +++ um/include/asm-um/byteorder.h       2003-12-16 22:26:55.000000000 -0500
38685 @@ -0,0 +1,6 @@
38686 +#ifndef __UM_BYTEORDER_H
38687 +#define __UM_BYTEORDER_H
38688 +
38689 +#include "asm/arch/byteorder.h"
38690 +
38691 +#endif
38692 diff -Naur -X ../exclude-files orig/include/asm-um/cache.h um/include/asm-um/cache.h
38693 --- orig/include/asm-um/cache.h 1969-12-31 19:00:00.000000000 -0500
38694 +++ um/include/asm-um/cache.h   2003-10-21 03:26:07.000000000 -0400
38695 @@ -0,0 +1,6 @@
38696 +#ifndef __UM_CACHE_H
38697 +#define __UM_CACHE_H
38698 +
38699 +#define        L1_CACHE_BYTES  32
38700 +
38701 +#endif
38702 diff -Naur -X ../exclude-files orig/include/asm-um/checksum.h um/include/asm-um/checksum.h
38703 --- orig/include/asm-um/checksum.h      1969-12-31 19:00:00.000000000 -0500
38704 +++ um/include/asm-um/checksum.h        2003-10-21 03:26:07.000000000 -0400
38705 @@ -0,0 +1,6 @@
38706 +#ifndef __UM_CHECKSUM_H
38707 +#define __UM_CHECKSUM_H
38708 +
38709 +#include "sysdep/checksum.h"
38710 +
38711 +#endif
38712 diff -Naur -X ../exclude-files orig/include/asm-um/cobalt.h um/include/asm-um/cobalt.h
38713 --- orig/include/asm-um/cobalt.h        1969-12-31 19:00:00.000000000 -0500
38714 +++ um/include/asm-um/cobalt.h  2003-10-21 03:26:07.000000000 -0400
38715 @@ -0,0 +1,6 @@
38716 +#ifndef __UM_COBALT_H
38717 +#define __UM_COBALT_H
38718 +
38719 +#include "asm/arch/cobalt.h"
38720 +
38721 +#endif
38722 diff -Naur -X ../exclude-files orig/include/asm-um/current.h um/include/asm-um/current.h
38723 --- orig/include/asm-um/current.h       1969-12-31 19:00:00.000000000 -0500
38724 +++ um/include/asm-um/current.h 2003-12-17 02:16:13.000000000 -0500
38725 @@ -0,0 +1,34 @@
38726 +/* 
38727 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
38728 + * Licensed under the GPL
38729 + */
38730 +
38731 +#ifndef __UM_CURRENT_H
38732 +#define __UM_CURRENT_H
38733 +
38734 +#ifndef __ASSEMBLY__
38735 +
38736 +#include "linux/config.h"
38737 +#include "asm/page.h"
38738 +
38739 +struct task_struct;
38740 +
38741 +#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \
38742 +                            (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
38743 +
38744 +#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); })
38745 +
38746 +#endif /* __ASSEMBLY__ */
38747 +
38748 +#endif
38749 +
38750 +/*
38751 + * Overrides for Emacs so that we follow Linus's tabbing style.
38752 + * Emacs will notice this stuff at the end of the file and automatically
38753 + * adjust the settings for this buffer only.  This must remain at the end
38754 + * of the file.
38755 + * ---------------------------------------------------------------------------
38756 + * Local variables:
38757 + * c-file-style: "linux"
38758 + * End:
38759 + */
38760 diff -Naur -X ../exclude-files orig/include/asm-um/delay.h um/include/asm-um/delay.h
38761 --- orig/include/asm-um/delay.h 1969-12-31 19:00:00.000000000 -0500
38762 +++ um/include/asm-um/delay.h   2003-12-16 22:26:58.000000000 -0500
38763 @@ -0,0 +1,7 @@
38764 +#ifndef __UM_DELAY_H
38765 +#define __UM_DELAY_H
38766 +
38767 +#include "asm/arch/delay.h"
38768 +#include "asm/archparam.h"
38769 +
38770 +#endif
38771 diff -Naur -X ../exclude-files orig/include/asm-um/desc.h um/include/asm-um/desc.h
38772 --- orig/include/asm-um/desc.h  1969-12-31 19:00:00.000000000 -0500
38773 +++ um/include/asm-um/desc.h    2003-10-21 03:26:07.000000000 -0400
38774 @@ -0,0 +1,6 @@
38775 +#ifndef __UM_DESC_H
38776 +#define __UM_DESC_H
38777 +
38778 +#include "asm/arch/desc.h"
38779 +
38780 +#endif
38781 diff -Naur -X ../exclude-files orig/include/asm-um/div64.h um/include/asm-um/div64.h
38782 --- orig/include/asm-um/div64.h 1969-12-31 19:00:00.000000000 -0500
38783 +++ um/include/asm-um/div64.h   2003-10-21 03:26:07.000000000 -0400
38784 @@ -0,0 +1,6 @@
38785 +#ifndef _UM_DIV64_H
38786 +#define _UM_DIV64_H
38787 +
38788 +#include "asm/arch/div64.h"
38789 +
38790 +#endif
38791 diff -Naur -X ../exclude-files orig/include/asm-um/dma.h um/include/asm-um/dma.h
38792 --- orig/include/asm-um/dma.h   1969-12-31 19:00:00.000000000 -0500
38793 +++ um/include/asm-um/dma.h     2003-12-15 00:26:39.000000000 -0500
38794 @@ -0,0 +1,10 @@
38795 +#ifndef __UM_DMA_H
38796 +#define __UM_DMA_H
38797 +
38798 +#include "asm/io.h"
38799 +
38800 +extern unsigned long uml_physmem;
38801 +
38802 +#define MAX_DMA_ADDRESS (uml_physmem)
38803 +
38804 +#endif
38805 diff -Naur -X ../exclude-files orig/include/asm-um/elf.h um/include/asm-um/elf.h
38806 --- orig/include/asm-um/elf.h   1969-12-31 19:00:00.000000000 -0500
38807 +++ um/include/asm-um/elf.h     2003-12-16 22:29:20.000000000 -0500
38808 @@ -0,0 +1,18 @@
38809 +#ifndef __UM_ELF_H
38810 +#define __UM_ELF_H
38811 +
38812 +#include "asm/archparam.h"
38813 +
38814 +#define ELF_HWCAP (0)
38815 +
38816 +#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
38817 +
38818 +#define ELF_EXEC_PAGESIZE 4096
38819 +
38820 +#define elf_check_arch(x) (1)
38821 +
38822 +#define ELF_CLASS ELFCLASS32
38823 +
38824 +#define USE_ELF_CORE_DUMP
38825 +
38826 +#endif
38827 diff -Naur -X ../exclude-files orig/include/asm-um/errno.h um/include/asm-um/errno.h
38828 --- orig/include/asm-um/errno.h 1969-12-31 19:00:00.000000000 -0500
38829 +++ um/include/asm-um/errno.h   2003-10-21 03:26:07.000000000 -0400
38830 @@ -0,0 +1,6 @@
38831 +#ifndef __UM_ERRNO_H
38832 +#define __UM_ERRNO_H
38833 +
38834 +#include "asm/arch/errno.h"
38835 +
38836 +#endif
38837 diff -Naur -X ../exclude-files orig/include/asm-um/fcntl.h um/include/asm-um/fcntl.h
38838 --- orig/include/asm-um/fcntl.h 1969-12-31 19:00:00.000000000 -0500
38839 +++ um/include/asm-um/fcntl.h   2003-10-21 03:26:07.000000000 -0400
38840 @@ -0,0 +1,6 @@
38841 +#ifndef __UM_FCNTL_H
38842 +#define __UM_FCNTL_H
38843 +
38844 +#include "asm/arch/fcntl.h"
38845 +
38846 +#endif
38847 diff -Naur -X ../exclude-files orig/include/asm-um/fixmap.h um/include/asm-um/fixmap.h
38848 --- orig/include/asm-um/fixmap.h        1969-12-31 19:00:00.000000000 -0500
38849 +++ um/include/asm-um/fixmap.h  2003-12-17 02:16:14.000000000 -0500
38850 @@ -0,0 +1,89 @@
38851 +#ifndef __UM_FIXMAP_H
38852 +#define __UM_FIXMAP_H
38853 +
38854 +#include <linux/config.h>
38855 +#include <asm/kmap_types.h>
38856 +
38857 +/*
38858 + * Here we define all the compile-time 'special' virtual
38859 + * addresses. The point is to have a constant address at
38860 + * compile time, but to set the physical address only
38861 + * in the boot process. We allocate these special  addresses
38862 + * from the end of virtual memory (0xfffff000) backwards.
38863 + * Also this lets us do fail-safe vmalloc(), we
38864 + * can guarantee that these special addresses and
38865 + * vmalloc()-ed addresses never overlap.
38866 + *
38867 + * these 'compile-time allocated' memory buffers are
38868 + * fixed-size 4k pages. (or larger if used with an increment
38869 + * highger than 1) use fixmap_set(idx,phys) to associate
38870 + * physical memory with fixmap indices.
38871 + *
38872 + * TLB entries of such buffers will not be flushed across
38873 + * task switches.
38874 + */
38875 +
38876 +/*
38877 + * on UP currently we will have no trace of the fixmap mechanizm,
38878 + * no page table allocations, etc. This might change in the
38879 + * future, say framebuffers for the console driver(s) could be
38880 + * fix-mapped?
38881 + */
38882 +enum fixed_addresses {
38883 +#ifdef CONFIG_HIGHMEM
38884 +       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
38885 +       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
38886 +#endif
38887 +       __end_of_fixed_addresses
38888 +};
38889 +
38890 +extern void __set_fixmap (enum fixed_addresses idx,
38891 +                         unsigned long phys, pgprot_t flags);
38892 +
38893 +#define set_fixmap(idx, phys) \
38894 +               __set_fixmap(idx, phys, PAGE_KERNEL)
38895 +/*
38896 + * Some hardware wants to get fixmapped without caching.
38897 + */
38898 +#define set_fixmap_nocache(idx, phys) \
38899 +               __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
38900 +/*
38901 + * used by vmalloc.c.
38902 + *
38903 + * Leave one empty page between vmalloc'ed areas and
38904 + * the start of the fixmap, and leave one page empty
38905 + * at the top of mem..
38906 + */
38907 +extern unsigned long get_kmem_end(void);
38908 +
38909 +#define FIXADDR_TOP    (get_kmem_end() - 0x2000)
38910 +#define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
38911 +#define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
38912 +
38913 +#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
38914 +
38915 +extern void __this_fixmap_does_not_exist(void);
38916 +
38917 +/*
38918 + * 'index to address' translation. If anyone tries to use the idx
38919 + * directly without tranlation, we catch the bug with a NULL-deference
38920 + * kernel oops. Illegal ranges of incoming indices are caught too.
38921 + */
38922 +static inline unsigned long fix_to_virt(const unsigned int idx)
38923 +{
38924 +       /*
38925 +        * this branch gets completely eliminated after inlining,
38926 +        * except when someone tries to use fixaddr indices in an
38927 +        * illegal way. (such as mixing up address types or using
38928 +        * out-of-range indices).
38929 +        *
38930 +        * If it doesn't get removed, the linker will complain
38931 +        * loudly with a reasonably clear error message..
38932 +        */
38933 +       if (idx >= __end_of_fixed_addresses)
38934 +               __this_fixmap_does_not_exist();
38935 +
38936 +        return __fix_to_virt(idx);
38937 +}
38938 +
38939 +#endif
38940 diff -Naur -X ../exclude-files orig/include/asm-um/floppy.h um/include/asm-um/floppy.h
38941 --- orig/include/asm-um/floppy.h        1969-12-31 19:00:00.000000000 -0500
38942 +++ um/include/asm-um/floppy.h  2003-10-21 03:26:07.000000000 -0400
38943 @@ -0,0 +1,6 @@
38944 +#ifndef __UM_FLOPPY_H
38945 +#define __UM_FLOPPY_H
38946 +
38947 +#include "asm/arch/floppy.h"
38948 +
38949 +#endif
38950 diff -Naur -X ../exclude-files orig/include/asm-um/hardirq.h um/include/asm-um/hardirq.h
38951 --- orig/include/asm-um/hardirq.h       1969-12-31 19:00:00.000000000 -0500
38952 +++ um/include/asm-um/hardirq.h 2003-12-17 02:16:13.000000000 -0500
38953 @@ -0,0 +1,6 @@
38954 +#ifndef __UM_HARDIRQ_H
38955 +#define __UM_HARDIRQ_H
38956 +
38957 +#include "asm/arch/hardirq.h"
38958 +
38959 +#endif
38960 diff -Naur -X ../exclude-files orig/include/asm-um/hdreg.h um/include/asm-um/hdreg.h
38961 --- orig/include/asm-um/hdreg.h 1969-12-31 19:00:00.000000000 -0500
38962 +++ um/include/asm-um/hdreg.h   2003-10-21 03:26:07.000000000 -0400
38963 @@ -0,0 +1,6 @@
38964 +#ifndef __UM_HDREG_H
38965 +#define __UM_HDREG_H
38966 +
38967 +#include "asm/arch/hdreg.h"
38968 +
38969 +#endif
38970 diff -Naur -X ../exclude-files orig/include/asm-um/highmem.h um/include/asm-um/highmem.h
38971 --- orig/include/asm-um/highmem.h       1969-12-31 19:00:00.000000000 -0500
38972 +++ um/include/asm-um/highmem.h 2003-12-17 02:16:14.000000000 -0500
38973 @@ -0,0 +1,12 @@
38974 +#ifndef __UM_HIGHMEM_H
38975 +#define __UM_HIGHMEM_H
38976 +
38977 +#include "asm/page.h"
38978 +#include "asm/fixmap.h"
38979 +#include "asm/arch/highmem.h"
38980 +
38981 +#undef PKMAP_BASE
38982 +
38983 +#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
38984 +
38985 +#endif
38986 diff -Naur -X ../exclude-files orig/include/asm-um/hw_irq.h um/include/asm-um/hw_irq.h
38987 --- orig/include/asm-um/hw_irq.h        1969-12-31 19:00:00.000000000 -0500
38988 +++ um/include/asm-um/hw_irq.h  2003-12-16 22:26:55.000000000 -0500
38989 @@ -0,0 +1,10 @@
38990 +#ifndef _ASM_UM_HW_IRQ_H
38991 +#define _ASM_UM_HW_IRQ_H
38992 +
38993 +#include "asm/irq.h"
38994 +#include "asm/archparam.h"
38995 +
38996 +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
38997 +{}
38998 +
38999 +#endif
39000 diff -Naur -X ../exclude-files orig/include/asm-um/ide.h um/include/asm-um/ide.h
39001 --- orig/include/asm-um/ide.h   1969-12-31 19:00:00.000000000 -0500
39002 +++ um/include/asm-um/ide.h     2003-12-15 00:29:05.000000000 -0500
39003 @@ -0,0 +1,6 @@
39004 +#ifndef __UM_IDE_H
39005 +#define __UM_IDE_H
39006 +
39007 +#include "asm/arch/ide.h"
39008 +
39009 +#endif
39010 diff -Naur -X ../exclude-files orig/include/asm-um/init.h um/include/asm-um/init.h
39011 --- orig/include/asm-um/init.h  1969-12-31 19:00:00.000000000 -0500
39012 +++ um/include/asm-um/init.h    2003-10-21 03:26:07.000000000 -0400
39013 @@ -0,0 +1,11 @@
39014 +#ifndef _UM_INIT_H
39015 +#define _UM_INIT_H
39016 +
39017 +#ifdef notdef
39018 +#define __init
39019 +#define __initdata
39020 +#define __initfunc(__arginit) __arginit
39021 +#define __cacheline_aligned 
39022 +#endif
39023 +
39024 +#endif
39025 diff -Naur -X ../exclude-files orig/include/asm-um/ioctl.h um/include/asm-um/ioctl.h
39026 --- orig/include/asm-um/ioctl.h 1969-12-31 19:00:00.000000000 -0500
39027 +++ um/include/asm-um/ioctl.h   2003-10-21 03:26:07.000000000 -0400
39028 @@ -0,0 +1,6 @@
39029 +#ifndef __UM_IOCTL_H
39030 +#define __UM_IOCTL_H
39031 +
39032 +#include "asm/arch/ioctl.h"
39033 +
39034 +#endif
39035 diff -Naur -X ../exclude-files orig/include/asm-um/ioctls.h um/include/asm-um/ioctls.h
39036 --- orig/include/asm-um/ioctls.h        1969-12-31 19:00:00.000000000 -0500
39037 +++ um/include/asm-um/ioctls.h  2003-11-07 02:10:43.000000000 -0500
39038 @@ -0,0 +1,6 @@
39039 +#ifndef __UM_IOCTLS_H
39040 +#define __UM_IOCTLS_H
39041 +
39042 +#include "asm/arch/ioctls.h"
39043 +
39044 +#endif
39045 diff -Naur -X ../exclude-files orig/include/asm-um/io.h um/include/asm-um/io.h
39046 --- orig/include/asm-um/io.h    1969-12-31 19:00:00.000000000 -0500
39047 +++ um/include/asm-um/io.h      2003-12-15 00:26:39.000000000 -0500
39048 @@ -0,0 +1,25 @@
39049 +#ifndef __UM_IO_H
39050 +#define __UM_IO_H
39051 +
39052 +#include "asm/page.h"
39053 +
39054 +#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
39055 +
39056 +static inline int inb(unsigned long i) { return(0); }
39057 +static inline void outb(char c, unsigned long i) { }
39058 +
39059 +/*
39060 + * Change virtual addresses to physical addresses and vv.
39061 + * These are pretty trivial
39062 + */
39063 +static inline unsigned long virt_to_phys(volatile void * address)
39064 +{
39065 +       return __pa((void *) address);
39066 +}
39067 +
39068 +static inline void * phys_to_virt(unsigned long address)
39069 +{
39070 +       return __va(address);
39071 +}
39072 +
39073 +#endif
39074 diff -Naur -X ../exclude-files orig/include/asm-um/ipcbuf.h um/include/asm-um/ipcbuf.h
39075 --- orig/include/asm-um/ipcbuf.h        1969-12-31 19:00:00.000000000 -0500
39076 +++ um/include/asm-um/ipcbuf.h  2003-10-21 03:26:07.000000000 -0400
39077 @@ -0,0 +1,6 @@
39078 +#ifndef __UM_IPCBUF_H
39079 +#define __UM_IPCBUF_H
39080 +
39081 +#include "asm/arch/ipcbuf.h"
39082 +
39083 +#endif
39084 diff -Naur -X ../exclude-files orig/include/asm-um/ipc.h um/include/asm-um/ipc.h
39085 --- orig/include/asm-um/ipc.h   1969-12-31 19:00:00.000000000 -0500
39086 +++ um/include/asm-um/ipc.h     2003-10-21 03:26:07.000000000 -0400
39087 @@ -0,0 +1,6 @@
39088 +#ifndef __UM_IPC_H
39089 +#define __UM_IPC_H
39090 +
39091 +#include "asm/arch/ipc.h"
39092 +
39093 +#endif
39094 diff -Naur -X ../exclude-files orig/include/asm-um/irq.h um/include/asm-um/irq.h
39095 --- orig/include/asm-um/irq.h   1969-12-31 19:00:00.000000000 -0500
39096 +++ um/include/asm-um/irq.h     2003-10-21 03:26:07.000000000 -0400
39097 @@ -0,0 +1,22 @@
39098 +#ifndef __UM_IRQ_H
39099 +#define __UM_IRQ_H
39100 +
39101 +#define TIMER_IRQ              0
39102 +#define UMN_IRQ                        1
39103 +#define CONSOLE_IRQ            2
39104 +#define CONSOLE_WRITE_IRQ      3
39105 +#define UBD_IRQ                        4
39106 +#define UM_ETH_IRQ             5
39107 +#define SSL_IRQ                        6
39108 +#define SSL_WRITE_IRQ          7
39109 +#define ACCEPT_IRQ             8
39110 +#define MCONSOLE_IRQ           9
39111 +#define WINCH_IRQ              10
39112 +#define SIGIO_WRITE_IRQ        11
39113 +#define TELNETD_IRQ            12
39114 +#define XTERM_IRQ              13
39115 +
39116 +#define LAST_IRQ XTERM_IRQ
39117 +#define NR_IRQS (LAST_IRQ + 1)
39118 +
39119 +#endif
39120 diff -Naur -X ../exclude-files orig/include/asm-um/keyboard.h um/include/asm-um/keyboard.h
39121 --- orig/include/asm-um/keyboard.h      1969-12-31 19:00:00.000000000 -0500
39122 +++ um/include/asm-um/keyboard.h        2003-10-21 03:26:07.000000000 -0400
39123 @@ -0,0 +1,6 @@
39124 +#ifndef __UM_KEYBOARD_H
39125 +#define __UM_KEYBOARD_H
39126 +
39127 +#include "asm/arch/keyboard.h"
39128 +
39129 +#endif
39130 diff -Naur -X ../exclude-files orig/include/asm-um/kmap_types.h um/include/asm-um/kmap_types.h
39131 --- orig/include/asm-um/kmap_types.h    1969-12-31 19:00:00.000000000 -0500
39132 +++ um/include/asm-um/kmap_types.h      2003-10-21 03:26:07.000000000 -0400
39133 @@ -0,0 +1,11 @@
39134 +/* 
39135 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39136 + * Licensed under the GPL
39137 + */
39138 +
39139 +#ifndef __UM_KMAP_TYPES_H
39140 +#define __UM_KMAP_TYPES_H
39141 +
39142 +#include "asm/arch/kmap_types.h"
39143 +
39144 +#endif
39145 diff -Naur -X ../exclude-files orig/include/asm-um/linux_logo.h um/include/asm-um/linux_logo.h
39146 --- orig/include/asm-um/linux_logo.h    1969-12-31 19:00:00.000000000 -0500
39147 +++ um/include/asm-um/linux_logo.h      2003-10-21 03:26:07.000000000 -0400
39148 @@ -0,0 +1,6 @@
39149 +#ifndef __UM_LINUX_LOGO_H
39150 +#define __UM_LINUX_LOGO_H
39151 +
39152 +#include "asm/arch/linux_logo.h"
39153 +
39154 +#endif
39155 diff -Naur -X ../exclude-files orig/include/asm-um/locks.h um/include/asm-um/locks.h
39156 --- orig/include/asm-um/locks.h 1969-12-31 19:00:00.000000000 -0500
39157 +++ um/include/asm-um/locks.h   2003-10-21 03:26:07.000000000 -0400
39158 @@ -0,0 +1,6 @@
39159 +#ifndef __UM_LOCKS_H
39160 +#define __UM_LOCKS_H
39161 +
39162 +#include "asm/arch/locks.h"
39163 +
39164 +#endif
39165 diff -Naur -X ../exclude-files orig/include/asm-um/mca_dma.h um/include/asm-um/mca_dma.h
39166 --- orig/include/asm-um/mca_dma.h       1969-12-31 19:00:00.000000000 -0500
39167 +++ um/include/asm-um/mca_dma.h 2003-10-21 03:26:07.000000000 -0400
39168 @@ -0,0 +1,6 @@
39169 +#ifndef mca___UM_DMA_H
39170 +#define mca___UM_DMA_H
39171 +
39172 +#include "asm/arch/mca_dma.h"
39173 +
39174 +#endif
39175 diff -Naur -X ../exclude-files orig/include/asm-um/mman.h um/include/asm-um/mman.h
39176 --- orig/include/asm-um/mman.h  1969-12-31 19:00:00.000000000 -0500
39177 +++ um/include/asm-um/mman.h    2003-10-21 03:26:07.000000000 -0400
39178 @@ -0,0 +1,6 @@
39179 +#ifndef __UM_MMAN_H
39180 +#define __UM_MMAN_H
39181 +
39182 +#include "asm/arch/mman.h"
39183 +
39184 +#endif
39185 diff -Naur -X ../exclude-files orig/include/asm-um/mmu_context.h um/include/asm-um/mmu_context.h
39186 --- orig/include/asm-um/mmu_context.h   1969-12-31 19:00:00.000000000 -0500
39187 +++ um/include/asm-um/mmu_context.h     2003-12-17 02:16:13.000000000 -0500
39188 @@ -0,0 +1,72 @@
39189 +/* 
39190 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39191 + * Licensed under the GPL
39192 + */
39193 +
39194 +#ifndef __UM_MMU_CONTEXT_H
39195 +#define __UM_MMU_CONTEXT_H
39196 +
39197 +#include "linux/sched.h"
39198 +#include "choose-mode.h"
39199 +
39200 +#define get_mmu_context(task) do ; while(0)
39201 +#define activate_context(tsk) do ; while(0)
39202 +
39203 +static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
39204 +{
39205 +}
39206 +
39207 +extern void switch_mm_skas(int mm_fd);
39208 +
39209 +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
39210 +                            struct task_struct *tsk, unsigned cpu)
39211 +{
39212 +       if(prev != next){
39213 +               clear_bit(cpu, &prev->cpu_vm_mask);
39214 +               set_bit(cpu, &next->cpu_vm_mask);
39215 +               if(next != &init_mm)
39216 +                       CHOOSE_MODE((void) 0, 
39217 +                                   switch_mm_skas(next->context.skas.mm_fd));
39218 +       }
39219 +}
39220 +
39221 +static inline void enter_lazy_tlb(struct mm_struct *mm, 
39222 +                                 struct task_struct *tsk, unsigned cpu)
39223 +{
39224 +}
39225 +
39226 +extern int init_new_context_skas(struct task_struct *task, 
39227 +                                struct mm_struct *mm);
39228 +
39229 +static inline int init_new_context_tt(struct task_struct *task, 
39230 +                                     struct mm_struct *mm)
39231 +{
39232 +       return(0);
39233 +}
39234 +
39235 +static inline int init_new_context(struct task_struct *task, 
39236 +                                  struct mm_struct *mm)
39237 +{
39238 +       return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas, 
39239 +                               task, mm));
39240 +}
39241 +
39242 +extern void destroy_context_skas(struct mm_struct *mm);
39243 +
39244 +static inline void destroy_context(struct mm_struct *mm)
39245 +{
39246 +       CHOOSE_MODE((void) 0, destroy_context_skas(mm));
39247 +}
39248 +
39249 +#endif
39250 +
39251 +/*
39252 + * Overrides for Emacs so that we follow Linus's tabbing style.
39253 + * Emacs will notice this stuff at the end of the file and automatically
39254 + * adjust the settings for this buffer only.  This must remain at the end
39255 + * of the file.
39256 + * ---------------------------------------------------------------------------
39257 + * Local variables:
39258 + * c-file-style: "linux"
39259 + * End:
39260 + */
39261 diff -Naur -X ../exclude-files orig/include/asm-um/mmu.h um/include/asm-um/mmu.h
39262 --- orig/include/asm-um/mmu.h   1969-12-31 19:00:00.000000000 -0500
39263 +++ um/include/asm-um/mmu.h     2003-10-21 03:26:07.000000000 -0400
39264 @@ -0,0 +1,22 @@
39265 +/* 
39266 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
39267 + * Licensed under the GPL
39268 + */
39269 +
39270 +#ifndef __MMU_H
39271 +#define __MMU_H
39272 +
39273 +#include "um_mmu.h"
39274 +
39275 +#endif
39276 +
39277 +/*
39278 + * Overrides for Emacs so that we follow Linus's tabbing style.
39279 + * Emacs will notice this stuff at the end of the file and automatically
39280 + * adjust the settings for this buffer only.  This must remain at the end
39281 + * of the file.
39282 + * ---------------------------------------------------------------------------
39283 + * Local variables:
39284 + * c-file-style: "linux"
39285 + * End:
39286 + */
39287 diff -Naur -X ../exclude-files orig/include/asm-um/module.h um/include/asm-um/module.h
39288 --- orig/include/asm-um/module.h        1969-12-31 19:00:00.000000000 -0500
39289 +++ um/include/asm-um/module.h  2003-10-21 03:26:07.000000000 -0400
39290 @@ -0,0 +1,6 @@
39291 +#ifndef __UM_MODULE_H
39292 +#define __UM_MODULE_H
39293 +
39294 +#include "asm/arch/module.h"
39295 +
39296 +#endif
39297 diff -Naur -X ../exclude-files orig/include/asm-um/msgbuf.h um/include/asm-um/msgbuf.h
39298 --- orig/include/asm-um/msgbuf.h        1969-12-31 19:00:00.000000000 -0500
39299 +++ um/include/asm-um/msgbuf.h  2003-10-21 03:26:07.000000000 -0400
39300 @@ -0,0 +1,6 @@
39301 +#ifndef __UM_MSGBUF_H
39302 +#define __UM_MSGBUF_H
39303 +
39304 +#include "asm/arch/msgbuf.h"
39305 +
39306 +#endif
39307 diff -Naur -X ../exclude-files orig/include/asm-um/mtrr.h um/include/asm-um/mtrr.h
39308 --- orig/include/asm-um/mtrr.h  1969-12-31 19:00:00.000000000 -0500
39309 +++ um/include/asm-um/mtrr.h    2003-12-17 10:48:33.000000000 -0500
39310 @@ -0,0 +1,6 @@
39311 +#ifndef __UM_MTRR_H
39312 +#define __UM_MTRR_H
39313 +
39314 +#include "asm/arch/mtrr.h"
39315 +
39316 +#endif
39317 diff -Naur -X ../exclude-files orig/include/asm-um/namei.h um/include/asm-um/namei.h
39318 --- orig/include/asm-um/namei.h 1969-12-31 19:00:00.000000000 -0500
39319 +++ um/include/asm-um/namei.h   2003-10-21 03:26:07.000000000 -0400
39320 @@ -0,0 +1,6 @@
39321 +#ifndef __UM_NAMEI_H
39322 +#define __UM_NAMEI_H
39323 +
39324 +#include "asm/arch/namei.h"
39325 +
39326 +#endif
39327 diff -Naur -X ../exclude-files orig/include/asm-um/page.h um/include/asm-um/page.h
39328 --- orig/include/asm-um/page.h  1969-12-31 19:00:00.000000000 -0500
39329 +++ um/include/asm-um/page.h    2003-12-15 00:26:37.000000000 -0500
39330 @@ -0,0 +1,68 @@
39331 +/* 
39332 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
39333 + * Licensed under the GPL
39334 + */
39335 +
39336 +#ifndef __UM_PAGE_H
39337 +#define __UM_PAGE_H
39338 +
39339 +struct page;
39340 +
39341 +#include "asm/arch/page.h"
39342 +
39343 +#undef BUG
39344 +#undef PAGE_BUG
39345 +#undef __pa
39346 +#undef __va
39347 +#undef virt_to_page
39348 +#undef VALID_PAGE
39349 +#undef PAGE_OFFSET
39350 +#undef KERNELBASE
39351 +
39352 +extern unsigned long uml_physmem;
39353 +
39354 +#define PAGE_OFFSET (uml_physmem)
39355 +#define KERNELBASE PAGE_OFFSET
39356 +
39357 +#ifndef __ASSEMBLY__
39358 +
39359 +extern void stop(void);
39360 +
39361 +#define BUG() do { \
39362 +       panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
39363 +} while (0)
39364 +
39365 +#define PAGE_BUG(page) do { \
39366 +       BUG(); \
39367 +} while (0)
39368 +
39369 +#endif /* __ASSEMBLY__ */
39370 +
39371 +#define __va_space (8*1024*1024)
39372 +
39373 +extern unsigned long to_phys(void *virt);
39374 +extern void *to_virt(unsigned long phys);
39375 +
39376 +#define __pa(virt) to_phys((void *) virt)
39377 +#define __va(phys) to_virt((unsigned long) phys)
39378 +
39379 +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
39380 +
39381 +extern struct page *arch_validate(struct page *page, int mask, int order);
39382 +#define HAVE_ARCH_VALIDATE
39383 +
39384 +extern void arch_free_page(struct page *page, int order);
39385 +#define HAVE_ARCH_FREE_PAGE
39386 +
39387 +#endif
39388 +
39389 +/*
39390 + * Overrides for Emacs so that we follow Linus's tabbing style.
39391 + * Emacs will notice this stuff at the end of the file and automatically
39392 + * adjust the settings for this buffer only.  This must remain at the end
39393 + * of the file.
39394 + * ---------------------------------------------------------------------------
39395 + * Local variables:
39396 + * c-file-style: "linux"
39397 + * End:
39398 + */
39399 diff -Naur -X ../exclude-files orig/include/asm-um/page_offset.h um/include/asm-um/page_offset.h
39400 --- orig/include/asm-um/page_offset.h   1969-12-31 19:00:00.000000000 -0500
39401 +++ um/include/asm-um/page_offset.h     2003-10-21 03:26:07.000000000 -0400
39402 @@ -0,0 +1 @@
39403 +#define PAGE_OFFSET_RAW (uml_physmem)
39404 diff -Naur -X ../exclude-files orig/include/asm-um/param.h um/include/asm-um/param.h
39405 --- orig/include/asm-um/param.h 1969-12-31 19:00:00.000000000 -0500
39406 +++ um/include/asm-um/param.h   2003-10-21 03:26:07.000000000 -0400
39407 @@ -0,0 +1,24 @@
39408 +#ifndef _UM_PARAM_H
39409 +#define _UM_PARAM_H
39410 +
39411 +#ifndef HZ
39412 +#define HZ 52
39413 +#endif
39414 +
39415 +#define EXEC_PAGESIZE   4096
39416 +
39417 +#ifndef NGROUPS
39418 +#define NGROUPS         32
39419 +#endif
39420 +
39421 +#ifndef NOGROUP
39422 +#define NOGROUP         (-1)
39423 +#endif
39424 +
39425 +#define MAXHOSTNAMELEN  64      /* max length of hostname */
39426 +
39427 +#ifdef __KERNEL__
39428 +# define CLOCKS_PER_SEC 100    /* frequency at which times() counts */
39429 +#endif
39430 +
39431 +#endif
39432 diff -Naur -X ../exclude-files orig/include/asm-um/pci.h um/include/asm-um/pci.h
39433 --- orig/include/asm-um/pci.h   1969-12-31 19:00:00.000000000 -0500
39434 +++ um/include/asm-um/pci.h     2003-10-21 03:26:07.000000000 -0400
39435 @@ -0,0 +1,6 @@
39436 +#ifndef __UM_PCI_H
39437 +#define __UM_PCI_H
39438 +
39439 +#define PCI_DMA_BUS_IS_PHYS     (1)
39440 +
39441 +#endif
39442 diff -Naur -X ../exclude-files orig/include/asm-um/pgalloc.h um/include/asm-um/pgalloc.h
39443 --- orig/include/asm-um/pgalloc.h       1969-12-31 19:00:00.000000000 -0500
39444 +++ um/include/asm-um/pgalloc.h 2003-12-17 02:16:14.000000000 -0500
39445 @@ -0,0 +1,164 @@
39446 +/* 
39447 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
39448 + * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
39449 + * Licensed under the GPL
39450 + */
39451 +
39452 +#ifndef __UM_PGALLOC_H
39453 +#define __UM_PGALLOC_H
39454 +
39455 +#include "linux/config.h"
39456 +#include "linux/mm.h"
39457 +#include "asm/fixmap.h"
39458 +#include "choose-mode.h"
39459 +
39460 +#define pgd_quicklist (current_cpu_data.pgd_quick)
39461 +#define pmd_quicklist (current_cpu_data.pmd_quick)
39462 +#define pte_quicklist (current_cpu_data.pte_quick)
39463 +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
39464 +
39465 +#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
39466 +
39467 +/*
39468 + * Allocate and free page tables.
39469 + */
39470 +
39471 +static inline pgd_t *get_pgd_slow_tt(void)
39472 +{
39473 +       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
39474 +
39475 +       if (pgd) {
39476 +               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
39477 +               memcpy(pgd + USER_PTRS_PER_PGD, 
39478 +                      swapper_pg_dir + USER_PTRS_PER_PGD, 
39479 +                      (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
39480 +       }
39481 +       return pgd;
39482 +}
39483 +
39484 +static inline pgd_t *get_pgd_slow_skas(void)
39485 +{
39486 +       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
39487 +
39488 +       if (pgd)
39489 +               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
39490 +       return pgd;
39491 +}
39492 +
39493 +static inline pgd_t *get_pgd_slow(void)
39494 +{
39495 +       return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas()));
39496 +}
39497 +
39498 +static inline pgd_t *get_pgd_fast(void)
39499 +{
39500 +       unsigned long *ret;
39501 +
39502 +       ret = pgd_quicklist;
39503 +       if (ret != NULL) {
39504 +               pgd_quicklist = (unsigned long *)(*ret);
39505 +               ret[0] = 0;
39506 +               pgtable_cache_size--;
39507 +       } else
39508 +               ret = (unsigned long *)get_pgd_slow();
39509 +       return (pgd_t *)ret;
39510 +}
39511 +
39512 +static inline void free_pgd_fast(pgd_t *pgd)
39513 +{
39514 +       *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
39515 +       pgd_quicklist = (unsigned long *) pgd;
39516 +       pgtable_cache_size++;
39517 +}
39518 +
39519 +static inline void free_pgd_slow(pgd_t *pgd)
39520 +{
39521 +       free_page((unsigned long)pgd);
39522 +}
39523 +
39524 +static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
39525 +{
39526 +       pte_t *pte;
39527 +
39528 +       pte = (pte_t *) __get_free_page(GFP_KERNEL);
39529 +       if (pte)
39530 +               clear_page(pte);
39531 +       return pte;
39532 +}
39533 +
39534 +static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
39535 +{
39536 +       unsigned long *ret;
39537 +
39538 +       ret = (unsigned long *)pte_quicklist;
39539 +       if (ret != NULL) {
39540 +               pte_quicklist = (unsigned long *)(*ret);
39541 +               ret[0] = ret[1];
39542 +               pgtable_cache_size--;
39543 +       }
39544 +       return (pte_t *)ret;
39545 +}
39546 +
39547 +static inline void pte_free_fast(pte_t *pte)
39548 +{
39549 +       *(unsigned long *)pte = (unsigned long) pte_quicklist;
39550 +       pte_quicklist = (unsigned long *) pte;
39551 +       pgtable_cache_size++;
39552 +}
39553 +
39554 +static inline void pte_free_slow(pte_t *pte)
39555 +{
39556 +       free_page((unsigned long)pte);
39557 +}
39558 +
39559 +#define pte_free(pte)           pte_free_fast(pte)
39560 +#define pgd_free(pgd)           free_pgd_slow(pgd)
39561 +#define pgd_alloc(mm)           get_pgd_fast()
39562 +
39563 +/*
39564 + * allocating and freeing a pmd is trivial: the 1-entry pmd is
39565 + * inside the pgd, so has no extra memory associated with it.
39566 + */
39567 +
39568 +#define pmd_alloc_one_fast(mm, addr)   ({ BUG(); ((pmd_t *)1); })
39569 +#define pmd_alloc_one(mm, addr)                ({ BUG(); ((pmd_t *)2); })
39570 +#define pmd_free_slow(x)               do { } while (0)
39571 +#define pmd_free_fast(x)               do { } while (0)
39572 +#define pmd_free(x)                    do { } while (0)
39573 +#define pgd_populate(mm, pmd, pte)     BUG()
39574 +
39575 +/*
39576 + * TLB flushing:
39577 + *
39578 + *  - flush_tlb() flushes the current mm struct TLBs
39579 + *  - flush_tlb_all() flushes all processes TLBs
39580 + *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
39581 + *  - flush_tlb_page(vma, vmaddr) flushes one page
39582 + *  - flush_tlb_kernel_vm() flushes the kernel vm area
39583 + *  - flush_tlb_range(mm, start, end) flushes a range of pages
39584 + *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
39585 + */
39586 +
39587 +extern void flush_tlb_all(void);
39588 +extern void flush_tlb_mm(struct mm_struct *mm);
39589 +extern void flush_tlb_range(struct mm_struct *mm, unsigned long start, 
39590 +                           unsigned long end);
39591 +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
39592 +extern void flush_tlb_kernel_vm(void);
39593 +
39594 +static inline void flush_tlb_pgtables(struct mm_struct *mm,
39595 +                                     unsigned long start, unsigned long end)
39596 +{
39597 +}
39598 +
39599 +#endif
39600 +/*
39601 + * Overrides for Emacs so that we follow Linus's tabbing style.
39602 + * Emacs will notice this stuff at the end of the file and automatically
39603 + * adjust the settings for this buffer only.  This must remain at the end
39604 + * of the file.
39605 + * ---------------------------------------------------------------------------
39606 + * Local variables:
39607 + * c-file-style: "linux"
39608 + * End:
39609 + */
39610 diff -Naur -X ../exclude-files orig/include/asm-um/pgtable.h um/include/asm-um/pgtable.h
39611 --- orig/include/asm-um/pgtable.h       1969-12-31 19:00:00.000000000 -0500
39612 +++ um/include/asm-um/pgtable.h 2003-12-17 02:16:13.000000000 -0500
39613 @@ -0,0 +1,413 @@
39614 +/* 
39615 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
39616 + * Derived from include/asm-i386/pgtable.h
39617 + * Licensed under the GPL
39618 + */
39619 +
39620 +#ifndef __UM_PGTABLE_H
39621 +#define __UM_PGTABLE_H
39622 +
39623 +#include "linux/sched.h"
39624 +#include "asm/processor.h"
39625 +#include "asm/page.h"
39626 +
39627 +extern pgd_t swapper_pg_dir[1024];
39628 +
39629 +#define flush_cache_all() do ; while (0)
39630 +#define flush_cache_mm(mm) do ; while (0)
39631 +#define flush_cache_range(vma, start, end) do ; while (0)
39632 +#define flush_cache_page(vma, vmaddr) do ; while (0)
39633 +#define flush_page_to_ram(page) do ; while (0)
39634 +#define flush_dcache_page(page)        do ; while (0)
39635 +#define flush_icache_range(from, to) do ; while (0)
39636 +#define flush_icache_page(vma,pg) do ; while (0)
39637 +#define flush_icache_user_range(vma,pg,adr,len)        do ; while (0)
39638 +
39639 +extern void __flush_tlb_one(unsigned long addr);
39640 +
39641 +extern void pte_free(pte_t *pte);
39642 +
39643 +extern void pgd_free(pgd_t *pgd);
39644 +
39645 +extern int do_check_pgt_cache(int, int);
39646 +
39647 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
39648 +                            pte_t *pte_out);
39649 +
39650 +/* zero page used for uninitialized stuff */
39651 +extern unsigned long *empty_zero_page;
39652 +
39653 +#define pgtable_cache_init() do ; while (0)
39654 +
39655 +/* PMD_SHIFT determines the size of the area a second-level page table can map */
39656 +#define PMD_SHIFT      22
39657 +#define PMD_SIZE       (1UL << PMD_SHIFT)
39658 +#define PMD_MASK       (~(PMD_SIZE-1))
39659 +
39660 +/* PGDIR_SHIFT determines what a third-level page table entry can map */
39661 +#define PGDIR_SHIFT    22
39662 +#define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
39663 +#define PGDIR_MASK     (~(PGDIR_SIZE-1))
39664 +
39665 +/*
39666 + * entries per page directory level: the i386 is two-level, so
39667 + * we don't really have any PMD directory physically.
39668 + */
39669 +#define PTRS_PER_PTE   1024
39670 +#define PTRS_PER_PMD   1
39671 +#define PTRS_PER_PGD   1024
39672 +#define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
39673 +#define FIRST_USER_PGD_NR       0
39674 +
39675 +#define pte_ERROR(e) \
39676 +        printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
39677 +#define pmd_ERROR(e) \
39678 +        printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
39679 +#define pgd_ERROR(e) \
39680 +        printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
39681 +
39682 +/*
39683 + * pgd entries used up by user/kernel:
39684 + */
39685 +
39686 +#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT)
39687 +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
39688 +
39689 +#ifndef __ASSEMBLY__
39690 +/* Just any arbitrary offset to the start of the vmalloc VM area: the
39691 + * current 8MB value just means that there will be a 8MB "hole" after the
39692 + * physical memory until the kernel virtual memory starts.  That means that
39693 + * any out-of-bounds memory accesses will hopefully be caught.
39694 + * The vmalloc() routines leaves a hole of 4kB between each vmalloced
39695 + * area for the same reason. ;)
39696 + */
39697 +
39698 +extern unsigned long end_iomem;
39699 +
39700 +#define VMALLOC_OFFSET (__va_space)
39701 +#define VMALLOC_START  ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
39702 +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
39703 +
39704 +#if CONFIG_HIGHMEM
39705 +# define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
39706 +#else
39707 +# define VMALLOC_END   (FIXADDR_START-2*PAGE_SIZE)
39708 +#endif
39709 +
39710 +#define _PAGE_PRESENT  0x001
39711 +#define _PAGE_NEWPAGE  0x002
39712 +#define _PAGE_PROTNONE 0x004   /* If not present */
39713 +#define _PAGE_RW       0x008
39714 +#define _PAGE_USER     0x010
39715 +#define _PAGE_ACCESSED 0x020
39716 +#define _PAGE_DIRTY    0x040
39717 +#define _PAGE_NEWPROT   0x080
39718 +
39719 +#define REGION_MASK    0xf0000000
39720 +#define REGION_SHIFT   28
39721 +
39722 +#define _PAGE_TABLE    (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
39723 +#define _KERNPG_TABLE  (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
39724 +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
39725 +
39726 +#define PAGE_NONE      __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
39727 +#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
39728 +#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
39729 +#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
39730 +#define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
39731 +#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
39732 +
39733 +/*
39734 + * The i386 can't do page protection for execute, and considers that the same are read.
39735 + * Also, write permissions imply read permissions. This is the closest we can get..
39736 + */
39737 +#define __P000 PAGE_NONE
39738 +#define __P001 PAGE_READONLY
39739 +#define __P010 PAGE_COPY
39740 +#define __P011 PAGE_COPY
39741 +#define __P100 PAGE_READONLY
39742 +#define __P101 PAGE_READONLY
39743 +#define __P110 PAGE_COPY
39744 +#define __P111 PAGE_COPY
39745 +
39746 +#define __S000 PAGE_NONE
39747 +#define __S001 PAGE_READONLY
39748 +#define __S010 PAGE_SHARED
39749 +#define __S011 PAGE_SHARED
39750 +#define __S100 PAGE_READONLY
39751 +#define __S101 PAGE_READONLY
39752 +#define __S110 PAGE_SHARED
39753 +#define __S111 PAGE_SHARED
39754 +
39755 +/*
39756 + * Define this if things work differently on an i386 and an i486:
39757 + * it will (on an i486) warn about kernel memory accesses that are
39758 + * done without a 'verify_area(VERIFY_WRITE,..)'
39759 + */
39760 +#undef TEST_VERIFY_AREA
39761 +
39762 +/* page table for 0-4MB for everybody */
39763 +extern unsigned long pg0[1024];
39764 +
39765 +/*
39766 + * BAD_PAGETABLE is used when we need a bogus page-table, while
39767 + * BAD_PAGE is used for a bogus page.
39768 + *
39769 + * ZERO_PAGE is a global shared page that is always zero: used
39770 + * for zero-mapped memory areas etc..
39771 + */
39772 +extern pte_t __bad_page(void);
39773 +extern pte_t * __bad_pagetable(void);
39774 +
39775 +#define BAD_PAGETABLE __bad_pagetable()
39776 +#define BAD_PAGE __bad_page()
39777 +
39778 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
39779 +
39780 +/* number of bits that fit into a memory pointer */
39781 +#define BITS_PER_PTR                   (8*sizeof(unsigned long))
39782 +
39783 +/* to align the pointer to a pointer address */
39784 +#define PTR_MASK                       (~(sizeof(void*)-1))
39785 +
39786 +/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
39787 +/* 64-bit machines, beware!  SRB. */
39788 +#define SIZEOF_PTR_LOG2                        2
39789 +
39790 +/* to find an entry in a page-table */
39791 +#define PAGE_PTR(address) \
39792 +((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
39793 +
39794 +#define pte_none(x)    !(pte_val(x) & ~_PAGE_NEWPAGE)
39795 +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
39796 +
39797 +#define pte_clear(xp)  do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
39798 +
39799 +#define pmd_none(x)    (!(pmd_val(x) & ~_PAGE_NEWPAGE))
39800 +#define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
39801 +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
39802 +#define pmd_clear(xp)  do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
39803 +
39804 +#define pmd_newpage(x)  (pmd_val(x) & _PAGE_NEWPAGE)
39805 +#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
39806 +
39807 +/*
39808 + * The "pgd_xxx()" functions here are trivial for a folded two-level
39809 + * setup: the pgd is never bad, and a pmd always exists (as it's folded
39810 + * into the pgd entry)
39811 + */
39812 +static inline int pgd_none(pgd_t pgd)          { return 0; }
39813 +static inline int pgd_bad(pgd_t pgd)           { return 0; }
39814 +static inline int pgd_present(pgd_t pgd)       { return 1; }
39815 +static inline void pgd_clear(pgd_t * pgdp)     { }
39816 +
39817 +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
39818 +
39819 +#define pte_page(pte) virt_to_page(__va(pte_val(pte)))
39820 +#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
39821 +
39822 +extern struct page *phys_to_page(const unsigned long phys);
39823 +extern struct page *__virt_to_page(const unsigned long virt);
39824 +#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
39825 +
39826 +static inline pte_t pte_mknewprot(pte_t pte)
39827 +{
39828 +       pte_val(pte) |= _PAGE_NEWPROT;
39829 +       return(pte);
39830 +}
39831 +
39832 +static inline pte_t pte_mknewpage(pte_t pte)
39833 +{
39834 +       pte_val(pte) |= _PAGE_NEWPAGE;
39835 +       return(pte);
39836 +}
39837 +
39838 +static inline void set_pte(pte_t *pteptr, pte_t pteval)
39839 +{
39840 +       /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
39841 +        * fix_range knows to unmap it.  _PAGE_NEWPROT is specific to
39842 +        * mapped pages.
39843 +        */
39844 +       *pteptr = pte_mknewpage(pteval);
39845 +       if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
39846 +}
39847 +
39848 +/*
39849 + * (pmds are folded into pgds so this doesnt get actually called,
39850 + * but the define is needed for a generic inline function.)
39851 + */
39852 +#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
39853 +#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
39854 +
39855 +/*
39856 + * The following only work if pte_present() is true.
39857 + * Undefined behaviour if not..
39858 + */
39859 +static inline int pte_read(pte_t pte)
39860 +{ 
39861 +       return((pte_val(pte) & _PAGE_USER) && 
39862 +              !(pte_val(pte) & _PAGE_PROTNONE));
39863 +}
39864 +
39865 +static inline int pte_exec(pte_t pte){
39866 +       return((pte_val(pte) & _PAGE_USER) &&
39867 +              !(pte_val(pte) & _PAGE_PROTNONE));
39868 +}
39869 +
39870 +static inline int pte_write(pte_t pte)
39871 +{
39872 +       return((pte_val(pte) & _PAGE_RW) &&
39873 +              !(pte_val(pte) & _PAGE_PROTNONE));
39874 +}
39875 +
39876 +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
39877 +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
39878 +static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
39879 +static inline int pte_newprot(pte_t pte)
39880 +{ 
39881 +       return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT)); 
39882 +}
39883 +
39884 +static inline pte_t pte_rdprotect(pte_t pte)
39885 +{ 
39886 +       pte_val(pte) &= ~_PAGE_USER; 
39887 +       return(pte_mknewprot(pte));
39888 +}
39889 +
39890 +static inline pte_t pte_exprotect(pte_t pte)
39891 +{ 
39892 +       pte_val(pte) &= ~_PAGE_USER;
39893 +       return(pte_mknewprot(pte));
39894 +}
39895 +
39896 +static inline pte_t pte_mkclean(pte_t pte)
39897 +{
39898 +       pte_val(pte) &= ~_PAGE_DIRTY; 
39899 +       return(pte);
39900 +}
39901 +
39902 +static inline pte_t pte_mkold(pte_t pte)       
39903 +{ 
39904 +       pte_val(pte) &= ~_PAGE_ACCESSED; 
39905 +       return(pte);
39906 +}
39907 +
39908 +static inline pte_t pte_wrprotect(pte_t pte)
39909 +{ 
39910 +       pte_val(pte) &= ~_PAGE_RW; 
39911 +       return(pte_mknewprot(pte)); 
39912 +}
39913 +
39914 +static inline pte_t pte_mkread(pte_t pte)
39915 +{ 
39916 +       pte_val(pte) |= _PAGE_USER; 
39917 +       return(pte_mknewprot(pte)); 
39918 +}
39919 +
39920 +static inline pte_t pte_mkexec(pte_t pte)
39921 +{ 
39922 +       pte_val(pte) |= _PAGE_USER; 
39923 +       return(pte_mknewprot(pte)); 
39924 +}
39925 +
39926 +static inline pte_t pte_mkdirty(pte_t pte)
39927 +{ 
39928 +       pte_val(pte) |= _PAGE_DIRTY; 
39929 +       return(pte);
39930 +}
39931 +
39932 +static inline pte_t pte_mkyoung(pte_t pte)
39933 +{
39934 +       pte_val(pte) |= _PAGE_ACCESSED; 
39935 +       return(pte);
39936 +}
39937 +
39938 +static inline pte_t pte_mkwrite(pte_t pte)     
39939 +{
39940 +       pte_val(pte) |= _PAGE_RW; 
39941 +       return(pte_mknewprot(pte)); 
39942 +}
39943 +
39944 +static inline pte_t pte_mkuptodate(pte_t pte)  
39945 +{
39946 +       pte_val(pte) &= ~_PAGE_NEWPAGE;
39947 +       if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT;
39948 +       return(pte); 
39949 +}
39950 +
39951 +extern unsigned long page_to_phys(struct page *page);
39952 +
39953 +/*
39954 + * Conversion functions: convert a page and protection to a page entry,
39955 + * and a page entry and page directory to the page they refer to.
39956 + */
39957 +
39958 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
39959 +
39960 +/* This takes a physical page address that is used by the remapping 
39961 + * functions 
39962 + */
39963 +#define mk_pte_phys(phys, pgprot) \
39964 +       (pte_mknewpage(mk_pte(virt_to_page(__va(phys)), pgprot)))
39965 +
39966 +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
39967 +{
39968 +       pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
39969 +       if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte));
39970 +       return pte; 
39971 +}
39972 +
39973 +/* to find an entry in a page-table-directory. */
39974 +#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
39975 +#define __pgd_offset(address) pgd_index(address)
39976 +
39977 +/* to find an entry in a page-table-directory */
39978 +#define pgd_offset(mm, address) \
39979 +((mm)->pgd + ((address) >> PGDIR_SHIFT))
39980 +
39981 +/* to find an entry in a kernel page-table-directory */
39982 +#define pgd_offset_k(address) pgd_offset(&init_mm, address)
39983 +
39984 +#define __pmd_offset(address) \
39985 +               (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
39986 +
39987 +/* Find an entry in the second-level page table.. */
39988 +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
39989 +{
39990 +       return (pmd_t *) dir;
39991 +}
39992 +
39993 +/* Find an entry in the third-level page table.. */ 
39994 +#define pte_offset(pmd, address) \
39995 +       ((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2))))
39996 +
39997 +#define update_mmu_cache(vma,address,pte) do ; while (0)
39998 +
39999 +/* Encode and de-code a swap entry */
40000 +#define SWP_TYPE(x)                    (((x).val >> 3) & 0x7f)
40001 +#define SWP_OFFSET(x)                  ((x).val >> 10)
40002 +
40003 +#define SWP_ENTRY(type, offset) \
40004 +       ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
40005 +#define pte_to_swp_entry(pte) \
40006 +       ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
40007 +#define swp_entry_to_pte(x)            ((pte_t) { (x).val })
40008 +
40009 +#define PageSkip(x) (0)
40010 +#define kern_addr_valid(addr) (1)
40011 +
40012 +#include <asm-generic/pgtable.h>
40013 +
40014 +#endif
40015 +
40016 +#endif
40017 +/*
40018 + * Overrides for Emacs so that we follow Linus's tabbing style.
40019 + * Emacs will notice this stuff at the end of the file and automatically
40020 + * adjust the settings for this buffer only.  This must remain at the end
40021 + * of the file.
40022 + * ---------------------------------------------------------------------------
40023 + * Local variables:
40024 + * c-file-style: "linux"
40025 + * End:
40026 + */
40027 diff -Naur -X ../exclude-files orig/include/asm-um/poll.h um/include/asm-um/poll.h
40028 --- orig/include/asm-um/poll.h  1969-12-31 19:00:00.000000000 -0500
40029 +++ um/include/asm-um/poll.h    2003-10-21 03:26:07.000000000 -0400
40030 @@ -0,0 +1,6 @@
40031 +#ifndef __UM_POLL_H
40032 +#define __UM_POLL_H
40033 +
40034 +#include "asm/arch/poll.h"
40035 +
40036 +#endif
40037 diff -Naur -X ../exclude-files orig/include/asm-um/posix_types.h um/include/asm-um/posix_types.h
40038 --- orig/include/asm-um/posix_types.h   1969-12-31 19:00:00.000000000 -0500
40039 +++ um/include/asm-um/posix_types.h     2003-10-21 03:26:07.000000000 -0400
40040 @@ -0,0 +1,6 @@
40041 +#ifndef __UM_POSIX_TYPES_H
40042 +#define __UM_POSIX_TYPES_H
40043 +
40044 +#include "asm/arch/posix_types.h"
40045 +
40046 +#endif
40047 diff -Naur -X ../exclude-files orig/include/asm-um/processor-generic.h um/include/asm-um/processor-generic.h
40048 --- orig/include/asm-um/processor-generic.h     1969-12-31 19:00:00.000000000 -0500
40049 +++ um/include/asm-um/processor-generic.h       2003-12-17 02:16:13.000000000 -0500
40050 @@ -0,0 +1,177 @@
40051 +/* 
40052 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40053 + * Licensed under the GPL
40054 + */
40055 +
40056 +#ifndef __UM_PROCESSOR_GENERIC_H
40057 +#define __UM_PROCESSOR_GENERIC_H
40058 +
40059 +struct pt_regs;
40060 +
40061 +struct task_struct;
40062 +
40063 +#include "linux/config.h"
40064 +#include "linux/signal.h"
40065 +#include "asm/ptrace.h"
40066 +#include "asm/siginfo.h"
40067 +#include "choose-mode.h"
40068 +
40069 +struct mm_struct;
40070 +
40071 +#define current_text_addr() ((void *) 0)
40072 +
40073 +#define cpu_relax()    do ; while (0)
40074 +
40075 +struct thread_struct {
40076 +       int forking;
40077 +       unsigned long kernel_stack;
40078 +       int nsyscalls;
40079 +       struct pt_regs regs;
40080 +       unsigned long cr2;
40081 +       int err;
40082 +       unsigned long trap_no;
40083 +       void *fault_addr;
40084 +       void *fault_catcher;
40085 +       struct task_struct *prev_sched;
40086 +       unsigned long temp_stack;
40087 +       void *exec_buf;
40088 +       struct arch_thread arch;
40089 +       union {
40090 +#ifdef CONFIG_MODE_TT
40091 +               struct {
40092 +                       int extern_pid;
40093 +                       int tracing;
40094 +                       int switch_pipe[2];
40095 +                       int singlestep_syscall;
40096 +                       int vm_seq;
40097 +               } tt;
40098 +#endif
40099 +#ifdef CONFIG_MODE_SKAS
40100 +               struct {
40101 +                       void *switch_buf;
40102 +                       void *fork_buf;
40103 +                       int mm_count;
40104 +               } skas;
40105 +#endif
40106 +       } mode;
40107 +       struct {
40108 +               int op;
40109 +               union {
40110 +                       struct {
40111 +                               int pid;
40112 +                       } fork, exec;
40113 +                       struct {
40114 +                               int (*proc)(void *);
40115 +                               void *arg;
40116 +                       } thread;
40117 +                       struct {
40118 +                               void (*proc)(void *);
40119 +                               void *arg;
40120 +                       } cb;
40121 +               } u;
40122 +       } request;
40123 +};
40124 +
40125 +#define INIT_THREAD \
40126 +{ \
40127 +       .forking                = 0, \
40128 +       .kernel_stack           = 0, \
40129 +       .nsyscalls              = 0, \
40130 +        .regs                  = EMPTY_REGS, \
40131 +       .cr2                    = 0, \
40132 +       .err                    = 0, \
40133 +       .fault_addr             = NULL, \
40134 +       .prev_sched             = NULL, \
40135 +       .temp_stack             = 0, \
40136 +       .exec_buf               = NULL, \
40137 +       .arch                   = INIT_ARCH_THREAD, \
40138 +       .request                = { 0 } \
40139 +}
40140 +
40141 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
40142 +
40143 +typedef struct {
40144 +       unsigned long seg;
40145 +} mm_segment_t;
40146 +
40147 +extern struct task_struct *alloc_task_struct(void);
40148 +extern void free_task_struct(struct task_struct *task);
40149 +
40150 +#define get_task_struct(tsk)      atomic_inc(&virt_to_page(tsk)->count)
40151 +
40152 +extern void release_thread(struct task_struct *);
40153 +extern int arch_kernel_thread(int (*fn)(void *), void * arg, 
40154 +                             unsigned long flags);
40155 +extern void dump_thread(struct pt_regs *regs, struct user *u);
40156 +
40157 +extern unsigned long thread_saved_pc(struct thread_struct *t);
40158 +
40159 +static inline void mm_copy_segments(struct mm_struct *from_mm, 
40160 +                                   struct mm_struct *new_mm)
40161 +{
40162 +}
40163 +
40164 +static inline void copy_segments(struct task_struct *p, 
40165 +                                struct mm_struct *new_mm)
40166 +{
40167 +}
40168 +
40169 +static inline void release_segments(struct mm_struct *mm)
40170 +{
40171 +}
40172 +
40173 +#define init_task      (init_task_union.task)
40174 +#define init_stack     (init_task_union.stack)
40175 +
40176 +/*
40177 + * User space process size: 3GB (default).
40178 + */
40179 +extern unsigned long task_size;
40180 +
40181 +#define TASK_SIZE      (task_size)
40182 +
40183 +/* This decides where the kernel will search for a free chunk of vm
40184 + * space during mmap's.
40185 + */
40186 +#define TASK_UNMAPPED_BASE     (0x40000000)
40187 +
40188 +extern void start_thread(struct pt_regs *regs, unsigned long entry, 
40189 +                        unsigned long stack);
40190 +
40191 +struct cpuinfo_um {
40192 +       unsigned long loops_per_jiffy;
40193 +       unsigned long *pgd_quick;
40194 +       unsigned long *pmd_quick;
40195 +       unsigned long *pte_quick;
40196 +       unsigned long pgtable_cache_sz;  
40197 +       int ipi_pipe[2];
40198 +};
40199 +
40200 +extern struct cpuinfo_um boot_cpu_data;
40201 +
40202 +#define my_cpu_data            cpu_data[smp_processor_id()]
40203 +
40204 +#ifdef CONFIG_SMP
40205 +extern struct cpuinfo_um cpu_data[];
40206 +#define current_cpu_data cpu_data[smp_processor_id()]
40207 +#else
40208 +#define cpu_data (&boot_cpu_data)
40209 +#define current_cpu_data boot_cpu_data
40210 +#endif
40211 +
40212 +#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
40213 +#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
40214 +#define get_wchan(p) (0)
40215 +
40216 +#endif
40217 +
40218 +/*
40219 + * Overrides for Emacs so that we follow Linus's tabbing style.
40220 + * Emacs will notice this stuff at the end of the file and automatically
40221 + * adjust the settings for this buffer only.  This must remain at the end
40222 + * of the file.
40223 + * ---------------------------------------------------------------------------
40224 + * Local variables:
40225 + * c-file-style: "linux"
40226 + * End:
40227 + */
40228 diff -Naur -X ../exclude-files orig/include/asm-um/processor-i386.h um/include/asm-um/processor-i386.h
40229 --- orig/include/asm-um/processor-i386.h        1969-12-31 19:00:00.000000000 -0500
40230 +++ um/include/asm-um/processor-i386.h  2003-12-17 02:16:13.000000000 -0500
40231 @@ -0,0 +1,35 @@
40232 +/* 
40233 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40234 + * Licensed under the GPL
40235 + */
40236 +
40237 +#ifndef __UM_PROCESSOR_I386_H
40238 +#define __UM_PROCESSOR_I386_H
40239 +
40240 +extern int cpu_has_xmm;
40241 +extern int cpu_has_cmov;
40242 +
40243 +struct arch_thread {
40244 +       unsigned long debugregs[8];
40245 +       int debugregs_seq;
40246 +};
40247 +
40248 +#define INIT_ARCH_THREAD { .debugregs                  = { [ 0 ... 7 ] = 0 }, \
40249 +                           .debugregs_seq      = 0 }
40250 +
40251 +#include "asm/arch/user.h"
40252 +
40253 +#include "asm/processor-generic.h"
40254 +
40255 +#endif
40256 +
40257 +/*
40258 + * Overrides for Emacs so that we follow Linus's tabbing style.
40259 + * Emacs will notice this stuff at the end of the file and automatically
40260 + * adjust the settings for this buffer only.  This must remain at the end
40261 + * of the file.
40262 + * ---------------------------------------------------------------------------
40263 + * Local variables:
40264 + * c-file-style: "linux"
40265 + * End:
40266 + */
40267 diff -Naur -X ../exclude-files orig/include/asm-um/processor-ppc.h um/include/asm-um/processor-ppc.h
40268 --- orig/include/asm-um/processor-ppc.h 1969-12-31 19:00:00.000000000 -0500
40269 +++ um/include/asm-um/processor-ppc.h   2003-10-21 03:26:07.000000000 -0400
40270 @@ -0,0 +1,15 @@
40271 +#ifndef __UM_PROCESSOR_PPC_H
40272 +#define __UM_PROCESSOR_PPC_H
40273 +
40274 +#if defined(__ASSEMBLY__)
40275 +
40276 +#define CONFIG_ALL_PPC
40277 +#include "arch/processor.h"
40278 +
40279 +#else
40280 +
40281 +#include "asm/processor-generic.h"
40282 +
40283 +#endif
40284 +
40285 +#endif
40286 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-generic.h um/include/asm-um/ptrace-generic.h
40287 --- orig/include/asm-um/ptrace-generic.h        1969-12-31 19:00:00.000000000 -0500
40288 +++ um/include/asm-um/ptrace-generic.h  2003-12-17 02:16:13.000000000 -0500
40289 @@ -0,0 +1,74 @@
40290 +/* 
40291 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40292 + * Licensed under the GPL
40293 + */
40294 +
40295 +#ifndef __UM_PTRACE_GENERIC_H
40296 +#define __UM_PTRACE_GENERIC_H
40297 +
40298 +#ifndef __ASSEMBLY__
40299 +
40300 +#include "linux/config.h"
40301 +
40302 +#include "asm/current.h"
40303 +
40304 +#define pt_regs pt_regs_subarch
40305 +#define show_regs show_regs_subarch
40306 +
40307 +#include "asm/arch/ptrace.h"
40308 +
40309 +#undef pt_regs
40310 +#undef show_regs
40311 +#undef user_mode
40312 +#undef instruction_pointer
40313 +
40314 +#include "sysdep/ptrace.h"
40315 +#include "skas_ptrace.h"
40316 +
40317 +struct pt_regs {
40318 +       union uml_pt_regs regs;
40319 +};
40320 +
40321 +#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
40322 +
40323 +#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
40324 +#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
40325 +
40326 +#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
40327 +#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
40328 +
40329 +#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
40330 +       UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
40331 +#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
40332 +
40333 +#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
40334 +
40335 +#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
40336 +
40337 +struct task_struct;
40338 +
40339 +extern unsigned long getreg(struct task_struct *child, int regno);
40340 +extern int putreg(struct task_struct *child, int regno, unsigned long value);
40341 +extern int get_fpregs(unsigned long buf, struct task_struct *child);
40342 +extern int set_fpregs(unsigned long buf, struct task_struct *child);
40343 +extern int get_fpxregs(unsigned long buf, struct task_struct *child);
40344 +extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
40345 +
40346 +extern void show_regs(struct pt_regs *regs);
40347 +
40348 +#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
40349 +
40350 +#endif
40351 +
40352 +#endif
40353 +
40354 +/*
40355 + * Overrides for Emacs so that we follow Linus's tabbing style.
40356 + * Emacs will notice this stuff at the end of the file and automatically
40357 + * adjust the settings for this buffer only.  This must remain at the end
40358 + * of the file.
40359 + * ---------------------------------------------------------------------------
40360 + * Local variables:
40361 + * c-file-style: "linux"
40362 + * End:
40363 + */
40364 diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-i386.h um/include/asm-um/ptrace-i386.h
40365 --- orig/include/asm-um/ptrace-i386.h   1969-12-31 19:00:00.000000000 -0500
40366 +++ um/include/asm-um/ptrace-i386.h     2003-12-17 02:16:13.000000000 -0500
40367 @@ -0,0 +1,46 @@
40368 +/* 
40369 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
40370 + * Licensed under the GPL
40371 + */
40372 +
40373 +#ifndef __UM_PTRACE_I386_H
40374 +#define __UM_PTRACE_I386_H
40375 +
40376 +#include "sysdep/ptrace.h"
40377 +#include "asm/ptrace-generic.h"
40378 +
40379 +#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
40380 +#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
40381 +#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs)
40382 +#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs)
40383 +#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs)
40384 +#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs)
40385 +#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs)
40386 +
40387 +#define PT_REGS_CS(r) UPT_CS(&(r)->regs)
40388 +#define PT_REGS_SS(r) UPT_SS(&(r)->regs)
40389 +#define PT_REGS_DS(r) UPT_DS(&(r)->regs)
40390 +#define PT_REGS_ES(r) UPT_ES(&(r)->regs)
40391 +#define PT_REGS_FS(r) UPT_FS(&(r)->regs)
40392 +#define PT_REGS_GS(r) UPT_GS(&(r)->regs)
40393 +
40394 +#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs)
40395 +
40396 +#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r)
40397 +#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
40398 +#define PT_FIX_EXEC_STACK(sp) do ; while(0)
40399 +
40400 +#define user_mode(r) UPT_IS_USER(&(r)->regs)
40401 +
40402 +#endif
40403 +
40404 +/*
40405 + * Overrides for Emacs so that we follow Linus's tabbing style.
40406 + * Emacs will notice this stuff at the end of the file and automatically
40407 + * adjust the settings for this buffer only.  This must remain at the end
40408 + * of the file.
40409 + * ---------------------------------------------------------------------------
40410 + * Local variables:
40411 + * c-file-style: "linux"
40412 + * End:
40413 + */
40414 diff -Naur -X ../exclude-files orig/include/asm-um/resource.h um/include/asm-um/resource.h
40415 --- orig/include/asm-um/resource.h      1969-12-31 19:00:00.000000000 -0500
40416 +++ um/include/asm-um/resource.h        2003-10-21 03:26:07.000000000 -0400
40417 @@ -0,0 +1,6 @@
40418 +#ifndef __UM_RESOURCE_H
40419 +#define __UM_RESOURCE_H
40420 +
40421 +#include "asm/arch/resource.h"
40422 +
40423 +#endif
40424 diff -Naur -X ../exclude-files orig/include/asm-um/rwlock.h um/include/asm-um/rwlock.h
40425 --- orig/include/asm-um/rwlock.h        1969-12-31 19:00:00.000000000 -0500
40426 +++ um/include/asm-um/rwlock.h  2003-10-21 03:26:07.000000000 -0400
40427 @@ -0,0 +1,6 @@
40428 +#ifndef __UM_RWLOCK_H
40429 +#define __UM_RWLOCK_H
40430 +
40431 +#include "asm/arch/rwlock.h"
40432 +
40433 +#endif
40434 diff -Naur -X ../exclude-files orig/include/asm-um/rwsem.h um/include/asm-um/rwsem.h
40435 --- orig/include/asm-um/rwsem.h 1969-12-31 19:00:00.000000000 -0500
40436 +++ um/include/asm-um/rwsem.h   2003-12-17 02:16:13.000000000 -0500
40437 @@ -0,0 +1,10 @@
40438 +#ifndef __UM_RWSEM_H__
40439 +#define __UM_RWSEM_H__
40440 +
40441 +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
40442 +#define __builtin_expect(exp,c) (exp)
40443 +#endif
40444 +
40445 +#include "asm/arch/rwsem.h"
40446 +
40447 +#endif
40448 diff -Naur -X ../exclude-files orig/include/asm-um/scatterlist.h um/include/asm-um/scatterlist.h
40449 --- orig/include/asm-um/scatterlist.h   1969-12-31 19:00:00.000000000 -0500
40450 +++ um/include/asm-um/scatterlist.h     2003-10-21 03:26:07.000000000 -0400
40451 @@ -0,0 +1,6 @@
40452 +#ifndef __UM_SCATTERLIST_H
40453 +#define __UM_SCATTERLIST_H
40454 +
40455 +#include "asm/arch/scatterlist.h"
40456 +
40457 +#endif
40458 diff -Naur -X ../exclude-files orig/include/asm-um/segment.h um/include/asm-um/segment.h
40459 --- orig/include/asm-um/segment.h       1969-12-31 19:00:00.000000000 -0500
40460 +++ um/include/asm-um/segment.h 2003-10-21 03:26:07.000000000 -0400
40461 @@ -0,0 +1,4 @@
40462 +#ifndef __UM_SEGMENT_H
40463 +#define __UM_SEGMENT_H
40464 +
40465 +#endif
40466 diff -Naur -X ../exclude-files orig/include/asm-um/semaphore.h um/include/asm-um/semaphore.h
40467 --- orig/include/asm-um/semaphore.h     1969-12-31 19:00:00.000000000 -0500
40468 +++ um/include/asm-um/semaphore.h       2003-12-17 02:16:13.000000000 -0500
40469 @@ -0,0 +1,6 @@
40470 +#ifndef __UM_SEMAPHORE_H
40471 +#define __UM_SEMAPHORE_H
40472 +
40473 +#include "asm/arch/semaphore.h"
40474 +
40475 +#endif
40476 diff -Naur -X ../exclude-files orig/include/asm-um/sembuf.h um/include/asm-um/sembuf.h
40477 --- orig/include/asm-um/sembuf.h        1969-12-31 19:00:00.000000000 -0500
40478 +++ um/include/asm-um/sembuf.h  2003-10-21 03:26:07.000000000 -0400
40479 @@ -0,0 +1,6 @@
40480 +#ifndef __UM_SEMBUF_H
40481 +#define __UM_SEMBUF_H
40482 +
40483 +#include "asm/arch/sembuf.h"
40484 +
40485 +#endif
40486 diff -Naur -X ../exclude-files orig/include/asm-um/serial.h um/include/asm-um/serial.h
40487 --- orig/include/asm-um/serial.h        1969-12-31 19:00:00.000000000 -0500
40488 +++ um/include/asm-um/serial.h  2003-10-21 03:26:07.000000000 -0400
40489 @@ -0,0 +1,6 @@
40490 +#ifndef __UM_SERIAL_H
40491 +#define __UM_SERIAL_H
40492 +
40493 +#include "asm/arch/serial.h"
40494 +
40495 +#endif
40496 diff -Naur -X ../exclude-files orig/include/asm-um/shmbuf.h um/include/asm-um/shmbuf.h
40497 --- orig/include/asm-um/shmbuf.h        1969-12-31 19:00:00.000000000 -0500
40498 +++ um/include/asm-um/shmbuf.h  2003-10-21 03:26:07.000000000 -0400
40499 @@ -0,0 +1,6 @@
40500 +#ifndef __UM_SHMBUF_H
40501 +#define __UM_SHMBUF_H
40502 +
40503 +#include "asm/arch/shmbuf.h"
40504 +
40505 +#endif
40506 diff -Naur -X ../exclude-files orig/include/asm-um/shmparam.h um/include/asm-um/shmparam.h
40507 --- orig/include/asm-um/shmparam.h      1969-12-31 19:00:00.000000000 -0500
40508 +++ um/include/asm-um/shmparam.h        2003-10-21 03:26:07.000000000 -0400
40509 @@ -0,0 +1,6 @@
40510 +#ifndef __UM_SHMPARAM_H
40511 +#define __UM_SHMPARAM_H
40512 +
40513 +#include "asm/arch/shmparam.h"
40514 +
40515 +#endif
40516 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-generic.h um/include/asm-um/sigcontext-generic.h
40517 --- orig/include/asm-um/sigcontext-generic.h    1969-12-31 19:00:00.000000000 -0500
40518 +++ um/include/asm-um/sigcontext-generic.h      2003-10-21 03:26:07.000000000 -0400
40519 @@ -0,0 +1,6 @@
40520 +#ifndef __UM_SIGCONTEXT_GENERIC_H
40521 +#define __UM_SIGCONTEXT_GENERIC_H
40522 +
40523 +#include "asm/arch/sigcontext.h"
40524 +
40525 +#endif
40526 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-i386.h um/include/asm-um/sigcontext-i386.h
40527 --- orig/include/asm-um/sigcontext-i386.h       1969-12-31 19:00:00.000000000 -0500
40528 +++ um/include/asm-um/sigcontext-i386.h 2003-10-21 03:26:07.000000000 -0400
40529 @@ -0,0 +1,6 @@
40530 +#ifndef __UM_SIGCONTEXT_I386_H
40531 +#define __UM_SIGCONTEXT_I386_H
40532 +
40533 +#include "asm/sigcontext-generic.h"
40534 +
40535 +#endif
40536 diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-ppc.h um/include/asm-um/sigcontext-ppc.h
40537 --- orig/include/asm-um/sigcontext-ppc.h        1969-12-31 19:00:00.000000000 -0500
40538 +++ um/include/asm-um/sigcontext-ppc.h  2003-10-21 03:26:07.000000000 -0400
40539 @@ -0,0 +1,10 @@
40540 +#ifndef __UM_SIGCONTEXT_PPC_H
40541 +#define __UM_SIGCONTEXT_PPC_H
40542 +
40543 +#define pt_regs sys_pt_regs
40544 +
40545 +#include "asm/sigcontext-generic.h"
40546 +
40547 +#undef pt_regs
40548 +
40549 +#endif
40550 diff -Naur -X ../exclude-files orig/include/asm-um/siginfo.h um/include/asm-um/siginfo.h
40551 --- orig/include/asm-um/siginfo.h       1969-12-31 19:00:00.000000000 -0500
40552 +++ um/include/asm-um/siginfo.h 2003-12-17 02:16:13.000000000 -0500
40553 @@ -0,0 +1,6 @@
40554 +#ifndef __UM_SIGINFO_H
40555 +#define __UM_SIGINFO_H
40556 +
40557 +#include "asm/arch/siginfo.h"
40558 +
40559 +#endif
40560 diff -Naur -X ../exclude-files orig/include/asm-um/signal.h um/include/asm-um/signal.h
40561 --- orig/include/asm-um/signal.h        1969-12-31 19:00:00.000000000 -0500
40562 +++ um/include/asm-um/signal.h  2003-12-17 02:16:13.000000000 -0500
40563 @@ -0,0 +1,22 @@
40564 +/* 
40565 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40566 + * Licensed under the GPL
40567 + */
40568 +
40569 +#ifndef __UM_SIGNAL_H
40570 +#define __UM_SIGNAL_H
40571 +
40572 +#include "asm/arch/signal.h"
40573 +
40574 +#endif
40575 +
40576 +/*
40577 + * Overrides for Emacs so that we follow Linus's tabbing style.
40578 + * Emacs will notice this stuff at the end of the file and automatically
40579 + * adjust the settings for this buffer only.  This must remain at the end
40580 + * of the file.
40581 + * ---------------------------------------------------------------------------
40582 + * Local variables:
40583 + * c-file-style: "linux"
40584 + * End:
40585 + */
40586 diff -Naur -X ../exclude-files orig/include/asm-um/smp.h um/include/asm-um/smp.h
40587 --- orig/include/asm-um/smp.h   1969-12-31 19:00:00.000000000 -0500
40588 +++ um/include/asm-um/smp.h     2003-12-17 02:16:13.000000000 -0500
40589 @@ -0,0 +1,19 @@
40590 +#ifndef __UM_SMP_H
40591 +#define __UM_SMP_H
40592 +
40593 +#ifdef CONFIG_SMP
40594 +
40595 +#include "linux/config.h"
40596 +#include "asm/current.h"
40597 +
40598 +#define smp_processor_id() (current->processor)
40599 +#define cpu_logical_map(n) (n)
40600 +#define cpu_number_map(n) (n)
40601 +#define PROC_CHANGE_PENALTY    15 /* Pick a number, any number */
40602 +extern int hard_smp_processor_id(void);
40603 +extern unsigned long cpu_online_map;
40604 +#define NO_PROC_ID -1
40605 +
40606 +#endif
40607 +
40608 +#endif
40609 diff -Naur -X ../exclude-files orig/include/asm-um/smplock.h um/include/asm-um/smplock.h
40610 --- orig/include/asm-um/smplock.h       1969-12-31 19:00:00.000000000 -0500
40611 +++ um/include/asm-um/smplock.h 2003-12-17 02:16:13.000000000 -0500
40612 @@ -0,0 +1,6 @@
40613 +#ifndef __UM_SMPLOCK_H
40614 +#define __UM_SMPLOCK_H
40615 +
40616 +#include "asm/arch/smplock.h"
40617 +
40618 +#endif
40619 diff -Naur -X ../exclude-files orig/include/asm-um/socket.h um/include/asm-um/socket.h
40620 --- orig/include/asm-um/socket.h        1969-12-31 19:00:00.000000000 -0500
40621 +++ um/include/asm-um/socket.h  2003-11-07 02:10:43.000000000 -0500
40622 @@ -0,0 +1,6 @@
40623 +#ifndef __UM_SOCKET_H
40624 +#define __UM_SOCKET_H
40625 +
40626 +#include "asm/arch/socket.h"
40627 +
40628 +#endif
40629 diff -Naur -X ../exclude-files orig/include/asm-um/sockios.h um/include/asm-um/sockios.h
40630 --- orig/include/asm-um/sockios.h       1969-12-31 19:00:00.000000000 -0500
40631 +++ um/include/asm-um/sockios.h 2003-10-21 03:26:07.000000000 -0400
40632 @@ -0,0 +1,6 @@
40633 +#ifndef __UM_SOCKIOS_H
40634 +#define __UM_SOCKIOS_H
40635 +
40636 +#include "asm/arch/sockios.h"
40637 +
40638 +#endif
40639 diff -Naur -X ../exclude-files orig/include/asm-um/softirq.h um/include/asm-um/softirq.h
40640 --- orig/include/asm-um/softirq.h       1969-12-31 19:00:00.000000000 -0500
40641 +++ um/include/asm-um/softirq.h 2003-12-17 02:16:13.000000000 -0500
40642 @@ -0,0 +1,13 @@
40643 +#ifndef __UM_SOFTIRQ_H
40644 +#define __UM_SOFTIRQ_H
40645 +
40646 +#include "linux/smp.h"
40647 +#include "asm/system.h"
40648 +#include "asm/processor.h"
40649 +
40650 +/* A gratuitous name change */
40651 +#define i386_bh_lock um_bh_lock
40652 +#include "asm/arch/softirq.h"
40653 +#undef i386_bh_lock
40654 +
40655 +#endif
40656 diff -Naur -X ../exclude-files orig/include/asm-um/spinlock.h um/include/asm-um/spinlock.h
40657 --- orig/include/asm-um/spinlock.h      1969-12-31 19:00:00.000000000 -0500
40658 +++ um/include/asm-um/spinlock.h        2003-12-17 02:16:13.000000000 -0500
40659 @@ -0,0 +1,10 @@
40660 +#ifndef __UM_SPINLOCK_H
40661 +#define __UM_SPINLOCK_H
40662 +
40663 +#include "linux/config.h"
40664 +
40665 +#ifdef CONFIG_SMP
40666 +#include "asm/arch/spinlock.h"
40667 +#endif
40668 +
40669 +#endif
40670 diff -Naur -X ../exclude-files orig/include/asm-um/statfs.h um/include/asm-um/statfs.h
40671 --- orig/include/asm-um/statfs.h        1969-12-31 19:00:00.000000000 -0500
40672 +++ um/include/asm-um/statfs.h  2003-12-17 02:16:13.000000000 -0500
40673 @@ -0,0 +1,6 @@
40674 +#ifndef _UM_STATFS_H
40675 +#define _UM_STATFS_H
40676 +
40677 +#include "asm/arch/statfs.h"
40678 +
40679 +#endif
40680 diff -Naur -X ../exclude-files orig/include/asm-um/stat.h um/include/asm-um/stat.h
40681 --- orig/include/asm-um/stat.h  1969-12-31 19:00:00.000000000 -0500
40682 +++ um/include/asm-um/stat.h    2003-10-21 03:26:07.000000000 -0400
40683 @@ -0,0 +1,6 @@
40684 +#ifndef __UM_STAT_H
40685 +#define __UM_STAT_H
40686 +
40687 +#include "asm/arch/stat.h"
40688 +
40689 +#endif
40690 diff -Naur -X ../exclude-files orig/include/asm-um/string.h um/include/asm-um/string.h
40691 --- orig/include/asm-um/string.h        1969-12-31 19:00:00.000000000 -0500
40692 +++ um/include/asm-um/string.h  2003-12-16 22:26:55.000000000 -0500
40693 @@ -0,0 +1,7 @@
40694 +#ifndef __UM_STRING_H
40695 +#define __UM_STRING_H
40696 +
40697 +#include "asm/arch/string.h"
40698 +#include "asm/archparam.h"
40699 +
40700 +#endif
40701 diff -Naur -X ../exclude-files orig/include/asm-um/system-generic.h um/include/asm-um/system-generic.h
40702 --- orig/include/asm-um/system-generic.h        1969-12-31 19:00:00.000000000 -0500
40703 +++ um/include/asm-um/system-generic.h  2003-12-17 02:16:13.000000000 -0500
40704 @@ -0,0 +1,50 @@
40705 +#ifndef __UM_SYSTEM_GENERIC_H
40706 +#define __UM_SYSTEM_GENERIC_H
40707 +
40708 +#include "asm/arch/system.h"
40709 +
40710 +#undef prepare_to_switch
40711 +#undef switch_to
40712 +#undef __save_flags
40713 +#undef save_flags
40714 +#undef __restore_flags
40715 +#undef restore_flags
40716 +#undef __cli
40717 +#undef __sti
40718 +#undef cli
40719 +#undef sti
40720 +#undef local_irq_save
40721 +#undef local_irq_restore
40722 +#undef local_irq_disable
40723 +#undef local_irq_enable
40724 +
40725 +#define prepare_to_switch() do ; while(0)
40726 +
40727 +void *_switch_to(void *prev, void *next);
40728 +
40729 +#define switch_to(prev, next, last) prev = _switch_to(prev, next)
40730 +
40731 +extern int get_signals(void);
40732 +extern int set_signals(int enable);
40733 +extern void block_signals(void);
40734 +extern void unblock_signals(void);
40735 +
40736 +#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0)
40737 +
40738 +#define local_irq_restore(flags) do { set_signals(flags); } while(0)
40739 +
40740 +#define local_irq_enable() unblock_signals()
40741 +#define local_irq_disable() block_signals()
40742 +
40743 +#define __sti() unblock_signals()
40744 +#define sti() unblock_signals()
40745 +#define __cli() block_signals()
40746 +#define cli() block_signals()
40747 +
40748 +#define __save_flags(x) do { (x) = get_signals(); } while(0)
40749 +#define save_flags(x) __save_flags(x)
40750 +
40751 +#define __restore_flags(x) local_irq_restore(x)
40752 +#define restore_flags(x) __restore_flags(x)
40753 +
40754 +#endif
40755 diff -Naur -X ../exclude-files orig/include/asm-um/system-i386.h um/include/asm-um/system-i386.h
40756 --- orig/include/asm-um/system-i386.h   1969-12-31 19:00:00.000000000 -0500
40757 +++ um/include/asm-um/system-i386.h     2003-12-17 02:16:13.000000000 -0500
40758 @@ -0,0 +1,39 @@
40759 +#ifndef __UM_SYSTEM_I386_H
40760 +#define __UM_SYSTEM_I386_H
40761 +
40762 +#include "asm/system-generic.h"
40763 +
40764 +#define __HAVE_ARCH_CMPXCHG 1
40765 +
40766 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
40767 +                                     unsigned long new, int size)
40768 +{
40769 +       unsigned long prev;
40770 +       switch (size) {
40771 +       case 1:
40772 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
40773 +                                    : "=a"(prev)
40774 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
40775 +                                    : "memory");
40776 +               return prev;
40777 +       case 2:
40778 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
40779 +                                    : "=a"(prev)
40780 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
40781 +                                    : "memory");
40782 +               return prev;
40783 +       case 4:
40784 +               __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
40785 +                                    : "=a"(prev)
40786 +                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
40787 +                                    : "memory");
40788 +               return prev;
40789 +       }
40790 +       return old;
40791 +}
40792 +
40793 +#define cmpxchg(ptr,o,n)\
40794 +       ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
40795 +                                       (unsigned long)(n),sizeof(*(ptr))))
40796 +    
40797 +#endif
40798 diff -Naur -X ../exclude-files orig/include/asm-um/system-ppc.h um/include/asm-um/system-ppc.h
40799 --- orig/include/asm-um/system-ppc.h    1969-12-31 19:00:00.000000000 -0500
40800 +++ um/include/asm-um/system-ppc.h      2003-10-21 03:26:07.000000000 -0400
40801 @@ -0,0 +1,12 @@
40802 +#ifndef __UM_SYSTEM_PPC_H
40803 +#define __UM_SYSTEM_PPC_H
40804 +
40805 +#define _switch_to _ppc_switch_to
40806 +
40807 +#include "asm/arch/system.h"
40808 +
40809 +#undef _switch_to
40810
40811 +#include "asm/system-generic.h"
40812 +
40813 +#endif
40814 diff -Naur -X ../exclude-files orig/include/asm-um/termbits.h um/include/asm-um/termbits.h
40815 --- orig/include/asm-um/termbits.h      1969-12-31 19:00:00.000000000 -0500
40816 +++ um/include/asm-um/termbits.h        2003-11-07 02:10:43.000000000 -0500
40817 @@ -0,0 +1,6 @@
40818 +#ifndef __UM_TERMBITS_H
40819 +#define __UM_TERMBITS_H
40820 +
40821 +#include "asm/arch/termbits.h"
40822 +
40823 +#endif
40824 diff -Naur -X ../exclude-files orig/include/asm-um/termios.h um/include/asm-um/termios.h
40825 --- orig/include/asm-um/termios.h       1969-12-31 19:00:00.000000000 -0500
40826 +++ um/include/asm-um/termios.h 2003-12-16 22:26:55.000000000 -0500
40827 @@ -0,0 +1,6 @@
40828 +#ifndef __UM_TERMIOS_H
40829 +#define __UM_TERMIOS_H
40830 +
40831 +#include "asm/arch/termios.h"
40832 +
40833 +#endif
40834 diff -Naur -X ../exclude-files orig/include/asm-um/timex.h um/include/asm-um/timex.h
40835 --- orig/include/asm-um/timex.h 1969-12-31 19:00:00.000000000 -0500
40836 +++ um/include/asm-um/timex.h   2003-12-17 02:16:13.000000000 -0500
40837 @@ -0,0 +1,18 @@
40838 +#ifndef __UM_TIMEX_H
40839 +#define __UM_TIMEX_H
40840 +
40841 +#include "linux/time.h"
40842 +
40843 +typedef unsigned long cycles_t;
40844 +
40845 +#define cacheflush_time (0)
40846 +
40847 +static inline cycles_t get_cycles (void)
40848 +{
40849 +       return 0;
40850 +}
40851 +
40852 +#define vxtime_lock()          do ; while (0)
40853 +#define vxtime_unlock()                do ; while (0)
40854 +
40855 +#endif
40856 diff -Naur -X ../exclude-files orig/include/asm-um/tlb.h um/include/asm-um/tlb.h
40857 --- orig/include/asm-um/tlb.h   1969-12-31 19:00:00.000000000 -0500
40858 +++ um/include/asm-um/tlb.h     2003-10-21 03:26:07.000000000 -0400
40859 @@ -0,0 +1 @@
40860 +#include <asm-generic/tlb.h>
40861 diff -Naur -X ../exclude-files orig/include/asm-um/types.h um/include/asm-um/types.h
40862 --- orig/include/asm-um/types.h 1969-12-31 19:00:00.000000000 -0500
40863 +++ um/include/asm-um/types.h   2003-12-15 00:26:37.000000000 -0500
40864 @@ -0,0 +1,6 @@
40865 +#ifndef __UM_TYPES_H
40866 +#define __UM_TYPES_H
40867 +
40868 +#include "asm/arch/types.h"
40869 +
40870 +#endif
40871 diff -Naur -X ../exclude-files orig/include/asm-um/uaccess.h um/include/asm-um/uaccess.h
40872 --- orig/include/asm-um/uaccess.h       1969-12-31 19:00:00.000000000 -0500
40873 +++ um/include/asm-um/uaccess.h 2003-12-17 02:16:13.000000000 -0500
40874 @@ -0,0 +1,99 @@
40875 +/* 
40876 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
40877 + * Licensed under the GPL
40878 + */
40879 +
40880 +#ifndef __UM_UACCESS_H
40881 +#define __UM_UACCESS_H
40882 +
40883 +#include "linux/sched.h"
40884 +
40885 +#define VERIFY_READ 0
40886 +#define VERIFY_WRITE 1
40887 +
40888 +/*
40889 + * The fs value determines whether argument validity checking should be
40890 + * performed or not.  If get_fs() == USER_DS, checking is performed, with
40891 + * get_fs() == KERNEL_DS, checking is bypassed.
40892 + *
40893 + * For historical reasons, these macros are grossly misnamed.
40894 + */
40895 +
40896 +#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
40897 +
40898 +#define KERNEL_DS      MAKE_MM_SEG(0xFFFFFFFF)
40899 +#define USER_DS                MAKE_MM_SEG(TASK_SIZE)
40900 +
40901 +#define get_ds()       (KERNEL_DS)
40902 +#define get_fs()       (current->addr_limit)
40903 +#define set_fs(x)      (current->addr_limit = (x))
40904 +
40905 +#define segment_eq(a, b) ((a).seg == (b).seg)
40906 +
40907 +#include "um_uaccess.h"
40908 +
40909 +#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
40910 +
40911 +#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
40912 +
40913 +#define __get_user(x, ptr) \
40914 +({ \
40915 +        const __typeof__(ptr) __private_ptr = ptr; \
40916 +        __typeof__(*(__private_ptr)) __private_val; \
40917 +        int __private_ret = -EFAULT; \
40918 +        (x) = 0; \
40919 +       if (__copy_from_user(&__private_val, (__private_ptr), \
40920 +           sizeof(*(__private_ptr))) == 0) {\
40921 +               (x) = (__typeof__(*(__private_ptr))) __private_val; \
40922 +               __private_ret = 0; \
40923 +       } \
40924 +        __private_ret; \
40925 +}) 
40926 +
40927 +#define get_user(x, ptr) \
40928 +({ \
40929 +        const __typeof__((*ptr)) *private_ptr = (ptr); \
40930 +        (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
40931 +        __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \
40932 +})
40933 +
40934 +#define __put_user(x, ptr) \
40935 +({ \
40936 +        __typeof__(ptr) __private_ptr = ptr; \
40937 +        __typeof__(*(__private_ptr)) __private_val; \
40938 +        int __private_ret = -EFAULT; \
40939 +        __private_val = (__typeof__(*(__private_ptr))) (x); \
40940 +        if (__copy_to_user((__private_ptr), &__private_val, \
40941 +                          sizeof(*(__private_ptr))) == 0) { \
40942 +               __private_ret = 0; \
40943 +       } \
40944 +        __private_ret; \
40945 +})
40946 +
40947 +#define put_user(x, ptr) \
40948 +({ \
40949 +        __typeof__(*(ptr)) *private_ptr = (ptr); \
40950 +        (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
40951 +        __put_user(x, private_ptr) : -EFAULT); \
40952 +})
40953 +
40954 +#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
40955 +
40956 +struct exception_table_entry
40957 +{
40958 +        unsigned long insn;
40959 +       unsigned long fixup;
40960 +};
40961 +
40962 +#endif
40963 +
40964 +/*
40965 + * Overrides for Emacs so that we follow Linus's tabbing style.
40966 + * Emacs will notice this stuff at the end of the file and automatically
40967 + * adjust the settings for this buffer only.  This must remain at the end
40968 + * of the file.
40969 + * ---------------------------------------------------------------------------
40970 + * Local variables:
40971 + * c-file-style: "linux"
40972 + * End:
40973 + */
40974 diff -Naur -X ../exclude-files orig/include/asm-um/ucontext.h um/include/asm-um/ucontext.h
40975 --- orig/include/asm-um/ucontext.h      1969-12-31 19:00:00.000000000 -0500
40976 +++ um/include/asm-um/ucontext.h        2003-10-21 03:26:07.000000000 -0400
40977 @@ -0,0 +1,6 @@
40978 +#ifndef _ASM_UM_UCONTEXT_H
40979 +#define _ASM_UM_UCONTEXT_H
40980 +
40981 +#include "asm/arch/ucontext.h"
40982 +
40983 +#endif
40984 diff -Naur -X ../exclude-files orig/include/asm-um/unaligned.h um/include/asm-um/unaligned.h
40985 --- orig/include/asm-um/unaligned.h     1969-12-31 19:00:00.000000000 -0500
40986 +++ um/include/asm-um/unaligned.h       2003-10-21 03:26:07.000000000 -0400
40987 @@ -0,0 +1,6 @@
40988 +#ifndef __UM_UNALIGNED_H
40989 +#define __UM_UNALIGNED_H
40990 +
40991 +#include "asm/arch/unaligned.h"
40992 +
40993 +#endif
40994 diff -Naur -X ../exclude-files orig/include/asm-um/unistd.h um/include/asm-um/unistd.h
40995 --- orig/include/asm-um/unistd.h        1969-12-31 19:00:00.000000000 -0500
40996 +++ um/include/asm-um/unistd.h  2003-12-17 02:16:14.000000000 -0500
40997 @@ -0,0 +1,121 @@
40998 +/* 
40999 + * Copyright (C) 2000, 2001  Jeff Dike (jdike@karaya.com)
41000 + * Licensed under the GPL
41001 + */
41002 +
41003 +#ifndef _UM_UNISTD_H_
41004 +#define _UM_UNISTD_H_
41005 +
41006 +#include "linux/resource.h"
41007 +#include "asm/uaccess.h"
41008 +
41009 +extern long sys_open(const char *filename, int flags, int mode);
41010 +extern long sys_dup(unsigned int fildes);
41011 +extern long sys_close(unsigned int fd);
41012 +extern int um_execve(const char *file, char *const argv[], char *const env[]);
41013 +extern long sys_setsid(void);
41014 +extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options);
41015 +extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options, 
41016 +                     struct rusage *ru);
41017 +extern long sys_mount(char *dev_name, char *dir_name, char *type, 
41018 +                     unsigned long flags, void *data);
41019 +extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, 
41020 +                      struct timeval *tvp);
41021 +extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence);
41022 +extern long sys_read(unsigned int fildes, char *buf, int len);
41023 +extern long sys_write(unsigned int fildes, char *buf, int len);
41024 +
41025 +#ifdef __KERNEL_SYSCALLS__
41026 +
41027 +#define KERNEL_CALL(ret_t, sys, args...)       \
41028 +       mm_segment_t fs = get_fs();             \
41029 +       ret_t ret;                              \
41030 +       set_fs(KERNEL_DS);                      \
41031 +       ret = sys(args);                        \
41032 +       set_fs(fs);                             \
41033 +       if (ret >= 0)                           \
41034 +               return ret;                     \
41035 +       errno = -(long)ret;                     \
41036 +       return -1;
41037 +
41038 +static inline long open(const char *pathname, int flags, int mode) 
41039 +{
41040 +       KERNEL_CALL(int, sys_open, pathname, flags, mode)
41041 +}
41042 +
41043 +static inline long dup(unsigned int fd)
41044 +{
41045 +       KERNEL_CALL(int, sys_dup, fd);
41046 +}
41047 +
41048 +static inline long close(unsigned int fd)
41049 +{
41050 +       KERNEL_CALL(int, sys_close, fd);
41051 +}
41052 +
41053 +static inline int execve(const char *filename, char *const argv[], 
41054 +                        char *const envp[])
41055 +{
41056 +       KERNEL_CALL(int, um_execve, filename, argv, envp);
41057 +}
41058 +
41059 +static inline long waitpid(pid_t pid, unsigned int *status, int options)
41060 +{
41061 +       KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL)
41062 +}
41063 +
41064 +static inline pid_t wait(int *status)
41065 +{
41066 +       KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL)
41067 +}
41068 +
41069 +static inline pid_t setsid(void)
41070 +{
41071 +       KERNEL_CALL(pid_t, sys_setsid)
41072 +}
41073 +
41074 +static inline long lseek(unsigned int fd, off_t offset, unsigned int whence)
41075 +{
41076 +       KERNEL_CALL(long, sys_lseek, fd, offset, whence)
41077 +}
41078 +
41079 +static inline int read(unsigned int fd, char * buf, int len)
41080 +{
41081 +       KERNEL_CALL(int, sys_read, fd, buf, len)
41082 +}
41083 +
41084 +static inline int write(unsigned int fd, char * buf, int len)
41085 +{
41086 +       KERNEL_CALL(int, sys_write, fd, buf, len)
41087 +}
41088 +
41089 +#endif
41090 +
41091 +/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying
41092 + * arch's unistd.h for the system call numbers, and restore the old 
41093 + * __KERNEL_SYSCALLS__.
41094 + */
41095 +
41096 +#ifdef __KERNEL_SYSCALLS__
41097 +#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__
41098 +#endif
41099 +
41100 +#undef __KERNEL_SYSCALLS__
41101 +#include "asm/arch/unistd.h"
41102 +
41103 +#ifdef __KERNEL_SYSCALLS__
41104 +#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__
41105 +#endif
41106 +
41107 +#endif
41108 +
41109 +/*
41110 + * Overrides for Emacs so that we follow Linus's tabbing style.
41111 + * Emacs will notice this stuff at the end of the file and automatically
41112 + * adjust the settings for this buffer only.  This must remain at the end
41113 + * of the file.
41114 + * ---------------------------------------------------------------------------
41115 + * Local variables:
41116 + * c-file-style: "linux"
41117 + * End:
41118 + */
41119 diff -Naur -X ../exclude-files orig/include/asm-um/user.h um/include/asm-um/user.h
41120 --- orig/include/asm-um/user.h  1969-12-31 19:00:00.000000000 -0500
41121 +++ um/include/asm-um/user.h    2003-12-17 02:18:31.000000000 -0500
41122 @@ -0,0 +1,6 @@
41123 +#ifndef __UM_USER_H
41124 +#define __UM_USER_H
41125 +
41126 +#include "asm/arch/user.h"
41127 +
41128 +#endif
41129 diff -Naur -X ../exclude-files orig/include/asm-um/vga.h um/include/asm-um/vga.h
41130 --- orig/include/asm-um/vga.h   1969-12-31 19:00:00.000000000 -0500
41131 +++ um/include/asm-um/vga.h     2003-10-21 03:26:07.000000000 -0400
41132 @@ -0,0 +1,6 @@
41133 +#ifndef __UM_VGA_H
41134 +#define __UM_VGA_H
41135 +
41136 +#include "asm/arch/vga.h"
41137 +
41138 +#endif
41139 diff -Naur -X ../exclude-files orig/include/asm-um/xor.h um/include/asm-um/xor.h
41140 --- orig/include/asm-um/xor.h   1969-12-31 19:00:00.000000000 -0500
41141 +++ um/include/asm-um/xor.h     2003-10-21 03:26:07.000000000 -0400
41142 @@ -0,0 +1,6 @@
41143 +#ifndef __UM_XOR_H
41144 +#define __UM_XOR_H
41145 +
41146 +#include "asm-generic/xor.h"
41147 +
41148 +#endif
41149 diff -Naur -X ../exclude-files orig/include/linux/blk.h um/include/linux/blk.h
41150 --- orig/include/linux/blk.h    2002-09-15 12:13:19.000000000 -0400
41151 +++ um/include/linux/blk.h      2003-12-17 02:16:30.000000000 -0500
41152 @@ -320,6 +320,24 @@
41153  #define DEVICE_REQUEST do_ida_request
41154  #define DEVICE_NR(device) (MINOR(device) >> 4)
41155  
41156 +#elif (MAJOR_NR == UBD_MAJOR)
41157 +
41158 +#define DEVICE_NAME "User-mode block device"
41159 +#define DEVICE_INTR do_ubd
41160 +#define DEVICE_REQUEST do_ubd_request
41161 +#define DEVICE_NR(device) (MINOR(device) >> UBD_SHIFT)
41162 +#define DEVICE_ON(device)
41163 +#define DEVICE_OFF(device)
41164 +
41165 +#elif (MAJOR_NR == COW_MAJOR)
41166 +
41167 +#define DEVICE_NAME "COW device"
41168 +#define DEVICE_INTR do_cow
41169 +#define DEVICE_REQUEST do_cow_request
41170 +#define DEVICE_NR(device) (MINOR(device) >> COW_SHIFT)
41171 +#define DEVICE_ON(device)
41172 +#define DEVICE_OFF(device)
41173 +
41174  #endif /* MAJOR_NR == whatever */
41175  
41176  /* provide DEVICE_xxx defaults, if not explicitly defined
41177 diff -Naur -X ../exclude-files orig/include/linux/fs.h um/include/linux/fs.h
41178 --- orig/include/linux/fs.h     2003-12-16 22:16:36.000000000 -0500
41179 +++ um/include/linux/fs.h       2003-12-17 02:16:13.000000000 -0500
41180 @@ -320,6 +320,8 @@
41181  #include <linux/ncp_fs_i.h>
41182  #include <linux/proc_fs_i.h>
41183  #include <linux/usbdev_fs_i.h>
41184 +#include <linux/hostfs_fs_i.h>
41185 +#include <linux/hppfs_fs_i.h>
41186  #include <linux/jffs2_fs_i.h>
41187  #include <linux/cramfs_fs_sb.h>
41188  
41189 @@ -516,7 +518,9 @@
41190                 struct proc_inode_info          proc_i;
41191                 struct socket                   socket_i;
41192                 struct usbdev_inode_info        usbdev_i;
41193 -               struct jffs2_inode_info         jffs2_i;
41194 +               struct hostfs_inode_info        hostfs_i;
41195 +               struct hppfs_inode_info         hppfs_i;
41196 +               struct jffs2_inode_info         jffs2_i;
41197                 void                            *generic_ip;
41198         } u;
41199  };
41200 @@ -864,6 +868,8 @@
41201         unsigned int (*poll) (struct file *, struct poll_table_struct *);
41202         int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
41203         int (*mmap) (struct file *, struct vm_area_struct *);
41204 +       void (*munmap) (struct file *, struct vm_area_struct *, 
41205 +                       unsigned long start, unsigned long len);
41206         int (*open) (struct inode *, struct file *);
41207         int (*flush) (struct file *);
41208         int (*release) (struct inode *, struct file *);
41209 diff -Naur -X ../exclude-files orig/include/linux/ghash.h um/include/linux/ghash.h
41210 --- orig/include/linux/ghash.h  1997-07-07 11:24:28.000000000 -0400
41211 +++ um/include/linux/ghash.h    2003-10-21 03:26:07.000000000 -0400
41212 @@ -153,6 +153,26 @@
41213         return NULL;\
41214  }
41215  
41216 +/* LINKAGE - empty or "static", depending on whether you want the definitions to
41217 + *     be public or not
41218 + * NAME - a string to stick in names to make this hash table type distinct from
41219 + *     any others
41220 + * HASHSIZE - number of buckets
41221 + * TYPE - type of data contained in the buckets - must be a structure, one 
41222 + *     field is of type NAME_ptrs, another is the hash key
41223 + * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
41224 + *     field
41225 + * KEYTYPE - type of the key field within TYPE
41226 + * KEY - name of the key field within TYPE
41227 + * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
41228 + *     prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, 
41229 + *     non-zero for not equal
41230 + * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
41231 + *     it returns a number in the range 0 ... HASHSIZE - 1
41232 + * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
41233 + * DEF_HASH.
41234 + */
41235 +
41236  #define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
41237  \
41238  struct NAME##_table {\
41239 @@ -165,7 +185,7 @@
41240         TYPE * prev_hash;\
41241  };
41242  
41243 -#define DEF_HASH(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
41244 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
41245  \
41246  LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
41247  {\
41248 @@ -206,12 +226,10 @@
41249  \
41250  LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
41251  {\
41252 -       int ix = hashfn(pos);\
41253 +       int ix = HASHFN(pos);\
41254         TYPE * ptr = tbl->hashtable[ix];\
41255         while(ptr && KEYCMP(ptr->KEY, pos))\
41256                 ptr = ptr->PTRS.next_hash;\
41257 -       if(ptr && !KEYEQ(ptr->KEY, pos))\
41258 -               ptr = NULL;\
41259         return ptr;\
41260  }
41261  
41262 diff -Naur -X ../exclude-files orig/include/linux/hostfs_fs_i.h um/include/linux/hostfs_fs_i.h
41263 --- orig/include/linux/hostfs_fs_i.h    1969-12-31 19:00:00.000000000 -0500
41264 +++ um/include/linux/hostfs_fs_i.h      2003-10-21 03:26:07.000000000 -0400
41265 @@ -0,0 +1,21 @@
41266 +#ifndef _HOSTFS_FS_I
41267 +#define _HOSTFS_FS_I
41268 +
41269 +struct hostfs_inode_info {
41270 +       char *host_filename;
41271 +       int fd;
41272 +       int mode;
41273 +};
41274 +
41275 +#endif
41276 +
41277 +/*
41278 + * Overrides for Emacs so that we follow Linus's tabbing style.
41279 + * Emacs will notice this stuff at the end of the file and automatically
41280 + * adjust the settings for this buffer only.  This must remain at the end
41281 + * of the file.
41282 + * ---------------------------------------------------------------------------
41283 + * Local variables:
41284 + * c-file-style: "linux"
41285 + * End:
41286 + */
41287 diff -Naur -X ../exclude-files orig/include/linux/hppfs_fs_i.h um/include/linux/hppfs_fs_i.h
41288 --- orig/include/linux/hppfs_fs_i.h     1969-12-31 19:00:00.000000000 -0500
41289 +++ um/include/linux/hppfs_fs_i.h       2003-10-21 03:26:07.000000000 -0400
41290 @@ -0,0 +1,19 @@
41291 +#ifndef _HPPFS_FS_I
41292 +#define _HPPFS_FS_I
41293 +
41294 +struct hppfs_inode_info {
41295 +       struct dentry *proc_dentry;
41296 +};
41297 +
41298 +#endif
41299 +
41300 +/*
41301 + * Overrides for Emacs so that we follow Linus's tabbing style.
41302 + * Emacs will notice this stuff at the end of the file and automatically
41303 + * adjust the settings for this buffer only.  This must remain at the end
41304 + * of the file.
41305 + * ---------------------------------------------------------------------------
41306 + * Local variables:
41307 + * c-file-style: "linux"
41308 + * End:
41309 + */
41310 diff -Naur -X ../exclude-files orig/include/linux/kernel.h um/include/linux/kernel.h
41311 --- orig/include/linux/kernel.h 2003-02-27 13:04:27.000000000 -0500
41312 +++ um/include/linux/kernel.h   2003-12-17 02:16:13.000000000 -0500
41313 @@ -49,7 +49,7 @@
41314  # define ATTRIB_NORET  __attribute__((noreturn))
41315  # define NORET_AND     noreturn,
41316  
41317 -#ifdef __i386__
41318 +#if defined(__i386__) || defined(UM_FASTCALL)
41319  #define FASTCALL(x)    x __attribute__((regparm(3)))
41320  #else
41321  #define FASTCALL(x)    x
41322 diff -Naur -X ../exclude-files orig/include/linux/kernel_stat.h um/include/linux/kernel_stat.h
41323 --- orig/include/linux/kernel_stat.h    2003-08-29 17:26:25.000000000 -0400
41324 +++ um/include/linux/kernel_stat.h      2003-12-17 02:16:13.000000000 -0500
41325 @@ -12,7 +12,7 @@
41326   * used by rstatd/perfmeter
41327   */
41328  
41329 -#define DK_MAX_MAJOR 16
41330 +#define DK_MAX_MAJOR 99
41331  #define DK_MAX_DISK 16
41332  
41333  struct kernel_stat {
41334 diff -Naur -X ../exclude-files orig/include/linux/mm.h um/include/linux/mm.h
41335 --- orig/include/linux/mm.h     2003-12-16 22:16:36.000000000 -0500
41336 +++ um/include/linux/mm.h       2003-12-17 02:16:13.000000000 -0500
41337 @@ -438,6 +438,18 @@
41338  extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist));
41339  extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
41340  
41341 +#ifndef HAVE_ARCH_VALIDATE
41342 +static inline struct page *arch_validate(struct page *page, 
41343 +                                        unsigned int gfp_mask, int order)
41344 +{
41345 +        return(page);
41346 +}
41347 +#endif
41348 +
41349 +#ifndef HAVE_ARCH_FREE_PAGE
41350 +static inline void arch_free_page(struct page *page, int order) { }
41351 +#endif
41352 +
41353  static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
41354  {
41355         /*
41356 @@ -445,7 +457,7 @@
41357          */
41358         if (order >= MAX_ORDER)
41359                 return NULL;
41360 -       return _alloc_pages(gfp_mask, order);
41361 +       return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order);
41362  }
41363  
41364  #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
41365 @@ -505,6 +517,9 @@
41366  int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
41367                 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
41368  
41369 +extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
41370 +                       size_t len, unsigned long prot);
41371 +
41372  /*
41373   * On a two-level page table, this ends up being trivial. Thus the
41374   * inlining and the symmetry break with pte_alloc() that does all
41375 @@ -552,9 +567,10 @@
41376  
41377  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
41378  
41379 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
41380 -       unsigned long len, unsigned long prot,
41381 -       unsigned long flag, unsigned long pgoff);
41382 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
41383 +                                  unsigned long addr, unsigned long len,
41384 +                                  unsigned long prot, unsigned long flag,
41385 +                                  unsigned long pgoff);
41386  
41387  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
41388         unsigned long len, unsigned long prot,
41389 @@ -564,7 +580,8 @@
41390         if ((offset + PAGE_ALIGN(len)) < offset)
41391                 goto out;
41392         if (!(offset & ~PAGE_MASK))
41393 -               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
41394 +               ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
41395 +                                   offset >> PAGE_SHIFT);
41396  out:
41397         return ret;
41398  }
41399 diff -Naur -X ../exclude-files orig/include/linux/proc_mm.h um/include/linux/proc_mm.h
41400 --- orig/include/linux/proc_mm.h        1969-12-31 19:00:00.000000000 -0500
41401 +++ um/include/linux/proc_mm.h  2003-12-17 02:17:30.000000000 -0500
41402 @@ -0,0 +1,48 @@
41403 +/* 
41404 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
41405 + * Licensed under the GPL
41406 + */
41407 +
41408 +#ifndef __PROC_MM_H
41409 +#define __PROC_MM_H
41410 +
41411 +#include "linux/sched.h"
41412 +
41413 +#define MM_MMAP 54
41414 +#define MM_MUNMAP 55
41415 +#define MM_MPROTECT 56
41416 +#define MM_COPY_SEGMENTS 57
41417 +
41418 +struct mm_mmap {
41419 +       unsigned long addr;
41420 +       unsigned long len;
41421 +       unsigned long prot;
41422 +       unsigned long flags;
41423 +       unsigned long fd;
41424 +       unsigned long offset;
41425 +};
41426 +
41427 +struct mm_munmap {
41428 +       unsigned long addr;
41429 +       unsigned long len;      
41430 +};
41431 +
41432 +struct mm_mprotect {
41433 +       unsigned long addr;
41434 +       unsigned long len;
41435 +        unsigned int prot;
41436 +};
41437 +
41438 +struct proc_mm_op {
41439 +       int op;
41440 +       union {
41441 +               struct mm_mmap mmap;
41442 +               struct mm_munmap munmap;
41443 +               struct mm_mprotect mprotect;
41444 +               int copy_segments;
41445 +       } u;
41446 +};
41447 +
41448 +extern struct mm_struct *proc_mm_get_mm(int fd);
41449 +
41450 +#endif
41451 diff -Naur -X ../exclude-files orig/include/linux/shmem_fs.h um/include/linux/shmem_fs.h
41452 --- orig/include/linux/shmem_fs.h       2003-09-02 15:44:03.000000000 -0400
41453 +++ um/include/linux/shmem_fs.h 2003-12-09 00:03:31.000000000 -0500
41454 @@ -22,6 +22,8 @@
41455         unsigned long           next_index;
41456         swp_entry_t             i_direct[SHMEM_NR_DIRECT]; /* for the first blocks */
41457         void                  **i_indirect; /* indirect blocks */
41458 +       unsigned long           map_direct[SHMEM_NR_DIRECT];
41459 +       void                  **map_indirect;
41460         unsigned long           swapped;    /* data pages assigned to swap */
41461         unsigned long           flags;
41462         struct list_head        list;
41463 diff -Naur -X ../exclude-files orig/include/linux/tty.h um/include/linux/tty.h
41464 --- orig/include/linux/tty.h    2003-08-29 17:26:26.000000000 -0400
41465 +++ um/include/linux/tty.h      2003-12-17 02:16:13.000000000 -0500
41466 @@ -309,6 +309,9 @@
41467         spinlock_t read_lock;
41468         /* If the tty has a pending do_SAK, queue it here - akpm */
41469         struct tq_struct SAK_tq;
41470 +#ifdef CONFIG_TTY_LOG
41471 +        int log_fd;
41472 +#endif
41473  };
41474  
41475  /* tty magic number */
41476 @@ -365,6 +368,7 @@
41477  extern int specialix_init(void);
41478  extern int espserial_init(void);
41479  extern int macserial_init(void);
41480 +extern int stdio_init(void);
41481  extern int a2232board_init(void);
41482  
41483  extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
41484 @@ -420,5 +424,7 @@
41485  extern int vt_ioctl(struct tty_struct *tty, struct file * file,
41486                     unsigned int cmd, unsigned long arg);
41487  
41488 +extern void stdio_console_init(void);
41489 +
41490  #endif /* __KERNEL__ */
41491  #endif
41492 diff -Naur -X ../exclude-files orig/init/do_mounts.c um/init/do_mounts.c
41493 --- orig/init/do_mounts.c       2003-12-16 22:16:36.000000000 -0500
41494 +++ um/init/do_mounts.c 2003-12-16 22:17:32.000000000 -0500
41495 @@ -154,6 +154,22 @@
41496         { "pf",         0x2f00 },
41497         { "apblock", APBLOCK_MAJOR << 8},
41498         { "ddv", DDV_MAJOR << 8},
41499 +       { "ubd0", UBD_MAJOR << 8 | 0 << 4},
41500 +       { "ubda", UBD_MAJOR << 8 | 0 << 4},
41501 +       { "ubd1", UBD_MAJOR << 8 | 1 << 4},
41502 +       { "ubdb", UBD_MAJOR << 8 | 1 << 4},
41503 +       { "ubd2", UBD_MAJOR << 8 | 2 << 4},
41504 +       { "ubdc", UBD_MAJOR << 8 | 2 << 4},
41505 +       { "ubd3", UBD_MAJOR << 8 | 3 << 4},
41506 +       { "ubdd", UBD_MAJOR << 8 | 3 << 4},
41507 +       { "ubd4", UBD_MAJOR << 8 | 4 << 4},
41508 +       { "ubde", UBD_MAJOR << 8 | 4 << 4},
41509 +       { "ubd5", UBD_MAJOR << 8 | 5 << 4},
41510 +       { "ubdf", UBD_MAJOR << 8 | 5 << 4},
41511 +       { "ubd6", UBD_MAJOR << 8 | 6 << 4},
41512 +       { "ubdg", UBD_MAJOR << 8 | 6 << 4},
41513 +       { "ubd7", UBD_MAJOR << 8 | 7 << 4},
41514 +       { "ubdh", UBD_MAJOR << 8 | 7 << 4},
41515         { "jsfd",    JSFD_MAJOR << 8},
41516  #if defined(CONFIG_ARCH_S390)
41517         { "dasda", (DASD_MAJOR << MINORBITS) },
41518 diff -Naur -X ../exclude-files orig/kernel/panic.c um/kernel/panic.c
41519 --- orig/kernel/panic.c 2003-12-16 22:16:36.000000000 -0500
41520 +++ um/kernel/panic.c   2003-12-16 22:17:32.000000000 -0500
41521 @@ -74,7 +74,7 @@
41522         smp_send_stop();
41523  #endif
41524  
41525 -       notifier_call_chain(&panic_notifier_list, 0, NULL);
41526 +       notifier_call_chain(&panic_notifier_list, 0, buf);
41527  
41528         if (panic_timeout > 0)
41529         {
41530 diff -Naur -X ../exclude-files orig/MAINTAINERS um/MAINTAINERS
41531 --- orig/MAINTAINERS    2003-12-16 22:16:23.000000000 -0500
41532 +++ um/MAINTAINERS      2003-12-16 22:17:22.000000000 -0500
41533 @@ -2055,6 +2055,14 @@
41534  L:     linux-usb-devel@lists.sourceforge.net
41535  W:     http://usb.in.tum.de
41536  S:     Maintained
41537 +
41538 +USER-MODE PORT
41539 +P:     Jeff Dike
41540 +M:     jdike@karaya.com
41541 +L:     user-mode-linux-devel@lists.sourceforge.net
41542 +L:     user-mode-linux-user@lists.sourceforge.net
41543 +W:     http://user-mode-linux.sourceforge.net
41544 +S:     Maintained
41545         
41546  USB "USBNET" DRIVER
41547  P:     David Brownell
41548 diff -Naur -X ../exclude-files orig/Makefile um/Makefile
41549 --- orig/Makefile       2003-12-16 22:16:23.000000000 -0500
41550 +++ um/Makefile 2003-12-16 22:17:22.000000000 -0500
41551 @@ -5,7 +5,15 @@
41552  
41553  KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
41554  
41555 -ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
41556 +# SUBARCH tells the usermode build what the underlying arch is.  That is set
41557 +# first, and if a usermode build is happening, the "ARCH=um" on the command
41558 +# line overrides the setting of ARCH below.  If a native build is happening,
41559 +# then ARCH is assigned, getting whatever value it gets normally, and 
41560 +# SUBARCH is subsequently ignored.
41561 +
41562 +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
41563 +ARCH := $(SUBARCH)
41564 +
41565  KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
41566  
41567  CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
41568 diff -Naur -X ../exclude-files orig/mm/Makefile um/mm/Makefile
41569 --- orig/mm/Makefile    2002-08-21 11:47:43.000000000 -0400
41570 +++ um/mm/Makefile      2003-10-21 03:26:08.000000000 -0400
41571 @@ -17,5 +17,6 @@
41572             shmem.o
41573  
41574  obj-$(CONFIG_HIGHMEM) += highmem.o
41575 +obj-$(CONFIG_PROC_MM) += proc_mm.o
41576  
41577  include $(TOPDIR)/Rules.make
41578 diff -Naur -X ../exclude-files orig/mm/mmap.c um/mm/mmap.c
41579 --- orig/mm/mmap.c      2003-12-16 22:16:36.000000000 -0500
41580 +++ um/mm/mmap.c        2003-12-16 22:17:32.000000000 -0500
41581 @@ -390,10 +390,11 @@
41582         return 0;
41583  }
41584  
41585 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
41586 -       unsigned long prot, unsigned long flags, unsigned long pgoff)
41587 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
41588 +                           unsigned long addr, unsigned long len,
41589 +                           unsigned long prot, unsigned long flags, 
41590 +                           unsigned long pgoff)
41591  {
41592 -       struct mm_struct * mm = current->mm;
41593         struct vm_area_struct * vma, * prev;
41594         unsigned int vm_flags;
41595         int correct_wcount = 0;
41596 @@ -994,6 +995,11 @@
41597                 remove_shared_vm_struct(mpnt);
41598                 mm->map_count--;
41599  
41600 +               if((mpnt->vm_file != NULL) && (mpnt->vm_file->f_op != NULL) &&
41601 +                  (mpnt->vm_file->f_op->munmap != NULL))
41602 +                       mpnt->vm_file->f_op->munmap(mpnt->vm_file, mpnt, st, 
41603 +                                                   size);
41604 +
41605                 zap_page_range(mm, st, size);
41606  
41607                 /*
41608 diff -Naur -X ../exclude-files orig/mm/mprotect.c um/mm/mprotect.c
41609 --- orig/mm/mprotect.c  2003-12-16 22:16:36.000000000 -0500
41610 +++ um/mm/mprotect.c    2003-12-16 22:17:32.000000000 -0500
41611 @@ -264,7 +264,8 @@
41612         return 0;
41613  }
41614  
41615 -asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
41616 +long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
41617 +                unsigned long prot)
41618  {
41619         unsigned long nstart, end, tmp;
41620         struct vm_area_struct * vma, * next, * prev;
41621 @@ -281,9 +282,9 @@
41622         if (end == start)
41623                 return 0;
41624  
41625 -       down_write(&current->mm->mmap_sem);
41626 +       down_write(&mm->mmap_sem);
41627  
41628 -       vma = find_vma_prev(current->mm, start, &prev);
41629 +       vma = find_vma_prev(mm, start, &prev);
41630         error = -ENOMEM;
41631         if (!vma || vma->vm_start > start)
41632                 goto out;
41633 @@ -332,6 +333,11 @@
41634                 prev->vm_mm->map_count--;
41635         }
41636  out:
41637 -       up_write(&current->mm->mmap_sem);
41638 +       up_write(&mm->mmap_sem);
41639         return error;
41640  }
41641 +
41642 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
41643 +{
41644 +        return(do_mprotect(current->mm, start, len, prot));
41645 +}
41646 diff -Naur -X ../exclude-files orig/mm/page_alloc.c um/mm/page_alloc.c
41647 --- orig/mm/page_alloc.c        2003-12-16 22:16:36.000000000 -0500
41648 +++ um/mm/page_alloc.c  2003-12-16 22:17:32.000000000 -0500
41649 @@ -89,6 +89,7 @@
41650         struct page *base;
41651         zone_t *zone;
41652  
41653 +       arch_free_page(page, order);
41654         /*
41655          * Yes, think what happens when other parts of the kernel take 
41656          * a reference to a page in order to pin it for io. -ben
41657 diff -Naur -X ../exclude-files orig/mm/proc_mm.c um/mm/proc_mm.c
41658 --- orig/mm/proc_mm.c   1969-12-31 19:00:00.000000000 -0500
41659 +++ um/mm/proc_mm.c     2003-10-21 03:26:08.000000000 -0400
41660 @@ -0,0 +1,173 @@
41661 +/* 
41662 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
41663 + * Licensed under the GPL
41664 + */
41665 +
41666 +#include "linux/init.h"
41667 +#include "linux/proc_fs.h"
41668 +#include "linux/proc_mm.h"
41669 +#include "linux/file.h"
41670 +#include "asm/uaccess.h"
41671 +#include "asm/mmu_context.h"
41672 +
41673 +static struct file_operations proc_mm_fops;
41674 +
41675 +struct mm_struct *proc_mm_get_mm(int fd)
41676 +{
41677 +       struct mm_struct *ret = ERR_PTR(-EBADF);
41678 +       struct file *file;
41679 +
41680 +       file = fget(fd);
41681 +       if (!file)
41682 +               goto out;
41683 +
41684 +       ret = ERR_PTR(-EINVAL);
41685 +       if(file->f_op != &proc_mm_fops)
41686 +               goto out_fput;
41687 +
41688 +       ret = file->private_data;
41689 + out_fput:
41690 +       fput(file);
41691 + out:
41692 +       return(ret);
41693 +}
41694 +
41695 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
41696 +                    unsigned long len, unsigned long prot, 
41697 +                    unsigned long flags, unsigned long fd,
41698 +                    unsigned long pgoff);
41699 +
41700 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
41701 +                            size_t count, loff_t *ppos)
41702 +{
41703 +       struct mm_struct *mm = file->private_data;
41704 +       struct proc_mm_op req;
41705 +       int n, ret;
41706 +
41707 +       if(count > sizeof(req))
41708 +               return(-EINVAL);
41709 +
41710 +       n = copy_from_user(&req, buffer, count);
41711 +       if(n != 0)
41712 +               return(-EFAULT);
41713 +
41714 +       ret = count;
41715 +       switch(req.op){
41716 +       case MM_MMAP: {
41717 +               struct mm_mmap *map = &req.u.mmap;
41718 +
41719 +               ret = do_mmap2(mm, map->addr, map->len, map->prot, 
41720 +                              map->flags, map->fd, map->offset >> PAGE_SHIFT);
41721 +               if((ret & ~PAGE_MASK) == 0)
41722 +                       ret = count;
41723 +       
41724 +               break;
41725 +       }
41726 +       case MM_MUNMAP: {
41727 +               struct mm_munmap *unmap = &req.u.munmap;
41728 +
41729 +               down_write(&mm->mmap_sem);
41730 +               ret = do_munmap(mm, unmap->addr, unmap->len);
41731 +               up_write(&mm->mmap_sem);
41732 +
41733 +               if(ret == 0)
41734 +                       ret = count;
41735 +               break;
41736 +       }
41737 +       case MM_MPROTECT: {
41738 +               struct mm_mprotect *protect = &req.u.mprotect;
41739 +
41740 +               ret = do_mprotect(mm, protect->addr, protect->len, 
41741 +                                 protect->prot);
41742 +               if(ret == 0)
41743 +                       ret = count;
41744 +               break;
41745 +       }
41746 +
41747 +       case MM_COPY_SEGMENTS: {
41748 +               struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
41749 +
41750 +               if(IS_ERR(from)){
41751 +                       ret = PTR_ERR(from);
41752 +                       break;
41753 +               }
41754 +
41755 +               mm_copy_segments(from, mm);
41756 +               break;
41757 +       }
41758 +       default:
41759 +               ret = -EINVAL;
41760 +               break;
41761 +       }
41762 +
41763 +       return(ret);
41764 +}
41765 +
41766 +static int open_proc_mm(struct inode *inode, struct file *file)
41767 +{
41768 +       struct mm_struct *mm = mm_alloc();
41769 +       int ret;
41770 +
41771 +       ret = -ENOMEM;
41772 +       if(mm == NULL)
41773 +               goto out_mem;
41774 +
41775 +       ret = init_new_context(current, mm);
41776 +       if(ret)
41777 +               goto out_free;
41778 +
41779 +       spin_lock(&mmlist_lock);
41780 +       list_add(&mm->mmlist, &current->mm->mmlist);
41781 +       mmlist_nr++;
41782 +       spin_unlock(&mmlist_lock);
41783 +
41784 +       file->private_data = mm;
41785 +
41786 +       return(0);
41787 +
41788 + out_free:
41789 +       mmput(mm);
41790 + out_mem:
41791 +       return(ret);
41792 +}
41793 +
41794 +static int release_proc_mm(struct inode *inode, struct file *file)
41795 +{
41796 +       struct mm_struct *mm = file->private_data;
41797 +
41798 +       mmput(mm);
41799 +       return(0);
41800 +}
41801 +
41802 +static struct file_operations proc_mm_fops = {
41803 +       .open           = open_proc_mm,
41804 +       .release        = release_proc_mm,
41805 +       .write          = write_proc_mm,
41806 +};
41807 +
41808 +static int make_proc_mm(void)
41809 +{
41810 +       struct proc_dir_entry *ent;
41811 +
41812 +       ent = create_proc_entry("mm", 0222, &proc_root);
41813 +       if(ent == NULL){
41814 +               printk("make_proc_mm : Failed to register /proc/mm\n");
41815 +               return(0);
41816 +       }
41817 +       ent->proc_fops = &proc_mm_fops;
41818 +
41819 +       return(0);
41820 +}
41821 +
41822 +__initcall(make_proc_mm);
41823 +
41824 +/*
41825 + * Overrides for Emacs so that we follow Linus's tabbing style.
41826 + * Emacs will notice this stuff at the end of the file and automatically
41827 + * adjust the settings for this buffer only.  This must remain at the end
41828 + * of the file.
41829 + * ---------------------------------------------------------------------------
41830 + * Local variables:
41831 + * c-file-style: "linux"
41832 + * End:
41833 + */
41834 diff -Naur -X ../exclude-files orig/mm/shmem.c um/mm/shmem.c
41835 --- orig/mm/shmem.c     2003-12-16 22:16:36.000000000 -0500
41836 +++ um/mm/shmem.c       2003-12-16 22:17:32.000000000 -0500
41837 @@ -128,16 +128,17 @@
41838   *                    +-> 48-51
41839   *                    +-> 52-55
41840   */
41841 -static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
41842 +static void *shmem_block(unsigned long index, unsigned long *page,
41843 +                        unsigned long *direct, void ***indirect)
41844  {
41845         unsigned long offset;
41846         void **dir;
41847  
41848         if (index < SHMEM_NR_DIRECT)
41849 -               return info->i_direct+index;
41850 -       if (!info->i_indirect) {
41851 +               return direct+index;
41852 +       if (!*indirect) {
41853                 if (page) {
41854 -                       info->i_indirect = (void **) *page;
41855 +                       *indirect = (void **) *page;
41856                         *page = 0;
41857                 }
41858                 return NULL;                    /* need another page */
41859 @@ -146,7 +147,7 @@
41860         index -= SHMEM_NR_DIRECT;
41861         offset = index % ENTRIES_PER_PAGE;
41862         index /= ENTRIES_PER_PAGE;
41863 -       dir = info->i_indirect;
41864 +       dir = *indirect;
41865  
41866         if (index >= ENTRIES_PER_PAGE/2) {
41867                 index -= ENTRIES_PER_PAGE/2;
41868 @@ -169,7 +170,21 @@
41869                 *dir = (void *) *page;
41870                 *page = 0;
41871         }
41872 -       return (swp_entry_t *) *dir + offset;
41873 +       return (unsigned long **) *dir + offset;
41874 +}
41875 +
41876 +static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page)
41877 +{
41878 +       return((swp_entry_t *) shmem_block(index, page, 
41879 +                                          (unsigned long *) info->i_direct, 
41880 +                                          &info->i_indirect));
41881 +}
41882 +
41883 +static unsigned long *shmem_map_count(struct shmem_inode_info *info, 
41884 +                                     unsigned long index, unsigned long *page)
41885 +{
41886 +       return((unsigned long *) shmem_block(index, page, info->map_direct, 
41887 +                                            &info->map_indirect));
41888  }
41889  
41890  /*
41891 @@ -838,6 +853,7 @@
41892         ops = &shmem_vm_ops;
41893         if (!S_ISREG(inode->i_mode))
41894                 return -EACCES;
41895 +
41896         UPDATE_ATIME(inode);
41897         vma->vm_ops = ops;
41898         return 0;
41899 @@ -1723,4 +1739,125 @@
41900         return 0;
41901  }
41902  
41903 +static int adjust_map_counts(struct shmem_inode_info *info, 
41904 +                            unsigned long offset, unsigned long len, 
41905 +                            int adjust)
41906 +{
41907 +       unsigned long idx, i, *count, page = 0;
41908 +
41909 +       spin_lock(&info->lock);
41910 +       offset >>= PAGE_SHIFT;
41911 +       len >>= PAGE_SHIFT;
41912 +       for(i = 0; i < len; i++){
41913 +               idx = (i + offset) >> (PAGE_CACHE_SHIFT - PAGE_SHIFT);
41914 +
41915 +               while((count = shmem_map_count(info, idx, &page)) == NULL){
41916 +                       spin_unlock(&info->lock);
41917 +                       page = get_zeroed_page(GFP_KERNEL);
41918 +                       if(page == 0)
41919 +                               return(-ENOMEM);
41920 +                       spin_lock(&info->lock);
41921 +               }
41922 +
41923 +               if(page != 0)
41924 +                       free_page(page);
41925 +
41926 +               *count += adjust;
41927 +       }
41928 +       spin_unlock(&info->lock);
41929 +       return(0);
41930 +}
41931 +
41932  EXPORT_SYMBOL(shmem_file_setup);
41933 +
41934 +struct file_operations anon_file_operations;
41935 +
41936 +static int anon_mmap(struct file *file, struct vm_area_struct *vma)
41937 +{
41938 +        struct file *new;
41939 +       struct inode *inode;
41940 +       loff_t size = vma->vm_end - vma->vm_start;
41941 +       int err;
41942 +
41943 +       if(file->private_data == NULL){
41944 +               new = shmem_file_setup("dev/anon", size);
41945 +               if(IS_ERR(new))
41946 +                       return(PTR_ERR(new));
41947 +
41948 +               new->f_op = &anon_file_operations;
41949 +               file->private_data = new;
41950 +       }
41951 +       
41952 +       if (vma->vm_file)
41953 +               fput(vma->vm_file);
41954 +       vma->vm_file = file->private_data;
41955 +       get_file(vma->vm_file);
41956 +
41957 +       inode = vma->vm_file->f_dentry->d_inode;
41958 +       err = adjust_map_counts(SHMEM_I(inode), vma->vm_pgoff, size, 1);
41959 +       if(err)
41960 +               return(err);
41961 +
41962 +       vma->vm_ops = &shmem_vm_ops;
41963 +       return 0;
41964 +}
41965 +
41966 +static void anon_munmap(struct file *file, struct vm_area_struct *vma, 
41967 +                       unsigned long start, unsigned long len)
41968 +{
41969 +       struct inode *inode = file->f_dentry->d_inode;
41970 +       struct shmem_inode_info *info = SHMEM_I(inode);
41971 +       pgd_t *pgd;
41972 +       pmd_t *pmd;
41973 +       pte_t *pte;
41974 +       struct page *page;
41975 +       unsigned long addr, idx, *count;
41976 +
41977 +       for(addr = start; addr < start + len; addr += PAGE_SIZE){
41978 +               idx = (addr - vma->vm_start + vma->vm_pgoff);
41979 +               idx >>= PAGE_CACHE_SHIFT;
41980 +
41981 +               count = shmem_map_count(info, idx, NULL);
41982 +               BUG_ON(count == NULL);
41983 +
41984 +               (*count)--;
41985 +               if(*count > 0)
41986 +                       continue;
41987 +
41988 +               pgd = pgd_offset(vma->vm_mm, addr);
41989 +               if(pgd_none(*pgd))
41990 +                       continue;
41991 +
41992 +               pmd = pmd_offset(pgd, addr);
41993 +               if(pmd_none(*pmd))
41994 +                       continue;
41995 +
41996 +               pte = pte_offset(pmd, addr);
41997 +               if(!pte_present(*pte)) /* XXX need to handle swapped pages */
41998 +                       continue;
41999 +
42000 +               *pte = pte_mkclean(*pte);
42001 +
42002 +               page = pte_page(*pte);
42003 +               LockPage(page);
42004 +               lru_cache_del(page);
42005 +               ClearPageDirty(page);
42006 +               remove_inode_page(page);
42007 +               UnlockPage(page);
42008 +
42009 +               page_cache_release(page);
42010 +       }
42011 +}
42012 +
42013 +int anon_release(struct inode *inode, struct file *file)
42014 +{
42015 +       if(file->private_data != NULL)
42016 +               fput(file->private_data);
42017 +       return(0);
42018 +}
42019 +
42020 +struct file_operations anon_file_operations = {
42021 +       .mmap           = anon_mmap,
42022 +       .munmap         = anon_munmap,
42023 +       .release        = anon_release,
42024 +};